From 47febfc6278e6eebf15f2940e5bac0c77c0034b5 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 16 Apr 2022 22:02:39 +0200 Subject: [PATCH 001/389] fix travis release for tagged commits; use jdk 17 instead of 11 for github releases --- .github/workflows/push-packages.yml | 2 +- .travis.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/push-packages.yml b/.github/workflows/push-packages.yml index 2f8ff1d8df6..5e57dfea31a 100644 --- a/.github/workflows/push-packages.yml +++ b/.github/workflows/push-packages.yml @@ -7,7 +7,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v2 with: - java-version: 11 + java-version: 17 distribution: temurin - name: Cache Maven artifacts uses: actions/cache@v2 diff --git a/.travis.yml b/.travis.yml index 998fc152d1f..993fbc97b97 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ env: matrix: include: - - env: JDK='8/ga' # for backward compatibility + - env: JDK='8/ga' # for backward compatibility and release - env: JDK='17/ga'# latest LTS - env: JDK='18/ga'# latest - env: JDK='19/ea'# latest early access @@ -44,11 +44,11 @@ after_success: mvn checkstyle:check forbiddenapis:check; fi # if tagged deploy then release to maven central or deploy snapshot artifacts to sonatype - - if [ "$TRAVIS_JDK_VERSION" == "openjdk8" ] && [ "$TRAVIS_TAG" != "" ]; then + - if [ "$JDK" == "8/ga" ] && [ "$TRAVIS_TAG" != "" ]; then echo "release to maven central"; mvn versions:set -DnewVersion=$TRAVIS_TAG -DgenerateBackupPoms=false; mvn deploy -P release --settings core/files/settings.xml -DskipTests=true -B; - elif [ "$TRAVIS_JDK_VERSION" == "openjdk8" ] && [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then + elif [ "$JDK" == "8/ga" ] && [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then mvn deploy --settings core/files/settings.xml -DskipTests=true -B; else echo "Not deploying artifacts for $TRAVIS_BRANCH"; From fce4f9092cd64e300f5c7de5b776fa1e153db4eb Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 28 Apr 2022 12:44:00 +0200 Subject: [PATCH 002/389] allow skipping the LM constraint check for A* (#2544) * LM constraint should be ignored for A* * make it possible to skip checkLMConstraints call * move checkLMConstraints call to LMSolver. Fix createSolver for mixed preparations * avoid fundamental default change but throw proper exception when lm.disable parameter missing --- .../routing/DefaultWeightingFactory.java | 3 -- .../java/com/graphhopper/routing/Router.java | 3 ++ .../java/com/graphhopper/GraphHopperTest.java | 48 ++++++++++++++++++- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java index f53d9642bbb..79383b31e37 100644 --- a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java +++ b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java @@ -75,9 +75,6 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis throw new IllegalArgumentException("custom weighting requires a CustomProfile but was profile=" + profile.getName()); CustomModel queryCustomModel = requestHints.getObject(CustomModel.KEY, null); CustomProfile customProfile = (CustomProfile) profile; - if (queryCustomModel != null) - queryCustomModel.checkLMConstraints(customProfile.getCustomModel()); - queryCustomModel = CustomModel.merge(customProfile.getCustomModel(), queryCustomModel); weighting = CustomModelParser.createWeighting(encoder, encodingManager, turnCostProvider, queryCustomModel); } else if ("shortest".equalsIgnoreCase(weightingStr)) { diff --git a/core/src/main/java/com/graphhopper/routing/Router.java b/core/src/main/java/com/graphhopper/routing/Router.java index 3851ebba60d..c82571760fc 100644 --- a/core/src/main/java/com/graphhopper/routing/Router.java +++ b/core/src/main/java/com/graphhopper/routing/Router.java @@ -561,6 +561,9 @@ protected FlexiblePathCalculator createPathCalculator(QueryGraph queryGraph) { throw new IllegalArgumentException("Cannot find LM preparation for the requested profile: '" + profile.getName() + "'" + "\nYou can try disabling LM using " + Parameters.Landmark.DISABLE + "=true" + "\navailable LM profiles: " + landmarks.keySet()); + if (profile instanceof CustomProfile && request.getCustomModel() != null + && !request.getHints().getBool("lm.disable", false)) + request.getCustomModel().checkLMConstraints(((CustomProfile) profile).getCustomModel()); RoutingAlgorithmFactory routingAlgorithmFactory = new LMRoutingAlgorithmFactory(landmarkStorage).setDefaultActiveLandmarks(routerConfig.getActiveLandmarkCount()); return new FlexiblePathCalculator(queryGraph, routingAlgorithmFactory, weighting, getAlgoOpts()); } diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index e1e8319319c..4e15b7c181e 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -1554,7 +1554,6 @@ public void testCrossQuery() { final String profile1 = "p1"; final String profile2 = "p2"; final String profile3 = "p3"; - final String vehicle = "car"; GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile(MONACO). @@ -1598,6 +1597,53 @@ private void testCrossQueryAssert(String profile, GraphHopper hopper, double exp assertEquals(expectedVisitedNodes, visitedNodes); } + @Test + public void testLMConstraintsForCustomProfiles() { + GraphHopper hopper = new GraphHopper(). + setGraphHopperLocation(GH_LOCATION). + setOSMFile(MONACO). + setProfiles( + new CustomProfile("p1").setCustomModel(new CustomModel().setDistanceInfluence(100)).setVehicle("car"), + new CustomProfile("p2").setCustomModel(new CustomModel().setDistanceInfluence(100)).setVehicle("car")). + setStoreOnFlush(true); + + hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("p1")); + hopper.setMinNetworkSize(0); + hopper.importOrLoad(); + + GHResponse response = hopper.route(new GHRequest(43.727687, 7.418737, 43.74958, 7.436566). + setProfile("p1").putHint("lm.disable", false)); + assertEquals(3587, response.getBest().getDistance(), 1); + + // use smaller distance influence to force violating the LM constraint + final CustomModel customModel = new CustomModel().setDistanceInfluence(0); + response = hopper.route(new GHRequest(43.727687, 7.418737, 43.74958, 7.436566). + setCustomModel(customModel). + setProfile("p1").putHint("lm.disable", false)); + assertTrue(response.hasErrors(), response.getErrors().toString()); + assertEquals(IllegalArgumentException.class, response.getErrors().get(0).getClass()); + + // but disabling LM must make it working as no LM is used + response = hopper.route(new GHRequest(43.727687, 7.418737, 43.74958, 7.436566). + setCustomModel(customModel). + setProfile("p1").putHint("lm.disable", true)); + assertFalse(response.hasErrors(), response.getErrors().toString()); + assertEquals(3587, response.getBest().getDistance(), 1); + + // currently required to disable LM for p2 too, see #1904 (default is LM for *all* profiles once LM preparation is enabled for any profile) + response = hopper.route(new GHRequest(43.727687, 7.418737, 43.74958, 7.436566). + setCustomModel(customModel). + setProfile("p2")); + assertTrue(response.getErrors().get(0).toString().contains("Cannot find LM preparation for the requested profile: 'p2'"), response.getErrors().toString()); + assertEquals(IllegalArgumentException.class, response.getErrors().get(0).getClass()); + + response = hopper.route(new GHRequest(43.727687, 7.418737, 43.74958, 7.436566). + setCustomModel(customModel). + setProfile("p2").putHint("lm.disable", true)); + assertFalse(response.hasErrors(), response.getErrors().toString()); + assertEquals(3587, response.getBest().getDistance(), 1); + } + @Test public void testCreateWeightingHintsMerging() { final String profile = "profile"; From 38c9a28bad7c4649158267e4a53fbb49e845c9e5 Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 29 Apr 2022 06:44:20 +0200 Subject: [PATCH 003/389] Add names for travis build jobs (to be shown under 'Jobs and Stages on GitHub)' --- .travis.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 993fbc97b97..96f017fa167 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,10 +11,14 @@ env: matrix: include: - - env: JDK='8/ga' # for backward compatibility and release - - env: JDK='17/ga'# latest LTS - - env: JDK='18/ga'# latest - - env: JDK='19/ea'# latest early access + - name: JDK8 + env: JDK='8/ga' # for backward compatibility and release + - name: JDK17 + env: JDK='17/ga'# latest LTS + - name: JDK18 + env: JDK='18/ga'# latest + - name: JDK19-ea + env: JDK='19/ea'# latest early access # avoid default dependency command for maven, 'true' means 'return true' and continue install: true From 291c030a397a24d677d3e1e46fd7f4d3009d8e5d Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 29 Apr 2022 08:02:06 +0200 Subject: [PATCH 004/389] Disable doclint explicitly --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 06a3e28b3ff..7756b41e132 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,10 @@ UTF-8 1.8 + + none @@ -322,6 +326,7 @@ maven-javadoc-plugin 3.1.1 + true From ed34caf4dd2648d8d550fe38d77afd8f2c406da0 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 29 Apr 2022 08:58:28 +0200 Subject: [PATCH 005/389] travis: only keep release build, related to #2552 --- .github/workflows/push-packages.yml | 37 ++++++++++++++++++++++++++++- .travis.yml | 6 ----- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/.github/workflows/push-packages.yml b/.github/workflows/push-packages.yml index 5e57dfea31a..9a9d4a2305a 100644 --- a/.github/workflows/push-packages.yml +++ b/.github/workflows/push-packages.yml @@ -30,9 +30,44 @@ jobs: key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml', '**/package.json') }} restore-keys: | ${{ runner.os}}-node_modules- - - name: Build and publish package + - name: Build and publish package ${{ matrix.java-version }} run: | mvn -B versions:set -DnewVersion=$GITHUB_SHA -DgenerateBackupPoms=false mvn -B -DskipTests -Pskip-shaded-web-jar -Pskip-tools-jar source:jar deploy env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + build-only: + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + java-version: [ 18 ] + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java-version }} + distribution: temurin + - name: Cache Maven artifacts + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Cache node + uses: actions/cache@v2 + with: + path: web-bundle/node + key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os}}-node- + - name: Cache node_modules + uses: actions/cache@v2 + with: + path: web-bundle/node_modules + key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml', '**/package.json') }} + restore-keys: | + ${{ runner.os}}-node_modules- + - name: Build ${{ matrix.java-version }} + run: mvn -B clean test diff --git a/.travis.yml b/.travis.yml index 96f017fa167..1d8e813a087 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,12 +13,6 @@ matrix: include: - name: JDK8 env: JDK='8/ga' # for backward compatibility and release - - name: JDK17 - env: JDK='17/ga'# latest LTS - - name: JDK18 - env: JDK='18/ga'# latest - - name: JDK19-ea - env: JDK='19/ea'# latest early access # avoid default dependency command for maven, 'true' means 'return true' and continue install: true From 2ae83d0a00c2a193a151bd6ce23d82bda0491e3b Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 29 Apr 2022 20:34:03 +0200 Subject: [PATCH 006/389] Clean up javadoc comments (#2569) * fix javadoc errors * remove javadoc plugin * make comment more readable * include javadoc again, revert unreadable comments * disable doclint for javadoc --- .../main/java/com/graphhopper/reader/dem/SRTMGL1Provider.java | 2 +- core/src/main/java/com/graphhopper/routing/ch/CHEntry.java | 2 +- .../main/java/com/graphhopper/routing/lm/LandmarkStorage.java | 2 +- .../java/com/graphhopper/routing/querygraph/QueryGraph.java | 2 +- .../graphhopper/routing/util/parsers/OSMMtbRatingParser.java | 2 +- .../routing/weighting/BalancedWeightApproximator.java | 2 +- core/src/main/java/com/graphhopper/storage/BaseGraph.java | 2 +- .../main/java/com/graphhopper/storage/CHStorageBuilder.java | 4 ++-- .../src/main/java/com/graphhopper/storage/RoutingCHGraph.java | 2 +- core/src/main/java/com/graphhopper/util/Constants.java | 4 ++-- core/src/main/java/com/graphhopper/util/DouglasPeucker.java | 2 +- pom.xml | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/dem/SRTMGL1Provider.java b/core/src/main/java/com/graphhopper/reader/dem/SRTMGL1Provider.java index e448c1ffa6e..091227b181b 100644 --- a/core/src/main/java/com/graphhopper/reader/dem/SRTMGL1Provider.java +++ b/core/src/main/java/com/graphhopper/reader/dem/SRTMGL1Provider.java @@ -31,7 +31,7 @@ *

* When using this data we have to acknowledge: * This material is based on data services provided by the OpenTopography Facility with support from the - * National Science Foundation under NSF Award Numbers 1226353 & 1225810 + * National Science Foundation under NSF Award Numbers 1226353 & 1225810 * National Geospatial-Intelligence Agency (NGA) and the National Aeronautics and Space Administration (NASA), 2013, * SRTMGL1: NASA Shuttle Radar Topography Mission Global 1 arc second V003. [Version]. NASA EOSDIS Land Processes DAAC, * USGS Earth Resources Observation and Science (EROS) Center, Sioux Falls, South Dakota (https://lpdaac.usgs.gov), diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHEntry.java b/core/src/main/java/com/graphhopper/routing/ch/CHEntry.java index 8abf3dea061..4685fd6a200 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHEntry.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHEntry.java @@ -26,7 +26,7 @@ public class CHEntry extends SPTEntry { * The id of the incoming original edge at this shortest path tree entry. For original edges this is the same * as the edge id, but for shortcuts this is the id of the last original edge of the shortcut. * - * @see EdgeIteratorState#getOrigEdgeLast() + * @see com.graphhopper.storage.RoutingCHEdgeIteratorState#getOrigEdgeLast() */ public int incEdge; diff --git a/core/src/main/java/com/graphhopper/routing/lm/LandmarkStorage.java b/core/src/main/java/com/graphhopper/routing/lm/LandmarkStorage.java index bcb97fcf62c..1ab2556aeff 100644 --- a/core/src/main/java/com/graphhopper/routing/lm/LandmarkStorage.java +++ b/core/src/main/java/com/graphhopper/routing/lm/LandmarkStorage.java @@ -224,7 +224,7 @@ boolean isInitialized() { } /** - * This method calculates the landmarks and initial weightings to & from them. + * This method calculates the landmarks and initial weightings to & from them. */ public void createLandmarks() { if (isInitialized()) diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/QueryGraph.java b/core/src/main/java/com/graphhopper/routing/querygraph/QueryGraph.java index 8a66b14695f..cf7dd1825f0 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/QueryGraph.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/QueryGraph.java @@ -41,7 +41,7 @@ * introducing virtual nodes and edges. It is lightweight in order to be created every time a new * query comes in, which makes the behaviour thread safe. *

- * Calling any create method creates virtual edges between the tower nodes of the existing + * Calling any create method creates virtual edges between the tower nodes of the existing * graph and new virtual tower nodes. Every virtual node has two adjacent nodes and is connected * to each adjacent nodes via 2 virtual edges with opposite base node / adjacent node encoding. * However, the edge explorer returned by {@link #createEdgeExplorer()} only returns two diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParser.java index 3590e997d91..e844dd29d71 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMMtbRatingParser.java @@ -26,7 +26,7 @@ * A mapping mtb:scale=0 corresponds to 1 and mtb:scale=1 to 2 until 7. * * @see Key:mtb:scale for details on OSM mountain biking difficulties. - * @see Single Trail Scale + * @see Single Trail Scale */ public class OSMMtbRatingParser implements TagParser { private final IntEncodedValue mtbRatingEnc; diff --git a/core/src/main/java/com/graphhopper/routing/weighting/BalancedWeightApproximator.java b/core/src/main/java/com/graphhopper/routing/weighting/BalancedWeightApproximator.java index 33a240a8e57..62cbc5d65c2 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/BalancedWeightApproximator.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/BalancedWeightApproximator.java @@ -33,7 +33,7 @@ * Mitoh, K. (1994). A fast algorithm for finding better routes by ai search techniques. In VNIS, * pages 291–296. * - * [2] Pijls, W.H.L.M, & Post, H. (2008). A new bidirectional algorithm for shortest paths (No. EI 2008-25). + * [2] Pijls, W.H.L.M, & Post, H. (2008). A new bidirectional algorithm for shortest paths (No. EI 2008-25). * Report / Econometric Institute, Erasmus University Rotterdam * * @author jansoe diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index 37159ad5c03..458e1c649f2 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -39,7 +39,7 @@ * Note: A RAM DataAccess Object is thread-safe in itself but if used in this Graph implementation * it is not write thread safe. *

- * Life cycle: (1) object creation, (2) configuration via setters & getters, (3) create or + * Life cycle: (1) object creation, (2) configuration via setters & getters, (3) create or * loadExisting, (4) usage, (5) flush, (6) close */ public class BaseGraph implements Graph, Closeable { diff --git a/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java b/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java index 15e8d041163..32b2c6ce8a9 100644 --- a/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java +++ b/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java @@ -63,8 +63,8 @@ public int addShortcutNodeBased(int a, int b, int accessFlags, double weight, in /** * @param origFirst The first original edge that is skipped by this shortcut. For example for the following shortcut - * edge from x to y, which itself skips the shortcuts x->v and v->y the first original edge would - * be x->u: x->u->v->w->y + * edge from x to y, which itself skips the shortcuts x->v and v->y the + * first original edge would be x->u: x->u->v->w->y * @param origLast like origFirst, but the last orig edge, i.e w->y in above example */ public int addShortcutEdgeBased(int a, int b, int accessFlags, double weight, int skippedEdge1, int skippedEdge2, diff --git a/core/src/main/java/com/graphhopper/storage/RoutingCHGraph.java b/core/src/main/java/com/graphhopper/storage/RoutingCHGraph.java index f56f846083d..f0c004f0924 100644 --- a/core/src/main/java/com/graphhopper/storage/RoutingCHGraph.java +++ b/core/src/main/java/com/graphhopper/storage/RoutingCHGraph.java @@ -35,7 +35,7 @@ public interface RoutingCHGraph { RoutingCHEdgeExplorer createInEdgeExplorer(); /** - * @see #createInEdgeExplorer(), but here the shortcuts/edges are going out of the given node. + * @see #createInEdgeExplorer() but here the shortcuts/edges are going out of the given node. */ RoutingCHEdgeExplorer createOutEdgeExplorer(); diff --git a/core/src/main/java/com/graphhopper/util/Constants.java b/core/src/main/java/com/graphhopper/util/Constants.java index 3935b1e1ca5..9db41eefd51 100644 --- a/core/src/main/java/com/graphhopper/util/Constants.java +++ b/core/src/main/java/com/graphhopper/util/Constants.java @@ -30,12 +30,12 @@ */ public class Constants { /** - * The value of System.getProperty("java.version"). * + * The value of System.getProperty("java.version"). * */ public static final String JAVA_VERSION = System.getProperty("java.version"); /** - * The value of System.getProperty("os.name"). * + * The value of System.getProperty("os.name"). * */ public static final String OS_NAME = System.getProperty("os.name"); /** diff --git a/core/src/main/java/com/graphhopper/util/DouglasPeucker.java b/core/src/main/java/com/graphhopper/util/DouglasPeucker.java index b82624f8ca0..f811f144dff 100644 --- a/core/src/main/java/com/graphhopper/util/DouglasPeucker.java +++ b/core/src/main/java/com/graphhopper/util/DouglasPeucker.java @@ -88,7 +88,7 @@ public int simplify(PointList points, int fromIndex, int lastIndex) { * @param points The PointList to simplify * @param fromIndex Start index to simplify, should be <= lastIndex * @param lastIndex Simplify up to this index - * @param compress Whether or not the points shall be compressed or not, if set to false no points + * @param compress Whether the points shall be compressed or not, if set to false no points * are actually removed, but instead their lat/lon/ele is only set to NaN * @return The number of removed points */ diff --git a/pom.xml b/pom.xml index 7756b41e132..c776a0c2939 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,7 @@ UTF-8 1.8 + @@ -320,7 +321,6 @@ true - org.apache.maven.plugins maven-javadoc-plugin From 9f429cbc13f4b60923e08385b8d4b00df41eae38 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 3 May 2022 08:52:30 +0200 Subject: [PATCH 007/389] Add flex alternatives to measurement --- .../com/graphhopper/tools/Measurement.java | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/tools/src/main/java/com/graphhopper/tools/Measurement.java b/tools/src/main/java/com/graphhopper/tools/Measurement.java index e8573a4e2bb..c836e91af3f 100644 --- a/tools/src/main/java/com/graphhopper/tools/Measurement.java +++ b/tools/src/main/java/com/graphhopper/tools/Measurement.java @@ -196,9 +196,16 @@ protected void importOSM() { boolean isLM = false; measureRouting(hopper, new QuerySettings("routing", count / 20, isCH, isLM). withInstructions()); - if (encoder.supportsTurnCosts()) + measureRouting(hopper, new QuerySettings("routing_alt", count / 1000, isCH, isLM). + alternative()); + if (encoder.supportsTurnCosts()) { measureRouting(hopper, new QuerySettings("routing_edge", count / 20, isCH, isLM). withInstructions().edgeBased()); + // unfortunately alt routes are so slow that we cannot really afford many iterations + measureRouting(hopper, new QuerySettings("routing_edge_alt", count / 1000, isCH, isLM). + edgeBased().alternative() + ); + } if (!blockAreaStr.isEmpty()) measureRouting(hopper, new QuerySettings("routing_block_area", count / 20, isCH, isLM). withInstructions().blockArea(blockAreaStr)); @@ -210,13 +217,17 @@ protected void importOSM() { boolean isLM = true; Helper.parseList(args.getString("measurement.lm.active_counts", "[4,8,12,16]")).stream() .mapToInt(Integer::parseInt).forEach(activeLMCount -> { - measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount, count / 20, isCH, isLM). - withInstructions().activeLandmarks(activeLMCount)); - if (args.getBool("measurement.lm.edge_based", encoder.supportsTurnCosts())) { - measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_edge", count / 20, isCH, isLM). - withInstructions().activeLandmarks(activeLMCount).edgeBased()); - } - }); + measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount, count / 20, isCH, isLM). + withInstructions().activeLandmarks(activeLMCount)); + measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_alt", count / 1000, isCH, isLM). + activeLandmarks(activeLMCount).alternative()); + if (args.getBool("measurement.lm.edge_based", encoder.supportsTurnCosts())) { + measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_edge", count / 20, isCH, isLM). + withInstructions().activeLandmarks(activeLMCount).edgeBased()); + measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_alt_edge", count / 1000, isCH, isLM). + activeLandmarks(activeLMCount).edgeBased().alternative()); + } + }); final int activeLMCount = 8; if (!blockAreaStr.isEmpty()) @@ -631,8 +642,12 @@ else if (!toLowerCase(rsp.getErrors().get(0).getMessage()).contains("not found") maxVisitedNodes.set(visitedNodes); } + rsp.getAll().forEach(p -> { + long dist = (long) p.getDistance(); + distSum.addAndGet(dist); + }); + long dist = (long) responsePath.getDistance(); - distSum.addAndGet(dist); GHPoint prev = req.getPoints().get(0); for (GHPoint point : req.getPoints()) { From 6ef82d29ca9a116cfa08272732397c7952f95e2c Mon Sep 17 00:00:00 2001 From: Andi Date: Wed, 4 May 2022 22:48:00 +0200 Subject: [PATCH 008/389] Do not remove SPT elements from the priority queue, speeds up flexible algorithms (#2571) --- CHANGELOG.md | 3 +- .../java/com/graphhopper/routing/AStar.java | 29 ++++++---------- .../graphhopper/routing/AStarBidirection.java | 8 ----- .../routing/AbstractBidirCHAlgo.java | 33 ++++++++++++++----- .../routing/AbstractNonCHBidirAlgo.java | 30 +++++++++-------- .../com/graphhopper/routing/Dijkstra.java | 25 ++++++-------- .../com/graphhopper/routing/SPTEntry.java | 8 +++++ .../routing/ch/CHTurnCostTest.java | 15 +++++++++ 8 files changed, 86 insertions(+), 65 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43a0f27111e..31fc5da68ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 6.0 [not yet released] -- don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) +- don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) +- faster flexible routing, especially in conjunction with turn costs ### 5.0 [23 Mar 2022] diff --git a/core/src/main/java/com/graphhopper/routing/AStar.java b/core/src/main/java/com/graphhopper/routing/AStar.java index 1d2143bb44c..f7f8f3fc98d 100644 --- a/core/src/main/java/com/graphhopper/routing/AStar.java +++ b/core/src/main/java/com/graphhopper/routing/AStar.java @@ -72,17 +72,20 @@ public Path calcPath(int from, int to) { this.to = to; weightApprox.setTo(to); double weightToGoal = weightApprox.approximate(from); - currEdge = new AStarEntry(EdgeIterator.NO_EDGE, from, 0 + weightToGoal, 0); - if (!traversalMode.isEdgeBased()) { + AStarEntry startEntry = new AStarEntry(EdgeIterator.NO_EDGE, from, 0 + weightToGoal, 0); + fromHeap.add(startEntry); + if (!traversalMode.isEdgeBased()) fromMap.put(from, currEdge); - } runAlgo(); return extractPath(); } private void runAlgo() { double currWeightToGoal, estimationFullWeight; - while (true) { + while (!fromHeap.isEmpty()) { + currEdge = fromHeap.poll(); + if (currEdge.isDeleted()) + continue; visitedNodes++; if (isMaxVisitedNodesExceeded() || finished()) break; @@ -111,26 +114,14 @@ private void runAlgo() { // assert (ase.weight > 0.9999999 * estimationFullWeight) : "Inconsistent distance estimate. It is expected weight >= estimationFullWeight but was " // + ase.weight + " < " + estimationFullWeight + " (" + ase.weight / estimationFullWeight + "), and weightOfVisitedPath:" // + ase.weightOfVisitedPath + " vs. alreadyVisitedWeight:" + alreadyVisitedWeight + " (" + ase.weightOfVisitedPath / alreadyVisitedWeight + ")"; - - fromHeap.remove(ase); - ase.edge = iter.getEdge(); - ase.weight = estimationFullWeight; - ase.weightOfVisitedPath = tmpWeight; - ase.parent = currEdge; + ase.setDeleted(); + ase = new AStarEntry(iter.getEdge(), neighborNode, estimationFullWeight, tmpWeight, currEdge); + fromMap.put(traversalId, ase); } - fromHeap.add(ase); - updateBestPath(iter, ase, traversalId); } } - - if (fromHeap.isEmpty()) - break; - - currEdge = fromHeap.poll(); - if (currEdge == null) - throw new AssertionError("Empty edge cannot happen"); } } diff --git a/core/src/main/java/com/graphhopper/routing/AStarBidirection.java b/core/src/main/java/com/graphhopper/routing/AStarBidirection.java index f8e5beed920..3b4c1527bfd 100644 --- a/core/src/main/java/com/graphhopper/routing/AStarBidirection.java +++ b/core/src/main/java/com/graphhopper/routing/AStarBidirection.java @@ -94,14 +94,6 @@ protected SPTEntry createEntry(EdgeIteratorState edge, double weight, SPTEntry p return new AStarEntry(edge.getEdge(), neighborNode, heapWeight, weight, parent); } - @Override - protected void updateEntry(SPTEntry entry, EdgeIteratorState edge, double weight, SPTEntry parent, boolean reverse) { - entry.edge = edge.getEdge(); - entry.weight = weight + weightApprox.approximate(edge.getAdjNode(), reverse); - ((AStarEntry) entry).weightOfVisitedPath = weight; - entry.parent = parent; - } - @Override protected double calcWeight(EdgeIteratorState iter, SPTEntry currEdge, boolean reverse) { // TODO performance: check if the node is already existent in the opposite direction diff --git a/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java b/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java index ee9ddfac58e..50fc264dca7 100644 --- a/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java +++ b/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java @@ -133,10 +133,13 @@ public boolean finished() { @Override boolean fillEdgesFrom() { - if (pqOpenSetFrom.isEmpty()) { - return false; + while (true) { + if (pqOpenSetFrom.isEmpty()) + return false; + currFrom = pqOpenSetFrom.poll(); + if (!currFrom.isDeleted()) + break; } - currFrom = pqOpenSetFrom.poll(); visitedCountFrom++; if (fromEntryCanBeSkipped()) { return true; @@ -151,10 +154,13 @@ boolean fillEdgesFrom() { @Override boolean fillEdgesTo() { - if (pqOpenSetTo.isEmpty()) { - return false; + while (true) { + if (pqOpenSetTo.isEmpty()) + return false; + currTo = pqOpenSetTo.poll(); + if (!currTo.isDeleted()) + break; } - currTo = pqOpenSetTo.poll(); visitedCountTo++; if (toEntryCanBeSkipped()) { return true; @@ -186,9 +192,20 @@ private void fillEdges(SPTEntry currEdge, PriorityQueue prioQueue, bestWeightMap.put(traversalId, entry); prioQueue.add(entry); } else if (entry.getWeightOfVisitedPath() > weight) { - prioQueue.remove(entry); - updateEntry(entry, iter.getEdge(), iter.getAdjNode(), origEdgeId, weight, currEdge, reverse); + // flagging this entry, so it will be ignored when it is polled the next time + // this is faster than removing the entry from the queue and adding again, but for CH it does not really + // make a difference overall. + entry.setDeleted(); + boolean isBestEntry = reverse ? (entry == bestBwdEntry) : (entry == bestFwdEntry); + entry = createEntry(iter.getEdge(), iter.getAdjNode(), origEdgeId, weight, currEdge, reverse); + bestWeightMap.put(traversalId, entry); prioQueue.add(entry); + // if this is the best entry we need to update the best reference as well. somehow this is only needed for CH? + if (isBestEntry) + if (reverse) + bestBwdEntry = entry; + else + bestFwdEntry = entry; } else continue; diff --git a/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java b/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java index 2e8d2036ebc..b857766b171 100644 --- a/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java +++ b/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java @@ -109,10 +109,13 @@ protected void fillEdgesToUsingFilter(EdgeFilter edgeFilter) { @Override boolean fillEdgesFrom() { - if (pqOpenSetFrom.isEmpty()) { - return false; + while (true) { + if (pqOpenSetFrom.isEmpty()) + return false; + currFrom = pqOpenSetFrom.poll(); + if (!currFrom.isDeleted()) + break; } - currFrom = pqOpenSetFrom.poll(); visitedCountFrom++; if (fromEntryCanBeSkipped()) { return true; @@ -127,10 +130,13 @@ boolean fillEdgesFrom() { @Override boolean fillEdgesTo() { - if (pqOpenSetTo.isEmpty()) { - return false; + while (true) { + if (pqOpenSetTo.isEmpty()) + return false; + currTo = pqOpenSetTo.poll(); + if (!currTo.isDeleted()) + break; } - currTo = pqOpenSetTo.poll(); visitedCountTo++; if (toEntryCanBeSkipped()) { return true; @@ -160,8 +166,10 @@ private void fillEdges(SPTEntry currEdge, PriorityQueue prioQueue, Int bestWeightMap.put(traversalId, entry); prioQueue.add(entry); } else if (entry.getWeightOfVisitedPath() > weight) { - prioQueue.remove(entry); - updateEntry(entry, iter, weight, currEdge, reverse); + // flagging this entry, so it will be ignored when it is polled the next time + entry.setDeleted(); + entry = createEntry(iter, weight, currEdge, reverse); + bestWeightMap.put(traversalId, entry); prioQueue.add(entry); } else continue; @@ -176,12 +184,6 @@ private void fillEdges(SPTEntry currEdge, PriorityQueue prioQueue, Int } } - protected void updateEntry(SPTEntry entry, EdgeIteratorState edge, double weight, SPTEntry parent, boolean reverse) { - entry.edge = edge.getEdge(); - entry.weight = weight; - entry.parent = parent; - } - protected double calcWeight(EdgeIteratorState iter, SPTEntry currEdge, boolean reverse) { // note that for node-based routing the weights will be wrong in case the weighting is returning non-zero // turn weights, see discussion in #1960 diff --git a/core/src/main/java/com/graphhopper/routing/Dijkstra.java b/core/src/main/java/com/graphhopper/routing/Dijkstra.java index d821918a464..bf86cf59356 100644 --- a/core/src/main/java/com/graphhopper/routing/Dijkstra.java +++ b/core/src/main/java/com/graphhopper/routing/Dijkstra.java @@ -58,16 +58,19 @@ protected void initCollections(int size) { public Path calcPath(int from, int to) { checkAlreadyRun(); this.to = to; - currEdge = new SPTEntry(from, 0); - if (!traversalMode.isEdgeBased()) { + SPTEntry startEntry = new SPTEntry(from, 0); + fromHeap.add(startEntry); + if (!traversalMode.isEdgeBased()) fromMap.put(from, currEdge); - } runAlgo(); return extractPath(); } protected void runAlgo() { - while (true) { + while (!fromHeap.isEmpty()) { + currEdge = fromHeap.poll(); + if (currEdge.isDeleted()) + continue; visitedNodes++; if (isMaxVisitedNodesExceeded() || finished()) break; @@ -90,23 +93,15 @@ protected void runAlgo() { fromMap.put(traversalId, nEdge); fromHeap.add(nEdge); } else if (nEdge.weight > tmpWeight) { - fromHeap.remove(nEdge); - nEdge.edge = iter.getEdge(); - nEdge.weight = tmpWeight; - nEdge.parent = currEdge; + nEdge.setDeleted(); + nEdge = new SPTEntry(iter.getEdge(), iter.getAdjNode(), tmpWeight, currEdge); + fromMap.put(traversalId, nEdge); fromHeap.add(nEdge); } else continue; updateBestPath(iter, nEdge, traversalId); } - - if (fromHeap.isEmpty()) - break; - - currEdge = fromHeap.poll(); - if (currEdge == null) - throw new AssertionError("Empty edge cannot happen"); } } diff --git a/core/src/main/java/com/graphhopper/routing/SPTEntry.java b/core/src/main/java/com/graphhopper/routing/SPTEntry.java index 8e16af0d6f4..7705a452601 100644 --- a/core/src/main/java/com/graphhopper/routing/SPTEntry.java +++ b/core/src/main/java/com/graphhopper/routing/SPTEntry.java @@ -42,6 +42,14 @@ public SPTEntry(int edgeId, int adjNode, double weight, SPTEntry parent) { this.parent = parent; } + public void setDeleted() { + adjNode = Integer.MIN_VALUE; + } + + public boolean isDeleted() { + return adjNode == Integer.MIN_VALUE; + } + /** * This method returns the weight to the origin e.g. to the start for the forward SPT and to the * destination for the backward SPT. Where the variable 'weight' is used to let heap select diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java index 6eb462ae6a4..cbf710c0731 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java @@ -1131,6 +1131,21 @@ void testZeroUTurnCosts_atBarrier_issue2564() { compareCHQueryWithDijkstra(0, 5); } + @Test + void testBestFwdBwdEntryUpdate() { + // 2-3 + // | | + // 0-4-1 + GHUtility.setSpeed(60, 60, encoder, graph.edge(2, 0).setDistance(800.22)); + GHUtility.setSpeed(60, 60, encoder, graph.edge(3, 4).setDistance(478.84)); + GHUtility.setSpeed(60, 60, encoder, graph.edge(0, 4).setDistance(547.08)); + GHUtility.setSpeed(60, 60, encoder, graph.edge(4, 1).setDistance(288.95)); + GHUtility.setSpeed(60, 60, encoder, graph.edge(2, 3).setDistance(90)); + graph.freeze(); + prepareCH(1, 3, 0, 2, 4); + compareCHQueryWithDijkstra(1, 2); + } + /** * This test runs on a random graph with random turn costs and a predefined (but random) contraction order. * It often produces exotic conditions that are hard to anticipate beforehand. From ee0703d53ad3fc26413c15f80f13168a58c000de Mon Sep 17 00:00:00 2001 From: Andi Date: Fri, 6 May 2022 08:44:07 +0200 Subject: [PATCH 009/389] Split flag encoders into encoded values and tag parsers (#2561) --- .../java/com/graphhopper/GraphHopper.java | 142 +++-- .../com/graphhopper/reader/osm/OSMReader.java | 32 +- .../routing/DefaultWeightingFactory.java | 4 +- .../routing/util/Bike2WeightTagParser.java | 25 +- .../routing/util/BikeCommonTagParser.java | 39 +- .../routing/util/BikeTagParser.java | 37 +- .../routing/util/Car4WDTagParser.java | 21 +- .../routing/util/CarTagParser.java | 52 +- .../util/DefaultVehicleTagParserFactory.java | 53 ++ .../routing/util/EncodingManager.java | 34 +- .../graphhopper/routing/util/FlagEncoder.java | 17 +- .../routing/util/FlagEncoders.java | 40 +- .../routing/util/FootTagParser.java | 56 +- .../routing/util/HikeTagParser.java | 37 +- .../routing/util/MotorcycleTagParser.java | 61 +- .../routing/util/MountainBikeTagParser.java | 27 +- .../graphhopper/routing/util/OSMParsers.java | 112 ++++ .../routing/util/RacingBikeTagParser.java | 28 +- .../routing/util/RoadsTagParser.java | 25 +- .../routing/util/TagParserManager.java | 581 ------------------ .../routing/util/VehicleEncodedValues.java | 283 +++++++++ .../routing/util/VehicleTagParser.java | 130 +--- .../routing/util/VehicleTagParserFactory.java | 26 + .../routing/util/WheelchairTagParser.java | 23 +- .../storage/GraphHopperStorage.java | 6 +- .../java/com/graphhopper/GraphHopperTest.java | 20 + .../reader/osm/GraphHopperOSMTest.java | 8 +- .../graphhopper/reader/osm/OSMReaderTest.java | 58 +- ...fficChangeWithNodeOrderingReusingTest.java | 19 +- .../routing/ev/DecimalEncodedValueTest.java | 10 +- .../util/AbstractBikeTagParserTester.java | 42 +- .../util/Bike2WeightTagParserTest.java | 51 +- .../routing/util/BikeTagParserTest.java | 42 +- .../routing/util/Car4WDTagParserTest.java | 13 +- .../routing/util/CarTagParserTest.java | 70 ++- .../routing/util/EncodingManagerTest.java | 31 +- .../routing/util/FootTagParserTest.java | 21 +- .../routing/util/HikeTagParserTest.java | 8 +- .../routing/util/MotorcycleTagParserTest.java | 17 +- .../util/MountainBikeTagParserTest.java | 26 +- .../routing/util/RacingBikeTagParserTest.java | 62 +- .../routing/util/RoadsTagParserTest.java | 18 +- .../routing/util/TagParserManagerTest.java | 165 ----- .../routing/util/TagParsingTest.java | 189 ++++++ .../routing/util/WheelchairTagParserTest.java | 50 +- 45 files changed, 1426 insertions(+), 1385 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/OSMParsers.java delete mode 100644 core/src/main/java/com/graphhopper/routing/util/TagParserManager.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/VehicleTagParserFactory.java delete mode 100644 core/src/test/java/com/graphhopper/routing/util/TagParserManagerTest.java create mode 100644 core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 60eceb90ed9..bb6aec3ad8c 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -37,8 +37,7 @@ import com.graphhopper.routing.subnetwork.PrepareRoutingSubnetworks.PrepareJob; import com.graphhopper.routing.util.*; import com.graphhopper.routing.util.countryrules.CountryRuleFactory; -import com.graphhopper.routing.util.parsers.DefaultTagParserFactory; -import com.graphhopper.routing.util.parsers.TagParserFactory; +import com.graphhopper.routing.util.parsers.*; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.routing.weighting.custom.CustomWeighting; @@ -87,7 +86,8 @@ public class GraphHopper { private String customAreasDirectory = ""; // for graph: private GraphHopperStorage ghStorage; - private TagParserManager tagParserManager; + private EncodingManager encodingManager; + private OSMParsers osmParsers; private int defaultSegmentSize = -1; private String ghLocation = ""; private DAType dataAccessDefaultType = DAType.RAM_STORE; @@ -117,6 +117,7 @@ public class GraphHopper { private String osmFile; private ElevationProvider eleProvider = ElevationProvider.NOOP; private FlagEncoderFactory flagEncoderFactory = new DefaultFlagEncoderFactory(); + private VehicleTagParserFactory vehicleTagParserFactory = new DefaultVehicleTagParserFactory(); private EncodedValueFactory encodedValueFactory = new DefaultEncodedValueFactory(); private TagParserFactory tagParserFactory = new DefaultTagParserFactory(); private PathDetailsBuilderFactory pathBuilderFactory = new PathDetailsBuilderFactory(); @@ -135,14 +136,10 @@ public GraphHopper setFlagEncodersString(String flagEncodersString) { return this; } - public TagParserManager getTagParserManager() { - if (tagParserManager == null) - throw new IllegalStateException("TagParserManager not yet built"); - return tagParserManager; - } - public EncodingManager getEncodingManager() { - return getTagParserManager().getEncodingManager(); + if (encodingManager == null) + throw new IllegalStateException("EncodingManager not yet built"); + return encodingManager; } public ElevationProvider getElevationProvider() { @@ -234,8 +231,8 @@ public GraphHopper setProfiles(Profile... profiles) { public GraphHopper setProfiles(List profiles) { if (!profilesByName.isEmpty()) throw new IllegalArgumentException("Cannot initialize profiles multiple times"); - if (tagParserManager != null) - throw new IllegalArgumentException("Cannot set profiles after TagParserManager was built"); + if (encodingManager != null) + throw new IllegalArgumentException("Cannot set profiles after EncodingManager was built"); for (Profile profile : profiles) { Profile previous = this.profilesByName.put(profile.getName(), profile); if (previous != null) @@ -392,6 +389,15 @@ public GraphHopper setEncodedValueFactory(EncodedValueFactory factory) { return this; } + public VehicleTagParserFactory getVehicleTagParserFactory() { + return this.vehicleTagParserFactory; + } + + public GraphHopper setVehicleTagParserFactory(VehicleTagParserFactory factory) { + this.vehicleTagParserFactory = factory; + return this; + } + public TagParserFactory getTagParserFactory() { return this.tagParserFactory; } @@ -474,13 +480,13 @@ public GraphHopper init(GraphHopperConfig ghConfig) { if (!ghConfig.getString("spatial_rules.max_bbox", "").isEmpty()) throw new IllegalArgumentException("spatial_rules.max_bbox has been deprecated. There is no replacement, all custom areas will be considered."); - if (tagParserManager != null) - throw new IllegalStateException("Cannot call init twice. TagParserManager was already initialized."); + if (encodingManager != null) + throw new IllegalStateException("Cannot call init twice. EncodingManager was already initialized."); setProfiles(ghConfig.getProfiles()); - String flagEncodersStr = ghConfig.getString("graph.flag_encoders", flagEncodersString); - String encodedValueStr = ghConfig.getString("graph.encoded_values", encodedValuesString); - String dateRangeParserStr = ghConfig.getString("datareader.date_range_parser_day", dateRangeParserString); - tagParserManager = buildTagParserManager(flagEncodersStr, encodedValueStr, dateRangeParserStr, profilesByName.values()); + flagEncodersString = ghConfig.getString("graph.flag_encoders", flagEncodersString); + encodedValuesString = ghConfig.getString("graph.encoded_values", encodedValuesString); + dateRangeParserString = ghConfig.getString("datareader.date_range_parser_day", dateRangeParserString); + buildEncodingManagerAndOSMParsers(flagEncodersString, encodedValuesString, dateRangeParserString, profilesByName.values()); if (ghConfig.getString("graph.locktype", "native").equals("simple")) lockFactory = new SimpleFSLockFactory(); @@ -529,34 +535,77 @@ public GraphHopper init(GraphHopperConfig ghConfig) { return this; } - private TagParserManager buildTagParserManager(String flagEncodersStr, String encodedValueStr, String dateRangeParserStr, Collection profiles) { - TagParserManager.Builder emBuilder = new TagParserManager.Builder(); - emBuilder.setDateRangeParser(DateRangeParser.createInstance(dateRangeParserStr)); - Map flagEncoderMap = new LinkedHashMap<>(); + private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String encodedValuesStr, String dateRangeParserString, Collection profiles) { + Map flagEncodersMap = new LinkedHashMap<>(); for (String encoderStr : flagEncodersStr.split(",")) { - String key = encoderStr.split("\\|")[0]; - if (!key.isEmpty()) { - if (flagEncoderMap.containsKey(key)) - throw new IllegalArgumentException("FlagEncoder " + key + " needs to be unique"); - flagEncoderMap.put(key, encoderStr); - } + String name = encoderStr.split("\\|")[0].trim(); + if (name.isEmpty()) + continue; + if (flagEncodersMap.containsKey(name)) + throw new IllegalArgumentException("Duplicate flag encoder: " + name + " in: " + encoderStr); + flagEncodersMap.put(name, encoderStr); } - Map implicitFlagEncoderMap = new LinkedHashMap<>(); + Map flagEncodersFromProfilesMap = new LinkedHashMap<>(); for (Profile profile : profiles) { - emBuilder.add(Subnetwork.create(profile.getName())); - if (!flagEncoderMap.containsKey(profile.getVehicle()) - // overwrite key in implicit map if turn cost support required - && (!implicitFlagEncoderMap.containsKey(profile.getVehicle()) || profile.isTurnCosts())) - implicitFlagEncoderMap.put(profile.getVehicle(), profile.getVehicle() + (profile.isTurnCosts() ? "|turn_costs=true" : "")); + // if a profile uses a flag encoder with turn costs make sure we add that flag encoder with turn costs + String vehicle = profile.getVehicle().trim(); + if (!flagEncodersFromProfilesMap.containsKey(vehicle) || profile.isTurnCosts()) + flagEncodersFromProfilesMap.put(vehicle, vehicle + (profile.isTurnCosts() ? "|turn_costs=true" : "")); } - flagEncoderMap.putAll(implicitFlagEncoderMap); - flagEncoderMap.values().forEach(s -> emBuilder.addIfAbsent(flagEncoderFactory, s)); + // flag encoders from profiles are only taken into account when they were not given explicitly + flagEncodersFromProfilesMap.forEach(flagEncodersMap::putIfAbsent); - for (String tpStr : encodedValueStr.split(",")) { - if (!tpStr.isEmpty()) emBuilder.addIfAbsent(encodedValueFactory, tagParserFactory, tpStr); - } + List encodedValueStrings = Arrays.stream(encodedValuesStr.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .collect(Collectors.toList()); - return emBuilder.build(); + EncodingManager.Builder emBuilder = new EncodingManager.Builder(); + flagEncodersMap.forEach((name, encoderStr) -> emBuilder.add(flagEncoderFactory.createFlagEncoder(name, new PMap(encoderStr)))); + profiles.forEach(profile -> emBuilder.add(Subnetwork.create(profile.getName()))); + encodedValueStrings.forEach(s -> emBuilder.add(encodedValueFactory.create(s))); + encodingManager = emBuilder.build(); + + osmParsers = new OSMParsers(); + encodedValueStrings.forEach(s -> osmParsers.addWayTagParser(tagParserFactory.create(encodingManager, s))); + + // this needs to be in sync with the default EVs added in EncodingManager.Builder#build. ideally I would like to remove + // all these defaults and just use the config as the single source of truth + if (!encodedValueStrings.contains(Roundabout.KEY)) + osmParsers.addWayTagParser(new OSMRoundaboutParser(encodingManager.getBooleanEncodedValue(Roundabout.KEY))); + if (!encodedValueStrings.contains(RoadClass.KEY)) + osmParsers.addWayTagParser(new OSMRoadClassParser(encodingManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class))); + if (!encodedValueStrings.contains(RoadClassLink.KEY)) + osmParsers.addWayTagParser(new OSMRoadClassLinkParser(encodingManager.getBooleanEncodedValue(RoadClassLink.KEY))); + if (!encodedValueStrings.contains(RoadEnvironment.KEY)) + osmParsers.addWayTagParser(new OSMRoadEnvironmentParser(encodingManager.getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class))); + if (!encodedValueStrings.contains(MaxSpeed.KEY)) + osmParsers.addWayTagParser(new OSMMaxSpeedParser(encodingManager.getDecimalEncodedValue(MaxSpeed.KEY))); + if (!encodedValueStrings.contains(RoadAccess.KEY)) + osmParsers.addWayTagParser(new OSMRoadAccessParser(encodingManager.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR))); + + DateRangeParser dateRangeParser = DateRangeParser.createInstance(dateRangeParserString); + flagEncodersMap.forEach((name, encoderStr) -> { + VehicleTagParser vehicleTagParser = vehicleTagParserFactory.createParser(encodingManager, name, new PMap(encoderStr)); + vehicleTagParser.init(dateRangeParser); + if (vehicleTagParser instanceof RoadsTagParser) { + if (encodingManager.hasEncodedValue("car_access") && !encodedValueStrings.contains("car_access")) + osmParsers.addWayTagParser(new OSMAccessParser(encodingManager.getBooleanEncodedValue("car_access"), encodingManager.getBooleanEncodedValue(Roundabout.KEY), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR), TransportationMode.CAR)); + if (encodingManager.hasEncodedValue("bike_access") && !encodedValueStrings.contains("bike_access")) + osmParsers.addWayTagParser(new OSMAccessParser(encodingManager.getBooleanEncodedValue("bike_access"), encodingManager.getBooleanEncodedValue(Roundabout.KEY), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.BIKE), TransportationMode.BIKE)); + } else if (vehicleTagParser instanceof BikeCommonTagParser) { + if (encodingManager.hasEncodedValue(BikeNetwork.KEY)) + osmParsers.addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig)); + if (encodingManager.hasEncodedValue(GetOffBike.KEY)) + osmParsers.addWayTagParser(new OSMGetOffBikeParser(encodingManager.getBooleanEncodedValue(GetOffBike.KEY))); + if (encodingManager.hasEncodedValue(Smoothness.KEY)) + osmParsers.addWayTagParser(new OSMSmoothnessParser(encodingManager.getEnumEncodedValue(Smoothness.KEY, Smoothness.class))); + } else if (vehicleTagParser instanceof FootTagParser) { + if (encodingManager.hasEncodedValue(FootNetwork.KEY)) + osmParsers.addRelationTagParser(relConfig -> new OSMFootNetworkTagParser(encodingManager.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class), relConfig)); + } + osmParsers.addVehicleTagParser(vehicleTagParser); + }); } private static ElevationProvider createElevationProvider(GraphHopperConfig ghConfig) { @@ -698,7 +747,7 @@ protected void importOSM() { AreaIndex areaIndex = new AreaIndex<>(customAreas); logger.info("start creating graph from " + osmFile); - OSMReader reader = new OSMReader(ghStorage.getBaseGraph(), tagParserManager, osmReaderConfig).setFile(_getOSMFile()). + OSMReader reader = new OSMReader(ghStorage.getBaseGraph(), encodingManager, osmParsers, osmReaderConfig).setFile(_getOSMFile()). setAreaIndex(areaIndex). setElevationProvider(eleProvider). setCountryRuleFactory(countryRuleFactory); @@ -769,18 +818,17 @@ public boolean load() { if (!allowWrites && dataAccessDefaultType.isMMap()) dataAccessDefaultType = DAType.MMAP_RO; - if (tagParserManager == null) - // we did not call init(), so we build the tag parser manager based on the changes made to emBuilder - // and the current profiles. + if (encodingManager == null) + // we did not call init(), so we build the encoding manager now. // just like when calling init, users have to make sure they use the same setup for import and load - tagParserManager = buildTagParserManager(flagEncodersString, encodedValuesString, dateRangeParserString, profilesByName.values()); + buildEncodingManagerAndOSMParsers(flagEncodersString, encodedValuesString, dateRangeParserString, profilesByName.values()); GHDirectory directory = new GHDirectory(ghLocation, dataAccessDefaultType); directory.configure(dataAccessConfig); ghStorage = new GraphBuilder(getEncodingManager()) .setDir(directory) .set3D(hasElevation()) - .withTurnCosts(tagParserManager.needsTurnCostsSupport()) + .withTurnCosts(encodingManager.needsTurnCostsSupport()) .setSegmentSize(defaultSegmentSize) .build(); checkProfilesConsistency(); @@ -1140,7 +1188,7 @@ private List buildSubnetworkRemovalJobs() { for (Profile profile : profilesByName.values()) { // if turn costs are enabled use u-turn costs of zero as we only want to make sure the graph is fully connected assuming finite u-turn costs Weighting weighting = createWeighting(profile, new PMap().putObject(Parameters.Routing.U_TURN_COSTS, 0)); - jobs.add(new PrepareJob(tagParserManager.getBooleanEncodedValue(Subnetwork.key(profile.getName())), weighting)); + jobs.add(new PrepareJob(encodingManager.getBooleanEncodedValue(Subnetwork.key(profile.getName())), weighting)); } return jobs; } diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 5d7bbeefc99..a4893df8c18 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -30,7 +30,8 @@ import com.graphhopper.routing.ev.Country; import com.graphhopper.routing.util.AreaIndex; import com.graphhopper.routing.util.CustomArea; -import com.graphhopper.routing.util.TagParserManager; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.OSMParsers; import com.graphhopper.routing.util.countryrules.CountryRule; import com.graphhopper.routing.util.countryrules.CountryRuleFactory; import com.graphhopper.routing.util.parsers.TurnCostParser; @@ -71,7 +72,8 @@ public class OSMReader { private final BaseGraph baseGraph; private final NodeAccess nodeAccess; private final TurnCostStorage turnCostStorage; - private final TagParserManager tagParserManager; + private final EncodingManager encodingManager; + private final OSMParsers osmParsers; private final DistanceCalc distCalc = DistanceCalcEarth.DIST_EARTH; private ElevationProvider eleProvider = ElevationProvider.NOOP; private AreaIndex areaIndex; @@ -88,19 +90,21 @@ public class OSMReader { private GHLongHashSet osmWayIdSet = new GHLongHashSet(); private IntLongMap edgeIdToOsmWayIdMap; - public OSMReader(BaseGraph baseGraph, TagParserManager tagParserManager, OSMReaderConfig config) { + public OSMReader(BaseGraph baseGraph, EncodingManager encodingManager, OSMParsers osmParsers, OSMReaderConfig config) { this.baseGraph = baseGraph; + this.encodingManager = encodingManager; this.config = config; this.nodeAccess = baseGraph.getNodeAccess(); - this.tagParserManager = tagParserManager; + this.osmParsers = osmParsers; simplifyAlgo.setMaxDistance(config.getMaxWayPointDistance()); simplifyAlgo.setElevationMaxDistance(config.getElevationMaxWayPointDistance()); turnCostStorage = baseGraph.getTurnCostStorage(); - tempRelFlags = tagParserManager.createRelationFlags(); + tempRelFlags = osmParsers.createRelationFlags(); if (tempRelFlags.length != 2) - throw new IllegalArgumentException("Cannot use relation flags with != 2 integers"); + // we use a long to store relation flags currently, so the relation flags ints ref must have length 2 + throw new IllegalArgumentException("OSMReader cannot use relation flags with != 2 integers"); } /** @@ -136,8 +140,8 @@ public OSMReader setCountryRuleFactory(CountryRuleFactory countryRuleFactory) { } public void readGraph() throws IOException { - if (tagParserManager == null) - throw new IllegalStateException("Encoding manager was not set."); + if (osmParsers == null) + throw new IllegalStateException("Tag parsers were not set."); if (osmFile == null) throw new IllegalStateException("No OSM file specified"); @@ -188,7 +192,7 @@ protected boolean acceptWay(ReaderWay way) { if (!way.hasTags()) return false; - return tagParserManager.acceptWay(way); + return osmParsers.acceptWay(way); } /** @@ -323,7 +327,8 @@ protected void addEdge(int fromIndex, int toIndex, PointList pointList, ReaderWa setArtificialWayTags(pointList, way, distance, nodeTags); IntsRef relationFlags = getRelFlagsMap(way.getId()); - IntsRef edgeFlags = tagParserManager.handleWayTags(way, relationFlags); + IntsRef edgeFlags = encodingManager.createEdgeFlags(); + edgeFlags = osmParsers.handleWayTags(edgeFlags, way, relationFlags); if (edgeFlags.isEmpty()) return; @@ -338,7 +343,7 @@ protected void addEdge(int fromIndex, int toIndex, PointList pointList, ReaderWa checkCoordinates(toIndex, pointList.get(pointList.size() - 1)); edge.setWayGeometry(pointList.shallowCopy(1, pointList.size() - 1, false)); } - tagParserManager.applyWayTags(way, edge); + osmParsers.applyWayTags(way, edge); checkDistance(edge); if (osmWayIdSet.contains(way.getId())) { @@ -480,7 +485,7 @@ protected void preprocessRelations(ReaderRelation relation) { if (member.getType() != ReaderRelation.Member.WAY) continue; IntsRef oldRelationFlags = getRelFlagsMap(member.getRef()); - IntsRef newRelationFlags = tagParserManager.handleRelationTags(relation, oldRelationFlags); + IntsRef newRelationFlags = osmParsers.handleRelationTags(relation, oldRelationFlags); putRelFlagsMap(member.getRef(), newRelationFlags); } } @@ -519,7 +524,7 @@ public long getOsmIdOfInternalEdge(int edgeId) { int viaNode = map.getInternalNodeIdOfOsmNode(turnRelation.getViaOsmNodeId()); // street with restriction was not included (access or tag limits etc) if (viaNode >= 0) - tagParserManager.handleTurnRelationTags(turnRelation, map, baseGraph); + osmParsers.handleTurnRelationTags(turnRelation, map, baseGraph); } } } @@ -598,7 +603,6 @@ static OSMTurnRelation createTurnRelation(ReaderRelation relation, String restri } private void finishedReading() { - tagParserManager.releaseParsers(); eleProvider.release(); osmWayIdToRelationFlagsMap = null; osmWayIdSet = null; diff --git a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java index 79383b31e37..5737515198f 100644 --- a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java +++ b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java @@ -80,12 +80,12 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis } else if ("shortest".equalsIgnoreCase(weightingStr)) { weighting = new ShortestWeighting(encoder, turnCostProvider); } else if ("fastest".equalsIgnoreCase(weightingStr)) { - if (encoder.supports(PriorityWeighting.class)) + if (encoder.getPriorityEnc() != null) weighting = new PriorityWeighting(encoder, hints, turnCostProvider); else weighting = new FastestWeighting(encoder, hints, turnCostProvider); } else if ("curvature".equalsIgnoreCase(weightingStr)) { - if (encoder.supports(CurvatureWeighting.class)) + if (encoder.getCurvatureEnc() != null) weighting = new CurvatureWeighting(encoder, hints, turnCostProvider); } else if ("short_fastest".equalsIgnoreCase(weightingStr)) { diff --git a/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java b/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java index fabff222ed6..3fd0b4311d7 100644 --- a/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java @@ -18,12 +18,14 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.FetchMode; import com.graphhopper.util.PMap; import com.graphhopper.util.PointList; +import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.util.Helper.keepIn; /** @@ -33,12 +35,27 @@ */ public class Bike2WeightTagParser extends BikeTagParser { - public Bike2WeightTagParser() { - this(new PMap()); + public Bike2WeightTagParser(EncodedValueLookup lookup, PMap properties) { + this( + lookup.getBooleanEncodedValue(getKey(properties.getString("name", "bike2"), "access")), + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "bike2"), "average_speed")), + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "bike2"), "priority")), + lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), + lookup.getBooleanEncodedValue(Roundabout.KEY), + lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class), + lookup.hasEncodedValue(TurnCost.key(properties.getString("name", "bike2"))) ? lookup.getDecimalEncodedValue(TurnCost.key(properties.getString("name", "bike2"))) : null, + properties + ); } - public Bike2WeightTagParser(PMap properties) { - super(new PMap(properties).putObject("speed_two_directions", true).putObject("name", properties.getString("name", "bike2"))); + public Bike2WeightTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, + DecimalEncodedValue priorityEnc, EnumEncodedValue bikeRouteEnc, + BooleanEncodedValue roundaboutEnc, + EnumEncodedValue smoothnessEnc, DecimalEncodedValue turnCostEnc, PMap properties) { + super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, properties.getString("name", "bike2"), + roundaboutEnc, turnCostEnc); + blockPrivate(properties.getBool("block_private", true)); + blockFords(properties.getBool("block_fords", false)); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java b/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java index 40e48264dbe..8438c89ff47 100644 --- a/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java @@ -19,14 +19,12 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.*; -import com.graphhopper.routing.weighting.PriorityWeighting; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; import java.util.*; import static com.graphhopper.routing.ev.RouteNetwork.*; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.PriorityCode.*; /** @@ -38,6 +36,8 @@ */ abstract public class BikeCommonTagParser extends VehicleTagParser { + public static double BIKE_MAX_SPEED = 30; + protected static final int PUSHING_SECTION_SPEED = 4; // Pushing section highways are parts where you need to get off your bike and push it (German: Schiebestrecke) protected final HashSet pushingSectionsHighways = new HashSet<>(); @@ -60,10 +60,13 @@ abstract public class BikeCommonTagParser extends VehicleTagParser { // This is the specific bicycle class private String classBicycleKey; - protected BikeCommonTagParser(String name, int speedBits, double speedFactor, int maxTurnCosts, boolean speedTwoDirections) { - super(name, speedBits, speedFactor, speedTwoDirections, maxTurnCosts); - - priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); + protected BikeCommonTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, + EnumEncodedValue bikeRouteEnc, EnumEncodedValue smoothnessEnc, + String name, BooleanEncodedValue roundaboutEnc, DecimalEncodedValue turnCostEnc) { + super(accessEnc, speedEnc, name, roundaboutEnc, turnCostEnc, TransportationMode.BIKE, speedEnc.getNextStorableValue(BIKE_MAX_SPEED)); + this.bikeRouteEnc = bikeRouteEnc; + this.smoothnessEnc = smoothnessEnc; + this.priorityEnc = priorityEnc; restrictedValues.add("agricultural"); restrictedValues.add("forestry"); @@ -100,8 +103,6 @@ protected BikeCommonTagParser(String name, int speedBits, double speedFactor, in unpavedSurfaceTags.add("sand"); unpavedSurfaceTags.add("wood"); - maxPossibleSpeed = avgSpeedEnc.getNextStorableValue(30); - setTrackTypeSpeed("grade1", 18); // paved setTrackTypeSpeed("grade2", 12); // now unpaved ... setTrackTypeSpeed("grade3", 8); @@ -182,20 +183,6 @@ protected BikeCommonTagParser(String name, int speedBits, double speedFactor, in setAvoidSpeedLimit(71); } - @Override - public TransportationMode getTransportationMode() { - return TransportationMode.BIKE; - } - - @Override - public void createEncodedValues(List registerNewEncodedValue) { - super.createEncodedValues(registerNewEncodedValue); - registerNewEncodedValue.add(priorityEnc); - - bikeRouteEnc = getEnumEncodedValue(RouteNetwork.key("bike"), RouteNetwork.class); - smoothnessEnc = getEnumEncodedValue(Smoothness.KEY, Smoothness.class); - } - @Override public EncodingManager.Access getAccess(ReaderWay way) { String highwayValue = way.getTag("highway"); @@ -563,14 +550,6 @@ void addPushingSection(String highway) { pushingSectionsHighways.add(highway); } - @Override - public boolean supports(Class feature) { - if (super.supports(feature)) - return true; - - return PriorityWeighting.class.isAssignableFrom(feature); - } - void setAvoidSpeedLimit(int limit) { avoidSpeedLimit = limit; } diff --git a/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java index 07234052fc0..082b1a3bef3 100644 --- a/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java @@ -17,9 +17,11 @@ */ package com.graphhopper.routing.util; +import com.graphhopper.routing.ev.*; import com.graphhopper.util.PMap; import static com.graphhopper.routing.ev.Smoothness.*; +import static com.graphhopper.routing.util.EncodingManager.getKey; /** * Specifies the settings for cycletouring/trekking @@ -28,31 +30,26 @@ * @author Peter Karich */ public class BikeTagParser extends BikeCommonTagParser { - public BikeTagParser() { - this("bike"); - } - - public BikeTagParser(String name) { - this(name, 4, 2, 0, false); - } - - public BikeTagParser(PMap properties) { - this(properties.getString("name", "bike"), - properties.getInt("speed_bits", 4), - properties.getInt("speed_factor", 2), - properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0), - properties.getBool("speed_two_directions", false)); + public BikeTagParser(EncodedValueLookup lookup, PMap properties) { + this( + lookup.getBooleanEncodedValue(getKey(properties.getString("name", "bike"), "access")), + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "bike"), "average_speed")), + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "bike"), "priority")), + lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), + lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class), + properties.getString("name", "bike"), + lookup.getBooleanEncodedValue(Roundabout.KEY), + lookup.hasEncodedValue(TurnCost.key(properties.getString("name", "bike"))) ? lookup.getDecimalEncodedValue(TurnCost.key(properties.getString("name", "bike"))) : null + ); blockPrivate(properties.getBool("block_private", true)); blockFords(properties.getBool("block_fords", false)); } - public BikeTagParser(int speedBits, double speedFactor, int maxTurnCosts, boolean speedTwoDirections) { - this("bike", speedBits, speedFactor, maxTurnCosts, speedTwoDirections); - } - - public BikeTagParser(String name, int speedBits, double speedFactor, int maxTurnCosts, boolean speedTwoDirections) { - super(name, speedBits, speedFactor, maxTurnCosts, speedTwoDirections); + public BikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, + EnumEncodedValue bikeRouteEnc, EnumEncodedValue smoothnessEnc, + String name, BooleanEncodedValue roundaboutEnc, DecimalEncodedValue turnCostEnc) { + super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, name, roundaboutEnc, turnCostEnc); addPushingSection("path"); addPushingSection("footway"); addPushingSection("pedestrian"); diff --git a/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java b/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java index b2eabfb9734..fcf81b82915 100644 --- a/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java @@ -17,8 +17,11 @@ */ package com.graphhopper.routing.util; +import com.graphhopper.routing.ev.*; import com.graphhopper.util.PMap; +import static com.graphhopper.routing.util.EncodingManager.getKey; + /** * Defines bit layout for cars with four wheel drive * @@ -26,8 +29,22 @@ */ public class Car4WDTagParser extends CarTagParser { - public Car4WDTagParser(PMap properties) { - super(new PMap(properties).putObject("name", properties.getString("name", "car4wd"))); + public Car4WDTagParser(EncodedValueLookup lookup, PMap properties) { + this( + lookup.getBooleanEncodedValue(getKey(properties.getString("name", "car4wd"), "access")), + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "car4wd"), "average_speed")), + lookup.hasEncodedValue(TurnCost.key(properties.getString("name", "car4wd"))) ? lookup.getDecimalEncodedValue(TurnCost.key(properties.getString("name", "car4wd"))) : null, + lookup.getBooleanEncodedValue(Roundabout.KEY), + new PMap(properties).putObject("name", "car4wd"), + TransportationMode.CAR + ); + } + + public Car4WDTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue turnCostEnc, + BooleanEncodedValue roundaboutEnc, + PMap properties, TransportationMode transportationMode) { + super(accessEnc, speedEnc, turnCostEnc, roundaboutEnc, new PMap(properties).putObject("name", properties.getString("name", "car4wd")), transportationMode, + speedEnc.getNextStorableValue(CAR_MAX_SPEED)); trackTypeSpeedMap.put("grade4", 5); // ... some hard or compressed materials trackTypeSpeedMap.put("grade5", 5); // ... no hard materials. soil/sand/grass } diff --git a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java index 212adbe8378..c3b5dfcd114 100644 --- a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java @@ -18,6 +18,7 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; import com.graphhopper.util.PMap; @@ -27,6 +28,8 @@ import java.util.Map; import java.util.Set; +import static com.graphhopper.routing.util.EncodingManager.getKey; + /** * Defines bit layout for cars. (speed, access, ferries, ...) * @@ -34,6 +37,7 @@ * @author Nop */ public class CarTagParser extends VehicleTagParser { + public static final double CAR_MAX_SPEED = 140; protected final Map trackTypeSpeedMap = new HashMap<>(); protected final Set badSurfaceSpeedMap = new HashSet<>(); // This value determines the maximal possible on roads with bad surfaces @@ -46,34 +50,24 @@ public class CarTagParser extends VehicleTagParser { */ protected final Map defaultSpeedMap = new HashMap<>(); - public CarTagParser() { - this(new PMap()); - } - - public CarTagParser(int speedBits, double speedFactor, int maxTurnCosts) { - this("car", speedBits, speedFactor, maxTurnCosts); - } - - public CarTagParser(String name, int speedBits, double speedFactor, int maxTurnCosts) { - this(name, speedBits, speedFactor, maxTurnCosts, false); - } - - public CarTagParser(int speedBits, double speedFactor, int maxTurnCosts, boolean speedTwoDirections) { - this("car", speedBits, speedFactor, maxTurnCosts, speedTwoDirections); + public CarTagParser(EncodedValueLookup lookup, PMap properties) { + this( + lookup.getBooleanEncodedValue(getKey(properties.getString("name", "car"), "access")), + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "car"), "average_speed")), + lookup.hasEncodedValue(TurnCost.key(properties.getString("name", "car"))) ? lookup.getDecimalEncodedValue(TurnCost.key(properties.getString("name", "car"))) : null, + lookup.getBooleanEncodedValue(Roundabout.KEY), + properties, + TransportationMode.CAR, + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "car"), "average_speed")).getNextStorableValue(CAR_MAX_SPEED) + ); } - public CarTagParser(String name, int speedBits, double speedFactor, int maxTurnCosts, boolean speedTwoDirections) { - this(new PMap().putObject("name", name).putObject("speed_bits", speedBits).putObject("speed_factor", speedFactor). - putObject("max_turn_costs", maxTurnCosts).putObject("speed_two_directions", speedTwoDirections)); - } - - public CarTagParser(PMap properties) { - super(properties.getString("name", "car"), - properties.getInt("speed_bits", 5), - properties.getDouble("speed_factor", 5), - properties.getBool("speed_two_directions", false), - properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0)); - + public CarTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue turnCostEnc, + BooleanEncodedValue roundaboutEnc, PMap properties, + TransportationMode transportationMode, double maxPossibleSpeed) { + super(accessEnc, speedEnc, + properties.getString("name", "car"), roundaboutEnc, + turnCostEnc, transportationMode, maxPossibleSpeed); restrictedValues.add("agricultural"); restrictedValues.add("forestry"); restrictedValues.add("no"); @@ -145,12 +139,6 @@ public CarTagParser(PMap properties) { // limit speed on bad surfaces to 30 km/h badSurfaceSpeed = 30; - maxPossibleSpeed = avgSpeedEnc.getNextStorableValue(properties.getDouble("max_speed", 140)); - } - - @Override - public TransportationMode getTransportationMode() { - return TransportationMode.CAR; } protected double getSpeed(ReaderWay way) { diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java new file mode 100644 index 00000000000..07a2da84ced --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java @@ -0,0 +1,53 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util; + +import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.util.PMap; + +import static com.graphhopper.routing.util.FlagEncoderFactory.*; + +public class DefaultVehicleTagParserFactory implements VehicleTagParserFactory { + public VehicleTagParser createParser(EncodedValueLookup lookup, String name, PMap configuration) { + if (name.equals(ROADS)) + return new RoadsTagParser(lookup); + if (name.equals(CAR)) + return new CarTagParser(lookup, configuration); + if (name.equals(CAR4WD)) + return new Car4WDTagParser(lookup, configuration); + if (name.equals(BIKE)) + return new BikeTagParser(lookup, configuration); + if (name.equals(BIKE2)) + return new Bike2WeightTagParser(lookup, configuration); + if (name.equals(RACINGBIKE)) + return new RacingBikeTagParser(lookup, configuration); + if (name.equals(MOUNTAINBIKE)) + return new MountainBikeTagParser(lookup, configuration); + if (name.equals(FOOT)) + return new FootTagParser(lookup, configuration); + if (name.equals(HIKE)) + return new HikeTagParser(lookup, configuration); + if (name.equals(MOTORCYCLE)) + return new MotorcycleTagParser(lookup, configuration); + if (name.equals(WHEELCHAIR)) + return new WheelchairTagParser(lookup, configuration); + + throw new IllegalArgumentException("Unknown name for vehicle tag parser: " + name); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java index dee0bb31642..c37e3a2d591 100644 --- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java +++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java @@ -17,7 +17,6 @@ */ package com.graphhopper.routing.util; -import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; @@ -105,8 +104,7 @@ private EncodingManager() { public static class Builder { private EncodingManager em; - private DateRangeParser dateRangeParser; - private final Map flagEncoderMap = new LinkedHashMap<>(); + private final Map flagEncoderMap = new LinkedHashMap<>(); private final Map encodedValueMap = new LinkedHashMap<>(); public Builder() { @@ -117,7 +115,7 @@ public Builder add(FlagEncoder encoder) { check(); if (flagEncoderMap.containsKey(encoder.toString())) throw new IllegalArgumentException("FlagEncoder already exists: " + encoder); - flagEncoderMap.put(encoder.toString(), (VehicleTagParser) encoder); + flagEncoderMap.put(encoder.toString(), (VehicleEncodedValues) encoder); return this; } @@ -155,31 +153,27 @@ public EncodingManager build() { em.addEncodedValue(new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class), false); } - if (dateRangeParser == null) - dateRangeParser = new DateRangeParser(DateRangeParser.createCalendar()); - - for (FlagEncoder encoder : flagEncoderMap.values()) { - if (encoder instanceof RoadsTagParser) { + for (VehicleEncodedValues encoder : flagEncoderMap.values()) { + if (encoder.getName().equals("roads")) { // TODO Later these EncodedValues can be added independently of RoadsFlagEncoder. Maybe add a foot_access and hgv_access? and remove the others "xy$access" if (!em.hasEncodedValue("car_access")) - em.addEncodedValue(new SimpleBooleanEncodedValue("car_access"), false); + em.addEncodedValue(new SimpleBooleanEncodedValue("car_access", true), false); if (!em.hasEncodedValue("bike_access")) - em.addEncodedValue(new SimpleBooleanEncodedValue("bike_access"), false); - } else if (encoder instanceof BikeCommonTagParser) { + em.addEncodedValue(new SimpleBooleanEncodedValue("bike_access", true), false); + } else if (encoder.getName().contains("bike") || encoder.getName().contains("mtb")) { if (!em.hasEncodedValue(RouteNetwork.key("bike"))) em.addEncodedValue(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class), false); if (!em.hasEncodedValue(GetOffBike.KEY)) em.addEncodedValue(GetOffBike.create(), false); if (!em.hasEncodedValue(Smoothness.KEY)) em.addEncodedValue(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class), false); - } else if (encoder instanceof FootTagParser) { + } else if (encoder.getName().contains("foot") || encoder.getName().contains("hike") || encoder.getName().contains("wheelchair")) { if (!em.hasEncodedValue(RouteNetwork.key("foot"))) em.addEncodedValue(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class), false); } } - for (VehicleTagParser encoder : flagEncoderMap.values()) { - encoder.init(dateRangeParser); + for (VehicleEncodedValues encoder : flagEncoderMap.values()) { em.addEncoder(encoder); } @@ -213,7 +207,7 @@ public int getIntsForFlags() { return edgeConfig.getRequiredInts(); } - private void addEncoder(VehicleTagParser encoder) { + private void addEncoder(VehicleEncodedValues encoder) { encoder.setEncodedValueLookup(this); List list = new ArrayList<>(); encoder.createEncodedValues(list); @@ -297,9 +291,10 @@ public String toFlagEncodersAsString() { if (str.length() > 0) str.append(","); - str.append(encoder.toString()) + str + .append(((VehicleEncodedValues) encoder).getName()) .append("|") - .append(((VehicleTagParser) encoder).getPropertiesString()); + .append(((VehicleEncodedValues) encoder).getSharedEncodedValueString()); } return str.toString(); @@ -403,8 +398,9 @@ public StringEncodedValue getStringEncodedValue(String key) { @Override public T getEncodedValue(String key, Class encodedValueType) { EncodedValue ev = encodedValueMap.get(key); + // todo: why do we not just return null when EV is missing? just like java.util.Map? -> https://github.com/graphhopper/graphhopper/pull/2561#discussion_r859770067 if (ev == null) - throw new IllegalArgumentException("Cannot find EncodedValue " + key + " in collection: " + ev); + throw new IllegalArgumentException("Cannot find EncodedValue " + key + " in collection: " + encodedValueMap.keySet()); return (T) ev; } diff --git a/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java index 8840f7ed4aa..978a203fed8 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java @@ -29,11 +29,7 @@ */ public interface FlagEncoder extends EncodedValueLookup { - default boolean isMotorVehicle() { - return getTransportationMode().isMotorVehicle(); - } - - TransportationMode getTransportationMode(); + boolean isMotorVehicle(); /** * @return the maximum speed in km/h @@ -50,13 +46,14 @@ default boolean isMotorVehicle() { */ DecimalEncodedValue getAverageSpeedEnc(); + DecimalEncodedValue getPriorityEnc(); + + DecimalEncodedValue getCurvatureEnc(); + + DecimalEncodedValue getTurnCostEnc(); + boolean supportsTurnCosts(); - /** - * Returns true if the feature class is supported like TurnWeighting or PriorityWeighting. - * Use support(String) instead. - */ - boolean supports(Class feature); /** * @return true if already registered in an EncodingManager diff --git a/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java b/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java index 3689995c3c5..5be8e989ac4 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java +++ b/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java @@ -4,82 +4,82 @@ public class FlagEncoders { public static FlagEncoder createFoot() { - return new FootTagParser(); + return createFoot(new PMap()); } public static FlagEncoder createFoot(PMap properties) { - return new FootTagParser(properties); + return VehicleEncodedValues.foot(properties); } public static FlagEncoder createHike() { - return new HikeTagParser(new PMap()); + return createHike(new PMap()); } public static FlagEncoder createHike(PMap properties) { - return new HikeTagParser(properties); + return VehicleEncodedValues.hike(properties); } public static FlagEncoder createWheelchair() { - return new WheelchairTagParser(); + return createWheelchair(new PMap()); } public static FlagEncoder createWheelchair(PMap properties) { - return new WheelchairTagParser(properties); + return VehicleEncodedValues.wheelchair(properties); } public static FlagEncoder createCar() { - return new CarTagParser(); + return createCar(new PMap()); } public static FlagEncoder createCar(PMap properties) { - return new CarTagParser(properties); + return VehicleEncodedValues.car(properties); } public static FlagEncoder createMotorcycle() { - return new MotorcycleTagParser(); + return createMotorcycle(new PMap()); } public static FlagEncoder createMotorcycle(PMap properties) { - return new MotorcycleTagParser(properties); + return VehicleEncodedValues.motorcycle(properties); } public static FlagEncoder createCar4wd(PMap properties) { - return new Car4WDTagParser(properties); + return VehicleEncodedValues.car4wd(properties); } public static FlagEncoder createRacingBike() { - return new RacingBikeTagParser(); + return createRacingBike(new PMap()); } public static FlagEncoder createRacingBike(PMap properties) { - return new RacingBikeTagParser(properties); + return VehicleEncodedValues.racingbike(properties); } public static FlagEncoder createBike() { - return new BikeTagParser(); + return createBike(new PMap()); } public static FlagEncoder createBike(PMap properties) { - return new BikeTagParser(properties); + return VehicleEncodedValues.bike(properties); } public static FlagEncoder createBike2() { - return new Bike2WeightTagParser(); + return createBike2(new PMap()); } public static FlagEncoder createBike2(PMap properties) { - return new Bike2WeightTagParser(properties); + return VehicleEncodedValues.bike2(properties); } public static FlagEncoder createMountainBike() { - return new MountainBikeTagParser(); + return createMountainBike(new PMap()); } public static FlagEncoder createMountainBike(PMap properties) { - return new MountainBikeTagParser(properties); + return VehicleEncodedValues.mountainbike(properties); } public static FlagEncoder createRoads() { - return new RoadsTagParser(); + return VehicleEncodedValues.roads(); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java b/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java index 9dbd883c5d0..489a52e86a2 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java @@ -19,7 +19,6 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.*; -import com.graphhopper.routing.weighting.PriorityWeighting; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; @@ -32,7 +31,7 @@ /** * Defines bit layout for pedestrians (speed, access, surface, ...). Here we put a penalty on unsafe * roads only. If you wish to also prefer routes due to beauty like hiking routes use the - * HikeFlagEncoder instead. + * HikeTagParser instead. *

* * @author Peter Karich @@ -54,27 +53,23 @@ public class FootTagParser extends VehicleTagParser { protected EnumEncodedValue footRouteEnc; protected Map routeMap = new HashMap<>(); - public FootTagParser() { - this(4, 1, false); - } - - public FootTagParser(PMap properties) { - this(properties.getString("name", "foot"), - properties.getInt("speed_bits", 4), - properties.getDouble("speed_factor", 1), - properties.getBool("speed_two_directions", false)); - + public FootTagParser(EncodedValueLookup lookup, PMap properties) { + this( + lookup.getBooleanEncodedValue(getKey(properties.getString("name", "foot"), "access")), + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "foot"), "average_speed")), + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "foot"), "priority")), + lookup.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class), + "foot" + ); blockPrivate(properties.getBool("block_private", true)); blockFords(properties.getBool("block_fords", false)); } - protected FootTagParser(int speedBits, double speedFactor, boolean speedTwoDirections) { - this("foot", speedBits, speedFactor, speedTwoDirections); - } - - protected FootTagParser(String name, int speedBits, double speedFactor, boolean speedTwoDirections) { - super(name, speedBits, speedFactor, speedTwoDirections, 0); - priorityWayEncoder = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); + protected FootTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, + EnumEncodedValue footRouteEnc, String name) { + super(accessEnc, speedEnc, name, null, null, TransportationMode.FOOT, speedEnc.getNextStorableValue(FERRY_SPEED)); + this.footRouteEnc = footRouteEnc; + priorityWayEncoder = priorityEnc; restrictedValues.add("no"); restrictedValues.add("restricted"); @@ -134,21 +129,6 @@ protected FootTagParser(String name, int speedBits, double speedFactor, boolean allowedSacScale.add("hiking"); allowedSacScale.add("mountain_hiking"); allowedSacScale.add("demanding_mountain_hiking"); - - maxPossibleSpeed = avgSpeedEnc.getNextStorableValue(FERRY_SPEED); - } - - @Override - public TransportationMode getTransportationMode() { - return TransportationMode.FOOT; - } - - @Override - public void createEncodedValues(List registerNewEncodedValue) { - super.createEncodedValues(registerNewEncodedValue); - registerNewEncodedValue.add(priorityWayEncoder); - - footRouteEnc = getEnumEncodedValue(RouteNetwork.key("foot"), RouteNetwork.class); } /** @@ -287,12 +267,4 @@ void collect(ReaderWay way, TreeMap weightToPrioMap) { if (way.hasTag("bicycle", "official") || way.hasTag("bicycle", "designated")) weightToPrioMap.put(44d, SLIGHT_AVOID.getValue()); } - - @Override - public boolean supports(Class feature) { - if (super.supports(feature)) - return true; - - return PriorityWeighting.class.isAssignableFrom(feature); - } } diff --git a/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java index 80090badc5e..75c0ff9817b 100644 --- a/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java @@ -18,13 +18,14 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.weighting.PriorityWeighting; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.*; import java.util.TreeMap; import static com.graphhopper.routing.ev.RouteNetwork.*; +import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.PriorityCode.*; /** @@ -34,27 +35,21 @@ */ public class HikeTagParser extends FootTagParser { - public HikeTagParser() { - this(4, 1, false); - } - - public HikeTagParser(PMap properties) { + public HikeTagParser(EncodedValueLookup lookup, PMap properties) { this( - properties.getString("name", "hike"), - properties.getInt("speed_bits", 4), - properties.getDouble("speed_factor", 1), - properties.getBool("speed_two_directions", false)); - + lookup.getBooleanEncodedValue(getKey(properties.getString("name", "hike"), "access")), + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "hike"), "average_speed")), + lookup.getDecimalEncodedValue(getKey(properties.getString("name", "hike"), "priority")), + lookup.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class), + properties.getString("name", "hike") + ); blockPrivate(properties.getBool("block_private", true)); blockFords(properties.getBool("block_fords", false)); } - protected HikeTagParser(int speedBits, double speedFactor, boolean speedTwoDirections) { - this("hike", speedBits, speedFactor, speedTwoDirections); - } - - protected HikeTagParser(String name, int speedBits, double speedFactor, boolean speedTwoDirections) { - super(name, speedBits, speedFactor, speedTwoDirections); + protected HikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, + EnumEncodedValue footRouteEnc, String name) { + super(accessEnc, speedEnc, priorityEnc, footRouteEnc, name); routeMap.put(INTERNATIONAL, BEST.getValue()); routeMap.put(NATIONAL, BEST.getValue()); @@ -129,12 +124,4 @@ public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { } } - @Override - public boolean supports(Class feature) { - if (super.supports(feature)) - return true; - - return PriorityWeighting.class.isAssignableFrom(feature); - } - } diff --git a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java index 8af5c74b7f5..6326d4d80ce 100644 --- a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java @@ -18,12 +18,8 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValueImpl; -import com.graphhopper.routing.ev.EncodedValue; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; -import com.graphhopper.routing.weighting.CurvatureWeighting; -import com.graphhopper.routing.weighting.PriorityWeighting; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.DistanceCalcEarth; import com.graphhopper.util.EdgeIteratorState; @@ -31,7 +27,6 @@ import com.graphhopper.util.PointList; import java.util.HashSet; -import java.util.List; import static com.graphhopper.routing.util.EncodingManager.getKey; @@ -43,20 +38,31 @@ * @author boldtrn */ public class MotorcycleTagParser extends CarTagParser { + public static final double MOTOR_CYCLE_MAX_SPEED = 120; private final HashSet avoidSet = new HashSet<>(); private final HashSet preferSet = new HashSet<>(); private final DecimalEncodedValue priorityWayEncoder; private final DecimalEncodedValue curvatureEncoder; - public MotorcycleTagParser() { - this(new PMap()); + public MotorcycleTagParser(EncodedValueLookup lookup, PMap properties) { + this( + lookup.getBooleanEncodedValue(getKey("motorcycle", "access")), + lookup.getDecimalEncodedValue(getKey("motorcycle", "average_speed")), + lookup.hasEncodedValue(TurnCost.key("motorcycle")) ? lookup.getDecimalEncodedValue(TurnCost.key("motorcycle")) : null, + lookup.getBooleanEncodedValue(Roundabout.KEY), + lookup.getDecimalEncodedValue(getKey("motorcycle", "priority")), + lookup.getDecimalEncodedValue(getKey("motorcycle", "curvature")), + new PMap(properties).putObject("name", "motorcycle"), + TransportationMode.MOTORCYCLE + ); } - public MotorcycleTagParser(PMap properties) { - super(properties.putObject("name", "motorcycle").putObject("speed_two_directions", true)); - - priorityWayEncoder = new DecimalEncodedValueImpl(getKey(getName(), "priority"), 4, PriorityCode.getFactor(1), false); - curvatureEncoder = new DecimalEncodedValueImpl(getKey(getName(), "curvature"), 4, 0.1, false); + public MotorcycleTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue turnCostEnc, + BooleanEncodedValue roundaboutEnc, + DecimalEncodedValue priorityWayEncoder, DecimalEncodedValue curvatureEnc, PMap properties, TransportationMode transportationMode) { + super(accessEnc, speedEnc, turnCostEnc, roundaboutEnc, new PMap(properties).putObject("name", "motorcycle"), transportationMode, speedEnc.getNextStorableValue(MOTOR_CYCLE_MAX_SPEED)); + this.priorityWayEncoder = priorityWayEncoder; + this.curvatureEncoder = curvatureEnc; barriers.remove("bus_trap"); barriers.remove("sump_buster"); @@ -79,8 +85,6 @@ public MotorcycleTagParser(PMap properties) { preferSet.add("secondary"); preferSet.add("tertiary"); - maxPossibleSpeed = avgSpeedEnc.getNextStorableValue(properties.getDouble("max_speed", 120)); - // autobahn defaultSpeedMap.put("motorway", 100); defaultSpeedMap.put("motorway_link", 70); @@ -108,16 +112,6 @@ public MotorcycleTagParser(PMap properties) { defaultSpeedMap.put("track", 15); } - /** - * Define the place of the speedBits in the edge flags for car. - */ - @Override - public void createEncodedValues(List registerNewEncodedValue) { - super.createEncodedValues(registerNewEncodedValue); - registerNewEncodedValue.add(priorityWayEncoder); - registerNewEncodedValue.add(curvatureEncoder); - } - @Override public EncodingManager.Access getAccess(ReaderWay way) { String highwayValue = way.getTag("highway"); @@ -280,21 +274,4 @@ protected double increaseBendinessImpact(double bendiness) { return (Math.pow(bendiness, 2)); } - @Override - public TransportationMode getTransportationMode() { - return TransportationMode.MOTORCYCLE; - } - - @Override - public boolean supports(Class feature) { - if (super.supports(feature)) - return true; - - if (CurvatureWeighting.class.isAssignableFrom(feature)) { - return true; - } - - return PriorityWeighting.class.isAssignableFrom(feature); - } - } diff --git a/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java index ce11331c8ce..b02fc0e1f65 100644 --- a/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java @@ -18,11 +18,13 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.*; import com.graphhopper.util.PMap; import java.util.TreeMap; import static com.graphhopper.routing.ev.RouteNetwork.*; +import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.PriorityCode.*; /** @@ -33,21 +35,26 @@ * @author Peter Karich */ public class MountainBikeTagParser extends BikeCommonTagParser { - public MountainBikeTagParser() { - this(4, 2, 0); - } - - public MountainBikeTagParser(PMap properties) { - this(properties.getInt("speed_bits", 4), - properties.getDouble("speed_factor", 2), - properties.getBool("turn_costs", false) ? 1 : 0); + public MountainBikeTagParser(EncodedValueLookup lookup, PMap properties) { + this( + lookup.getBooleanEncodedValue(getKey("mtb", "access")), + lookup.getDecimalEncodedValue(getKey("mtb", "average_speed")), + lookup.getDecimalEncodedValue(getKey("mtb", "priority")), + lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), + lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class), + lookup.getBooleanEncodedValue(Roundabout.KEY), + lookup.hasEncodedValue(TurnCost.key("mtb")) ? lookup.getDecimalEncodedValue(TurnCost.key("mtb")) : null + ); blockPrivate(properties.getBool("block_private", true)); blockFords(properties.getBool("block_fords", false)); } - protected MountainBikeTagParser(int speedBits, double speedFactor, int maxTurnCosts) { - super("mtb", speedBits, speedFactor, maxTurnCosts, false); + protected MountainBikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, + EnumEncodedValue bikeRouteEnc, EnumEncodedValue smoothnessEnc, + BooleanEncodedValue roundaboutEnc, + DecimalEncodedValue turnCostEnc) { + super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, "mtb", roundaboutEnc, turnCostEnc); setTrackTypeSpeed("grade1", 18); // paved setTrackTypeSpeed("grade2", 16); // now unpaved ... setTrackTypeSpeed("grade3", 12); diff --git a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java new file mode 100644 index 00000000000..858bbae3c60 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java @@ -0,0 +1,112 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util; + +import com.graphhopper.reader.OSMTurnRelation; +import com.graphhopper.reader.ReaderRelation; +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.EncodedValue; +import com.graphhopper.routing.util.parsers.OSMTurnRelationParser; +import com.graphhopper.routing.util.parsers.RelationTagParser; +import com.graphhopper.routing.util.parsers.TagParser; +import com.graphhopper.routing.util.parsers.TurnCostParser; +import com.graphhopper.storage.Graph; +import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.EdgeIteratorState; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +public class OSMParsers { + private final List wayTagParsers; + private final List vehicleTagParsers; + private final List relationTagParsers; + private final List turnCostParsers; + private final EncodedValue.InitializerConfig relConfig = new EncodedValue.InitializerConfig(); + + public OSMParsers() { + this(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); + } + + public OSMParsers(List wayTagParsers, List vehicleTagParsers, List relationTagParsers, List turnCostParsers) { + this.wayTagParsers = wayTagParsers; + this.vehicleTagParsers = vehicleTagParsers; + this.relationTagParsers = relationTagParsers; + this.turnCostParsers = turnCostParsers; + } + + public OSMParsers addWayTagParser(TagParser tagParser) { + wayTagParsers.add(tagParser); + return this; + } + + public OSMParsers addVehicleTagParser(VehicleTagParser vehicleTagParser) { + vehicleTagParsers.add(vehicleTagParser); + if (vehicleTagParser.supportsTurnCosts()) + turnCostParsers.add(new OSMTurnRelationParser(vehicleTagParser.getAccessEnc(), vehicleTagParser.getTurnCostEnc(), vehicleTagParser.getRestrictions())); + return this; + } + + public OSMParsers addRelationTagParser(Function createRelationTagParser) { + relationTagParsers.add(createRelationTagParser.apply(relConfig)); + return this; + } + + public OSMParsers addTurnCostTagParser(TurnCostParser turnCostParser) { + turnCostParsers.add(turnCostParser); + return this; + } + + public boolean acceptWay(ReaderWay way) { + return vehicleTagParsers.stream().anyMatch(v -> !v.getAccess(way).equals(EncodingManager.Access.CAN_SKIP)); + } + + public IntsRef handleRelationTags(ReaderRelation relation, IntsRef relFlags) { + for (RelationTagParser relParser : relationTagParsers) { + relParser.handleRelationTags(relFlags, relation); + } + return relFlags; + } + + public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + for (RelationTagParser relParser : relationTagParsers) + relParser.handleWayTags(edgeFlags, way, relationFlags); + for (TagParser parser : wayTagParsers) + parser.handleWayTags(edgeFlags, way, relationFlags); + for (VehicleTagParser vehicleTagParser : vehicleTagParsers) + vehicleTagParser.handleWayTags(edgeFlags, way, relationFlags); + return edgeFlags; + } + + public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { + vehicleTagParsers.forEach(t -> t.applyWayTags(way, edge)); + } + + public void handleTurnRelationTags(OSMTurnRelation turnRelation, TurnCostParser.ExternalInternalMap map, Graph graph) { + turnCostParsers.forEach(t -> t.handleTurnRelationTags(turnRelation, map, graph)); + } + + public IntsRef createRelationFlags() { + int requiredInts = relConfig.getRequiredInts(); + if (requiredInts > 2) + throw new IllegalStateException("More than two ints are needed for relation flags, but OSMReader does not allow this"); + return new IntsRef(2); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java index 5a5aa83c86c..68b678fe698 100644 --- a/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java @@ -18,11 +18,13 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.*; import com.graphhopper.util.PMap; import java.util.TreeMap; import static com.graphhopper.routing.ev.RouteNetwork.*; +import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.PriorityCode.*; /** @@ -32,21 +34,23 @@ * @author Peter Karich */ public class RacingBikeTagParser extends BikeCommonTagParser { - public RacingBikeTagParser() { - this(4, 2, 0); - } - - public RacingBikeTagParser(PMap properties) { - this(properties.getInt("speed_bits", 4), - properties.getDouble("speed_factor", 2), - properties.getBool("turn_costs", false) ? 1 : 0); - blockPrivate(properties.getBool("block_private", true)); - blockFords(properties.getBool("block_fords", false)); + public RacingBikeTagParser(EncodedValueLookup lookup, PMap properties) { + this( + lookup.getBooleanEncodedValue(getKey("racingbike", "access")), + lookup.getDecimalEncodedValue(getKey("racingbike", "average_speed")), + lookup.getDecimalEncodedValue(getKey("racingbike", "priority")), + lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), + lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class), + lookup.getBooleanEncodedValue(Roundabout.KEY), + lookup.hasEncodedValue(TurnCost.key("racingbike")) ? lookup.getDecimalEncodedValue(TurnCost.key("racingbike")) : null + ); } - protected RacingBikeTagParser(int speedBits, double speedFactor, int maxTurnCosts) { - super("racingbike", speedBits, speedFactor, maxTurnCosts, false); + protected RacingBikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, + EnumEncodedValue bikeRouteEnc, EnumEncodedValue smoothnessEnc, + BooleanEncodedValue roundaboutEnc, DecimalEncodedValue turnCostEnc) { + super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, "racingbike", roundaboutEnc, turnCostEnc); preferHighwayTags.add("road"); preferHighwayTags.add("secondary"); preferHighwayTags.add("secondary_link"); diff --git a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java index 6e2c60c4b00..0102c904be9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java @@ -1,13 +1,27 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.storage.IntsRef; +import static com.graphhopper.routing.util.EncodingManager.getKey; + public class RoadsTagParser extends VehicleTagParser { + public static final double ROADS_MAX_SPEED = 254; + + public RoadsTagParser(EncodedValueLookup lookup) { + this( + lookup.getBooleanEncodedValue(getKey("roads", "access")), + lookup.getDecimalEncodedValue(getKey("roads", "average_speed")), + lookup.getDecimalEncodedValue(TurnCost.key("roads")) + ); + } - public RoadsTagParser() { - super("roads", 7, 2, true, 3); - maxPossibleSpeed = avgSpeedEnc.getNextStorableValue(254); + public RoadsTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue turnCostEnc) { + super(accessEnc, speedEnc, "roads", null, turnCostEnc, TransportationMode.VEHICLE, speedEnc.getNextStorableValue(ROADS_MAX_SPEED)); } @Override @@ -29,9 +43,4 @@ public EncodingManager.Access getAccess(ReaderWay way) { return EncodingManager.Access.WAY; } - @Override - public TransportationMode getTransportationMode() { - return TransportationMode.VEHICLE; - } - } diff --git a/core/src/main/java/com/graphhopper/routing/util/TagParserManager.java b/core/src/main/java/com/graphhopper/routing/util/TagParserManager.java deleted file mode 100644 index e49ecb9bb59..00000000000 --- a/core/src/main/java/com/graphhopper/routing/util/TagParserManager.java +++ /dev/null @@ -1,581 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.routing.util; - -import com.graphhopper.reader.OSMTurnRelation; -import com.graphhopper.reader.ReaderRelation; -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.reader.osm.conditional.DateRangeParser; -import com.graphhopper.routing.ev.*; -import com.graphhopper.routing.util.parsers.*; -import com.graphhopper.storage.Graph; -import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.EdgeIteratorState; -import com.graphhopper.util.PMap; - -import java.util.*; -import java.util.stream.Collectors; - -import static com.graphhopper.routing.util.EncodingManager.isValidEncodedValue; -import static com.graphhopper.util.Helper.toLowerCase; -import static java.util.Collections.emptyMap; - -/** - * Manager class to register encoder, assign their flag values and check objects with all encoders - * during parsing. Create one via: - *

- * EncodingManager.start(4).add(new CarFlagEncoder()).build(); - * - * @author Peter Karich - * @author Nop - */ -public class TagParserManager implements EncodedValueLookup { - private final List edgeEncoders = new ArrayList<>(); - private final Map encodedValueMap = new LinkedHashMap<>(); - private final List relationTagParsers = new ArrayList<>(); - private final List edgeTagParsers = new ArrayList<>(); - private final Map turnCostParsers = new LinkedHashMap<>(); - private final EncodedValue.InitializerConfig turnCostConfig; - private final EncodedValue.InitializerConfig relationConfig; - private final EncodedValue.InitializerConfig edgeConfig; - private EncodingManager encodingManager; - - /** - * Instantiate manager with the given list of encoders. The manager knows several default - * encoders using DefaultFlagEncoderFactory. - */ - public static TagParserManager create(String flagEncodersStr) { - return create(new DefaultFlagEncoderFactory(), flagEncodersStr); - } - - public static TagParserManager create(FlagEncoderFactory factory, String flagEncodersStr) { - return createBuilder(Arrays.stream(flagEncodersStr.split(",")).filter(s -> !s.trim().isEmpty()). - map(s -> parseEncoderString(factory, s)).collect(Collectors.toList())).build(); - } - - /** - * Instantiate manager with the given list of encoders. - */ - public static TagParserManager create(FlagEncoder... flagEncoders) { - return create(Arrays.asList(flagEncoders)); - } - - /** - * Instantiate manager with the given list of encoders. - */ - public static TagParserManager create(List flagEncoders) { - return createBuilder(flagEncoders).build(); - } - - private static TagParserManager.Builder createBuilder(List flagEncoders) { - Builder builder = new Builder(); - for (FlagEncoder flagEncoder : flagEncoders) { - builder.add(flagEncoder); - } - return builder; - } - - /** - * Starts the build process of an EncodingManager - */ - public static Builder start() { - return new Builder(); - } - - private TagParserManager() { - this.turnCostConfig = new EncodedValue.InitializerConfig(); - this.relationConfig = new EncodedValue.InitializerConfig(); - this.edgeConfig = new EncodedValue.InitializerConfig(); - } - - public EncodingManager getEncodingManager() { - return encodingManager; - } - - public void releaseParsers() { - turnCostParsers.clear(); - edgeTagParsers.clear(); - relationTagParsers.clear(); - } - - public static class Builder { - private TagParserManager em; - private DateRangeParser dateRangeParser; - private final Map flagEncoderMap = new LinkedHashMap<>(); - private final Map encodedValueMap = new LinkedHashMap<>(); - private final Set tagParserSet = new LinkedHashSet<>(); - private final List turnCostParsers = new ArrayList<>(); - private final List relationTagParsers = new ArrayList<>(); - - public Builder() { - em = new TagParserManager(); - } - - public boolean addIfAbsent(FlagEncoderFactory factory, String flagEncoderString) { - check(); - String key = flagEncoderString.split("\\|")[0].trim(); - if (flagEncoderMap.containsKey(key)) - return false; - FlagEncoder fe = parseEncoderString(factory, flagEncoderString); - flagEncoderMap.put(fe.toString(), (VehicleTagParser) fe); - return true; - } - - public boolean addIfAbsent(EncodedValueFactory encodedValueFactory, TagParserFactory factory, String tagParserString) { - check(); - tagParserString = tagParserString.trim(); - if (tagParserString.isEmpty()) return false; - - if (!tagParserString.equals(toLowerCase(tagParserString))) - throw new IllegalArgumentException("Use lower case for TagParser: " + tagParserString); - - add(encodedValueFactory.create(tagParserString)); - - TagParser tagParser = factory.create(new EncodedValueLookup() { - @Override - public List getEncodedValues() { - return new ArrayList<>(encodedValueMap.values()); - } - - @Override - public T getEncodedValue(String key, Class encodedValueType) { - return (T) encodedValueMap.get(key); - } - - @Override - public BooleanEncodedValue getBooleanEncodedValue(String key) { - return (BooleanEncodedValue) encodedValueMap.get(key); - } - - @Override - public IntEncodedValue getIntEncodedValue(String key) { - return (IntEncodedValue) encodedValueMap.get(key); - } - - @Override - public DecimalEncodedValue getDecimalEncodedValue(String key) { - return (DecimalEncodedValue) encodedValueMap.get(key); - } - - @Override - public > EnumEncodedValue getEnumEncodedValue(String key, Class enumType) { - return (EnumEncodedValue) encodedValueMap.get(key); - } - - @Override - public StringEncodedValue getStringEncodedValue(String key) { - return (StringEncodedValue) encodedValueMap.get(key); - } - - @Override - public boolean hasEncodedValue(String key) { - return encodedValueMap.containsKey(key); - } - }, tagParserString); - return tagParserSet.add(tagParser); - } - - public Builder addTurnCostParser(TurnCostParser parser) { - check(); - turnCostParsers.add(parser); - return this; - } - - public Builder addRelationTagParser(RelationTagParser tagParser) { - check(); - relationTagParsers.add(tagParser); - return this; - } - - public Builder add(FlagEncoder encoder) { - check(); - if (flagEncoderMap.containsKey(encoder.toString())) - throw new IllegalArgumentException("FlagEncoder already exists: " + encoder); - flagEncoderMap.put(encoder.toString(), (VehicleTagParser) encoder); - return this; - } - - public Builder add(EncodedValue encodedValue) { - check(); - if (encodedValueMap.containsKey(encodedValue.getName())) - throw new IllegalArgumentException("EncodedValue already exists: " + encodedValue.getName()); - encodedValueMap.put(encodedValue.getName(), encodedValue); - return this; - } - - /** - * This method adds the specified TagParser and automatically adds EncodedValues as requested in - * createEncodedValues. - */ - public Builder add(TagParser tagParser) { - check(); - if (!tagParserSet.add(tagParser)) - throw new IllegalArgumentException("TagParser already exists: " + tagParser); - - return this; - } - - public Builder setDateRangeParser(DateRangeParser dateRangeParser) { - check(); - this.dateRangeParser = dateRangeParser; - return this; - } - - private void check() { - if (em == null) - throw new IllegalStateException("Cannot call method after Builder.build() was called"); - } - - private void _addEdgeTagParser(TagParser tagParser) { - if (!em.edgeEncoders.isEmpty()) - throw new IllegalStateException("Avoid mixing encoded values from FlagEncoder with shared encoded values until we have a more clever mechanism, see #1862"); - em.edgeTagParsers.add(tagParser); - } - - private void _addRelationTagParser(RelationTagParser tagParser) { - em.relationTagParsers.add(tagParser); - _addEdgeTagParser(tagParser); - } - - private void _addTurnCostParser(TurnCostParser parser) { - List list = new ArrayList<>(); - parser.createTurnCostEncodedValues(em, list); - for (EncodedValue ev : list) { - ev.init(em.turnCostConfig); - if (em.encodedValueMap.containsKey(ev.getName())) - throw new IllegalArgumentException("Already defined: " + ev.getName() + ". Please note that " + - "EncodedValues for edges and turn cost are in the same namespace."); - em.encodedValueMap.put(ev.getName(), ev); - } - em.turnCostParsers.put(parser.getName(), parser); - } - - public TagParserManager build() { - check(); - - for (RelationTagParser tagParser : relationTagParsers) { - _addRelationTagParser(tagParser); - } - - for (TagParser tagParser : tagParserSet) { - _addEdgeTagParser(tagParser); - } - - for (EncodedValue ev : encodedValueMap.values()) { - em.addEncodedValue(ev, false); - } - - if (!em.hasEncodedValue(Roundabout.KEY)) { - em.addEncodedValue(Roundabout.create(), false); - _addEdgeTagParser(new OSMRoundaboutParser(em.getBooleanEncodedValue(Roundabout.KEY))); - } - if (!em.hasEncodedValue(RoadClass.KEY)) { - em.addEncodedValue(new EnumEncodedValue<>(RoadClass.KEY, RoadClass.class), false); - _addEdgeTagParser(new OSMRoadClassParser(em.getEnumEncodedValue(RoadClass.KEY, RoadClass.class))); - } - if (!em.hasEncodedValue(RoadClassLink.KEY)) { - em.addEncodedValue(new SimpleBooleanEncodedValue(RoadClassLink.KEY), false); - _addEdgeTagParser(new OSMRoadClassLinkParser(em.getBooleanEncodedValue(RoadClassLink.KEY))); - } - if (!em.hasEncodedValue(RoadEnvironment.KEY)) { - em.addEncodedValue(new EnumEncodedValue<>(RoadEnvironment.KEY, RoadEnvironment.class), false); - _addEdgeTagParser(new OSMRoadEnvironmentParser(em.getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class))); - } - if (!em.hasEncodedValue(MaxSpeed.KEY)) { - em.addEncodedValue(MaxSpeed.create(), false); - _addEdgeTagParser(new OSMMaxSpeedParser(em.getDecimalEncodedValue(MaxSpeed.KEY))); - } - if (!em.hasEncodedValue(RoadAccess.KEY)) { - em.addEncodedValue(new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class), false); - // TODO introduce road_access for different vehicles? But how to create it in DefaultTagParserFactory? - _addEdgeTagParser(new OSMRoadAccessParser(em.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR))); - } - - if (dateRangeParser == null) - dateRangeParser = new DateRangeParser(DateRangeParser.createCalendar()); - - for (VehicleTagParser encoder : flagEncoderMap.values()) { - if (encoder instanceof RoadsTagParser) { - // TODO Later these EncodedValues can be added independently of RoadsFlagEncoder. Maybe add a foot_access and hgv_access? and remove the others "xy$access" - if (!em.hasEncodedValue("car_access")) { - em.addEncodedValue(new SimpleBooleanEncodedValue("car_access", true), false); - _addEdgeTagParser(new OSMAccessParser(em.getBooleanEncodedValue("car_access"), em.getBooleanEncodedValue(Roundabout.KEY), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR), TransportationMode.CAR)); - } - if (!em.hasEncodedValue("bike_access")) { - em.addEncodedValue(new SimpleBooleanEncodedValue("bike_access", true), false); - _addEdgeTagParser(new OSMAccessParser(em.getBooleanEncodedValue("bike_access"), em.getBooleanEncodedValue(Roundabout.KEY), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.BIKE), TransportationMode.BIKE)); - } - } else if (encoder instanceof BikeCommonTagParser) { - if (!em.hasEncodedValue(RouteNetwork.key("bike"))) { - em.addEncodedValue(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class), false); - _addRelationTagParser(new OSMBikeNetworkTagParser(em.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), em.relationConfig)); - } - if (!em.hasEncodedValue(GetOffBike.KEY)) { - em.addEncodedValue(GetOffBike.create(), false); - _addEdgeTagParser(new OSMGetOffBikeParser(em.getBooleanEncodedValue(GetOffBike.KEY))); - } - if (!em.hasEncodedValue(Smoothness.KEY)) { - em.addEncodedValue(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class), false); - _addEdgeTagParser(new OSMSmoothnessParser(em.getEnumEncodedValue(Smoothness.KEY, Smoothness.class))); - } - } else if (encoder instanceof FootTagParser) { - if (!em.hasEncodedValue(RouteNetwork.key("foot"))) - em.addEncodedValue(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class), false); - _addRelationTagParser(new OSMFootNetworkTagParser(em.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class), em.relationConfig)); - } - } - - for (VehicleTagParser encoder : flagEncoderMap.values()) { - encoder.init(dateRangeParser); - em.addEncoder(encoder); - } - - for (TurnCostParser parser : turnCostParsers) { - _addTurnCostParser(parser); - } - - // FlagEncoder can demand TurnCostParsers => add them after the explicitly added ones - for (VehicleTagParser encoder : flagEncoderMap.values()) { - if (encoder.supportsTurnCosts() && !em.turnCostParsers.containsKey(TurnCost.key(encoder.toString()))) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue turnCostEnc = encoder.getTurnCostEnc(); - _addTurnCostParser(new OSMTurnRelationParser(accessEnc, turnCostEnc, encoder.getRestrictions())); - } - } - - if (em.encodedValueMap.isEmpty()) - throw new IllegalStateException("No EncodedValues found"); - - em.encodingManager = new EncodingManager(new ArrayList<>(em.edgeEncoders), em.encodedValueMap, - em.turnCostConfig, em.edgeConfig); - - TagParserManager tmp = em; - em = null; - return tmp; - } - } - - static FlagEncoder parseEncoderString(FlagEncoderFactory factory, String encoderString) { - if (!encoderString.equals(toLowerCase(encoderString))) - throw new IllegalArgumentException("An upper case name for the FlagEncoder is not allowed: " + encoderString); - - encoderString = encoderString.trim(); - if (encoderString.isEmpty()) - throw new IllegalArgumentException("FlagEncoder cannot be empty. " + encoderString); - - String entryVal = ""; - if (encoderString.contains("|")) { - entryVal = encoderString; - encoderString = encoderString.split("\\|")[0]; - } - PMap configuration = new PMap(entryVal); - return factory.createFlagEncoder(encoderString, configuration); - } - - public int getIntsForFlags() { - return edgeConfig.getRequiredInts(); - } - - private void addEncoder(VehicleTagParser encoder) { - encoder.setEncodedValueLookup(this); - List list = new ArrayList<>(); - encoder.createEncodedValues(list); - for (EncodedValue ev : list) - addEncodedValue(ev, true); - edgeEncoders.add(encoder); - } - - private void addEncodedValue(EncodedValue ev, boolean withNamespace) { - String normalizedKey = ev.getName().replaceAll(SPECIAL_SEPARATOR, "_"); - if (hasEncodedValue(normalizedKey)) - throw new IllegalStateException("EncodedValue " + ev.getName() + " collides with " + normalizedKey); - if (!withNamespace && !isSharedEncodedValues(ev)) - throw new IllegalArgumentException("EncodedValue " + ev.getName() + " must not contain namespace character '" + SPECIAL_SEPARATOR + "'"); - if (withNamespace && isSharedEncodedValues(ev)) - throw new IllegalArgumentException("EncodedValue " + ev.getName() + " must contain namespace character '" + SPECIAL_SEPARATOR + "'"); - ev.init(edgeConfig); - encodedValueMap.put(ev.getName(), ev); - } - - public boolean hasEncodedValue(String key) { - return encodedValueMap.get(key) != null; - } - - /** - * @return true if the specified encoder is found - */ - public boolean hasEncoder(String encoder) { - return getEncoder(encoder, false) != null; - } - - public FlagEncoder getEncoder(String name) { - return getEncoder(name, true); - } - - private FlagEncoder getEncoder(String name, boolean throwExc) { - for (FlagEncoder encoder : edgeEncoders) { - if (name.equalsIgnoreCase(encoder.toString())) - return encoder; - } - if (throwExc) - throw new IllegalArgumentException("FlagEncoder for " + name + " not found. Existing: " + edgeEncoders.stream().map(FlagEncoder::toString).collect(Collectors.toList())); - return null; - } - - /** - * Determine whether a way is routable for one of the added encoders. - * - * @return if at least one encoder consumes the specified way - */ - public boolean acceptWay(ReaderWay way) { - return edgeEncoders.stream().anyMatch(encoder -> !encoder.getAccess(way).equals(EncodingManager.Access.CAN_SKIP)); - } - - public IntsRef handleRelationTags(ReaderRelation relation, IntsRef relFlags) { - for (RelationTagParser relParser : relationTagParsers) { - relParser.handleRelationTags(relFlags, relation); - } - return relFlags; - } - - public void handleTurnRelationTags(OSMTurnRelation turnRelation, TurnCostParser.ExternalInternalMap map, Graph graph) { - for (TurnCostParser parser : turnCostParsers.values()) { - parser.handleTurnRelationTags(turnRelation, map, graph); - } - } - - /** - * Processes way properties of different kind to determine speed and direction. - * - * @param relationFlags The preprocessed relation flags is used to influence the way properties. - */ - public IntsRef handleWayTags(ReaderWay way, IntsRef relationFlags) { - IntsRef edgeFlags = createEdgeFlags(); - for (TagParser parser : edgeTagParsers) { - parser.handleWayTags(edgeFlags, way, relationFlags); - } - for (VehicleTagParser encoder : edgeEncoders) { - encoder.handleWayTags(edgeFlags, way); - if (!edgeFlags.isEmpty()) { - Map nodeTags = way.getTag("node_tags", emptyMap()); - encoder.handleNodeTags(edgeFlags, nodeTags); - } - } - return edgeFlags; - } - - @Override - public String toString() { - StringBuilder str = new StringBuilder(); - for (FlagEncoder encoder : edgeEncoders) { - if (str.length() > 0) - str.append(","); - - str.append(encoder.toString()); - } - - return str.toString(); - } - - // TODO hide IntsRef even more in a later version: https://gist.github.com/karussell/f4c2b2b1191be978d7ee9ec8dd2cd48f - public IntsRef createEdgeFlags() { - return new IntsRef(getIntsForFlags()); - } - - public IntsRef createRelationFlags() { - // for backward compatibility use 2 ints - return new IntsRef(2); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - TagParserManager that = (TagParserManager) o; - return edgeEncoders.equals(that.edgeEncoders) && - encodedValueMap.equals(that.encodedValueMap); - } - - @Override - public int hashCode() { - return Objects.hash(edgeEncoders, encodedValueMap); - } - - public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { - for (VehicleTagParser encoder : edgeEncoders) - encoder.applyWayTags(way, edge); - } - - public List fetchEdgeEncoders() { - return new ArrayList<>(edgeEncoders); - } - - public boolean needsTurnCostsSupport() { - for (FlagEncoder encoder : edgeEncoders) { - if (encoder.supportsTurnCosts()) - return true; - } - return false; - } - - @Override - public List getEncodedValues() { - return Collections.unmodifiableList(new ArrayList<>(encodedValueMap.values())); - } - - @Override - public BooleanEncodedValue getBooleanEncodedValue(String key) { - return getEncodedValue(key, BooleanEncodedValue.class); - } - - @Override - public IntEncodedValue getIntEncodedValue(String key) { - return getEncodedValue(key, IntEncodedValue.class); - } - - @Override - public DecimalEncodedValue getDecimalEncodedValue(String key) { - return getEncodedValue(key, DecimalEncodedValue.class); - } - - @SuppressWarnings("unchecked") - @Override - public > EnumEncodedValue getEnumEncodedValue(String key, Class type) { - return getEncodedValue(key, EnumEncodedValue.class); - } - - @Override - public StringEncodedValue getStringEncodedValue(String key) { - return getEncodedValue(key, StringEncodedValue.class); - } - - @Override - public T getEncodedValue(String key, Class encodedValueType) { - EncodedValue ev = encodedValueMap.get(key); - if (ev == null) - throw new IllegalArgumentException("Cannot find EncodedValue " + key + " in collection: " + ev); - return (T) ev; - } - - private static final String SPECIAL_SEPARATOR = "$"; - - private static boolean isSharedEncodedValues(EncodedValue ev) { - return isValidEncodedValue(ev.getName()) && !ev.getName().contains(SPECIAL_SEPARATOR); - } - -} \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java new file mode 100644 index 00000000000..90a58934f80 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -0,0 +1,283 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util; + +import com.graphhopper.routing.ev.*; +import com.graphhopper.util.PMap; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.graphhopper.routing.util.BikeCommonTagParser.BIKE_MAX_SPEED; +import static com.graphhopper.routing.util.CarTagParser.CAR_MAX_SPEED; +import static com.graphhopper.routing.util.EncodingManager.getKey; +import static com.graphhopper.routing.util.FootTagParser.FERRY_SPEED; +import static com.graphhopper.routing.util.MotorcycleTagParser.MOTOR_CYCLE_MAX_SPEED; +import static com.graphhopper.routing.util.RoadsTagParser.ROADS_MAX_SPEED; + +public final class VehicleEncodedValues implements FlagEncoder { + private final String name; + private final boolean isMotorVehicle; + private final double maxPossibleSpeed; + private final BooleanEncodedValue accessEnc; + private final DecimalEncodedValue avgSpeedEnc; + private final DecimalEncodedValue priorityEnc; + private final DecimalEncodedValue curvatureEnc; + private final DecimalEncodedValue turnCostEnc; + private EncodedValueLookup encodedValueLookup; + + public static VehicleEncodedValues foot(PMap properties) { + String name = properties.getString("name", "foot"); + int speedBits = properties.getInt("speed_bits", 4); + double speedFactor = properties.getDouble("speed_factor", 1); + boolean speedTwoDirections = properties.getBool("speed_two_directions", false); + int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); + double maxSpeed = properties.getDouble("max_speed", FERRY_SPEED); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); + DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); + DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), false); + } + + public static VehicleEncodedValues hike(PMap properties) { + return foot(new PMap(properties).putObject("name", properties.getString("name", "hike"))); + } + + public static VehicleEncodedValues wheelchair(PMap properties) { + if (properties.has("speed_two_directions")) + throw new IllegalArgumentException("bike2 always uses two directions"); + return foot(new PMap(properties) + .putObject("name", properties.getString("name", "wheelchair")) + .putObject("speed_two_directions", true) + ); + } + + public static VehicleEncodedValues bike(PMap properties) { + String name = properties.getString("name", "bike"); + int speedBits = properties.getInt("speed_bits", 4); + double speedFactor = properties.getDouble("speed_factor", 2); + boolean speedTwoDirections = properties.getBool("speed_two_directions", false); + int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); + double maxSpeed = properties.getDouble("max_speed", BIKE_MAX_SPEED); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); + DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); + DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), false); + } + + public static VehicleEncodedValues bike2(PMap properties) { + if (properties.has("speed_two_directions")) + throw new IllegalArgumentException("bike2 always uses two directions"); + return bike(new PMap(properties) + .putObject("name", properties.getString("name", "bike2")) + .putObject("speed_two_directions", true) + ); + } + + public static VehicleEncodedValues racingbike(PMap properties) { + return bike(new PMap(properties).putObject("name", properties.getString("name", "racingbike"))); + } + + public static VehicleEncodedValues mountainbike(PMap properties) { + return bike(new PMap(properties).putObject("name", properties.getString("name", "mtb"))); + } + + public static VehicleEncodedValues car(PMap properties) { + String name = properties.getString("name", "car"); + int speedBits = properties.getInt("speed_bits", 5); + double speedFactor = properties.getDouble("speed_factor", 5); + boolean speedTwoDirections = properties.getBool("speed_two_directions", false); + int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); + double maxSpeed = properties.getDouble("max_speed", CAR_MAX_SPEED); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); + DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), true); + } + + public static VehicleEncodedValues car4wd(PMap properties) { + return car(new PMap(properties).putObject("name", properties.getString("name", "car4wd"))); + } + + public static VehicleEncodedValues motorcycle(PMap properties) { + String name = properties.getString("name", "motorcycle"); + int speedBits = properties.getInt("speed_bits", 5); + double speedFactor = properties.getDouble("speed_factor", 5); + boolean speedTwoDirections = properties.getBool("speed_two_directions", true); + int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); + double maxSpeed = properties.getDouble("max_speed", MOTOR_CYCLE_MAX_SPEED); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); + DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); + DecimalEncodedValue curvatureEnc = new DecimalEncodedValueImpl(getKey(name, "curvature"), 4, 0.1, false); + DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, curvatureEnc, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), true); + } + + public static VehicleEncodedValues roads() { + String name = "roads"; + int speedBits = 7; + double speedFactor = 2; + boolean speedTwoDirections = true; + int maxTurnCosts = 3; + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); + DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, speedEnc.getNextStorableValue(ROADS_MAX_SPEED), true); + } + + public VehicleEncodedValues(String name, BooleanEncodedValue accessEnc, DecimalEncodedValue avgSpeedEnc, + DecimalEncodedValue priorityEnc, DecimalEncodedValue curvatureEnc, + DecimalEncodedValue turnCostEnc, double maxPossibleSpeed, boolean isMotorVehicle) { + this.name = name; + this.accessEnc = accessEnc; + this.avgSpeedEnc = avgSpeedEnc; + this.priorityEnc = priorityEnc; + this.curvatureEnc = curvatureEnc; + this.turnCostEnc = turnCostEnc; + this.maxPossibleSpeed = maxPossibleSpeed; + this.isMotorVehicle = isMotorVehicle; + } + + public void setEncodedValueLookup(EncodedValueLookup encodedValueLookup) { + this.encodedValueLookup = encodedValueLookup; + } + + @Override + public boolean isRegistered() { + return encodedValueLookup != null; + } + + public void createEncodedValues(List registerNewEncodedValue) { + if (accessEnc != null) + registerNewEncodedValue.add(accessEnc); + if (avgSpeedEnc != null) + registerNewEncodedValue.add(avgSpeedEnc); + if (priorityEnc != null) + registerNewEncodedValue.add(priorityEnc); + if (curvatureEnc != null) + registerNewEncodedValue.add(curvatureEnc); + } + + public void createTurnCostEncodedValues(List registerNewTurnCostEncodedValues) { + if (turnCostEnc != null) + registerNewTurnCostEncodedValues.add(turnCostEnc); + } + + @Override + public double getMaxSpeed() { + return maxPossibleSpeed; + } + + + @Override + public BooleanEncodedValue getAccessEnc() { + return accessEnc; + } + + @Override + public DecimalEncodedValue getAverageSpeedEnc() { + return avgSpeedEnc; + } + + @Override + public DecimalEncodedValue getPriorityEnc() { + return priorityEnc; + } + + @Override + public DecimalEncodedValue getCurvatureEnc() { + return curvatureEnc; + } + + @Override + public DecimalEncodedValue getTurnCostEnc() { + return turnCostEnc; + } + + public String getSharedEncodedValueString() { + return Stream.of(accessEnc, avgSpeedEnc, priorityEnc, curvatureEnc, turnCostEnc) + .filter(Objects::nonNull) + .map(EncodedValueSerializer::serializeEncodedValue) + .collect(Collectors.joining(",")); + } + + @Override + public List getEncodedValues() { + return encodedValueLookup.getEncodedValues(); + } + + @Override + public T getEncodedValue(String key, Class encodedValueType) { + return encodedValueLookup.getEncodedValue(key, encodedValueType); + } + + @Override + public BooleanEncodedValue getBooleanEncodedValue(String key) { + return encodedValueLookup.getBooleanEncodedValue(key); + } + + @Override + public IntEncodedValue getIntEncodedValue(String key) { + return encodedValueLookup.getIntEncodedValue(key); + } + + @Override + public DecimalEncodedValue getDecimalEncodedValue(String key) { + return encodedValueLookup.getDecimalEncodedValue(key); + } + + @Override + public > EnumEncodedValue getEnumEncodedValue(String key, Class enumType) { + return encodedValueLookup.getEnumEncodedValue(key, enumType); + } + + @Override + public StringEncodedValue getStringEncodedValue(String key) { + return encodedValueLookup.getStringEncodedValue(key); + } + + @Override + public boolean isMotorVehicle() { + return isMotorVehicle; + } + + @Override + public boolean supportsTurnCosts() { + return turnCostEnc != null; + } + + @Override + public boolean hasEncodedValue(String key) { + return encodedValueLookup.hasEncodedValue(key); + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return getName(); + } +} \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java index 1dda76642c6..68e87bb1553 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java @@ -22,15 +22,17 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.osm.conditional.ConditionalOSMTagInspector; import com.graphhopper.reader.osm.conditional.DateRangeParser; -import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.parsers.OSMRoadAccessParser; +import com.graphhopper.routing.util.parsers.TagParser; import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.EdgeIteratorState; import java.util.*; -import static com.graphhopper.routing.util.EncodingManager.getKey; +import static java.util.Collections.emptyMap; /** * Abstract class which handles flag decoding and encoding. Every encoder should be registered to a @@ -41,7 +43,7 @@ * @author Nop * @see EncodingManager */ -public abstract class VehicleTagParser implements FlagEncoder { +public abstract class VehicleTagParser implements TagParser { private final String name; protected final Set intendedValues = new HashSet<>(5); // order is important @@ -51,33 +53,27 @@ public abstract class VehicleTagParser implements FlagEncoder { protected final Set oneways = new HashSet<>(5); // http://wiki.openstreetmap.org/wiki/Mapfeatures#Barrier protected final Set barriers = new HashSet<>(5); - private final String propertiesString; protected final BooleanEncodedValue accessEnc; protected final DecimalEncodedValue avgSpeedEnc; private final DecimalEncodedValue turnCostEnc; - protected BooleanEncodedValue roundaboutEnc; + protected final BooleanEncodedValue roundaboutEnc; // This value determines the maximal possible speed of any road regardless of the maxspeed value // lower values allow more compact representation of the routing graph - protected double maxPossibleSpeed; + protected final double maxPossibleSpeed; private boolean blockFords = true; - private boolean registered; - protected EncodedValueLookup encodedValueLookup; private ConditionalTagInspector conditionalTagInspector; - protected FerrySpeedCalculator ferrySpeedCalc; + protected final FerrySpeedCalculator ferrySpeedCalc; - /** - * @param speedBits specify the number of bits used for speed - * @param speedFactor specify the factor to multiply the stored value (can be used to increase - * or decrease accuracy of speed value) - * @param maxTurnCosts specify the maximum value used for turn costs, if this value is reached a - * turn is forbidden and results in costs of positive infinity. - */ - protected VehicleTagParser(String name, int speedBits, double speedFactor, boolean speedTwoDirections, int maxTurnCosts) { + protected VehicleTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, String name, + BooleanEncodedValue roundaboutEnc, + DecimalEncodedValue turnCostEnc, TransportationMode transportationMode, double maxPossibleSpeed) { this.name = name; - this.accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); - this.avgSpeedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); - this.turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - this.propertiesString = "speed_factor=" + speedFactor + "|speed_bits=" + speedBits + "|turn_costs=" + (maxTurnCosts > 0); + this.maxPossibleSpeed = maxPossibleSpeed; + + this.accessEnc = accessEnc; + this.avgSpeedEnc = speedEnc; + this.turnCostEnc = turnCostEnc; + this.roundaboutEnc = roundaboutEnc; oneways.add("yes"); oneways.add("true"); @@ -87,15 +83,11 @@ protected VehicleTagParser(String name, int speedBits, double speedFactor, boole ferries.add("shuttle_train"); ferries.add("ferry"); - restrictions.addAll(OSMRoadAccessParser.toOSMRestrictions(getTransportationMode())); + ferrySpeedCalc = new FerrySpeedCalculator(speedEnc.getSmallestNonZeroValue(), maxPossibleSpeed, 5); + restrictions.addAll(OSMRoadAccessParser.toOSMRestrictions(transportationMode)); } - protected void init(DateRangeParser dateRangeParser) { - if (registered) - throw new IllegalStateException("You must not register a FlagEncoder (" + this + ") twice or for two EncodingManagers!"); - registered = true; - - ferrySpeedCalc = new FerrySpeedCalculator(avgSpeedEnc.getSmallestNonZeroValue(), maxPossibleSpeed, 5); + public void init(DateRangeParser dateRangeParser) { setConditionalTagInspector(new ConditionalOSMTagInspector(Collections.singletonList(dateRangeParser), restrictions, restrictedValues, intendedValues, false)); } @@ -104,11 +96,6 @@ protected void setConditionalTagInspector(ConditionalTagInspector inspector) { conditionalTagInspector = inspector; } - @Override - public boolean isRegistered() { - return registered; - } - public boolean isBlockFords() { return blockFords; } @@ -129,25 +116,21 @@ public ConditionalTagInspector getConditionalTagInspector() { return conditionalTagInspector; } - /** - * Defines bits used for edge flags used for access, speed etc. - */ - public void createEncodedValues(List registerNewEncodedValue) { - registerNewEncodedValue.add(accessEnc); - registerNewEncodedValue.add(avgSpeedEnc); - roundaboutEnc = getBooleanEncodedValue(Roundabout.KEY); - } - - public void createTurnCostEncodedValues(List registerNewTurnCostEncodedValues) { - if (supportsTurnCosts()) - registerNewTurnCostEncodedValues.add(turnCostEnc); + @Override + public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + edgeFlags = handleWayTags(edgeFlags, way); + if (!edgeFlags.isEmpty()) { + Map nodeTags = way.getTag("node_tags", emptyMap()); + handleNodeTags(edgeFlags, nodeTags); + } + return edgeFlags; } /** * Analyze properties of a way and create the edge flags. This method is called in the second * parsing step. */ - public abstract IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way); + protected abstract IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way); /** * Updates the given edge flags based on node tags @@ -190,7 +173,6 @@ else if (node.hasTag("barrier", barriers)) return blockFords && node.hasTag("ford", "yes"); } - @Override public double getMaxSpeed() { return maxPossibleSpeed; } @@ -242,50 +224,6 @@ protected void setSpeed(boolean reverse, IntsRef edgeFlags, double speed) { } } - protected String getPropertiesString() { - return propertiesString; - } - - @Override - public List getEncodedValues() { - return encodedValueLookup.getEncodedValues(); - } - - @Override - public T getEncodedValue(String key, Class encodedValueType) { - return encodedValueLookup.getEncodedValue(key, encodedValueType); - } - - @Override - public BooleanEncodedValue getBooleanEncodedValue(String key) { - return encodedValueLookup.getBooleanEncodedValue(key); - } - - @Override - public IntEncodedValue getIntEncodedValue(String key) { - return encodedValueLookup.getIntEncodedValue(key); - } - - @Override - public DecimalEncodedValue getDecimalEncodedValue(String key) { - return encodedValueLookup.getDecimalEncodedValue(key); - } - - @Override - public > EnumEncodedValue getEnumEncodedValue(String key, Class enumType) { - return encodedValueLookup.getEnumEncodedValue(key, enumType); - } - - @Override - public StringEncodedValue getStringEncodedValue(String key) { - return encodedValueLookup.getStringEncodedValue(key); - } - - public void setEncodedValueLookup(EncodedValueLookup encodedValueLookup) { - this.encodedValueLookup = encodedValueLookup; - } - - @Override public boolean supportsTurnCosts() { return turnCostEnc != null; } @@ -294,16 +232,6 @@ public DecimalEncodedValue getTurnCostEnc() { return turnCostEnc; } - @Override - public boolean supports(Class feature) { - return false; - } - - @Override - public boolean hasEncodedValue(String key) { - return encodedValueLookup.hasEncodedValue(key); - } - public final List getRestrictions() { return restrictions; } diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParserFactory.java new file mode 100644 index 00000000000..acbf5932bca --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParserFactory.java @@ -0,0 +1,26 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util; + +import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.util.PMap; + +public interface VehicleTagParserFactory { + VehicleTagParser createParser(EncodedValueLookup lookup, String name, PMap configuration); +} diff --git a/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java b/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java index 8a71e6c67dc..9ccf0701fe2 100644 --- a/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java @@ -18,6 +18,7 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.FetchMode; @@ -28,6 +29,7 @@ import java.util.Set; import java.util.TreeMap; +import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.PriorityCode.AVOID; import static com.graphhopper.routing.util.PriorityCode.VERY_NICE; @@ -41,19 +43,20 @@ public class WheelchairTagParser extends FootTagParser { private final Set excludeSmoothness = new HashSet<>(); private final int maxInclinePercent = 6; - public WheelchairTagParser() { - this(4, 1); - } - - public WheelchairTagParser(PMap properties) { - this(properties.getInt("speed_bits", 4), properties.getDouble("speed_factor", 1)); - + public WheelchairTagParser(EncodedValueLookup lookup, PMap properties) { + this( + lookup.getBooleanEncodedValue(getKey("wheelchair", "access")), + lookup.getDecimalEncodedValue(getKey("wheelchair", "average_speed")), + lookup.getDecimalEncodedValue(getKey("wheelchair", "priority")), + lookup.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class) + ); blockPrivate(properties.getBool("block_private", true)); blockFords(properties.getBool("block_fords", false)); } - protected WheelchairTagParser(int speedBits, double speedFactor) { - super("wheelchair", speedBits, speedFactor, true); + protected WheelchairTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, + EnumEncodedValue footRouteEnc) { + super(accessEnc, speedEnc, priorityEnc, footRouteEnc, "wheelchair"); restrictions.add("wheelchair"); @@ -91,8 +94,6 @@ protected WheelchairTagParser(int speedBits, double speedFactor) { excludeSmoothness.add("impassable"); allowedSacScale.clear(); - - maxPossibleSpeed = avgSpeedEnc.getNextStorableValue(FERRY_SPEED); } /** diff --git a/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java b/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java index 9824ab67d46..1e8fb134506 100644 --- a/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java +++ b/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java @@ -99,9 +99,9 @@ public boolean loadExisting() { String flagEncodersStr = properties.get("graph.flag_encoders"); if (!encodingManager.toFlagEncodersAsString().equalsIgnoreCase(flagEncodersStr)) { - throw new IllegalStateException("Encoding does not match:" + throw new IllegalStateException("Flag encoders do not match:" + "\nGraphhopper config: " + encodingManager.toFlagEncodersAsString() - + "\nGraph: " + flagEncodersStr + + "\nLoaded graph: " + flagEncodersStr + "\nChange configuration to match the graph or delete " + dir.getLocation()); } @@ -109,7 +109,7 @@ public boolean loadExisting() { if (!encodingManager.toEncodedValuesAsString().equalsIgnoreCase(encodedValueStr)) { throw new IllegalStateException("Encoded values do not match:" + "\nGraphhopper config: " + encodingManager.toEncodedValuesAsString() - + "\nGraph: " + encodedValueStr + + "\nLoaded graph: " + encodedValueStr + "\nChange configuration to match the graph or delete " + dir.getLocation()); } baseGraph.loadExisting(); diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 4e15b7c181e..83b2af87a46 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -2570,4 +2570,24 @@ public void testLoadGraph_implicitEncodedValues_issue1862() { hopper.close(); } + @Test + void testLoadingWithAnotherSpeedFactorFails() { + { + GraphHopper hopper = new GraphHopper() + .setFlagEncodersString("car|speed_factor=7") + .setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")) + .setGraphHopperLocation(GH_LOCATION) + .setOSMFile(BAYREUTH); + hopper.importOrLoad(); + } + { + GraphHopper hopper = new GraphHopper() + .setFlagEncodersString("car|speed_factor=9") + .setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")) + .setGraphHopperLocation(GH_LOCATION); + IllegalStateException ex = assertThrows(IllegalStateException.class, hopper::load); + assertTrue(ex.getMessage().contains("Flag encoders do not match"), ex.getMessage()); + } + } + } diff --git a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java index cdbad782967..734444ea1c2 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java @@ -484,7 +484,7 @@ public void testFailsForWrongConfig() { tmpGH.load(); fail(); } catch (Exception ex) { - assertTrue(ex.getMessage().startsWith("Encoding does not match"), ex.getMessage()); + assertTrue(ex.getMessage().startsWith("Flag encoders do not match"), ex.getMessage()); } // different order is no longer okay, see #350 @@ -502,7 +502,7 @@ public void testFailsForWrongConfig() { tmpGH.load(); fail(); } catch (Exception ex) { - assertTrue(ex.getMessage().startsWith("Encoding does not match"), ex.getMessage()); + assertTrue(ex.getMessage().startsWith("Flag encoders do not match"), ex.getMessage()); } // different encoded values should fail to load @@ -848,7 +848,7 @@ public void testProfilesMustNotBeChanged() { IllegalStateException e = assertThrows(IllegalStateException.class, hopper::importOrLoad); // so far we get another error message in this case, because GraphHopperStorage checks the encoded values // in loadExisting already - assertTrue(e.getMessage().contains("Encoded values do not match"), e.getMessage()); + assertTrue(e.getMessage().contains("Flag encoders do not match"), e.getMessage()); hopper.close(); } { @@ -858,7 +858,7 @@ public void testProfilesMustNotBeChanged() { new Profile("car").setVehicle("car").setWeighting("shortest") )); IllegalStateException e = assertThrows(IllegalStateException.class, hopper::importOrLoad); - assertTrue(e.getMessage().contains("Encoded values do not match"), e.getMessage()); + assertTrue(e.getMessage().contains("Flag encoders do not match"), e.getMessage()); hopper.close(); } } diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 97dbac9e177..8f70263eaf8 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -25,11 +25,14 @@ import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.dem.ElevationProvider; import com.graphhopper.reader.dem.SRTMProvider; +import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.OSMReaderConfig; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.*; import com.graphhopper.routing.util.countryrules.CountryRuleFactory; import com.graphhopper.routing.util.parsers.CountryParser; +import com.graphhopper.routing.util.parsers.OSMBikeNetworkTagParser; +import com.graphhopper.routing.util.parsers.OSMRoadAccessParser; import com.graphhopper.storage.*; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.Snap; @@ -491,7 +494,10 @@ public void testBarriersOnTowerNodes() { @Test public void testRelation() { - TagParserManager manager = TagParserManager.create("bike"); + EncodingManager manager = EncodingManager.create("bike"); + EnumEncodedValue bikeNetworkEnc = manager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class); + OSMParsers osmParsers = new OSMParsers() + .addRelationTagParser(relConf -> new OSMBikeNetworkTagParser(bikeNetworkEnc, relConf)); ReaderRelation osmRel = new ReaderRelation(1); osmRel.add(new ReaderRelation.Member(ReaderRelation.WAY, 1, "")); osmRel.add(new ReaderRelation.Member(ReaderRelation.WAY, 2, "")); @@ -500,17 +506,17 @@ public void testRelation() { osmRel.setTag("network", "lcn"); IntsRef flags = manager.createRelationFlags(); - manager.handleRelationTags(osmRel, flags); + osmParsers.handleRelationTags(osmRel, flags); assertFalse(flags.isEmpty()); // unchanged network IntsRef before = IntsRef.deepCopyOf(flags); - manager.handleRelationTags(osmRel, flags); + osmParsers.handleRelationTags(osmRel, flags); assertEquals(before, flags); // overwrite network osmRel.setTag("network", "ncn"); - manager.handleRelationTags(osmRel, flags); + osmParsers.handleRelationTags(osmRel, flags); assertNotEquals(before, flags); } @@ -660,16 +666,25 @@ public void testTurnFlagCombination() { GraphHopper hopper = new GraphHopper(); hopper.setFlagEncoderFactory((name, config) -> { if (name.equals("truck")) { - return new CarTagParser(new PMap(config).putObject("name", "truck")) { - @Override - public TransportationMode getTransportationMode() { - return TransportationMode.HGV; - } - }; + return FlagEncoders.createCar(new PMap(config).putObject("name", "truck")); } else { return new DefaultFlagEncoderFactory().createFlagEncoder(name, config); } }); + hopper.setVehicleTagParserFactory((lookup, name, config) -> { + if (name.equals("truck")) { + return new CarTagParser( + lookup.getBooleanEncodedValue(EncodingManager.getKey("truck", "access")), + lookup.getDecimalEncodedValue(EncodingManager.getKey("truck", "average_speed")), + lookup.hasEncodedValue(TurnCost.key("truck")) ? lookup.getDecimalEncodedValue(TurnCost.key("truck")) : null, + lookup.getBooleanEncodedValue(Roundabout.KEY), + config, + TransportationMode.HGV, + 120 + ); + } + return new DefaultVehicleTagParserFactory().createParser(lookup, name, config); + }); hopper.setOSMFile(getClass().getResource("test-multi-profile-turn-restrictions.xml").getFile()). setGraphHopperLocation(dir). setProfiles( @@ -911,10 +926,15 @@ protected File _getOSMFile() { @Test public void testCountries() throws IOException { - TagParserManager em = TagParserManager.create("car"); + EncodingManager em = EncodingManager.create("car"); EnumEncodedValue roadAccessEnc = em.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class); - BaseGraph graph = new BaseGraph.Builder(em.getEncodingManager()).create(); - OSMReader reader = new OSMReader(graph, em, new OSMReaderConfig()); + OSMParsers osmParsers = new OSMParsers(); + osmParsers.addWayTagParser(new OSMRoadAccessParser(roadAccessEnc, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR))); + CarTagParser parser = new CarTagParser(em, new PMap()); + parser.init(new DateRangeParser()); + osmParsers.addVehicleTagParser(parser); + BaseGraph graph = new BaseGraph.Builder(em).create(); + OSMReader reader = new OSMReader(graph, em, osmParsers, new OSMReaderConfig()); reader.setCountryRuleFactory(new CountryRuleFactory()); reader.setAreaIndex(createCountryIndex()); // there are two edges, both with highway=track, one in Berlin, one in Paris @@ -934,13 +954,17 @@ public void testCountries() throws IOException { public void testCurvedWayAlongBorder() throws IOException { // see https://discuss.graphhopper.com/t/country-of-way-is-wrong-on-road-near-border-with-curvature/6908/2 EnumEncodedValue countryEnc = new EnumEncodedValue<>(Country.KEY, Country.class); - TagParserManager em = TagParserManager.start() + EncodingManager em = EncodingManager.start() .add(FlagEncoders.createCar()) .add(countryEnc) - .add(new CountryParser(countryEnc)) .build(); - BaseGraph graph = new BaseGraph.Builder(em.getEncodingManager()).create(); - OSMReader reader = new OSMReader(graph, em, new OSMReaderConfig()); + CarTagParser carParser = new CarTagParser(em, new PMap()); + carParser.init(new DateRangeParser()); + OSMParsers osmParsers = new OSMParsers() + .addWayTagParser(new CountryParser(countryEnc)) + .addVehicleTagParser(carParser); + BaseGraph graph = new BaseGraph.Builder(em).create(); + OSMReader reader = new OSMReader(graph, em, osmParsers, new OSMReaderConfig()); reader.setCountryRuleFactory(new CountryRuleFactory()); reader.setAreaIndex(createCountryIndex()); reader.setFile(new File(getClass().getResource("test-osm12.xml").getFile())); diff --git a/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java b/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java index e7af18a99ee..fe81932c04b 100644 --- a/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java +++ b/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java @@ -1,12 +1,10 @@ package com.graphhopper.routing; import com.graphhopper.reader.osm.OSMReader; +import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory; import com.graphhopper.routing.ch.PrepareContractionHierarchies; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; -import com.graphhopper.routing.util.TagParserManager; -import com.graphhopper.routing.util.TraversalMode; +import com.graphhopper.routing.util.*; import com.graphhopper.routing.weighting.AbstractWeighting; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -45,17 +43,22 @@ public class TrafficChangeWithNodeOrderingReusingTest { private static class Fixture { private final int maxDeviationPercentage; private final BaseGraph graph; - private final TagParserManager em; + private final EncodingManager em; + private final OSMParsers osmParsers; private final CHConfig baseCHConfig; private final CHConfig trafficCHConfig; public Fixture(int maxDeviationPercentage) { this.maxDeviationPercentage = maxDeviationPercentage; FlagEncoder encoder = FlagEncoders.createCar(); - em = TagParserManager.create(encoder); + em = EncodingManager.create(encoder); + CarTagParser carParser = new CarTagParser(em, new PMap()); + carParser.init(new DateRangeParser()); + osmParsers = new OSMParsers() + .addVehicleTagParser(carParser); baseCHConfig = CHConfig.nodeBased("base", new FastestWeighting(encoder)); trafficCHConfig = CHConfig.nodeBased("traffic", new RandomDeviationWeighting(baseCHConfig.getWeighting(), encoder, maxDeviationPercentage)); - graph = new BaseGraph.Builder(em.getEncodingManager()).create(); + graph = new BaseGraph.Builder(em).create(); } @Override @@ -85,7 +88,7 @@ public void testPerformanceForRandomTrafficChange(Fixture f) throws IOException LOGGER.info("Running performance test, max deviation percentage: " + f.maxDeviationPercentage); // read osm - OSMReader reader = new OSMReader(f.graph, f.em, new OSMReaderConfig()); + OSMReader reader = new OSMReader(f.graph, f.em, f.osmParsers, new OSMReaderConfig()); reader.setFile(new File(OSM_FILE)); reader.readGraph(); f.graph.freeze(); diff --git a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java index 84a70bdf03f..37ca18a0904 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java @@ -1,9 +1,13 @@ package com.graphhopper.routing.ev; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.util.CarTagParser; import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -22,14 +26,16 @@ public void testInit() { @Test public void testMaxValue() { - CarTagParser carEncoder = new CarTagParser(10, 0.5, 0); + FlagEncoder carEncoder = FlagEncoders.createCar(new PMap("speed_bits=10|speed_factor=0.5")); EncodingManager em = EncodingManager.create(carEncoder); DecimalEncodedValue carAverageSpeedEnc = em.getDecimalEncodedValue(EncodingManager.getKey(carEncoder, "average_speed")); + CarTagParser carTagParser = new CarTagParser(em, new PMap()); + carTagParser.init(new DateRangeParser()); ReaderWay way = new ReaderWay(1); way.setTag("highway", "motorway_link"); way.setTag("maxspeed", "70 mph"); - IntsRef flags = carEncoder.handleWayTags(em.createEdgeFlags(), way); + IntsRef flags = carTagParser.handleWayTags(em.createEdgeFlags(), way); assertEquals(101.5, carAverageSpeedEnc.getDecimal(true, flags), 1e-1); DecimalEncodedValue instance1 = new DecimalEncodedValueImpl("test1", 8, 0.5, false); diff --git a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java index cedfa2cd4b7..73078448b2c 100644 --- a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java @@ -37,27 +37,36 @@ * @author ratrun */ public abstract class AbstractBikeTagParserTester { + protected EncodingManager encodingManager; protected BikeCommonTagParser parser; - protected TagParserManager encodingManager; + protected OSMParsers osmParsers; protected BooleanEncodedValue roundaboutEnc; protected DecimalEncodedValue priorityEnc; protected DecimalEncodedValue avgSpeedEnc; @BeforeEach public void setUp() { - encodingManager = TagParserManager.create(parser = createBikeTagParser()); + encodingManager = createEncodingManager(); + if (encodingManager.fetchEdgeEncoders().size() > 1) + fail("currently we assume there is only one encoder per test"); + parser = createBikeTagParser(encodingManager); + osmParsers = createOSMParsers(parser, encodingManager); roundaboutEnc = encodingManager.getBooleanEncodedValue(Roundabout.KEY); - priorityEnc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(parser, "priority")); + priorityEnc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(parser.getName(), "priority")); avgSpeedEnc = parser.getAverageSpeedEnc(); } - protected abstract BikeCommonTagParser createBikeTagParser(); + protected abstract EncodingManager createEncodingManager(); + + protected abstract BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup); + + protected abstract OSMParsers createOSMParsers(BikeCommonTagParser parser, EncodedValueLookup lookup); protected void assertPriority(int expectedPrio, ReaderWay way) { - IntsRef relFlags = encodingManager.handleRelationTags(new ReaderRelation(0), encodingManager.createRelationFlags()); - IntsRef edgeFlags = encodingManager.handleWayTags(way, relFlags); - DecimalEncodedValue enc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(parser.toString(), "priority")); - assertEquals(PriorityCode.getValue(expectedPrio), enc.getDecimal(false, edgeFlags), 0.01); + IntsRef relFlags = osmParsers.handleRelationTags(new ReaderRelation(0), osmParsers.createRelationFlags()); + IntsRef edgeFlags = encodingManager.createEdgeFlags(); + edgeFlags = osmParsers.handleWayTags(edgeFlags, way, relFlags); + assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeFlags), 0.01); } protected void assertPriorityAndSpeed(int expectedPrio, double expectedSpeed, ReaderWay way) { @@ -65,8 +74,9 @@ protected void assertPriorityAndSpeed(int expectedPrio, double expectedSpeed, Re } protected void assertPriorityAndSpeed(int expectedPrio, double expectedSpeed, ReaderWay way, ReaderRelation rel) { - IntsRef relFlags = encodingManager.handleRelationTags(rel, encodingManager.createRelationFlags()); - IntsRef edgeFlags = encodingManager.handleWayTags(way, relFlags); + IntsRef relFlags = osmParsers.handleRelationTags(rel, osmParsers.createRelationFlags()); + IntsRef edgeFlags = encodingManager.createEdgeFlags(); + edgeFlags = osmParsers.handleWayTags(edgeFlags, way, relFlags); DecimalEncodedValue enc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(parser.toString(), "priority")); assertEquals(PriorityCode.getValue(expectedPrio), enc.getDecimal(false, edgeFlags), 0.01); assertEquals(expectedSpeed, parser.getAverageSpeedEnc().getDecimal(false, edgeFlags), 0.1); @@ -74,8 +84,9 @@ protected void assertPriorityAndSpeed(int expectedPrio, double expectedSpeed, Re } protected double getSpeedFromFlags(ReaderWay way) { - IntsRef relFlags = encodingManager.createRelationFlags(); - IntsRef flags = encodingManager.handleWayTags(way, relFlags); + IntsRef relFlags = osmParsers.createRelationFlags(); + IntsRef flags = encodingManager.createEdgeFlags(); + flags = osmParsers.handleWayTags(flags, way, relFlags); return avgSpeedEnc.getDecimal(false, flags); } @@ -236,8 +247,9 @@ public void testRelation() { // two relation tags => we currently cannot store a list, so pick the lower ordinal 'regional' // Example https://www.openstreetmap.org/way/213492914 => two hike 84544, 2768803 and two bike relations 3162932, 5254650 - IntsRef relFlags = encodingManager.handleRelationTags(rel2, encodingManager.handleRelationTags(rel, encodingManager.createRelationFlags())); - IntsRef edgeFlags = encodingManager.handleWayTags(way, relFlags); + IntsRef relFlags = osmParsers.handleRelationTags(rel2, osmParsers.handleRelationTags(rel, osmParsers.createRelationFlags())); + IntsRef edgeFlags = encodingManager.createEdgeFlags(); + edgeFlags = osmParsers.handleWayTags(edgeFlags, way, relFlags); EnumEncodedValue enc = encodingManager.getEnumEncodedValue(RouteNetwork.key("bike"), RouteNetwork.class); assertEquals(RouteNetwork.REGIONAL, enc.getEnum(false, edgeFlags)); } @@ -354,7 +366,7 @@ public void testHandleWayTagsCallsHandlePriority() { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "cycleway"); IntsRef edgeFlags = parser.handleWayTags(encodingManager.createEdgeFlags(), osmWay); - DecimalEncodedValue priorityEnc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(parser, "priority")); + DecimalEncodedValue priorityEnc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(parser.getName(), "priority")); assertEquals(PriorityCode.getValue(VERY_NICE.getValue()), priorityEnc.getDecimal(false, edgeFlags), 1e-3); } diff --git a/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java index 7e6ec37b6f2..bfb188d1b13 100644 --- a/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java @@ -18,7 +18,10 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.reader.osm.conditional.DateRangeParser; +import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.util.parsers.OSMBikeNetworkTagParser; +import com.graphhopper.routing.util.parsers.OSMSmoothnessParser; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.storage.IntsRef; @@ -34,19 +37,36 @@ public class Bike2WeightTagParserTest extends BikeTagParserTest { @Override - protected BikeTagParser createBikeTagParser() { - return new Bike2WeightTagParser(new PMap("block_fords=true")); + protected EncodingManager createEncodingManager() { + return EncodingManager.create("bike2"); + } + + @Override + protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup) { + Bike2WeightTagParser parser = new Bike2WeightTagParser(lookup, new PMap("block_fords=true")); + parser.init(new DateRangeParser()); + return parser; + } + + @Override + protected OSMParsers createOSMParsers(BikeCommonTagParser parser, EncodedValueLookup lookup) { + return new OSMParsers() + .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig)) + .addWayTagParser(new OSMSmoothnessParser(lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class))) + .addVehicleTagParser(parser); } private Graph initExampleGraph() { - BaseGraph gs = new BaseGraph.Builder(encodingManager.getEncodingManager()).set3D(true).create(); + BaseGraph gs = new BaseGraph.Builder(encodingManager).set3D(true).create(); NodeAccess na = gs.getNodeAccess(); // 50--(0.0001)-->49--(0.0004)-->55--(0.0005)-->60 na.setNode(0, 51.1, 12.001, 50); na.setNode(1, 51.1, 12.002, 60); EdgeIteratorState edge = gs.edge(0, 1). + setDistance(100). setWayGeometry(Helper.createPointList3D(51.1, 12.0011, 49, 51.1, 12.0015, 55)); - GHUtility.setSpeed(10, 15, parser, edge.setDistance(100)); + edge.set(avgSpeedEnc, 10, 15); + edge.set(parser.getAccessEnc(), true, true); return gs; } @@ -78,9 +98,11 @@ public void testUnchangedForStepsBridgeAndTunnel() { @Test public void testSetSpeed0_issue367() { - IntsRef edgeFlags = GHUtility.setSpeed(10, 10, parser, encodingManager.createEdgeFlags()); - assertEquals(10, avgSpeedEnc.getDecimal(false, edgeFlags), .1); - assertEquals(10, avgSpeedEnc.getDecimal(true, edgeFlags), .1); + IntsRef edgeFlags = encodingManager.createEdgeFlags(); + avgSpeedEnc.setDecimal(false, edgeFlags, 10); + avgSpeedEnc.setDecimal(true, edgeFlags, 10); + parser.getAccessEnc().setBool(false, edgeFlags, true); + parser.getAccessEnc().setBool(true, edgeFlags, true); parser.setSpeed(false, edgeFlags, 0); @@ -92,22 +114,21 @@ public void testSetSpeed0_issue367() { @Test public void testRoutingFailsWithInvalidGraph_issue665() { - BaseGraph graph = new BaseGraph.Builder(encodingManager.getEncodingManager()).set3D(true).create(); + BaseGraph graph = new BaseGraph.Builder(encodingManager).set3D(true).create(); ReaderWay way = new ReaderWay(0); way.setTag("route", "ferry"); way.setTag("edge_distance", 500.0); assertNotEquals(EncodingManager.Access.CAN_SKIP, parser.getAccess(way)); - IntsRef wayFlags = encodingManager.handleWayTags(way, encodingManager.createRelationFlags()); - graph.edge(0, 1).setDistance(247).setFlags(wayFlags); + IntsRef edgeFlags = encodingManager.createEdgeFlags(); + edgeFlags = osmParsers.handleWayTags(edgeFlags, way, encodingManager.createRelationFlags()); + graph.edge(0, 1).setDistance(247).setFlags(edgeFlags); - assertTrue(isGraphValid(graph, parser)); + assertTrue(isGraphValid(graph, parser.getAccessEnc())); } - private boolean isGraphValid(Graph graph, FlagEncoder encoder) { + private boolean isGraphValid(Graph graph, BooleanEncodedValue accessEnc) { EdgeExplorer explorer = graph.createEdgeExplorer(); - - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); // iterator at node 0 considers the edge 0-1 to be undirected EdgeIterator iter0 = explorer.setBaseNode(0); iter0.next(); diff --git a/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java index cc0abec4b69..929aa7c9099 100644 --- a/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java @@ -20,6 +20,13 @@ import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; +import com.graphhopper.routing.ev.BikeNetwork; +import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.RouteNetwork; +import com.graphhopper.routing.ev.Smoothness; +import com.graphhopper.routing.util.parsers.OSMBikeNetworkTagParser; +import com.graphhopper.routing.util.parsers.OSMSmoothnessParser; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -35,8 +42,23 @@ public class BikeTagParserTest extends AbstractBikeTagParserTester { @Override - protected BikeTagParser createBikeTagParser() { - return new BikeTagParser(new PMap("block_fords=true")); + protected EncodingManager createEncodingManager() { + return EncodingManager.create("bike"); + } + + @Override + protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup) { + BikeTagParser parser = new BikeTagParser(lookup, new PMap("block_fords=true")); + parser.init(new DateRangeParser()); + return parser; + } + + @Override + protected OSMParsers createOSMParsers(BikeCommonTagParser parser, EncodedValueLookup lookup) { + return new OSMParsers() + .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig)) + .addWayTagParser(new OSMSmoothnessParser(lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class))) + .addVehicleTagParser(parser); } @Test @@ -527,21 +549,29 @@ public void testCalcPriority() { ReaderRelation osmRel = new ReaderRelation(1); osmRel.setTag("route", "bicycle"); osmRel.setTag("network", "icn"); - IntsRef relFlags = encodingManager.handleRelationTags(osmRel, encodingManager.createRelationFlags()); - IntsRef flags = encodingManager.handleWayTags(osmWay, relFlags); + IntsRef relFlags = osmParsers.handleRelationTags(osmRel, osmParsers.createRelationFlags()); + IntsRef flags = encodingManager.createEdgeFlags(); + flags = osmParsers.handleWayTags(flags, osmWay, relFlags); + assertEquals(RouteNetwork.INTERNATIONAL, encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class).getEnum(false, flags)); assertEquals(PriorityCode.getValue(BEST.getValue()), priorityEnc.getDecimal(false, flags), .1); // for some highways the priority is UNCHANGED + osmRel = new ReaderRelation(1); osmWay = new ReaderWay(1); osmWay.setTag("highway", "track"); - flags = encodingManager.handleWayTags(osmWay, encodingManager.createRelationFlags()); + flags = encodingManager.createEdgeFlags(); + flags = osmParsers.handleWayTags(flags, osmWay, osmParsers.createRelationFlags()); + assertEquals(RouteNetwork.MISSING, encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class).getEnum(false, flags)); assertEquals(PriorityCode.getValue(UNCHANGED.getValue()), priorityEnc.getDecimal(false, flags), .1); // for unknown highways we should probably keep the priority unchanged, but currently it does not matter // because the access will be false anyway + osmRel = new ReaderRelation(1); osmWay = new ReaderWay(1); osmWay.setTag("highway", "whatever"); - flags = encodingManager.handleWayTags(osmWay, encodingManager.createRelationFlags()); + flags = encodingManager.createEdgeFlags(); + flags = osmParsers.handleWayTags(flags, osmWay, osmParsers.createRelationFlags()); + assertEquals(RouteNetwork.MISSING, encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class).getEnum(false, flags)); assertEquals(EXCLUDE.getValue(), priorityEnc.getDecimal(false, flags), .1); } diff --git a/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java index d486272e692..7a3a3c12e1d 100644 --- a/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java @@ -18,6 +18,8 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; +import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.util.Helper; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -34,8 +36,15 @@ public class Car4WDTagParserTest extends CarTagParserTest { @Override - CarTagParser createParser() { - return new Car4WDTagParser(new PMap("speed_two_directions=true|block_fords=true")); + FlagEncoder createEncoder(PMap properties) { + return FlagEncoders.createCar4wd(properties); + } + + @Override + CarTagParser createParser(EncodedValueLookup lookup, PMap properties) { + Car4WDTagParser parser = new Car4WDTagParser(lookup, properties); + parser.init(new DateRangeParser()); + return parser; } @Override diff --git a/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java index 1a5a0f623ce..2be9b603b40 100644 --- a/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java @@ -19,8 +19,10 @@ import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.ev.Roundabout; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; @@ -36,17 +38,26 @@ * @author Peter Karich */ public class CarTagParserTest { - final CarTagParser parser = createParser(); - private final TagParserManager em = new TagParserManager.Builder(). - add(parser). - add(FlagEncoders.createBike()).add(FlagEncoders.createFoot()).build(); + final FlagEncoder encoder = createEncoder(new PMap("turn_costs=true|speed_two_directions=true")); + private final EncodingManager em = new EncodingManager.Builder() + .add(encoder) + .add(FlagEncoders.createBike()) + .add(FlagEncoders.createFoot()) + .build(); + final CarTagParser parser = createParser(em, new PMap("block_fords=true")); private final BooleanEncodedValue roundaboutEnc = em.getBooleanEncodedValue(Roundabout.KEY); private final DecimalEncodedValue avSpeedEnc = parser.getAverageSpeedEnc(); private final BooleanEncodedValue accessEnc = parser.getAccessEnc(); - CarTagParser createParser() { - return new CarTagParser(new PMap("speed_two_directions=true|block_fords=true")); + FlagEncoder createEncoder(PMap properties) { + return FlagEncoders.createCar(properties); + } + + CarTagParser createParser(EncodedValueLookup lookup, PMap properties) { + CarTagParser carTagParser = new CarTagParser(lookup, properties); + carTagParser.init(new DateRangeParser()); + return carTagParser; } @Test @@ -153,10 +164,9 @@ public void testFordAccess() { assertTrue(parser.getAccess(way).canSkip()); assertTrue(parser.isBarrier(node)); - CarTagParser tmpEncoder = new CarTagParser(new PMap("block_fords=false")); - EncodingManager.create(tmpEncoder); - assertTrue(tmpEncoder.getAccess(way).isWay()); - assertFalse(tmpEncoder.isBarrier(node)); + CarTagParser tmpParser = createParser(em, new PMap("block_fords=false")); + assertTrue(tmpParser.getAccess(way).isWay()); + assertFalse(tmpParser.isBarrier(node)); } @Test @@ -229,33 +239,33 @@ public void testMaxSpeed() { ReaderWay way = new ReaderWay(1); way.setTag("highway", "trunk"); way.setTag("maxspeed", "500"); - IntsRef relFlags = em.createRelationFlags(); - IntsRef edgeFlags = em.handleWayTags(way, relFlags); + IntsRef edgeFlags = em.createEdgeFlags(); + parser.handleWayTags(edgeFlags, way); assertEquals(140, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); way = new ReaderWay(1); way.setTag("highway", "primary"); way.setTag("maxspeed:backward", "10"); way.setTag("maxspeed:forward", "20"); - edgeFlags = em.handleWayTags(way, relFlags); + edgeFlags = parser.handleWayTags(edgeFlags, way); assertEquals(10, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); way = new ReaderWay(1); way.setTag("highway", "primary"); way.setTag("maxspeed:forward", "20"); - edgeFlags = em.handleWayTags(way, relFlags); + edgeFlags = parser.handleWayTags(edgeFlags, way); assertEquals(20, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); way = new ReaderWay(1); way.setTag("highway", "primary"); way.setTag("maxspeed:backward", "20"); - edgeFlags = em.handleWayTags(way, relFlags); + edgeFlags = parser.handleWayTags(edgeFlags, way); assertEquals(20, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); way = new ReaderWay(1); way.setTag("highway", "motorway"); way.setTag("maxspeed", "none"); - edgeFlags = em.handleWayTags(way, relFlags); + edgeFlags = parser.handleWayTags(edgeFlags, way); assertEquals(135, avSpeedEnc.getDecimal(false, edgeFlags), .1); } @@ -500,13 +510,10 @@ public void testBarrierAccess() { // barrier! assertTrue(parser.isBarrier(node)); - CarTagParser tmpEncoder = new CarTagParser(); - EncodingManager.create(tmpEncoder); - // Test if cattle_grid is not blocking node = new ReaderNode(1, -1, -1); node.setTag("barrier", "cattle_grid"); - assertFalse(tmpEncoder.isBarrier(node)); + assertFalse(parser.isBarrier(node)); } @Test @@ -523,13 +530,14 @@ public void testChainBarrier() { @Test public void testMaxValue() { - CarTagParser instance = new CarTagParser(10, 0.5, 0); - EncodingManager em = EncodingManager.create(instance); - DecimalEncodedValue avSpeedEnc = em.getDecimalEncodedValue(EncodingManager.getKey(instance, "average_speed")); + FlagEncoder encoder = createEncoder(new PMap("speed_bits=10|speed_factor=0.5")); + EncodingManager em = EncodingManager.create(encoder); + CarTagParser parser = createParser(em, new PMap()); + DecimalEncodedValue avSpeedEnc = em.getDecimalEncodedValue(EncodingManager.getKey(encoder, "average_speed")); ReaderWay way = new ReaderWay(1); way.setTag("highway", "motorway_link"); way.setTag("maxspeed", "60 mph"); - IntsRef edgeFlags = instance.handleWayTags(em.createEdgeFlags(), way); + IntsRef edgeFlags = parser.handleWayTags(em.createEdgeFlags(), way); // double speed = AbstractFlagEncoder.parseSpeed("60 mph"); // => 96.56 * 0.9 => 86.9 @@ -540,7 +548,7 @@ public void testMaxValue() { way = new ReaderWay(2); way.setTag("highway", "motorway_link"); way.setTag("maxspeed", "70 mph"); - edgeFlags = instance.handleWayTags(em.createEdgeFlags(), way); + edgeFlags = parser.handleWayTags(em.createEdgeFlags(), way); assertEquals(101.5, avSpeedEnc.getDecimal(false, edgeFlags), .1); } @@ -564,9 +572,13 @@ public void testCombination() { way.setTag("highway", "cycleway"); way.setTag("sac_scale", "hiking"); + BikeTagParser bikeParser = new BikeTagParser(em, new PMap()); + bikeParser.init(new DateRangeParser()); assertEquals(EncodingManager.Access.CAN_SKIP, parser.getAccess(way)); - assertNotEquals(EncodingManager.Access.CAN_SKIP, ((BikeTagParser) em.getEncoder("bike")).getAccess(way)); - IntsRef edgeFlags = em.handleWayTags(way, em.createRelationFlags()); + assertNotEquals(EncodingManager.Access.CAN_SKIP, bikeParser.getAccess(way)); + IntsRef edgeFlags = em.createEdgeFlags(); + parser.handleWayTags(edgeFlags, way); + bikeParser.handleWayTags(edgeFlags, way); assertFalse(accessEnc.getBool(true, edgeFlags)); assertFalse(accessEnc.getBool(false, edgeFlags)); BooleanEncodedValue bikeAccessEnc = em.getEncoder("bike").getAccessEnc(); @@ -594,10 +606,10 @@ public void testIssue_1256() { assertEquals(5, parser.getAverageSpeedEnc().getDecimal(false, edgeFlags), .1); // for a smaller speed factor the minimum speed is also smaller - CarTagParser lowFactorCar = new CarTagParser(10, 1, 0); + FlagEncoder lowFactorCar = createEncoder(new PMap("speed_bits=10|speed_factor=1")); EncodingManager lowFactorEm = EncodingManager.create(lowFactorCar); edgeFlags = lowFactorEm.createEdgeFlags(); - lowFactorCar.handleWayTags(edgeFlags, way); + createParser(lowFactorEm, new PMap()).handleWayTags(edgeFlags, way); assertEquals(1, lowFactorCar.getAverageSpeedEnc().getDecimal(false, edgeFlags), .1); } } diff --git a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java index 2620ca833fc..8f2f1430893 100644 --- a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java @@ -17,6 +17,7 @@ */ package com.graphhopper.routing.util; +import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -53,29 +54,23 @@ public void testWrongEncoders() { @Test public void testSupportFords() { - // 1) no encoder crossing fords String flagEncoderStrings = "car,bike,foot"; EncodingManager manager = EncodingManager.create(flagEncoderStrings); - assertFalse(((CarTagParser) manager.getEncoder("car")).isBlockFords()); - assertFalse(((BikeTagParser) manager.getEncoder("bike")).isBlockFords()); - assertFalse(((FootTagParser) manager.getEncoder("foot")).isBlockFords()); + // 1) default -> no block fords + assertFalse(new CarTagParser(manager, new PMap()).isBlockFords()); + assertFalse(new BikeTagParser(manager, new PMap()).isBlockFords()); + assertFalse(new FootTagParser(manager, new PMap()).isBlockFords()); - // 2) two encoders crossing fords - flagEncoderStrings = "car, bike|block_fords=true, foot|block_fords=false"; - manager = EncodingManager.create(flagEncoderStrings); + // 2) true + assertTrue(new CarTagParser(manager, new PMap("block_fords=true")).isBlockFords()); + assertTrue(new BikeTagParser(manager, new PMap("block_fords=true")).isBlockFords()); + assertTrue(new FootTagParser(manager, new PMap("block_fords=true")).isBlockFords()); - assertFalse(((CarTagParser) manager.getEncoder("car")).isBlockFords()); - assertTrue(((BikeTagParser) manager.getEncoder("bike")).isBlockFords()); - assertFalse(((FootTagParser) manager.getEncoder("foot")).isBlockFords()); - - // 2) Try combined with another tag - flagEncoderStrings = "car|turn_costs=true|block_fords=true, bike, foot|block_fords=false"; - manager = EncodingManager.create(flagEncoderStrings); - - assertTrue(((CarTagParser) manager.getEncoder("car")).isBlockFords()); - assertFalse(((BikeTagParser) manager.getEncoder("bike")).isBlockFords()); - assertFalse(((FootTagParser) manager.getEncoder("foot")).isBlockFords()); + // 3) false + assertFalse(new CarTagParser(manager, new PMap("block_fords=false")).isBlockFords()); + assertFalse(new BikeTagParser(manager, new PMap("block_fords=false")).isBlockFords()); + assertFalse(new FootTagParser(manager, new PMap("block_fords=false")).isBlockFords()); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java index 4e8581daa17..3afa22d6461 100644 --- a/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java @@ -19,6 +19,7 @@ import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.storage.BaseGraph; @@ -36,12 +37,17 @@ */ public class FootTagParserTest { private final EncodingManager encodingManager = EncodingManager.create("car,bike,foot"); - private final FootTagParser footParser = (FootTagParser) encodingManager.getEncoder("foot"); - private final DecimalEncodedValue footAvgSpeedEnc = footParser.getAverageSpeedEnc(); - private final BooleanEncodedValue footAccessEnc = footParser.getAccessEnc(); + private final FlagEncoder encoder = encodingManager.getEncoder("foot"); + private final FootTagParser footParser = new FootTagParser(encodingManager, new PMap()); + private final DecimalEncodedValue footAvgSpeedEnc = encoder.getAverageSpeedEnc(); + private final BooleanEncodedValue footAccessEnc = encoder.getAccessEnc(); private final DecimalEncodedValue carAvSpeedEnc = encodingManager.getEncoder("car").getAverageSpeedEnc(); private final BooleanEncodedValue carAccessEnc = encodingManager.getEncoder("car").getAccessEnc(); + public FootTagParserTest() { + footParser.init(new DateRangeParser()); + } + @Test public void testGetSpeed() { IntsRef fl = encodingManager.createEdgeFlags(); @@ -91,7 +97,7 @@ public void testGraph() { g.edge(0, 1).setDistance(10).set(footAvgSpeedEnc, 10.0).set(footAccessEnc, true, true); g.edge(0, 2).setDistance(10).set(footAvgSpeedEnc, 5.0).set(footAccessEnc, true, true); g.edge(1, 3).setDistance(10).set(footAvgSpeedEnc, 10.0).set(footAccessEnc, true, true); - EdgeExplorer out = g.createEdgeExplorer(AccessFilter.outEdges(footParser.getAccessEnc())); + EdgeExplorer out = g.createEdgeExplorer(AccessFilter.outEdges(footAccessEnc)); assertEquals(GHUtility.asSet(1, 2), GHUtility.getNeighbors(out.setBaseNode(0))); assertEquals(GHUtility.asSet(0, 3), GHUtility.getNeighbors(out.setBaseNode(1))); assertEquals(GHUtility.asSet(0), GHUtility.getNeighbors(out.setBaseNode(2))); @@ -405,15 +411,14 @@ public void testFord() { node.setTag("foot", "no"); assertTrue(footParser.isBarrier(node)); - FootTagParser tmpEncoder = new FootTagParser(new PMap("block_fords=true")); - EncodingManager.create(tmpEncoder); + FootTagParser blockFordsParser = new FootTagParser(encodingManager, new PMap("block_fords=true")); node = new ReaderNode(1, -1, -1); node.setTag("ford", "no"); - assertFalse(tmpEncoder.isBarrier(node)); + assertFalse(blockFordsParser.isBarrier(node)); node = new ReaderNode(1, -1, -1); node.setTag("ford", "yes"); - assertTrue(tmpEncoder.isBarrier(node)); + assertTrue(blockFordsParser.isBarrier(node)); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/HikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/HikeTagParserTest.java index f65c7b893a9..e56b0ceb46e 100644 --- a/core/src/test/java/com/graphhopper/routing/util/HikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/HikeTagParserTest.java @@ -18,6 +18,8 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; +import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -28,7 +30,11 @@ */ public class HikeTagParserTest { private final EncodingManager encodingManager = EncodingManager.create("car,hike"); - private final HikeTagParser hikeParser = (HikeTagParser) encodingManager.getEncoder("hike"); + private final HikeTagParser hikeParser = new HikeTagParser(encodingManager, new PMap()); + + public HikeTagParserTest() { + hikeParser.init(new DateRangeParser()); + } @Test public void testAccess() { diff --git a/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java index cc25e7b22b6..4a2e6303a18 100644 --- a/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java @@ -18,8 +18,8 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.storage.IntsRef; @@ -38,8 +38,14 @@ */ public class MotorcycleTagParserTest { private final EncodingManager em = EncodingManager.create("motorcycle,foot"); - private final MotorcycleTagParser parser = (MotorcycleTagParser) em.getEncoder("motorcycle"); - private final BooleanEncodedValue accessEnc = parser.getAccessEnc(); + private final FlagEncoder encoder = em.getEncoder("motorcycle"); + private final MotorcycleTagParser parser; + private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + + public MotorcycleTagParserTest() { + parser = new MotorcycleTagParser(em, new PMap()); + parser.init(new DateRangeParser()); + } private Graph initExampleGraph() { BaseGraph gs = new BaseGraph.Builder(em).set3D(true).create(); @@ -51,7 +57,7 @@ private Graph initExampleGraph() { setWayGeometry(Helper.createPointList3D(51.1, 12.0011, 49, 51.1, 12.0015, 55)); edge.setDistance(100); - edge.set(accessEnc, true, true).set(parser.getAverageSpeedEnc(), 10.0, 15.0); + edge.set(accessEnc, true, true).set(encoder.getAverageSpeedEnc(), 10.0, 15.0); return gs; } @@ -185,7 +191,6 @@ private double getBendiness(EdgeIteratorState edge, double beelineDistance) { IntsRef flags = parser.handleWayTags(em.createEdgeFlags(), way); edge.setFlags(flags); parser.applyWayTags(way, edge); - DecimalEncodedValue curvatureEnc = parser.getDecimalEncodedValue(EncodingManager.getKey(parser, "curvature")); - return edge.get(curvatureEnc); + return edge.get(encoder.getCurvatureEnc()); } } diff --git a/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java index b5e532ced61..9a4059fb9fb 100644 --- a/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java @@ -20,6 +20,13 @@ import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; +import com.graphhopper.routing.ev.BikeNetwork; +import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.RouteNetwork; +import com.graphhopper.routing.ev.Smoothness; +import com.graphhopper.routing.util.parsers.OSMBikeNetworkTagParser; +import com.graphhopper.routing.util.parsers.OSMSmoothnessParser; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -29,8 +36,23 @@ public class MountainBikeTagParserTest extends AbstractBikeTagParserTester { @Override - protected BikeCommonTagParser createBikeTagParser() { - return new MountainBikeTagParser(new PMap("block_fords=true")); + protected EncodingManager createEncodingManager() { + return EncodingManager.create("mtb"); + } + + @Override + protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup) { + MountainBikeTagParser parser = new MountainBikeTagParser(lookup, new PMap("block_fords=true")); + parser.init(new DateRangeParser()); + return parser; + } + + @Override + protected OSMParsers createOSMParsers(BikeCommonTagParser parser, EncodedValueLookup lookup) { + return new OSMParsers() + .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig)) + .addWayTagParser(new OSMSmoothnessParser(lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class))) + .addVehicleTagParser(parser); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java index 8f69864e287..cba2ce60dfb 100644 --- a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java @@ -19,9 +19,11 @@ import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.reader.osm.conditional.DateRangeParser; +import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.util.parsers.OSMBikeNetworkTagParser; +import com.graphhopper.routing.util.parsers.OSMSmoothnessParser; import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.GHUtility; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -35,9 +37,25 @@ * @author ratrun */ public class RacingBikeTagParserTest extends AbstractBikeTagParserTester { + + @Override + protected EncodingManager createEncodingManager() { + return EncodingManager.create("racingbike"); + } + + @Override + protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup) { + RacingBikeTagParser parser = new RacingBikeTagParser(lookup, new PMap("block_fords=true")); + parser.init(new DateRangeParser()); + return parser; + } + @Override - protected BikeCommonTagParser createBikeTagParser() { - return new RacingBikeTagParser(new PMap("block_fords=true")); + protected OSMParsers createOSMParsers(BikeCommonTagParser parser, EncodedValueLookup lookup) { + return new OSMParsers() + .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig)) + .addWayTagParser(new OSMSmoothnessParser(lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class))) + .addVehicleTagParser(parser); } @Test @@ -89,8 +107,8 @@ public void testSacScale() { @Test public void testGetSpeed() { - IntsRef intsRef = GHUtility.setSpeed(10, 0, parser, encodingManager.createEdgeFlags()); - assertEquals(10, avgSpeedEnc.getDecimal(false, intsRef), 1e-1); + IntsRef intsRef = encodingManager.createEdgeFlags(); + avgSpeedEnc.setDecimal(false, intsRef, 10); ReaderWay way = new ReaderWay(1); way.setTag("highway", "track"); way.setTag("tracktype", "grade3"); @@ -201,63 +219,63 @@ public void testHandleWayTagsInfluencedByRelation() { @Test public void testPriority_avoidanceOfHighMaxSpeed() { // here we test the priority that would be calculated if the way was accessible (even when it is not) - // therefore we need a modified encoder that always yields access=WAY - BikeCommonTagParser encoder = new RacingBikeTagParser(new PMap("block_fords=true")) { + // therefore we need a modified parser that always yields access=WAY + EncodingManager encodingManager = EncodingManager.create("racingbike"); + BikeCommonTagParser parser = new RacingBikeTagParser(encodingManager, new PMap("block_fords=true")) { @Override public EncodingManager.Access getAccess(ReaderWay way) { return WAY; } }; - TagParserManager encodingManager = TagParserManager.create(encoder); ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "tertiary"); osmWay.setTag("maxspeed", "50"); - assertPriorityAndSpeed(encodingManager, PREFER.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, parser, PREFER.getValue(), 20, osmWay); osmWay.setTag("maxspeed", "60"); - assertPriorityAndSpeed(encodingManager, PREFER.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, parser, PREFER.getValue(), 20, osmWay); osmWay.setTag("maxspeed", "80"); - assertPriorityAndSpeed(encodingManager, PREFER.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, parser, PREFER.getValue(), 20, osmWay); osmWay.setTag("maxspeed", "90"); - assertPriorityAndSpeed(encodingManager, UNCHANGED.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, parser, UNCHANGED.getValue(), 20, osmWay); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, UNCHANGED.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, parser, UNCHANGED.getValue(), 20, osmWay); osmWay.setTag("highway", "motorway"); - assertPriorityAndSpeed(encodingManager, AVOID.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, parser, AVOID.getValue(), 18, osmWay); osmWay.setTag("tunnel", "yes"); - assertPriorityAndSpeed(encodingManager, AVOID_MORE.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, parser, AVOID_MORE.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "motorway"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "80"); - assertPriorityAndSpeed(encodingManager, AVOID_MORE.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, parser, AVOID_MORE.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "motorway"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, AVOID_MORE.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, parser, AVOID_MORE.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "notdefined"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, AVOID_MORE.getValue(), 4, osmWay); + assertPriorityAndSpeed(encodingManager, parser, AVOID_MORE.getValue(), 4, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "notdefined"); osmWay.setTag("maxspeed", "50"); - assertPriorityAndSpeed(encodingManager, UNCHANGED.getValue(), 4, osmWay); + assertPriorityAndSpeed(encodingManager, parser, UNCHANGED.getValue(), 4, osmWay); } - private void assertPriorityAndSpeed(TagParserManager encodingManager, int expectedPrio, double expectedSpeed, ReaderWay way) { - IntsRef edgeFlags = encodingManager.handleWayTags(way, encodingManager.createRelationFlags()); + private void assertPriorityAndSpeed(EncodingManager encodingManager, VehicleTagParser parser, int expectedPrio, double expectedSpeed, ReaderWay way) { + IntsRef edgeFlags = parser.handleWayTags(encodingManager.createEdgeFlags(), way); FlagEncoder encoder = encodingManager.fetchEdgeEncoders().iterator().next(); DecimalEncodedValue enc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(encoder.toString(), "priority")); assertEquals(expectedSpeed, encoder.getAverageSpeedEnc().getDecimal(false, edgeFlags), 0.1); diff --git a/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java index c2417160027..ac9d0c4c21d 100644 --- a/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java @@ -1,6 +1,7 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.storage.IntsRef; import org.junit.jupiter.api.Test; @@ -9,24 +10,29 @@ class RoadsTagParserTest { private final EncodingManager encodingManager = EncodingManager.create("roads"); - private final RoadsTagParser roadsEncoder = (RoadsTagParser) encodingManager.getEncoder("roads"); + private final RoadsTagParser parser; + + public RoadsTagParserTest() { + parser = new RoadsTagParser(encodingManager); + parser.init(new DateRangeParser()); + } @Test public void testAccess() { ReaderWay way = new ReaderWay(1); - assertTrue(roadsEncoder.getAccess(way).canSkip()); + assertTrue(parser.getAccess(way).canSkip()); way.setTag("highway", "motorway"); - assertTrue(roadsEncoder.getAccess(way).isWay()); + assertTrue(parser.getAccess(way).isWay()); way.setTag("highway", "footway"); - assertTrue(roadsEncoder.getAccess(way).isWay()); + assertTrue(parser.getAccess(way).isWay()); } @Test public void testSpeed() { ReaderWay way = new ReaderWay(1); - IntsRef flags = roadsEncoder.handleWayTags(encodingManager.createEdgeFlags(), way); - assertTrue(roadsEncoder.getAverageSpeedEnc().getDecimal(false, flags) > 200); + IntsRef flags = parser.handleWayTags(encodingManager.createEdgeFlags(), way); + assertTrue(parser.getAverageSpeedEnc().getDecimal(false, flags) > 200); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/TagParserManagerTest.java b/core/src/test/java/com/graphhopper/routing/util/TagParserManagerTest.java deleted file mode 100644 index 849808c688e..00000000000 --- a/core/src/test/java/com/graphhopper/routing/util/TagParserManagerTest.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ - -package com.graphhopper.routing.util; - -import com.graphhopper.reader.ReaderRelation; -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.Roundabout; -import com.graphhopper.routing.ev.RouteNetwork; -import com.graphhopper.storage.IntsRef; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -class TagParserManagerTest { - @Test - public void testToDetailsString() { - FlagEncoder encoder = new VehicleTagParser("new_encoder", 1, 2.0, true, 0) { - @Override - public TransportationMode getTransportationMode() { - return TransportationMode.BIKE; - } - - @Override - protected String getPropertiesString() { - return "my_properties"; - } - - @Override - public EncodingManager.Access getAccess(ReaderWay way) { - return EncodingManager.Access.WAY; - } - - @Override - public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { - return edgeFlags; - } - }; - - EncodingManager subject = EncodingManager.create(encoder); - - assertEquals("new_encoder|my_properties", subject.toFlagEncodersAsString()); - } - - @Test - public void testCombineRelations() { - ReaderWay osmWay = new ReaderWay(1); - osmWay.setTag("highway", "track"); - ReaderRelation osmRel = new ReaderRelation(1); - - BikeTagParser defaultBike = new BikeTagParser(); - BikeTagParser lessRelationCodes = new BikeTagParser("less_relation_bits") { - @Override - public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { - if (bikeRouteEnc.getEnum(false, edgeFlags) != RouteNetwork.MISSING) - priorityEnc.setDecimal(false, edgeFlags, PriorityCode.getFactor(2)); - return edgeFlags; - } - }; - TagParserManager manager = new TagParserManager.Builder().add(lessRelationCodes).add(defaultBike).build(); - - // relation code is PREFER - osmRel.setTag("route", "bicycle"); - osmRel.setTag("network", "lcn"); - IntsRef relFlags = manager.handleRelationTags(osmRel, manager.createRelationFlags()); - IntsRef edgeFlags = manager.handleWayTags(osmWay, relFlags); - - assertTrue(defaultBike.priorityEnc.getDecimal(false, edgeFlags) - > lessRelationCodes.priorityEnc.getDecimal(false, edgeFlags)); - } - - @Test - public void testMixBikeTypesAndRelationCombination() { - ReaderWay osmWay = new ReaderWay(1); - osmWay.setTag("highway", "track"); - osmWay.setTag("tracktype", "grade1"); - - ReaderRelation osmRel = new ReaderRelation(1); - - BikeTagParser bikeEncoder = new BikeTagParser(); - MountainBikeTagParser mtbEncoder = new MountainBikeTagParser(); - TagParserManager manager = TagParserManager.create(bikeEncoder, mtbEncoder); - - // relation code for network rcn is NICE for bike and PREFER for mountainbike - osmRel.setTag("route", "bicycle"); - osmRel.setTag("network", "rcn"); - IntsRef relFlags = manager.handleRelationTags(osmRel, manager.createRelationFlags()); - IntsRef edgeFlags = manager.handleWayTags(osmWay, relFlags); - - // bike: uninfluenced speed for grade but via network => NICE - // mtb: uninfluenced speed only PREFER - assertTrue(bikeEncoder.priorityEnc.getDecimal(false, edgeFlags) - > mtbEncoder.priorityEnc.getDecimal(false, edgeFlags)); - } - - @Test - public void testCompatibilityBug() { - TagParserManager manager2 = TagParserManager.create(new DefaultFlagEncoderFactory(), "bike2"); - ReaderWay osmWay = new ReaderWay(1); - osmWay.setTag("highway", "footway"); - osmWay.setTag("name", "test"); - - BikeTagParser singleBikeEnc = (BikeTagParser) manager2.getEncoder("bike2"); - IntsRef flags = manager2.handleWayTags(osmWay, manager2.createRelationFlags()); - double singleSpeed = singleBikeEnc.avgSpeedEnc.getDecimal(false, flags); - assertEquals(4, singleSpeed, 1e-3); - assertEquals(singleSpeed, singleBikeEnc.avgSpeedEnc.getDecimal(true, flags), 1e-3); - - TagParserManager manager = TagParserManager.create(new DefaultFlagEncoderFactory(), "bike2,bike,foot"); - FootTagParser foot = (FootTagParser) manager.getEncoder("foot"); - BikeTagParser bike = (BikeTagParser) manager.getEncoder("bike2"); - - flags = manager.handleWayTags(osmWay, manager.createRelationFlags()); - assertEquals(singleSpeed, bike.avgSpeedEnc.getDecimal(false, flags), 1e-2); - assertEquals(singleSpeed, bike.avgSpeedEnc.getDecimal(true, flags), 1e-2); - - assertEquals(5, foot.avgSpeedEnc.getDecimal(false, flags), 1e-2); - assertEquals(5, foot.avgSpeedEnc.getDecimal(true, flags), 1e-2); - } - - @Test - public void testSharedEncodedValues() { - TagParserManager manager = TagParserManager.create("car,foot,bike,motorcycle,mtb"); - - BooleanEncodedValue roundaboutEnc = manager.getBooleanEncodedValue(Roundabout.KEY); - for (FlagEncoder tmp : manager.fetchEdgeEncoders()) { - BooleanEncodedValue accessEnc = tmp.getAccessEnc(); - - ReaderWay way = new ReaderWay(1); - way.setTag("highway", "primary"); - way.setTag("junction", "roundabout"); - IntsRef edgeFlags = manager.handleWayTags(way, manager.createRelationFlags()); - assertTrue(accessEnc.getBool(false, edgeFlags)); - if (!(tmp instanceof FootTagParser)) - assertFalse(accessEnc.getBool(true, edgeFlags), tmp.toString()); - assertTrue(roundaboutEnc.getBool(false, edgeFlags), tmp.toString()); - - way.clearTags(); - way.setTag("highway", "tertiary"); - way.setTag("junction", "circular"); - edgeFlags = manager.handleWayTags(way, manager.createRelationFlags()); - assertTrue(accessEnc.getBool(false, edgeFlags)); - if (!(tmp instanceof FootTagParser)) - assertFalse(accessEnc.getBool(true, edgeFlags), tmp.toString()); - assertTrue(roundaboutEnc.getBool(false, edgeFlags), tmp.toString()); - } - } - -} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java b/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java new file mode 100644 index 00000000000..244ba6cb9d3 --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java @@ -0,0 +1,189 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util; + +import com.graphhopper.reader.ReaderRelation; +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; +import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.util.parsers.OSMBikeNetworkTagParser; +import com.graphhopper.routing.util.parsers.OSMRoadClassParser; +import com.graphhopper.routing.util.parsers.OSMRoundaboutParser; +import com.graphhopper.routing.util.parsers.TagParser; +import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.PMap; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; + +import static com.graphhopper.routing.util.EncodingManager.getKey; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TagParsingTest { + @Test + public void testCombineRelations() { + ReaderWay osmWay = new ReaderWay(1); + osmWay.setTag("highway", "track"); + ReaderRelation osmRel = new ReaderRelation(1); + + FlagEncoder defaultBike = FlagEncoders.createBike(); + FlagEncoder lessRelationCodes = FlagEncoders.createBike(new PMap("name=less_relation_bits")); + + EncodingManager em = EncodingManager.create(defaultBike, lessRelationCodes); + EnumEncodedValue bikeNetworkEnc = em.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class); + BikeTagParser defaultBikeParser = new BikeTagParser(em, new PMap("name=bike")); + defaultBikeParser.init(new DateRangeParser()); + BikeTagParser lessRelationCodesParser = new BikeTagParser(em, new PMap("name=less_relation_bits")) { + @Override + public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { + if (bikeRouteEnc.getEnum(false, edgeFlags) != RouteNetwork.MISSING) + priorityEnc.setDecimal(false, edgeFlags, PriorityCode.getFactor(2)); + return edgeFlags; + } + }; + lessRelationCodesParser.init(new DateRangeParser()); + OSMParsers osmParsers = new OSMParsers() + .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(bikeNetworkEnc, relConfig)) + .addWayTagParser(new OSMRoadClassParser(em.getEnumEncodedValue(RoadClass.KEY, RoadClass.class))) + .addWayTagParser(defaultBikeParser) + .addWayTagParser(lessRelationCodesParser); + + // relation code is PREFER + osmRel.setTag("route", "bicycle"); + osmRel.setTag("network", "lcn"); + IntsRef relFlags = osmParsers.createRelationFlags(); + relFlags = osmParsers.handleRelationTags(osmRel, relFlags); + IntsRef edgeFlags = em.createEdgeFlags(); + edgeFlags = osmParsers.handleWayTags(edgeFlags, osmWay, relFlags); + assertEquals(RouteNetwork.LOCAL, bikeNetworkEnc.getEnum(false, edgeFlags)); + assertTrue(defaultBike.getPriorityEnc().getDecimal(false, edgeFlags) > lessRelationCodes.getPriorityEnc().getDecimal(false, edgeFlags)); + } + + @Test + public void testMixBikeTypesAndRelationCombination() { + ReaderWay osmWay = new ReaderWay(1); + osmWay.setTag("highway", "track"); + osmWay.setTag("tracktype", "grade1"); + + ReaderRelation osmRel = new ReaderRelation(1); + + FlagEncoder bikeEncoder = FlagEncoders.createBike(); + FlagEncoder mtbEncoder = FlagEncoders.createMountainBike(); + EncodingManager manager = EncodingManager.create(bikeEncoder, mtbEncoder); + + EnumEncodedValue bikeNetworkEnc = manager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class); + BikeTagParser bikeTagParser = new BikeTagParser(manager, new PMap()); + bikeTagParser.init(new DateRangeParser()); + MountainBikeTagParser mtbTagParser = new MountainBikeTagParser(manager, new PMap()); + mtbTagParser.init(new DateRangeParser()); + OSMParsers osmParsers = new OSMParsers() + .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(bikeNetworkEnc, relConfig)) + .addWayTagParser(new OSMRoadClassParser(manager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class))) + .addWayTagParser(bikeTagParser) + .addWayTagParser(mtbTagParser); + + // relation code for network rcn is NICE for bike and PREFER for mountainbike + osmRel.setTag("route", "bicycle"); + osmRel.setTag("network", "rcn"); + IntsRef relFlags = osmParsers.createRelationFlags(); + relFlags = osmParsers.handleRelationTags(osmRel, relFlags); + IntsRef edgeFlags = manager.createEdgeFlags(); + edgeFlags = osmParsers.handleWayTags(edgeFlags, osmWay, relFlags); + // bike: uninfluenced speed for grade but via network => NICE + // mtb: uninfluenced speed only PREFER + assertTrue(bikeEncoder.getPriorityEnc().getDecimal(false, edgeFlags) > mtbEncoder.getPriorityEnc().getDecimal(false, edgeFlags)); + } + + @Test + public void testCompatibilityBug() { + EncodingManager manager2 = EncodingManager.create("bike2"); + ReaderWay osmWay = new ReaderWay(1); + osmWay.setTag("highway", "footway"); + osmWay.setTag("name", "test"); + + Bike2WeightTagParser parser = new Bike2WeightTagParser(manager2, new PMap()); + parser.init(new DateRangeParser()); + IntsRef flags = parser.handleWayTags(manager2.createEdgeFlags(), osmWay); + double singleSpeed = parser.avgSpeedEnc.getDecimal(false, flags); + assertEquals(4, singleSpeed, 1e-3); + assertEquals(singleSpeed, parser.avgSpeedEnc.getDecimal(true, flags), 1e-3); + + EncodingManager manager = EncodingManager.create("bike2,bike,foot"); + FootTagParser footParser = new FootTagParser(manager, new PMap()); + footParser.init(new DateRangeParser()); + Bike2WeightTagParser bikeParser = new Bike2WeightTagParser(manager, new PMap()); + bikeParser.init(new DateRangeParser()); + + flags = footParser.handleWayTags(manager.createEdgeFlags(), osmWay); + flags = bikeParser.handleWayTags(flags, osmWay); + DecimalEncodedValue bikeSpeedEnc = manager.getDecimalEncodedValue(getKey("bike2", "average_speed")); + assertEquals(singleSpeed, bikeSpeedEnc.getDecimal(false, flags), 1e-2); + assertEquals(singleSpeed, bikeSpeedEnc.getDecimal(true, flags), 1e-2); + + DecimalEncodedValue footSpeedEnc = manager.getDecimalEncodedValue(getKey("foot", "average_speed")); + assertEquals(5, footSpeedEnc.getDecimal(false, flags), 1e-2); + assertEquals(5, footSpeedEnc.getDecimal(true, flags), 1e-2); + } + + @Test + public void testSharedEncodedValues() { + EncodingManager manager = EncodingManager.create("car,foot,bike,motorcycle,mtb"); + + BooleanEncodedValue roundaboutEnc = manager.getBooleanEncodedValue(Roundabout.KEY); + List tagParsers = Arrays.asList( + new OSMRoundaboutParser(roundaboutEnc), + new CarTagParser(manager, new PMap()), + new FootTagParser(manager, new PMap()), + new BikeTagParser(manager, new PMap()), + new MotorcycleTagParser(manager, new PMap()), + new MountainBikeTagParser(manager, new PMap()) + ); + for (TagParser tagParser : tagParsers) + if (tagParser instanceof VehicleTagParser) + ((VehicleTagParser) tagParser).init(new DateRangeParser()); + + final IntsRef edgeFlags = manager.createEdgeFlags(); + IntsRef relFlags = manager.createRelationFlags(); + ReaderWay way = new ReaderWay(1); + way.setTag("highway", "primary"); + way.setTag("junction", "roundabout"); + tagParsers.forEach(p -> p.handleWayTags(edgeFlags, way, relFlags)); + + for (FlagEncoder tmp : manager.fetchEdgeEncoders()) { + BooleanEncodedValue accessEnc = tmp.getAccessEnc(); + assertTrue(accessEnc.getBool(false, edgeFlags)); + assertTrue(roundaboutEnc.getBool(false, edgeFlags), tmp.toString()); + } + + final IntsRef edgeFlags2 = manager.createEdgeFlags(); + way.clearTags(); + way.setTag("highway", "tertiary"); + way.setTag("junction", "circular"); + tagParsers.forEach(p -> p.handleWayTags(edgeFlags2, way, relFlags)); + + for (FlagEncoder tmp : manager.fetchEdgeEncoders()) { + BooleanEncodedValue accessEnc = tmp.getAccessEnc(); + assertTrue(accessEnc.getBool(false, edgeFlags)); + assertTrue(roundaboutEnc.getBool(false, edgeFlags), tmp.toString()); + } + } + +} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java index c87e6a5c8b2..4ec73839e2d 100644 --- a/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java @@ -19,15 +19,13 @@ import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.NodeAccess; -import com.graphhopper.util.EdgeExplorer; -import com.graphhopper.util.EdgeIteratorState; -import com.graphhopper.util.GHUtility; -import com.graphhopper.util.Helper; +import com.graphhopper.util.*; import org.junit.jupiter.api.Test; import java.text.DateFormat; @@ -40,12 +38,19 @@ */ public class WheelchairTagParserTest { private final EncodingManager encodingManager = EncodingManager.create("car,wheelchair"); - private final WheelchairTagParser wheelchairParser = (WheelchairTagParser) encodingManager.getEncoder("wheelchair"); - private final DecimalEncodedValue wheelchairAvSpeedEnc = wheelchairParser.getAverageSpeedEnc(); - private final BooleanEncodedValue wheelchairAccessEnc = wheelchairParser.getAccessEnc(); + private final WheelchairTagParser wheelchairParser; + private final DecimalEncodedValue wheelchairAvSpeedEnc; + private final BooleanEncodedValue wheelchairAccessEnc; private final DecimalEncodedValue carAvSpeedEnc = encodingManager.getEncoder("car").getAverageSpeedEnc(); private final BooleanEncodedValue carAccessEnc = encodingManager.getEncoder("car").getAccessEnc(); + public WheelchairTagParserTest() { + wheelchairParser = new WheelchairTagParser(encodingManager, new PMap()); + wheelchairParser.init(new DateRangeParser()); + wheelchairAvSpeedEnc = wheelchairParser.getAverageSpeedEnc(); + wheelchairAccessEnc = wheelchairParser.getAccessEnc(); + } + @Test public void testGetSpeed() { IntsRef fl = encodingManager.createEdgeFlags(); @@ -404,45 +409,42 @@ public void testBarrierAccess() { @Test public void testBlockByDefault() { - WheelchairTagParser tmpWheelchairEncoder = new WheelchairTagParser(); - EncodingManager.create(tmpWheelchairEncoder); - ReaderNode node = new ReaderNode(1, -1, -1); node.setTag("barrier", "gate"); // passByDefaultBarriers are no barrier by default - assertFalse(tmpWheelchairEncoder.isBarrier(node)); + assertFalse(wheelchairParser.isBarrier(node)); node.setTag("access", "no"); - assertTrue(tmpWheelchairEncoder.isBarrier(node)); + assertTrue(wheelchairParser.isBarrier(node)); // these barriers block node = new ReaderNode(1, -1, -1); node.setTag("barrier", "fence"); - assertTrue(tmpWheelchairEncoder.isBarrier(node)); + assertTrue(wheelchairParser.isBarrier(node)); node.setTag("barrier", "wall"); - assertTrue(tmpWheelchairEncoder.isBarrier(node)); + assertTrue(wheelchairParser.isBarrier(node)); node.setTag("barrier", "handrail"); - assertTrue(tmpWheelchairEncoder.isBarrier(node)); + assertTrue(wheelchairParser.isBarrier(node)); node.setTag("barrier", "turnstile"); - assertTrue(tmpWheelchairEncoder.isBarrier(node)); + assertTrue(wheelchairParser.isBarrier(node)); // Explictly allowed access is allowed node.setTag("barrier", "fence"); node.setTag("access", "yes"); - assertFalse(tmpWheelchairEncoder.isBarrier(node)); + assertFalse(wheelchairParser.isBarrier(node)); node = new ReaderNode(1, -1, -1); node.setTag("barrier", "gate"); node.setTag("access", "yes"); - assertFalse(tmpWheelchairEncoder.isBarrier(node)); + assertFalse(wheelchairParser.isBarrier(node)); node = new ReaderNode(1, -1, -1); node.setTag("barrier", "kerb"); - assertFalse(tmpWheelchairEncoder.isBarrier(node)); + assertFalse(wheelchairParser.isBarrier(node)); node.setTag("wheelchair", "yes"); - assertFalse(tmpWheelchairEncoder.isBarrier(node)); + assertFalse(wheelchairParser.isBarrier(node)); node = new ReaderNode(1, -1, -1); node.setTag("barrier", "fence"); - assertTrue(tmpWheelchairEncoder.isBarrier(node)); + assertTrue(wheelchairParser.isBarrier(node)); } @Test @@ -502,21 +504,21 @@ public void testApplyWayTags() { na.setNode(1, 51.1, 12.0015, 55); EdgeIteratorState edge01 = graph.edge(0, 1).setWayGeometry(Helper.createPointList3D(51.1, 12.0011, 49, 51.1, 12.0015, 55)); edge01.setDistance(100); - GHUtility.setSpeed(5, 5, wheelchairParser, edge01); + GHUtility.setSpeed(5, 5, encodingManager.getEncoder("wheelchair"), edge01); // incline of 10% & shorter edge na.setNode(2, 51.2, 12.1010, 50); na.setNode(3, 51.2, 12.1015, 60); EdgeIteratorState edge23 = graph.edge(2, 3).setWayGeometry(Helper.createPointList3D(51.2, 12.1011, 49, 51.2, 12.1015, 55)); edge23.setDistance(30); - GHUtility.setSpeed(5, 5, wheelchairParser, edge23); + GHUtility.setSpeed(5, 5, encodingManager.getEncoder("wheelchair"), edge23); // incline of 10% & longer edge na.setNode(4, 51.2, 12.101, 50); na.setNode(5, 51.2, 12.102, 60); EdgeIteratorState edge45 = graph.edge(2, 3).setWayGeometry(Helper.createPointList3D(51.2, 12.1011, 49, 51.2, 12.1015, 55)); edge45.setDistance(100); - GHUtility.setSpeed(5, 5, wheelchairParser, edge45); + GHUtility.setSpeed(5, 5, encodingManager.getEncoder("wheelchair"), edge45); wheelchairParser.applyWayTags(new ReaderWay(1), edge01); From c28a5123d198156f8aff9242e6f8f15fb50a3de0 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 11 May 2022 08:09:06 +0200 Subject: [PATCH 010/389] Remove final from VehicleEncodedValues --- .../com/graphhopper/routing/util/VehicleEncodedValues.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index 90a58934f80..1b7aaea8ec7 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -33,7 +33,7 @@ import static com.graphhopper.routing.util.MotorcycleTagParser.MOTOR_CYCLE_MAX_SPEED; import static com.graphhopper.routing.util.RoadsTagParser.ROADS_MAX_SPEED; -public final class VehicleEncodedValues implements FlagEncoder { +public class VehicleEncodedValues implements FlagEncoder { private final String name; private final boolean isMotorVehicle; private final double maxPossibleSpeed; @@ -189,7 +189,6 @@ public double getMaxSpeed() { return maxPossibleSpeed; } - @Override public BooleanEncodedValue getAccessEnc() { return accessEnc; From 0b53de3abfc1c98006ee16d4366b8d92297ab562 Mon Sep 17 00:00:00 2001 From: otbutz Date: Wed, 11 May 2022 13:57:57 +0200 Subject: [PATCH 011/389] Log available country rules (#2579) Co-authored-by: Thomas Butz --- core/src/main/java/com/graphhopper/GraphHopper.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index bb6aec3ad8c..9f4a64de71a 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -745,6 +745,12 @@ protected void importOSM() { customAreas.addAll(readCustomAreas()); } AreaIndex areaIndex = new AreaIndex<>(customAreas); + + if (countryRuleFactory == null || countryRuleFactory.getCountryToRuleMap().isEmpty()) { + logger.info("No country rules available"); + } else { + logger.info("Applying rules for the following countries: {}", countryRuleFactory.getCountryToRuleMap().keySet()); + } logger.info("start creating graph from " + osmFile); OSMReader reader = new OSMReader(ghStorage.getBaseGraph(), encodingManager, osmParsers, osmReaderConfig).setFile(_getOSMFile()). From 15330acd61dea3541c4f7fd32496a7c0ac0d9d80 Mon Sep 17 00:00:00 2001 From: easbar Date: Sun, 15 May 2022 14:02:37 +0200 Subject: [PATCH 012/389] Give access to vehicle tag parsers --- core/src/main/java/com/graphhopper/GraphHopper.java | 6 ++++++ .../main/java/com/graphhopper/routing/util/OSMParsers.java | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 9f4a64de71a..54bdfe0ce05 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -142,6 +142,12 @@ public EncodingManager getEncodingManager() { return encodingManager; } + public OSMParsers getOSMParsers() { + if (osmParsers == null) + throw new IllegalStateException("OSMParsers not yet built"); + return osmParsers; + } + public ElevationProvider getElevationProvider() { return eleProvider; } diff --git a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java index 858bbae3c60..1b68876fed2 100644 --- a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java +++ b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java @@ -109,4 +109,8 @@ public IntsRef createRelationFlags() { throw new IllegalStateException("More than two ints are needed for relation flags, but OSMReader does not allow this"); return new IntsRef(2); } + + public List getVehicleTagParsers() { + return vehicleTagParsers; + } } From 2bdfbc5b7cbfad6657b5d78976f05cd8a00f2b9c Mon Sep 17 00:00:00 2001 From: easbar Date: Mon, 16 May 2022 19:53:50 +0200 Subject: [PATCH 013/389] Update bestFwd/BwdEntry for flexible algorithms when deleting SPT entries, fix #2581 --- .../routing/AbstractBidirCHAlgo.java | 2 +- .../routing/AbstractNonCHBidirAlgo.java | 7 +++ .../routing/DirectedRoutingTest.java | 58 ++++++++++++++++++- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java b/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java index 50fc264dca7..67ffb91c3bb 100644 --- a/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java +++ b/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java @@ -200,7 +200,7 @@ private void fillEdges(SPTEntry currEdge, PriorityQueue prioQueue, entry = createEntry(iter.getEdge(), iter.getAdjNode(), origEdgeId, weight, currEdge, reverse); bestWeightMap.put(traversalId, entry); prioQueue.add(entry); - // if this is the best entry we need to update the best reference as well. somehow this is only needed for CH? + // if this is the best entry we need to update the best reference as well if (isBestEntry) if (reverse) bestBwdEntry = entry; diff --git a/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java b/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java index b857766b171..a5cab91c84e 100644 --- a/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java +++ b/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java @@ -168,9 +168,16 @@ private void fillEdges(SPTEntry currEdge, PriorityQueue prioQueue, Int } else if (entry.getWeightOfVisitedPath() > weight) { // flagging this entry, so it will be ignored when it is polled the next time entry.setDeleted(); + boolean isBestEntry = reverse ? (entry == bestBwdEntry) : (entry == bestFwdEntry); entry = createEntry(iter, weight, currEdge, reverse); bestWeightMap.put(traversalId, entry); prioQueue.add(entry); + // if this is the best entry we need to update the best reference as well + if (isBestEntry) + if (reverse) + bestBwdEntry = entry; + else + bestFwdEntry = entry; } else continue; diff --git a/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java b/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java index bce784dfc89..8fed14a094b 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java @@ -20,12 +20,14 @@ import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory; import com.graphhopper.routing.ch.PrepareContractionHierarchies; +import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.lm.LMConfig; import com.graphhopper.routing.lm.LMRoutingAlgorithmFactory; import com.graphhopper.routing.lm.LandmarkStorage; import com.graphhopper.routing.lm.PrepareLandmarks; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.querygraph.QueryRoutingCHGraph; +import com.graphhopper.routing.subnetwork.PrepareRoutingSubnetworks; import com.graphhopper.routing.util.*; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; @@ -37,6 +39,8 @@ import com.graphhopper.util.EdgeIterator; import com.graphhopper.util.GHUtility; import com.graphhopper.util.PMap; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -46,6 +50,7 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.stream.Stream; @@ -57,6 +62,7 @@ import static com.graphhopper.util.Parameters.Algorithms.ASTAR_BI; import static com.graphhopper.util.Parameters.Algorithms.DIJKSTRA_BI; import static com.graphhopper.util.Parameters.Routing.ALGORITHM; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; /** @@ -99,7 +105,7 @@ public Fixture(Algo algo, int uTurnCosts, boolean prepareCH, boolean prepareLM) // fail sometimes for edge-based algorithms, #1631, but maybe we can should disable different fwd/bwd speeds // only for loops instead? encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxTurnCosts)); - encodingManager = EncodingManager.create(encoder); + encodingManager = EncodingManager.start().add(encoder).add(Subnetwork.create("c2")).build(); graph = new BaseGraph.Builder(encodingManager).setDir(dir).withTurnCosts(true).create(); turnCostStorage = graph.getTurnCostStorage(); weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, turnCostStorage, uTurnCosts)); @@ -124,6 +130,12 @@ private void preProcessGraph() { routingCHGraph = RoutingCHGraphImpl.fromGraph(graph, res.getCHStorage(), res.getCHConfig()); } if (prepareLM) { + // we need the subnetwork EV for LM + PrepareRoutingSubnetworks preparation = new PrepareRoutingSubnetworks(graph, + Arrays.asList(new PrepareRoutingSubnetworks.PrepareJob(encodingManager.getBooleanEncodedValue(Subnetwork.key("c2")), lmConfig.getWeighting()))); + preparation.setMinNetworkSize(0); + preparation.doWork(); + PrepareLandmarks prepare = new PrepareLandmarks(dir, graph, encodingManager, lmConfig, 16); prepare.setMaximumWeight(1000); prepare.doWork(); @@ -279,6 +291,50 @@ public void randomGraph_withQueryGraph(Fixture f) { } } + @Disabled("todo: fix this, #1971") + @Test + public void issue_2581() { + Fixture f = new Fixture(Algo.LM, 40, false, true); + // this test failed with 'forward and backward entries must have same adjacent nodes' before #2581 was fixed. + // but it still fails with a wrong shortest path weight, probably because of #1971. + NodeAccess na = f.graph.getNodeAccess(); + na.setNode(0, 49.406624, 9.703301); + na.setNode(1, 49.404040, 9.704504); + na.setNode(2, 49.407601, 9.700407); + na.setNode(3, 49.406038, 9.700309); + na.setNode(4, 49.400086, 9.705911); + na.setNode(5, 49.405893, 9.704811); + na.setNode(6, 49.409435, 9.701510); + na.setNode(7, 49.407531, 9.701966); + // 3-0=1-2=7-5 + // | + // 4 + GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(0, 1).setDistance(300.186000)); // edgeId=0 + GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(0, 4).setDistance(751.113000)); // edgeId=1 + GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(7, 2).setDistance(113.102000)); // edgeId=2 + GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(3, 0).setDistance(226.030000)); // edgeId=3 + GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(1, 2).setDistance(494.601000)); // edgeId=4 + GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(7, 2).setDistance(113.102000)); // edgeId=5 + GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(5, 7).setDistance(274.848000)); // edgeId=6 + GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(0, 1).setDistance(300.186000)); // edgeId=7 + f.preProcessGraph(); + LocationIndexTree index = new LocationIndexTree(f.graph, f.dir); + index.prepareIndex(); + Snap snap1 = index.findClosest(49.40513869516064, 9.703482698430037, EdgeFilter.ALL_EDGES); + Snap snap2 = index.findClosest(49.40650971100665, 9.704468799032508, EdgeFilter.ALL_EDGES); + List snaps = Arrays.asList(snap1, snap2); + QueryGraph queryGraph = QueryGraph.create(f.graph, snaps); + int source = snaps.get(0).getClosestNode(); + int target = snaps.get(1).getClosestNode(); + int sourceOutEdge = 8; + int targetInEdge = 11; + Path refPath = new DijkstraBidirectionRef(queryGraph, ((Graph) queryGraph).wrapWeighting(f.weighting), TraversalMode.EDGE_BASED) + .calcPath(source, target, sourceOutEdge, targetInEdge); + Path path = f.createAlgo(queryGraph) + .calcPath(source, target, sourceOutEdge, targetInEdge); + assertTrue(comparePaths(refPath, path, source, target, false, -1).isEmpty()); + } + private List comparePaths(Path refPath, Path path, int source, int target, boolean checkNodes, long seed) { List strictViolations = new ArrayList<>(); double refWeight = refPath.getWeight(); From 8abdad3f9880cd25f5f0894d75f777d8127fe047 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 17 May 2022 10:17:24 +0200 Subject: [PATCH 014/389] Travis: Fix warnings in build config validation It said: Build config validation root: deprecated key sudo (The key `sudo` has no effect anymore.) root: missing os, using the default linux root: key matrix is an alias for jobs, using jobs --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1d8e813a087..eaa1953277c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: java -sudo: true +os: linux dist: xenial env: @@ -9,7 +9,7 @@ env: - secure: "j6a61/qnfFcSjx5XxmxO2hqBOwtVx5HWrD1+4Atl7WG/pRKz9+jSga1Y7oDAFb2SIl8S65kDmPQB/vC8aHxUDj/Wizjxnxn1FhPqoe9yO6Ztft+984FKFyvj7s6tsBJKcehGec+chTOwZQpH4oI4rU6IlepDHnGLHiOd0Iviryg=" - secure: "GiFr+v2lTQk/sTQB7CYjju1/mupS8LSJupmizLqY454utiZkabDMBOZQnF9ukpy7WhveB9hKQyEKf9iP2w7HSYEjgvogT26vZ5f2MeLnR4SWvqEtf/WBvvh+W+k/rb2f6YgitkB4Jlxn2izemBEDuKplGJphzGW41lf8XZ2IxVI=" -matrix: +jobs: include: - name: JDK8 env: JDK='8/ga' # for backward compatibility and release From 90729f3266b020351e762207e69c6f6a3cd131d2 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 18 May 2022 10:59:27 +0200 Subject: [PATCH 015/389] Add VehicleEncodedValues#isHGV --- .../graphhopper/routing/util/FlagEncoder.java | 2 ++ .../routing/util/VehicleEncodedValues.java | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java index 978a203fed8..0f2b87c940a 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java @@ -31,6 +31,8 @@ public interface FlagEncoder extends EncodedValueLookup { boolean isMotorVehicle(); + boolean isHGV(); + /** * @return the maximum speed in km/h */ diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index 1b7aaea8ec7..8ef954dc7fa 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -36,6 +36,7 @@ public class VehicleEncodedValues implements FlagEncoder { private final String name; private final boolean isMotorVehicle; + private final boolean isHGV; private final double maxPossibleSpeed; private final BooleanEncodedValue accessEnc; private final DecimalEncodedValue avgSpeedEnc; @@ -55,7 +56,7 @@ public static VehicleEncodedValues foot(PMap properties) { DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), false, false); } public static VehicleEncodedValues hike(PMap properties) { @@ -82,7 +83,7 @@ public static VehicleEncodedValues bike(PMap properties) { DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), false, false); } public static VehicleEncodedValues bike2(PMap properties) { @@ -112,7 +113,7 @@ public static VehicleEncodedValues car(PMap properties) { BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), true); + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), true, false); } public static VehicleEncodedValues car4wd(PMap properties) { @@ -131,7 +132,7 @@ public static VehicleEncodedValues motorcycle(PMap properties) { DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); DecimalEncodedValue curvatureEnc = new DecimalEncodedValueImpl(getKey(name, "curvature"), 4, 0.1, false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, curvatureEnc, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), true); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, curvatureEnc, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), true, false); } public static VehicleEncodedValues roads() { @@ -143,12 +144,12 @@ public static VehicleEncodedValues roads() { BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, speedEnc.getNextStorableValue(ROADS_MAX_SPEED), true); + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, speedEnc.getNextStorableValue(ROADS_MAX_SPEED), true, false); } public VehicleEncodedValues(String name, BooleanEncodedValue accessEnc, DecimalEncodedValue avgSpeedEnc, DecimalEncodedValue priorityEnc, DecimalEncodedValue curvatureEnc, - DecimalEncodedValue turnCostEnc, double maxPossibleSpeed, boolean isMotorVehicle) { + DecimalEncodedValue turnCostEnc, double maxPossibleSpeed, boolean isMotorVehicle, boolean isHGV) { this.name = name; this.accessEnc = accessEnc; this.avgSpeedEnc = avgSpeedEnc; @@ -157,6 +158,7 @@ public VehicleEncodedValues(String name, BooleanEncodedValue accessEnc, DecimalE this.turnCostEnc = turnCostEnc; this.maxPossibleSpeed = maxPossibleSpeed; this.isMotorVehicle = isMotorVehicle; + this.isHGV = isHGV; } public void setEncodedValueLookup(EncodedValueLookup encodedValueLookup) { @@ -261,6 +263,11 @@ public boolean isMotorVehicle() { return isMotorVehicle; } + @Override + public boolean isHGV() { + return isHGV; + } + @Override public boolean supportsTurnCosts() { return turnCostEnc != null; From 40ad3ce9277acc8dbc525cd786f84ba0af330b92 Mon Sep 17 00:00:00 2001 From: Andi Date: Fri, 20 May 2022 06:57:20 +0200 Subject: [PATCH 016/389] Use more recent node/npm versions to fix the build (#2583) --- web-bundle/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web-bundle/pom.xml b/web-bundle/pom.xml index eca0cedc5a5..b028a33b985 100644 --- a/web-bundle/pom.xml +++ b/web-bundle/pom.xml @@ -128,7 +128,7 @@ com.github.eirslett frontend-maven-plugin - 1.10.0 + 1.12.1 install node and npm @@ -136,8 +136,8 @@ install-node-and-npm - v12.3.1 - 6.14.5 + v16.13.0 + 8.1.0 From cff273999af74eff25cdd888087b068de21020b1 Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 20 May 2022 08:50:38 +0200 Subject: [PATCH 017/389] Update readme for 5.3 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 740d43888b3..75e5a478541 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ We even have [good first issues](https://github.com/graphhopper/graphhopper/issu To get started you can try [GraphHopper Maps](README.md#graphhopper-maps), read through our documentation and install the GraphHopper Web Service locally. * 5.x: [documentation](https://github.com/graphhopper/graphhopper/blob/5.x/docs/index.md) - , [web service jar](https://github.com/graphhopper/graphhopper/releases/download/5.1/graphhopper-web-5.1.jar) + , [web service jar](https://github.com/graphhopper/graphhopper/releases/download/5.3/graphhopper-web-5.3.jar) , [announcement](https://www.graphhopper.com/blog/2022/03/23/graphhopper-routing-engine-5-0-released/) * unstable master: [documentation](https://github.com/graphhopper/graphhopper/blob/master/docs/index.md) @@ -78,7 +78,7 @@ To get started you can try [GraphHopper Maps](README.md#graphhopper-maps), read To install the [GraphHopper Maps](https://graphhopper.com/maps/) UI and the web service locally you [need a JVM](https://adoptopenjdk.net/) (>= Java 8) and do: ```bash -wget https://github.com/graphhopper/graphhopper/releases/download/5.1/graphhopper-web-5.1.jar https://raw.githubusercontent.com/graphhopper/graphhopper/5.x/config-example.yml http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf +wget https://github.com/graphhopper/graphhopper/releases/download/5.3/graphhopper-web-5.3.jar https://raw.githubusercontent.com/graphhopper/graphhopper/5.x/config-example.yml http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf java -Ddw.graphhopper.datareader.file=berlin-latest.osm.pbf -jar *.jar server config-example.yml ``` From 6311a5560eca6c4992e7a629cf191d1e7dc4eaeb Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 24 May 2022 11:28:12 +0200 Subject: [PATCH 018/389] update deployment guide (#2576) * update deployment guide * Update deploy.md * review comments * mention max_visited_nodes --- README.md | 5 +++-- docs/core/deploy.md | 45 ++++++++++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 75e5a478541..383a6011e47 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ To get started you can try [GraphHopper Maps](README.md#graphhopper-maps), read ## Installation -To install the [GraphHopper Maps](https://graphhopper.com/maps/) UI and the web service locally you [need a JVM](https://adoptopenjdk.net/) (>= Java 8) and do: +To install the [GraphHopper Maps](https://graphhopper.com/maps/) UI and the web service locally you [need a JVM](https://adoptium.net) (>= Java 8) and do: ```bash wget https://github.com/graphhopper/graphhopper/releases/download/5.3/graphhopper-web-5.3.jar https://raw.githubusercontent.com/graphhopper/graphhopper/5.x/config-example.yml http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf @@ -85,7 +85,8 @@ java -Ddw.graphhopper.datareader.file=berlin-latest.osm.pbf -jar *.jar server co After a while you see a log message with 'Server - Started', then go to http://localhost:8989/ and you'll see a map of Berlin. You should be able to right click on the map to create a route. -For more details about the installation, see [here](./docs/web/quickstart.md). +For more details about the installation, see [here](./docs/web/quickstart.md) +and the [deployment guide](./docs/core/deploy.md). ### Docker diff --git a/docs/core/deploy.md b/docs/core/deploy.md index 2efe90971d2..470ef765381 100644 --- a/docs/core/deploy.md +++ b/docs/core/deploy.md @@ -5,20 +5,29 @@ This guide is written for everyone interested in deploying graphhopper on a serv ## Basics See the [installation section](../../README.md#installation) on how to start the server. -Embed this command in a shell script and use this from e.g. [Docker](../../README.md#docker) or systemd. + +Then you can embed these commands in a shell script and use this from e.g. [Docker](../../README.md#docker) or systemd. For production usage you have a web service included where you can use [this configuration](https://raw.githubusercontent.com/graphhopper/graphhopper/master/config-example.yml) -Increase the -Xmx/-Xms values of your server accordingly. +Increase the -Xmx/-Xms parameters of the command accordingly. -If you use JDK11 you should try a different garbage collectors like G1, ZGC or Shenandoah. -The G1 is the default but the other two GCs are better suited for JVMs with bigger heaps (>32GB) and low pauses. -You enabled them with `-XX:+UseZGC` or `-XX:+UseShenandoahGC`. Please note that especially ZGC and G1 require quite a -bit memory additionally to the heap and so sometimes speed can be increased when you lower the `Xmx` value. +You can reduce the memory requirements for the import step when you run the +"import" command explicitly before the "server" command: -Notes: +``` +java [options] -jar *.jar import config.yml +java [options] -jar *.jar server config.yml # calls the import command implicitly, if not done before +``` + +Try different garbage collectors (GCs) like ZGC or Shenandoah for serving the +routing requests. The G1 is the default GC but the other two GCs are better suited for JVMs with bigger heaps (>32GB) and low pauses. +You enable them with `-XX:+UseZGC` or `-XX:+UseShenandoahGC`. Please note that especially ZGC and G1 require quite a +bit memory additionally to the heap and so sometimes speed can be increased when you lower the `Xmx` value. - * If you want to support none-CH requests you should at least enable landmarks or limit the request to a certain - * distance otherwise it might require lots of RAM per request! See [#734](https://github.com/graphhopper/graphhopper/issues/734). +If you want to support none-CH requests you should consider enabling landmarks or limit requests to a +certain distance via `routing.non_ch.max_waypoint_distance` (in meter, default is 1) or +to a node count via `routing.max_visited_nodes`. +Otherwise it might require lots of RAM per request! See [#734](https://github.com/graphhopper/graphhopper/issues/734). ### API Tokens @@ -34,11 +43,21 @@ To be able to use the autocomplete feature of the point inputs you have to: ## Worldwide Setup -GraphHopper is able to handle coverage for the whole [OpenStreetMap road network](http://planet.osm.org/). -It needs approximately 25GB RAM for the import (CAR only) and ~1 hour (plus ~5h for contraction). -If you can accept slower import times this can be reduced to 14GB RAM - you'll need to set `datareader.dataaccess=MMAP` in the config file. +GraphHopper can handle the world-wide [OpenStreetMap road network](http://planet.osm.org/). + +Parsing this planet file and creating the GraphHopper base graph requires ~60GB RAM and takes ~3h for the import. If you can accept +much slower import times (3 days!) this can be reduced to 31GB RAM when you set `datareader.dataaccess=MMAP` in the config file. +As of May 2022 the graph has around 415M edges (150M for Europe, 86M for North America). + +Running the CH preparation, required for best response times, needs ~120GB RAM and the additional CH preparation takes ~25 hours +(for the car profile with turn cost) but heavily depends on the CPU and memory speed. Without turn cost +support, e.g. sufficient for bike, it takes much less (~5 hours). + +Running the LM preparation for the car profile needs ~80GB RAM and +the additional LM preparation takes ~4 hours. -Then 'only' 15GB are necessary and without contraction hierarchy this can be further reduced to about 9GB. +It is also possible to add CH/LM preparations for existing profiles after the initial import. +Adding or modifying profiles is not possible and you need to run a new import instead. ### System tuning From 6cae1ce955c7b8a3a6f5a1fdfa56700e28c16b5d Mon Sep 17 00:00:00 2001 From: otbutz Date: Tue, 24 May 2022 16:40:09 +0200 Subject: [PATCH 019/389] Replace deprecated dropwizard parameter types (#2574) Co-authored-by: Thomas Butz --- .../resources/IsochroneResource.java | 39 ++++++++----------- .../graphhopper/resources/SPTResource.java | 11 +++--- .../resources/IsochroneResourceTest.java | 1 + 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java b/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java index b2910476f88..fa6bf52f0b7 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java @@ -23,8 +23,6 @@ import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.Snap; import com.graphhopper.util.*; -import io.dropwizard.jersey.params.IntParam; -import io.dropwizard.jersey.params.LongParam; import org.hibernate.validator.constraints.Range; import org.locationtech.jts.geom.*; import org.slf4j.Logger; @@ -40,6 +38,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.OptionalInt; +import java.util.OptionalLong; import java.util.function.ToDoubleFunction; import static com.graphhopper.resources.IsochroneResource.ResponseType.geojson; @@ -71,12 +71,12 @@ public enum ResponseType {json, geojson} public Response doGet( @Context UriInfo uriInfo, @QueryParam("profile") String profileName, - @QueryParam("buckets") @Range(min = 1, max = 20) @DefaultValue("1") IntParam nBuckets, + @QueryParam("buckets") @Range(min = 1, max = 20) @DefaultValue("1") OptionalInt nBuckets, @QueryParam("reverse_flow") @DefaultValue("false") boolean reverseFlow, @QueryParam("point") @NotNull GHPointParam point, - @QueryParam("time_limit") @DefaultValue("600") LongParam timeLimitInSeconds, - @QueryParam("distance_limit") @DefaultValue("-1") LongParam distanceLimitInMeter, - @QueryParam("weight_limit") @DefaultValue("-1") LongParam weightLimit, + @QueryParam("time_limit") @DefaultValue("600") OptionalLong timeLimitInSeconds, + @QueryParam("distance_limit") @DefaultValue("-1") OptionalLong distanceLimitInMeter, + @QueryParam("weight_limit") @DefaultValue("-1") OptionalLong weightLimit, @QueryParam("type") @DefaultValue("json") ResponseType respType, @QueryParam("tolerance") @DefaultValue("0") double toleranceInMeter, @QueryParam("full_geometry") @DefaultValue("false") boolean fullGeometry) { @@ -111,31 +111,26 @@ public Response doGet( ShortestPathTree shortestPathTree = new ShortestPathTree(queryGraph, queryGraph.wrapWeighting(weighting), reverseFlow, traversalMode); double limit; - if (weightLimit.get() > 0) { - limit = weightLimit.get(); + ToDoubleFunction fz; + if (weightLimit.orElseThrow(() -> new IllegalArgumentException("query param weight_limit is not a number.")) > 0) { + limit = weightLimit.getAsLong(); shortestPathTree.setWeightLimit(limit + Math.max(limit * 0.14, 2_000)); - } else if (distanceLimitInMeter.get() > 0) { - limit = distanceLimitInMeter.get(); + fz = l -> l.weight; + } else if (distanceLimitInMeter.orElseThrow(() -> new IllegalArgumentException("query param distance_limit is not a number.")) > 0) { + limit = distanceLimitInMeter.getAsLong(); shortestPathTree.setDistanceLimit(limit + Math.max(limit * 0.14, 2_000)); + fz = l -> l.distance; } else { - limit = timeLimitInSeconds.get() * 1000; + limit = timeLimitInSeconds.orElseThrow(() -> new IllegalArgumentException("query param time_limit is not a number.")) * 1000d; shortestPathTree.setTimeLimit(limit + Math.max(limit * 0.14, 200_000)); + fz = l -> l.time; } ArrayList zs = new ArrayList<>(); - double delta = limit / nBuckets.get(); - for (int i = 0; i < nBuckets.get(); i++) { + double delta = limit / nBuckets.orElseThrow(() -> new IllegalArgumentException("query param buckets is not a number.")); + for (int i = 0; i < nBuckets.getAsInt(); i++) { zs.add((i + 1) * delta); } - ToDoubleFunction fz; - if (weightLimit.get() > 0) { - fz = l -> l.weight; - } else if (distanceLimitInMeter.get() > 0) { - fz = l -> l.distance; - } else { - fz = l -> l.time; - } - Triangulator.Result result = triangulator.triangulate(snap, queryGraph, shortestPathTree, fz, degreesFromMeters(toleranceInMeter)); ContourBuilder contourBuilder = new ContourBuilder(result.triangulation); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java index fe2630c25bf..b2916fc81cf 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java @@ -20,7 +20,6 @@ import com.graphhopper.storage.index.Snap; import com.graphhopper.util.*; import com.graphhopper.util.shapes.GHPoint; -import io.dropwizard.jersey.params.LongParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -79,8 +78,8 @@ public Response doGet( @QueryParam("reverse_flow") @DefaultValue("false") boolean reverseFlow, @QueryParam("point") @NotNull GHPointParam point, @QueryParam("columns") String columnsParam, - @QueryParam("time_limit") @DefaultValue("600") LongParam timeLimitInSeconds, - @QueryParam("distance_limit") @DefaultValue("-1") LongParam distanceInMeter) { + @QueryParam("time_limit") @DefaultValue("600") OptionalLong timeLimitInSeconds, + @QueryParam("distance_limit") @DefaultValue("-1") OptionalLong distanceInMeter) { StopWatch sw = new StopWatch().start(); PMap hintsMap = new PMap(); RouteResource.initHints(hintsMap, uriInfo.getQueryParameters()); @@ -112,10 +111,10 @@ public Response doGet( TraversalMode traversalMode = profile.isTurnCosts() ? EDGE_BASED : NODE_BASED; ShortestPathTree shortestPathTree = new ShortestPathTree(queryGraph, queryGraph.wrapWeighting(weighting), reverseFlow, traversalMode); - if (distanceInMeter.get() > 0) { - shortestPathTree.setDistanceLimit(distanceInMeter.get()); + if (distanceInMeter.orElseThrow(() -> new IllegalArgumentException("query param distance_limit is not a number.")) > 0) { + shortestPathTree.setDistanceLimit(distanceInMeter.getAsLong()); } else { - double limit = timeLimitInSeconds.get() * 1000; + double limit = timeLimitInSeconds.orElseThrow(() -> new IllegalArgumentException("query param time_limit is not a number.")) * 1000d; shortestPathTree.setTimeLimit(limit); } diff --git a/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java index 7bb6f28ab7e..969d899fc2f 100644 --- a/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java @@ -274,6 +274,7 @@ public void requestNotANumber() { Response response = clientTarget(app, "/isochrone?profile=fast_car&point=42.531073,1.573792&time_limit=wurst") .request().buildGet().invoke(); + assertEquals(400, response.getStatus()); JsonNode json = response.readEntity(JsonNode.class); String message = json.path("message").asText(); From 4570089fb2bd3137fb4ecc689acd46b6055acfa5 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 25 May 2022 09:45:33 +0200 Subject: [PATCH 020/389] Use epsilon=0.9 for LM map-matching --- .../src/main/java/com/graphhopper/matching/MapMatching.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java index 6522fc87658..caa3f1b170f 100644 --- a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java +++ b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java @@ -399,7 +399,10 @@ protected void initCollections(int size) { } }; int activeLM = Math.min(8, landmarks.getLandmarkCount()); - algo.setApproximation(LMApproximator.forLandmarks(queryGraph, landmarks, activeLM)); + LMApproximator lmApproximator = LMApproximator.forLandmarks(queryGraph, landmarks, activeLM); + // todo: we use 0.9, because of some LM bug we do not understand yet + lmApproximator.setEpsilon(0.9); + algo.setApproximation(lmApproximator); algo.setMaxVisitedNodes(maxVisitedNodes); router = algo; } else { From 0752a88872b94937f9738910136c09a66fe898d4 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 14 May 2022 10:35:19 +0200 Subject: [PATCH 021/389] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31fc5da68ea..1d4dcb419be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ### 6.0 [not yet released] - don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) -- faster flexible routing, especially in conjunction with turn costs +- faster flexible routing, especially in conjunction with turn costs (#2571) ### 5.0 [23 Mar 2022] From 4a57859ad7a7d45b6b28ac2e0dd8c22d469bbf78 Mon Sep 17 00:00:00 2001 From: Andi Date: Fri, 27 May 2022 16:40:34 +0200 Subject: [PATCH 022/389] Use edge keys consistently, store keys in CH shortcuts (#2567) --- .../routing/AbstractBidirAlgo.java | 2 - .../routing/AbstractBidirCHAlgo.java | 24 +-- .../AbstractBidirectionEdgeCHNoSOD.java | 18 +- .../routing/AbstractNonCHBidirAlgo.java | 5 - .../graphhopper/routing/AlternativeRoute.java | 16 +- .../DijkstraBidirectionEdgeCHNoSOD.java | 1 + .../routing/ch/BridgePathFinder.java | 2 +- .../com/graphhopper/routing/ch/CHEntry.java | 4 +- .../routing/ch/CHPreparationGraph.java | 45 ++--- .../routing/ch/EdgeBasedNodeContractor.java | 9 +- .../ch/EdgeBasedWitnessPathSearcher.java | 20 +- .../routing/ch/ShortcutUnpacker.java | 8 +- .../querygraph/QueryOverlayBuilder.java | 6 +- .../querygraph/QueryRoutingCHGraph.java | 35 ++-- .../querygraph/VirtualEdgeIterator.java | 5 + .../querygraph/VirtualEdgeIteratorState.java | 5 + .../subnetwork/EdgeBasedTarjanSCC.java | 25 +-- .../subnetwork/PrepareRoutingSubnetworks.java | 4 +- .../routing/util/TraversalMode.java | 49 ++--- .../com/graphhopper/storage/BaseGraph.java | 7 +- .../com/graphhopper/storage/CHStorage.java | 36 ++-- .../graphhopper/storage/CHStorageBuilder.java | 13 +- .../storage/RoutingCHEdgeIteratorImpl.java | 2 +- .../storage/RoutingCHEdgeIteratorState.java | 18 +- .../RoutingCHEdgeIteratorStateImpl.java | 12 +- .../java/com/graphhopper/util/Constants.java | 2 +- .../graphhopper/util/EdgeIteratorState.java | 5 + .../java/com/graphhopper/util/GHUtility.java | 30 +-- .../routing/CHQueryWithTurnCostsTest.java | 76 ++++---- .../routing/QueryRoutingCHGraphTest.java | 10 +- .../routing/RoutingCHGraphImplTest.java | 18 +- .../routing/ch/CHPreparationGraphTest.java | 6 +- .../routing/ch/CHTurnCostTest.java | 26 +++ .../ch/EdgeBasedNodeContractorTest.java | 181 +++++++++--------- .../routing/querygraph/QueryGraphTest.java | 9 +- .../routing/util/AccessFilterTest.java | 2 +- .../weighting/FastestWeightingTest.java | 2 +- .../storage/ShortcutUnpackerTest.java | 34 ++-- .../com/graphhopper/util/GHUtilityTest.java | 18 +- .../resources/MapMatchingResource.java | 2 +- 40 files changed, 375 insertions(+), 417 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/AbstractBidirAlgo.java b/core/src/main/java/com/graphhopper/routing/AbstractBidirAlgo.java index 989e36ec6e4..54902049af7 100644 --- a/core/src/main/java/com/graphhopper/routing/AbstractBidirAlgo.java +++ b/core/src/main/java/com/graphhopper/routing/AbstractBidirAlgo.java @@ -196,8 +196,6 @@ protected void updateBestPath(double edgeWeight, SPTEntry entry, int origEdgeIdF protected abstract double getInEdgeWeight(SPTEntry entry); - protected abstract int getOtherNode(int edge, int node); - protected int getIncomingEdge(SPTEntry entry) { return entry.edge; } diff --git a/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java b/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java index 67ffb91c3bb..b4c4455286b 100644 --- a/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java +++ b/core/src/main/java/com/graphhopper/routing/AbstractBidirCHAlgo.java @@ -21,6 +21,7 @@ import com.graphhopper.routing.ch.NodeBasedCHBidirPathExtractor; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.storage.*; +import com.graphhopper.util.GHUtility; import java.util.PriorityQueue; import java.util.function.Supplier; @@ -84,7 +85,7 @@ protected void postInitFrom() { } else { // need to use a local reference here, because levelEdgeFilter is modified when calling fillEdgesFromUsingFilter final CHEdgeFilter tmpFilter = levelEdgeFilter; - fillEdgesFromUsingFilter(edgeState -> (tmpFilter == null || tmpFilter.accept(edgeState)) && edgeState.getOrigEdgeFirst() == fromOutEdge); + fillEdgesFromUsingFilter(edgeState -> (tmpFilter == null || tmpFilter.accept(edgeState)) && GHUtility.getEdgeFromEdgeKey(edgeState.getOrigEdgeKeyFirst()) == fromOutEdge); } } @@ -94,7 +95,7 @@ protected void postInitTo() { fillEdgesToUsingFilter(levelEdgeFilter); } else { final CHEdgeFilter tmpFilter = levelEdgeFilter; - fillEdgesToUsingFilter(edgeState -> (tmpFilter == null || tmpFilter.accept(edgeState)) && edgeState.getOrigEdgeLast() == toInEdge); + fillEdgesToUsingFilter(edgeState -> (tmpFilter == null || tmpFilter.accept(edgeState)) && GHUtility.getEdgeFromEdgeKey(edgeState.getOrigEdgeKeyLast()) == toInEdge); } } @@ -184,8 +185,8 @@ private void fillEdges(SPTEntry currEdge, PriorityQueue prioQueue, if (Double.isInfinite(weight)) { continue; } - final int origEdgeId = getOrigEdgeId(iter, reverse); - final int traversalId = getTraversalId(iter, origEdgeId, reverse); + final int origEdgeId = GHUtility.getEdgeFromEdgeKey(reverse ? iter.getOrigEdgeKeyFirst() : iter.getOrigEdgeKeyLast()); + final int traversalId = traversalMode.createTraversalId(iter, reverse); SPTEntry entry = bestWeightMap.get(traversalId); if (entry == null) { entry = createEntry(iter.getEdge(), iter.getAdjNode(), origEdgeId, weight, currEdge, reverse); @@ -218,7 +219,7 @@ private void fillEdges(SPTEntry currEdge, PriorityQueue prioQueue, protected double calcWeight(RoutingCHEdgeIteratorState edgeState, boolean reverse, int prevOrNextEdgeId) { double edgeWeight = edgeState.getWeight(reverse); - final int origEdgeId = reverse ? edgeState.getOrigEdgeLast() : edgeState.getOrigEdgeFirst(); + final int origEdgeId = GHUtility.getEdgeFromEdgeKey(reverse ? edgeState.getOrigEdgeKeyLast() : edgeState.getOrigEdgeKeyFirst()); double turnCosts = reverse ? graph.getTurnWeight(origEdgeId, edgeState.getBaseNode(), prevOrNextEdgeId) : graph.getTurnWeight(prevOrNextEdgeId, edgeState.getBaseNode(), origEdgeId); @@ -240,19 +241,6 @@ protected boolean accept(RoutingCHEdgeIteratorState edge, SPTEntry currEdge, boo return levelEdgeFilter == null || levelEdgeFilter.accept(edge); } - protected int getOrigEdgeId(RoutingCHEdgeIteratorState edge, boolean reverse) { - return edge.getEdge(); - } - - protected int getTraversalId(RoutingCHEdgeIteratorState edge, int origEdgeId, boolean reverse) { - return traversalMode.createTraversalId(edge.getBaseNode(), edge.getAdjNode(), edge.getEdge(), reverse); - } - - @Override - protected int getOtherNode(int edge, int node) { - return graph.getBaseGraph().getOtherNode(edge, node); - } - protected double calcWeight(RoutingCHEdgeIteratorState iter, SPTEntry currEdge, boolean reverse) { return calcWeight(iter, reverse, getIncomingEdge(currEdge)) + currEdge.getWeightOfVisitedPath(); } diff --git a/core/src/main/java/com/graphhopper/routing/AbstractBidirectionEdgeCHNoSOD.java b/core/src/main/java/com/graphhopper/routing/AbstractBidirectionEdgeCHNoSOD.java index 445719c9cd1..5c01da51040 100644 --- a/core/src/main/java/com/graphhopper/routing/AbstractBidirectionEdgeCHNoSOD.java +++ b/core/src/main/java/com/graphhopper/routing/AbstractBidirectionEdgeCHNoSOD.java @@ -55,7 +55,7 @@ protected void postInitFrom() { if (fromOutEdge == ANY_EDGE) { fillEdgesFromUsingFilter(CHEdgeFilter.ALL_EDGES); } else { - fillEdgesFromUsingFilter(edgeState -> edgeState.getOrigEdgeFirst() == fromOutEdge); + fillEdgesFromUsingFilter(edgeState -> GHUtility.getEdgeFromEdgeKey(edgeState.getOrigEdgeKeyFirst()) == fromOutEdge); } } @@ -64,7 +64,7 @@ protected void postInitTo() { if (toInEdge == ANY_EDGE) { fillEdgesToUsingFilter(CHEdgeFilter.ALL_EDGES); } else { - fillEdgesToUsingFilter(edgeState -> edgeState.getOrigEdgeLast() == toInEdge); + fillEdgesToUsingFilter(edgeState -> GHUtility.getEdgeFromEdgeKey(edgeState.getOrigEdgeKeyLast()) == toInEdge); } } @@ -91,7 +91,7 @@ protected void updateBestPath(double edgeWeight, SPTEntry entry, int origEdgeId, EdgeIterator iter = innerExplorer.setBaseNode(entry.adjNode); while (iter.next()) { final int edgeId = iter.getEdge(); - int key = GHUtility.createEdgeKey(iter.getAdjNode(), iter.getBaseNode(), edgeId, !reverse); + int key = traversalMode.createTraversalId(iter, reverse); SPTEntry entryOther = bestWeightMapOther.get(key); if (entryOther == null) { continue; @@ -105,27 +105,17 @@ protected void updateBestPath(double edgeWeight, SPTEntry entry, int origEdgeId, if (newWeight < bestWeight) { bestFwdEntry = reverse ? entryOther : entry; bestBwdEntry = reverse ? entry : entryOther; + assert bestFwdEntry.adjNode == bestBwdEntry.adjNode; bestWeight = newWeight; } } } - @Override - protected int getOrigEdgeId(RoutingCHEdgeIteratorState edge, boolean reverse) { - return reverse ? edge.getOrigEdgeFirst() : edge.getOrigEdgeLast(); - } - @Override protected int getIncomingEdge(SPTEntry entry) { return ((CHEntry) entry).incEdge; } - @Override - protected int getTraversalId(RoutingCHEdgeIteratorState edge, int origEdgeId, boolean reverse) { - int baseNode = getOtherNode(origEdgeId, edge.getAdjNode()); - return GHUtility.createEdgeKey(baseNode, edge.getAdjNode(), origEdgeId, reverse); - } - @Override protected boolean accept(RoutingCHEdgeIteratorState edge, SPTEntry currEdge, boolean reverse) { return levelEdgeFilter == null || levelEdgeFilter.accept(edge); diff --git a/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java b/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java index a5cab91c84e..18cd9eef738 100644 --- a/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java +++ b/core/src/main/java/com/graphhopper/routing/AbstractNonCHBidirAlgo.java @@ -202,11 +202,6 @@ protected double getInEdgeWeight(SPTEntry entry) { return weighting.calcEdgeWeight(graph.getEdgeIteratorState(entry.edge, entry.adjNode), false); } - @Override - protected int getOtherNode(int edge, int node) { - return graph.getOtherNode(edge, node); - } - @Override protected Path extractPath() { if (finished()) diff --git a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java index 4bb1a73dc92..900f0362060 100644 --- a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java +++ b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java @@ -58,12 +58,7 @@ * @author Peter Karich */ public class AlternativeRoute implements RoutingAlgorithm { - private static final Comparator ALT_COMPARATOR = new Comparator() { - @Override - public int compare(AlternativeInfo o1, AlternativeInfo o2) { - return Double.compare(o1.sortBy, o2.sortBy); - } - }; + private static final Comparator ALT_COMPARATOR = Comparator.comparingDouble(o -> o.sortBy); private final Graph graph; private final Weighting weighting; private final TraversalMode traversalMode; @@ -356,8 +351,7 @@ public boolean apply(final int traversalId, final SPTEntry fromSPTEntry) { // e.g. when starting point has two edges and one is part of the best path the other edge is path of an alternative assert traversalMode.isEdgeBased(); } else { - int nextToTraversalId = traversalMode.createTraversalId(tmpFromEntry.adjNode, - tmpFromEntry.parent.adjNode, tmpFromEntry.edge, true); + int nextToTraversalId = traversalMode.createTraversalId(graph.getEdgeIteratorState(tmpFromEntry.edge, tmpFromEntry.parent.adjNode), true); SPTEntry tmpNextToSPTEntry = bestWeightMapTo.get(nextToTraversalId); if (tmpNextToSPTEntry == null) return true; @@ -384,9 +378,7 @@ public boolean apply(final int traversalId, final SPTEntry fromSPTEntry) { SPTEntry prevToSPTEntry = toSPTEntry; // List plateauEdges = new ArrayList(); while (prevToSPTEntry.parent != null) { - int nextFromTraversalId = traversalMode.createTraversalId(prevToSPTEntry.adjNode, prevToSPTEntry.parent.adjNode, - prevToSPTEntry.edge, false); - + int nextFromTraversalId = traversalMode.createTraversalId(graph.getEdgeIteratorState(prevToSPTEntry.edge, prevToSPTEntry.parent.adjNode), false); SPTEntry nextFromSPTEntry = bestWeightMapFrom.get(nextFromTraversalId); // end of a plateau if (nextFromSPTEntry == null) @@ -445,7 +437,7 @@ public boolean apply(final int traversalId, final SPTEntry fromSPTEntry) { SPTEntry getFirstShareEE(SPTEntry startEE, boolean reverse) { while (startEE.parent != null) { // TODO we could make use of traversal ID directly if stored in SPTEntry - int tid = traversalMode.createTraversalId(startEE.adjNode, startEE.parent.adjNode, startEE.edge, reverse); + int tid = traversalMode.createTraversalId(graph.getEdgeIteratorState(startEE.edge, startEE.parent.adjNode), reverse); if (isAlreadyExisting(tid)) return startEE; diff --git a/core/src/main/java/com/graphhopper/routing/DijkstraBidirectionEdgeCHNoSOD.java b/core/src/main/java/com/graphhopper/routing/DijkstraBidirectionEdgeCHNoSOD.java index 116f95a8e1c..12bb4c441a4 100644 --- a/core/src/main/java/com/graphhopper/routing/DijkstraBidirectionEdgeCHNoSOD.java +++ b/core/src/main/java/com/graphhopper/routing/DijkstraBidirectionEdgeCHNoSOD.java @@ -40,6 +40,7 @@ protected CHEntry createEntry(int edge, int adjNode, int incEdge, double weight, @Override protected void updateEntry(SPTEntry entry, int edge, int adjNode, int incEdge, double weight, SPTEntry parent, boolean reverse) { + assert entry.adjNode == adjNode; entry.edge = edge; ((CHEntry) entry).incEdge = incEdge; entry.weight = weight; diff --git a/core/src/main/java/com/graphhopper/routing/ch/BridgePathFinder.java b/core/src/main/java/com/graphhopper/routing/ch/BridgePathFinder.java index 8e7234155b6..9d6176bb895 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/BridgePathFinder.java +++ b/core/src/main/java/com/graphhopper/routing/ch/BridgePathFinder.java @@ -121,7 +121,7 @@ public IntObjectMap find(int startInEdgeKey, int startNode, int } } } - // We arrived at some node that is not the center node. We do not expand the search as we oare only + // We arrived at some node that is not the center node. We do not expand the search as we are only // concerned with finding bridge paths. } } diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHEntry.java b/core/src/main/java/com/graphhopper/routing/ch/CHEntry.java index 4685fd6a200..b0cbf058723 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHEntry.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHEntry.java @@ -18,15 +18,15 @@ package com.graphhopper.routing.ch; import com.graphhopper.routing.SPTEntry; +import com.graphhopper.storage.RoutingCHEdgeIteratorState; import com.graphhopper.util.EdgeIterator; -import com.graphhopper.util.EdgeIteratorState; public class CHEntry extends SPTEntry { /** * The id of the incoming original edge at this shortest path tree entry. For original edges this is the same * as the edge id, but for shortcuts this is the id of the last original edge of the shortcut. * - * @see com.graphhopper.storage.RoutingCHEdgeIteratorState#getOrigEdgeLast() + * @see RoutingCHEdgeIteratorState#getOrigEdgeKeyLast() */ public int incEdge; diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java index 92fe48fb111..403d9428734 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java @@ -473,7 +473,7 @@ public void setOrigEdgeCount(int origEdgeCount) { @Override public String toString() { - return currEdge == null ? "not_started" : getBaseNode() + "-" + getAdjNode(); + return currEdge == null ? "not_started" : currEdge.toString(); } private boolean nodeAisBase() { @@ -578,14 +578,12 @@ public double getWeightBA() { @Override public int getOrigEdgeKeyFirstAB() { - int key = prepareEdge << 1; - return nodeA > nodeB ? key + 1 : key; + return GHUtility.createEdgeKey(prepareEdge, nodeA == nodeB, false); } @Override public int getOrigEdgeKeyFirstBA() { - int key = prepareEdge << 1; - return nodeB > nodeA ? key + 1 : key; + return GHUtility.createEdgeKey(prepareEdge, nodeA == nodeB, true); } @Override @@ -858,14 +856,14 @@ public String toString() { private static class OrigGraph { // we store a list of 'edges' in the format: adjNode|edgeId|accessFlags, we use two ints for each edge private final IntArrayList adjNodes; - private final IntArrayList edgesAndFlags; + private final IntArrayList keysAndFlags; // for each node we store the index at which the edges for this node begin in the above edge list private final IntArrayList firstEdgesByNode; - private OrigGraph(IntArrayList firstEdgesByNode, IntArrayList adjNodes, IntArrayList edgesAndFlags) { + private OrigGraph(IntArrayList firstEdgesByNode, IntArrayList adjNodes, IntArrayList keysAndFlags) { this.firstEdgesByNode = firstEdgesByNode; this.adjNodes = adjNodes; - this.edgesAndFlags = edgesAndFlags; + this.keysAndFlags = keysAndFlags; } PrepareGraphOrigEdgeExplorer createOutOrigEdgeExplorer() { @@ -879,20 +877,20 @@ PrepareGraphOrigEdgeExplorer createInOrigEdgeExplorer() { static class Builder { private final IntArrayList fromNodes = new IntArrayList(); private final IntArrayList toNodes = new IntArrayList(); - private final IntArrayList edgesAndFlags = new IntArrayList(); + private final IntArrayList keysAndFlags = new IntArrayList(); private int maxFrom = -1; private int maxTo = -1; void addEdge(int from, int to, int edge, boolean fwd, boolean bwd) { fromNodes.add(from); toNodes.add(to); - edgesAndFlags.add(getEdgeWithFlags(edge, fwd, bwd)); + keysAndFlags.add(getKeyWithFlags(GHUtility.createEdgeKey(edge, from == to, false), fwd, bwd)); maxFrom = Math.max(maxFrom, from); maxTo = Math.max(maxTo, to); fromNodes.add(to); toNodes.add(from); - edgesAndFlags.add(getEdgeWithFlags(edge, bwd, fwd)); + keysAndFlags.add(getKeyWithFlags(GHUtility.createEdgeKey(edge, from == to, true), bwd, fwd)); maxFrom = Math.max(maxFrom, to); maxTo = Math.max(maxTo, from); } @@ -901,21 +899,21 @@ OrigGraph build() { int[] sortOrder = IndirectSort.mergesort(0, fromNodes.elementsCount, new IndirectComparator.AscendingIntComparator(fromNodes.buffer)); sortAndTrim(fromNodes, sortOrder); sortAndTrim(toNodes, sortOrder); - sortAndTrim(edgesAndFlags, sortOrder); - return new OrigGraph(buildFirstEdgesByNode(), toNodes, edgesAndFlags); + sortAndTrim(keysAndFlags, sortOrder); + return new OrigGraph(buildFirstEdgesByNode(), toNodes, keysAndFlags); } - private int getEdgeWithFlags(int edge, boolean fwd, boolean bwd) { - // we use only 30 bits for the edge Id and store two access flags along with the same int - if (edge >= Integer.MAX_VALUE >> 2) + private int getKeyWithFlags(int key, boolean fwd, boolean bwd) { + // we use only 30 bits for the key and store two access flags along with the same int + if (key >= Integer.MAX_VALUE >> 2) throw new IllegalArgumentException("Maximum edge ID exceeded: " + Integer.MAX_VALUE); - edge <<= 1; + key <<= 1; if (fwd) - edge++; - edge <<= 1; + key++; + key <<= 1; if (bwd) - edge++; - return edge; + key++; + return key; } private IntArrayList buildFirstEdgesByNode() { @@ -985,8 +983,7 @@ public int getAdjNode() { @Override public int getOrigEdgeKeyFirst() { - int e = graph.edgesAndFlags.get(index); - return GHUtility.createEdgeKey(node, getAdjNode(), e >> 2, false); + return graph.keysAndFlags.get(index) >> 2; } @Override @@ -995,7 +992,7 @@ public int getOrigEdgeKeyLast() { } private boolean hasAccess() { - int e = graph.edgesAndFlags.get(index); + int e = graph.keysAndFlags.get(index); if (reverse) { return (e & 0b01) == 0b01; } else { diff --git a/core/src/main/java/com/graphhopper/routing/ch/EdgeBasedNodeContractor.java b/core/src/main/java/com/graphhopper/routing/ch/EdgeBasedNodeContractor.java index 328b369f271..12fb49057cc 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/EdgeBasedNodeContractor.java +++ b/core/src/main/java/com/graphhopper/routing/ch/EdgeBasedNodeContractor.java @@ -31,7 +31,6 @@ import java.util.Locale; import static com.graphhopper.routing.ch.CHParameters.*; -import static com.graphhopper.util.GHUtility.getEdgeFromEdgeKey; import static com.graphhopper.util.GHUtility.reverseEdgeKey; import static com.graphhopper.util.Helper.nf; @@ -247,8 +246,8 @@ private void insertOutShortcuts(int node) { int shortcut = chBuilder.addShortcutEdgeBased(node, iter.getAdjNode(), PrepareEncoder.getScFwdDir(), iter.getWeight(), iter.getSkipped1(), iter.getSkipped2(), - getEdgeFromEdgeKey(iter.getOrigEdgeKeyFirst()), - getEdgeFromEdgeKey(iter.getOrigEdgeKeyLast())); + iter.getOrigEdgeKeyFirst(), + iter.getOrigEdgeKeyLast()); prepareGraph.setShortcutForPrepareEdge(iter.getPrepareEdge(), prepareGraph.getOriginalEdges() + shortcut); addedShortcutsCount++; } @@ -265,8 +264,8 @@ private void insertInShortcuts(int node) { int shortcut = chBuilder.addShortcutEdgeBased(node, iter.getAdjNode(), PrepareEncoder.getScBwdDir(), iter.getWeight(), iter.getSkipped1(), iter.getSkipped2(), - getEdgeFromEdgeKey(iter.getOrigEdgeKeyFirst()), - getEdgeFromEdgeKey(iter.getOrigEdgeKeyLast())); + iter.getOrigEdgeKeyFirst(), + iter.getOrigEdgeKeyLast()); prepareGraph.setShortcutForPrepareEdge(iter.getPrepareEdge(), prepareGraph.getOriginalEdges() + shortcut); addedShortcutsCount++; } diff --git a/core/src/main/java/com/graphhopper/routing/ch/EdgeBasedWitnessPathSearcher.java b/core/src/main/java/com/graphhopper/routing/ch/EdgeBasedWitnessPathSearcher.java index f9da7866212..ccf5b2e977e 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/EdgeBasedWitnessPathSearcher.java +++ b/core/src/main/java/com/graphhopper/routing/ch/EdgeBasedWitnessPathSearcher.java @@ -69,7 +69,7 @@ public class EdgeBasedWitnessPathSearcher { private double[] weights; private int[] parents; private int[] adjNodesAndIsPathToCenters; - private IntArrayList changedEdges; + private IntArrayList changedEdgeKeys; private IntFloatBinaryHeap dijkstraHeap; // statistics to analyze performance @@ -103,7 +103,7 @@ public void initSearch(int sourceEdgeKey, int sourceNode, int centerNode, Stats weights[sourceEdgeKey] = 0; parents[sourceEdgeKey] = -1; setAdjNodeAndPathToCenter(sourceEdgeKey, sourceNode, true); - changedEdges.add(sourceEdgeKey); + changedEdgeKeys.add(sourceEdgeKey); dijkstraHeap.insert(0, sourceEdgeKey); } @@ -160,7 +160,7 @@ public double runSearch(int targetNode, int targetEdgeKey, double acceptedWeight weights[key] = weight; parents[key] = currKey; setAdjNodeAndPathToCenter(key, iter.getAdjNode(), isPathToCenter); - changedEdges.add(key); + changedEdgeKeys.add(key); dijkstraHeap.insert(weight, key); if (iter.getAdjNode() == targetNode && (!isPathToCenter(currKey) || parents[currKey] < 0)) foundWeight = Math.min(foundWeight, weight + calcTurnWeight(key, targetNode, targetEdgeKey)); @@ -191,8 +191,8 @@ public void finishSearch() { // update stats using values of last search stats.numPolls += numPolls; stats.maxPolls = Math.max(stats.maxPolls, numPolls); - stats.numExplored += changedEdges.size(); - stats.maxExplored = Math.max(stats.maxExplored, changedEdges.size()); + stats.numExplored += changedEdgeKeys.size(); + stats.maxExplored = Math.max(stats.maxExplored, changedEdgeKeys.size()); stats.numUpdates += numUpdates; stats.maxUpdates = Math.max(stats.maxUpdates, numUpdates); reset(); @@ -217,7 +217,7 @@ public void close() { weights = null; parents = null; adjNodesAndIsPathToCenters = null; - changedEdges.release(); + changedEdgeKeys.release(); dijkstraHeap = null; } @@ -234,7 +234,7 @@ private void initStorage(int numEntries) { } private void initCollections() { - changedEdges = new IntArrayList(1000); + changedEdgeKeys = new IntArrayList(1000); dijkstraHeap = new IntFloatBinaryHeap(1000); } @@ -245,9 +245,9 @@ private void reset() { } private void resetShortestPathTree() { - for (int i = 0; i < changedEdges.size(); ++i) - resetEntry(changedEdges.get(i)); - changedEdges.elementsCount = 0; + for (int i = 0; i < changedEdgeKeys.size(); ++i) + resetEntry(changedEdgeKeys.get(i)); + changedEdgeKeys.elementsCount = 0; dijkstraHeap.clear(); } diff --git a/core/src/main/java/com/graphhopper/routing/ch/ShortcutUnpacker.java b/core/src/main/java/com/graphhopper/routing/ch/ShortcutUnpacker.java index a32e0d07881..d55ac53a31a 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/ShortcutUnpacker.java +++ b/core/src/main/java/com/graphhopper/routing/ch/ShortcutUnpacker.java @@ -3,6 +3,7 @@ import com.graphhopper.storage.RoutingCHEdgeIteratorState; import com.graphhopper.storage.RoutingCHGraph; import com.graphhopper.util.EdgeIteratorState; +import com.graphhopper.util.GHUtility; import java.util.Locale; @@ -108,11 +109,10 @@ private void expandSkippedEdgesNodeBased(int skippedEdge1, int skippedEdge2, int private int getOppositeEdge(RoutingCHEdgeIteratorState edgeState, int adjNode) { assert edgeState.getBaseNode() == adjNode || edgeState.getAdjNode() == adjNode : "adjNode " + adjNode + " must be one of adj/base of edgeState: " + edgeState; - // since the first/last orig edge is not stateful (just like skipped1/2) we have to find out which one + // since the first/last orig edge key is not stateful (just like skipped1/2) we have to find out which one // is attached to adjNode, similar as we do for skipped1/2. - return graph.getBaseGraph().isAdjacentToNode(edgeState.getOrigEdgeLast(), adjNode) - ? edgeState.getOrigEdgeFirst() - : edgeState.getOrigEdgeLast(); + boolean adjacentToNode = graph.getBaseGraph().isAdjacentToNode(GHUtility.getEdgeFromEdgeKey(edgeState.getOrigEdgeKeyLast()), adjNode); + return GHUtility.getEdgeFromEdgeKey(adjacentToNode ? edgeState.getOrigEdgeKeyFirst() : edgeState.getOrigEdgeKeyLast()); } private RoutingCHEdgeIteratorState getEdge(int edgeId, int adjNode) { diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java b/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java index a15daab548f..100900ae52c 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java @@ -147,7 +147,7 @@ private double distanceOfSnappedPointToPillarNode(Snap o) { GHPoint3D prevPoint = fullPL.get(0); int adjNode = closestEdge.getAdjNode(); int origEdgeKey = closestEdge.getEdgeKey(); - int origRevEdgeKey = GHUtility.reverseEdgeKey(origEdgeKey); + int origRevEdgeKey = closestEdge.getReverseEdgeKey(); int prevWayIndex = 1; int prevNodeId = baseNode; int virtNodeId = queryOverlay.getVirtualNodes().size() + firstVirtualNodeId; @@ -225,9 +225,9 @@ private void createEdges(int origEdgeKey, int origRevEdgeKey, boolean reverse = closestEdge.get(EdgeIteratorState.REVERSE_STATE); // edges between base and snapped point - VirtualEdgeIteratorState baseEdge = new VirtualEdgeIteratorState(origEdgeKey, GHUtility.createEdgeKey(virtEdgeId, false), + VirtualEdgeIteratorState baseEdge = new VirtualEdgeIteratorState(origEdgeKey, GHUtility.createEdgeKey(virtEdgeId, prevNodeId == nodeId, false), prevNodeId, nodeId, baseDistance, closestEdge.getFlags(), closestEdge.getName(), basePoints, reverse); - VirtualEdgeIteratorState baseReverseEdge = new VirtualEdgeIteratorState(origRevEdgeKey, GHUtility.createEdgeKey(virtEdgeId, true), + VirtualEdgeIteratorState baseReverseEdge = new VirtualEdgeIteratorState(origRevEdgeKey, GHUtility.createEdgeKey(virtEdgeId, prevNodeId == nodeId, true), nodeId, prevNodeId, baseDistance, IntsRef.deepCopyOf(closestEdge.getFlags()), closestEdge.getName(), baseReversePoints, !reverse); baseEdge.setReverseEdge(baseReverseEdge); diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/QueryRoutingCHGraph.java b/core/src/main/java/com/graphhopper/routing/querygraph/QueryRoutingCHGraph.java index 1137af8ae89..cca752fefda 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/QueryRoutingCHGraph.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/QueryRoutingCHGraph.java @@ -197,11 +197,11 @@ public void apply(int node, QueryOverlay.EdgeChanges edgeChanges) { // shortcuts cannot be in the removed edge set because this was determined on the (base) query graph if (iter.isShortcut()) { virtualEdges.add(new VirtualCHEdgeIteratorState(iter.getEdge(), NO_EDGE, - iter.getBaseNode(), iter.getAdjNode(), iter.getOrigEdgeFirst(), iter.getOrigEdgeLast(), + iter.getBaseNode(), iter.getAdjNode(), iter.getOrigEdgeKeyFirst(), iter.getOrigEdgeKeyLast(), iter.getSkippedEdge1(), iter.getSkippedEdge2(), iter.getWeight(false), iter.getWeight(true))); } else if (!edgeChanges.getRemovedEdges().contains(iter.getOrigEdge())) { virtualEdges.add(new VirtualCHEdgeIteratorState(iter.getEdge(), iter.getOrigEdge(), - iter.getBaseNode(), iter.getAdjNode(), iter.getOrigEdgeFirst(), iter.getOrigEdgeLast(), + iter.getBaseNode(), iter.getAdjNode(), iter.getOrigEdgeKeyFirst(), iter.getOrigEdgeKeyLast(), NO_EDGE, NO_EDGE, iter.getWeight(false), iter.getWeight(true))); } } @@ -230,11 +230,10 @@ private VirtualCHEdgeIteratorState buildVirtualCHEdgeState(VirtualEdgeIteratorSt } private VirtualCHEdgeIteratorState buildVirtualCHEdgeState(EdgeIteratorState edgeState, int edgeID) { - int origEdge = edgeState.getEdge(); double fwdWeight = weighting.calcEdgeWeightWithAccess(edgeState, false); double bwdWeight = weighting.calcEdgeWeightWithAccess(edgeState, true); - return new VirtualCHEdgeIteratorState(edgeID, origEdge, edgeState.getBaseNode(), edgeState.getAdjNode(), - origEdge, origEdge, NO_EDGE, NO_EDGE, fwdWeight, bwdWeight); + return new VirtualCHEdgeIteratorState(edgeID, edgeState.getEdge(), edgeState.getBaseNode(), edgeState.getAdjNode(), + edgeState.getEdgeKey(), edgeState.getEdgeKey(), NO_EDGE, NO_EDGE, fwdWeight, bwdWeight); } private int shiftVirtualEdgeIDForCH(int edge) { @@ -258,20 +257,20 @@ private static class VirtualCHEdgeIteratorState implements RoutingCHEdgeIterator private final int origEdge; private final int baseNode; private final int adjNode; - private final int origEdgeFirst; - private final int origEdgeLast; + private final int origEdgeKeyFirst; + private final int origEdgeKeyLast; private final int skippedEdge1; private final int skippedEdge2; private final double weightFwd; private final double weightBwd; - public VirtualCHEdgeIteratorState(int edge, int origEdge, int baseNode, int adjNode, int origEdgeFirst, int origEdgeLast, int skippedEdge1, int skippedEdge2, double weightFwd, double weightBwd) { + public VirtualCHEdgeIteratorState(int edge, int origEdge, int baseNode, int adjNode, int origEdgeKeyFirst, int origEdgeKeyLast, int skippedEdge1, int skippedEdge2, double weightFwd, double weightBwd) { this.edge = edge; this.origEdge = origEdge; this.baseNode = baseNode; this.adjNode = adjNode; - this.origEdgeFirst = origEdgeFirst; - this.origEdgeLast = origEdgeLast; + this.origEdgeKeyFirst = origEdgeKeyFirst; + this.origEdgeKeyLast = origEdgeKeyLast; this.skippedEdge1 = skippedEdge1; this.skippedEdge2 = skippedEdge2; this.weightFwd = weightFwd; @@ -289,13 +288,13 @@ public int getOrigEdge() { } @Override - public int getOrigEdgeFirst() { - return origEdgeFirst; + public int getOrigEdgeKeyFirst() { + return origEdgeKeyFirst; } @Override - public int getOrigEdgeLast() { - return origEdgeLast; + public int getOrigEdgeKeyLast() { + return origEdgeKeyLast; } @Override @@ -361,13 +360,13 @@ public int getOrigEdge() { } @Override - public int getOrigEdgeFirst() { - return getCurrent().getOrigEdgeFirst(); + public int getOrigEdgeKeyFirst() { + return getCurrent().getOrigEdgeKeyFirst(); } @Override - public int getOrigEdgeLast() { - return getCurrent().getOrigEdgeLast(); + public int getOrigEdgeKeyLast() { + return getCurrent().getOrigEdgeKeyLast(); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java index aa561b468a5..ac3562c015f 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java @@ -73,6 +73,11 @@ public int getEdgeKey() { return getCurrentEdge().getEdgeKey(); } + @Override + public int getReverseEdgeKey() { + return getCurrentEdge().getReverseEdgeKey(); + } + @Override public int getBaseNode() { return getCurrentEdge().getBaseNode(); diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java index c5144d268a2..b387bd72f36 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java @@ -77,6 +77,11 @@ public int getEdgeKey() { return edgeKey; } + @Override + public int getReverseEdgeKey() { + return baseNode == adjNode ? edgeKey : GHUtility.reverseEdgeKey(edgeKey); + } + @Override public int getBaseNode() { return baseNode; diff --git a/core/src/main/java/com/graphhopper/routing/subnetwork/EdgeBasedTarjanSCC.java b/core/src/main/java/com/graphhopper/routing/subnetwork/EdgeBasedTarjanSCC.java index e57f2babb88..1819a8edc95 100644 --- a/core/src/main/java/com/graphhopper/routing/subnetwork/EdgeBasedTarjanSCC.java +++ b/core/src/main/java/com/graphhopper/routing/subnetwork/EdgeBasedTarjanSCC.java @@ -21,17 +21,17 @@ import com.carrotsearch.hppc.*; import com.carrotsearch.hppc.cursors.IntCursor; import com.graphhopper.routing.util.AllEdgesIterator; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.storage.Graph; import com.graphhopper.util.BitUtil; -import com.graphhopper.util.EdgeExplorer; -import com.graphhopper.util.EdgeIterator; -import com.graphhopper.util.EdgeIteratorState; +import com.graphhopper.util.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import static com.graphhopper.util.EdgeIterator.NO_EDGE; +import static com.graphhopper.util.GHUtility.getEdgeFromEdgeKey; /** * Edge-based version of Tarjan's algorithm to find strongly connected components on a directed graph. Compared @@ -148,7 +148,7 @@ private ConnectedComponents findComponentsRecursive() { private void findComponentForEdgeKey(int p, int adjNode) { setupNextEdgeKey(p); // we have to create a new explorer on each iteration because of the nested edge iterations - final int edge = getEdgeFromKey(p); + final int edge = getEdgeFromEdgeKey(p); EdgeExplorer explorer = graph.createEdgeExplorer(); EdgeIterator iter = explorer.setBaseNode(adjNode); while (iter.next()) { @@ -266,7 +266,7 @@ private void startSearch() { setupNextEdgeKey(p); // we push buildComponent first so it will run *after* we finished traversing the edges pushBuildComponent(p); - final int edge = getEdgeFromKey(p); + final int edge = getEdgeFromEdgeKey(p); EdgeIterator it = explorer.setBaseNode(adj); while (it.next()) { if (!edgeTransitionFilter.accept(edge, it)) @@ -343,19 +343,8 @@ private void pushHandleNeighbor(int p, int q, int adj) { dfsStackAdj.addLast(adj); } - /** - * Use this method to return the edge for the specified edgeKeys that get returned by {@link #findComponents()}} etc. - * The implementation is like GHUtility.getEdgeFromEdgeKey but might be different in the future. See #2152. - */ - public static int getEdgeFromKey(int edgeKey) { - return edgeKey / 2; - } - public static int createEdgeKey(EdgeIteratorState edgeState, boolean reverse) { - int edgeKey = edgeState.getEdge() << 1; - if (edgeState.get(EdgeIteratorState.REVERSE_STATE) == !reverse) - edgeKey++; - return edgeKey; + return TraversalMode.EDGE_BASED.createTraversalId(edgeState, reverse); } public static class ConnectedComponents { @@ -377,7 +366,7 @@ public static class ConnectedComponents { * A list of arrays each containing the edge keys of a strongly connected component. Components with only a single * edge key are not included here, but need to be obtained using {@link #getSingleEdgeComponents()}. * The edge key is either 2*edgeId (if the edge direction corresponds to the storage order) or 2*edgeId+1 (for - * the opposite direction). Use {@link EdgeBasedTarjanSCC#getEdgeFromKey(int)} to convert edge keys back to + * the opposite direction). Use {@link GHUtility#getEdgeFromEdgeKey(int)} to convert edge keys back to * edge IDs. */ public List getComponents() { diff --git a/core/src/main/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworks.java b/core/src/main/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworks.java index 0ad5b3e3068..5b47ae37dae 100644 --- a/core/src/main/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworks.java +++ b/core/src/main/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworks.java @@ -33,6 +33,8 @@ import java.util.List; +import static com.graphhopper.util.GHUtility.getEdgeFromEdgeKey; + /** * Detects and marks 'subnetworks' with a dedicated subnetwork encoded value. Subnetworks are parts of the road network * that are not connected to the rest of the network and that are below a certain size. These can be isolated nodes with @@ -159,7 +161,7 @@ private int setSubnetworkEdge(int edgeKey, Weighting weighting, BooleanEncodedVa return 0; // now get edge again but in stored direction so that subnetwork EV is not overwritten (as it is unidirectional) - EdgeIteratorState edgeState = graph.getEdgeIteratorState(EdgeBasedTarjanSCC.getEdgeFromKey(edgeKey), Integer.MIN_VALUE); + EdgeIteratorState edgeState = graph.getEdgeIteratorState(getEdgeFromEdgeKey(edgeKey), Integer.MIN_VALUE); if (!edgeState.get(subnetworkEnc)) { edgeState.set(subnetworkEnc, true); return 1; diff --git a/core/src/main/java/com/graphhopper/routing/util/TraversalMode.java b/core/src/main/java/com/graphhopper/routing/util/TraversalMode.java index 53feba97f3a..8936afb9138 100644 --- a/core/src/main/java/com/graphhopper/routing/util/TraversalMode.java +++ b/core/src/main/java/com/graphhopper/routing/util/TraversalMode.java @@ -17,30 +17,15 @@ */ package com.graphhopper.routing.util; +import com.graphhopper.storage.RoutingCHEdgeIteratorState; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; -import java.util.Arrays; - -import static com.graphhopper.util.Helper.toUpperCase; - /** - * Defines how the graph can be traversed while Dijkstra or similar RoutingAlgorithm is in progress. - * Different options define how precise turn restrictions and costs are taken into account, but - * still all are without via-way support. BTW: this would not be done at runtime, this would be a - * pre-processing step to avoid performance penalties. - *

- * * @author Peter Karich */ public enum TraversalMode { - /** - * The simplest traversal mode but without turn restrictions or cost support. - */ NODE_BASED(false), - /** - * The edged-based traversal mode with turn restriction and cost support. 2 times slower than node based. - */ EDGE_BASED(true); private final boolean edgeBased; @@ -49,38 +34,34 @@ public enum TraversalMode { this.edgeBased = edgeBased; } - public static TraversalMode fromString(String name) { - try { - return valueOf(toUpperCase(name)); - } catch (Exception ex) { - throw new IllegalArgumentException("TraversalMode " + name + " not supported. " - + "Supported are: " + Arrays.asList(TraversalMode.values())); - } - } - /** * Returns the identifier to access the map of the shortest path tree according to the traversal * mode. E.g. returning the adjacent node id in node-based behavior whilst returning the edge id * in edge-based behavior *

* - * @param iterState the current {@link EdgeIteratorState} + * @param edgeState the current {@link EdgeIteratorState} * @param reverse true, if traversal in backward direction. Will be true only for * backward searches in bidirectional algorithms. * @return the identifier to access the shortest path tree */ - public final int createTraversalId(EdgeIteratorState iterState, boolean reverse) { - return createTraversalId(iterState.getBaseNode(), iterState.getAdjNode(), iterState.getEdge(), reverse); + public final int createTraversalId(EdgeIteratorState edgeState, boolean reverse) { + if (edgeBased) + return reverse ? edgeState.getReverseEdgeKey() : edgeState.getEdgeKey(); + return edgeState.getAdjNode(); } - /** - * If you have an EdgeIteratorState the other createTraversalId is preferred! - */ - public final int createTraversalId(int baseNode, int adjNode, int edgeId, boolean reverse) { + public final int createTraversalId(RoutingCHEdgeIteratorState chEdgeState, boolean reverse) { if (edgeBased) { - return GHUtility.createEdgeKey(baseNode, adjNode, edgeId, reverse); + int key = reverse ? chEdgeState.getOrigEdgeKeyFirst() : chEdgeState.getOrigEdgeKeyLast(); + // For reverse traversal we need to revert the edge key, but not for loops and not for shortcuts. + // Why not for shortcuts? Because of our definition of the first/last edge keys: they do not depend on the + // 'state' of the edge state, but are defined in terms of the direction of the (always directed) shortcut. + if (reverse && !chEdgeState.isShortcut() && chEdgeState.getBaseNode() != chEdgeState.getAdjNode()) + key = GHUtility.reverseEdgeKey(key); + return key; } - return adjNode; + return chEdgeState.getAdjNode(); } public boolean isEdgeBased() { diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index 458e1c649f2..e33d3c6553b 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -945,7 +945,12 @@ public int getEdge() { @Override public int getEdgeKey() { - return GHUtility.createEdgeKey(edgeId, reverse); + return GHUtility.createEdgeKey(edgeId, baseNode == adjNode, reverse); + } + + @Override + public int getReverseEdgeKey() { + return baseNode == adjNode ? getEdgeKey() : GHUtility.reverseEdgeKey(getEdgeKey()); } @Override diff --git a/core/src/main/java/com/graphhopper/storage/CHStorage.java b/core/src/main/java/com/graphhopper/storage/CHStorage.java index d961e6e426b..0a1c356ce8e 100644 --- a/core/src/main/java/com/graphhopper/storage/CHStorage.java +++ b/core/src/main/java/com/graphhopper/storage/CHStorage.java @@ -52,7 +52,7 @@ public class CHStorage { // shortcuts private final DataAccess shortcuts; - private final int S_NODEA, S_NODEB, S_WEIGHT, S_SKIP_EDGE1, S_SKIP_EDGE2, S_ORIG_FIRST, S_ORIG_LAST; + private final int S_NODEA, S_NODEB, S_WEIGHT, S_SKIP_EDGE1, S_SKIP_EDGE2, S_ORIG_KEY_FIRST, S_ORIG_KEY_LAST; private int shortcutEntryBytes; private int shortcutCount = 0; @@ -103,9 +103,9 @@ public CHStorage(Directory dir, String name, int segmentSize, boolean edgeBased) S_WEIGHT = S_NODEB + 4; S_SKIP_EDGE1 = S_WEIGHT + 4; S_SKIP_EDGE2 = S_SKIP_EDGE1 + 4; - S_ORIG_FIRST = S_SKIP_EDGE2 + (edgeBased ? 4 : 0); - S_ORIG_LAST = S_ORIG_FIRST + (edgeBased ? 4 : 0); - shortcutEntryBytes = S_ORIG_LAST + 4; + S_ORIG_KEY_FIRST = S_SKIP_EDGE2 + (edgeBased ? 4 : 0); + S_ORIG_KEY_LAST = S_ORIG_KEY_FIRST + (edgeBased ? 4 : 0); + shortcutEntryBytes = S_ORIG_KEY_LAST + 4; // nodes/levels are stored consecutively using this layout: // LEVEL | N_LAST_SC @@ -201,11 +201,11 @@ public int shortcutNodeBased(int nodeA, int nodeB, int accessFlags, double weigh return shortcut(nodeA, nodeB, accessFlags, weight, skip1, skip2); } - public int shortcutEdgeBased(int nodeA, int nodeB, int accessFlags, double weight, int skip1, int skip2, int origFirst, int origLast) { + public int shortcutEdgeBased(int nodeA, int nodeB, int accessFlags, double weight, int skip1, int skip2, int origKeyFirst, int origKeyLast) { if (!edgeBased) throw new IllegalArgumentException("Cannot add edge-based shortcuts to node-based CH"); int shortcut = shortcut(nodeA, nodeB, accessFlags, weight, skip1, skip2); - setOrigEdges(toShortcutPointer(shortcut), origFirst, origLast); + setOrigEdgeKeys(toShortcutPointer(shortcut), origKeyFirst, origKeyLast); return shortcut; } @@ -292,11 +292,11 @@ public void setSkippedEdges(long shortcutPointer, int edge1, int edge2) { shortcuts.setInt(shortcutPointer + S_SKIP_EDGE2, edge2); } - public void setOrigEdges(long shortcutPointer, int origFirst, int origLast) { + public void setOrigEdgeKeys(long shortcutPointer, int origKeyFirst, int origKeyLast) { if (!edgeBased) - throw new IllegalArgumentException("Setting orig edges is only possible for edge-based CH"); - shortcuts.setInt(shortcutPointer + S_ORIG_FIRST, origFirst); - shortcuts.setInt(shortcutPointer + S_ORIG_LAST, origLast); + throw new IllegalArgumentException("Setting orig edge keys is only possible for edge-based CH"); + shortcuts.setInt(shortcutPointer + S_ORIG_KEY_FIRST, origKeyFirst); + shortcuts.setInt(shortcutPointer + S_ORIG_KEY_LAST, origKeyLast); } public int getNodeA(long shortcutPointer) { @@ -327,14 +327,14 @@ public int getSkippedEdge2(long shortcutPointer) { return shortcuts.getInt(shortcutPointer + S_SKIP_EDGE2); } - public int getOrigEdgeFirst(long shortcutPointer) { - assert edgeBased : "orig edges are only available for edge-based CH"; - return shortcuts.getInt(shortcutPointer + S_ORIG_FIRST); + public int getOrigEdgeKeyFirst(long shortcutPointer) { + assert edgeBased : "orig edge keys are only available for edge-based CH"; + return shortcuts.getInt(shortcutPointer + S_ORIG_KEY_FIRST); } - public int getOrigEdgeLast(long shortcutPointer) { - assert edgeBased : "orig edges are only available for edge-based CH"; - return shortcuts.getInt(shortcutPointer + S_ORIG_LAST); + public int getOrigEdgeKeyLast(long shortcutPointer) { + assert edgeBased : "orig edge keys are only available for edge-based CH"; + return shortcuts.getInt(shortcutPointer + S_ORIG_KEY_LAST); } public NodeOrderingProvider getNodeOrderingProvider() { @@ -381,8 +381,8 @@ public void debugPrint() { getSkippedEdge2(ptr)); if (edgeBased) { edgeString += String.format(Locale.ROOT, formatShortcutExt, - getOrigEdgeFirst(ptr), - getOrigEdgeLast(ptr)); + getOrigEdgeKeyFirst(ptr), + getOrigEdgeKeyLast(ptr)); } System.out.println(edgeString); } diff --git a/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java b/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java index 32b2c6ce8a9..8aa941241e2 100644 --- a/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java +++ b/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java @@ -62,15 +62,16 @@ public int addShortcutNodeBased(int a, int b, int accessFlags, double weight, in } /** - * @param origFirst The first original edge that is skipped by this shortcut. For example for the following shortcut - * edge from x to y, which itself skips the shortcuts x->v and v->y the - * first original edge would be x->u: x->u->v->w->y - * @param origLast like origFirst, but the last orig edge, i.e w->y in above example + * @param origKeyFirst The first original edge key that is skipped by this shortcut *in the direction of the shortcut*. + * This definition assumes that edge-based shortcuts are one-directional, and they are. + * For example for the following shortcut edge from x to y: x->u->v->w->y , + * which skips the shortcuts x->v and v->y the first original edge key would be the one of the edge x->u + * @param origKeyLast like origKeyFirst, but the last orig edge key, i.e. the key of w->y in above example */ public int addShortcutEdgeBased(int a, int b, int accessFlags, double weight, int skippedEdge1, int skippedEdge2, - int origFirst, int origLast) { + int origKeyFirst, int origKeyLast) { checkNewShortcut(a, b); - int shortcut = storage.shortcutEdgeBased(a, b, accessFlags, weight, skippedEdge1, skippedEdge2, origFirst, origLast); + int shortcut = storage.shortcutEdgeBased(a, b, accessFlags, weight, skippedEdge1, skippedEdge2, origKeyFirst, origKeyLast); setLastShortcut(a, shortcut); return shortcut; } diff --git a/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorImpl.java b/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorImpl.java index f0245508d97..907fac4062e 100644 --- a/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorImpl.java +++ b/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorImpl.java @@ -94,7 +94,7 @@ public boolean next() { @Override public String toString() { - return baseIterator.toString(); + return getEdge() + " " + getBaseNode() + "-" + getAdjNode(); } private boolean finiteWeight(boolean reverse) { diff --git a/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorState.java b/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorState.java index e22a6d3dce8..6afc42de524 100644 --- a/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorState.java @@ -33,16 +33,22 @@ public interface RoutingCHEdgeIteratorState { int getOrigEdge(); /** - * For shortcuts of an edge-based CH graph this is the ID of the first original edge of this edge state, otherwise - * it is the same as {@link #getOrigEdge()}} + * For shortcuts of an edge-based CH graph this is the key of the first original edge of this edge state + * *in the direction of the shortcut*, i.e. the one this shortcut starts with. Otherwise it is the key of the + * original/base/query graph edge this CH edge state represents. + * It is not so obvious how the direction of this key shall be defined. For base graph edges it is clear as we use + * the storage direction and the value of the key simply depends on which node is the base node + * (the one stored first or second). For shortcut edges we use the direction of the shortcut to define the direction + * of the first/last original edge key. */ - int getOrigEdgeFirst(); + int getOrigEdgeKeyFirst(); /** - * For shortcuts of an edge-based CH graph this is the ID of the last original edge of this edge state, otherwise - * it is the same as {@link #getOrigEdge()}} + * @see #getOrigEdgeKeyFirst(), but for the last edge, i.e. the one the shortcut points to. + * For shortcuts of an edge-based CH graph this is the key of the last original edge of this edge state, otherwise + * it is the key of the original/base/query graph edge this CH edge state represents. */ - int getOrigEdgeLast(); + int getOrigEdgeKeyLast(); int getBaseNode(); diff --git a/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorStateImpl.java b/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorStateImpl.java index 29fe7b264f3..8ee744bb965 100644 --- a/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorStateImpl.java +++ b/core/src/main/java/com/graphhopper/storage/RoutingCHEdgeIteratorStateImpl.java @@ -74,17 +74,17 @@ public int getOrigEdge() { } @Override - public int getOrigEdgeFirst() { + public int getOrigEdgeKeyFirst() { if (!isShortcut() || !store.isEdgeBased()) - return getEdge(); - return store.getOrigEdgeFirst(shortcutPointer); + return edgeState().getEdgeKey(); + return store.getOrigEdgeKeyFirst(shortcutPointer); } @Override - public int getOrigEdgeLast() { + public int getOrigEdgeKeyLast() { if (!isShortcut() || !store.isEdgeBased()) - return getEdge(); - return store.getOrigEdgeLast(shortcutPointer); + return edgeState().getEdgeKey(); + return store.getOrigEdgeKeyLast(shortcutPointer); } @Override diff --git a/core/src/main/java/com/graphhopper/util/Constants.java b/core/src/main/java/com/graphhopper/util/Constants.java index 9db41eefd51..5f2d5f0a6d2 100644 --- a/core/src/main/java/com/graphhopper/util/Constants.java +++ b/core/src/main/java/com/graphhopper/util/Constants.java @@ -68,7 +68,7 @@ public class Constants { public static final int VERSION_NODE = 9; public static final int VERSION_EDGE = 21; - public static final int VERSION_SHORTCUT = 8; + public static final int VERSION_SHORTCUT = 9; public static final int VERSION_NODE_CH = 0; public static final int VERSION_GEOMETRY = 6; public static final int VERSION_LOCATION_IDX = 5; diff --git a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java index d40c1fdf53f..8b2f0166cdf 100644 --- a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java @@ -89,6 +89,11 @@ public boolean isStoreTwoDirections() { */ int getEdgeKey(); + /** + * Like #getEdgeKey, but returns the reverse key. For loops the reverse key is the same as the key. + */ + int getReverseEdgeKey(); + /** * Returns the node used to instantiate the EdgeIterator. Often only used for convenience reasons. * Do not confuse this with a source node of a directed edge. diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index 39d95ac075e..c5ce254dc64 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -565,36 +565,17 @@ public static int count(EdgeIterator iterator, int adj) { return count; } - /** - * Creates unique positive number for specified edgeId taking into account the direction defined - * by nodeA, nodeB and reverse. - */ - public static int createEdgeKey(int nodeA, int nodeB, int edgeId, boolean reverse) { - edgeId = edgeId << 1; - if (reverse) - return (nodeA >= nodeB) ? edgeId : edgeId + 1; - return (nodeA > nodeB) ? edgeId + 1 : edgeId; - } - /** * Creates an edge key, i.e. an integer number that encodes an edge ID and the direction of an edge */ - public static int createEdgeKey(int edgeId, boolean reverse) { + public static int createEdgeKey(int edgeId, boolean isLoop, boolean reverse) { // edge state in storage direction -> edge key is even // edge state against storage direction -> edge key is odd - return (edgeId << 1) + (reverse ? 1 : 0); - } - - /** - * Returns if the specified edgeKeys (created by createEdgeKey) are identical regardless of the - * direction. - */ - public static boolean isSameEdgeKeys(int edgeKey1, int edgeKey2) { - return edgeKey1 / 2 == edgeKey2 / 2; + return (edgeId << 1) + ((reverse && !isLoop) ? 1 : 0); } /** - * Returns the edgeKey of the opposite direction + * Returns the edgeKey of the opposite direction, be careful not to use this for loops! */ public static int reverseEdgeKey(int edgeKey) { return edgeKey % 2 == 0 ? edgeKey + 1 : edgeKey - 1; @@ -789,6 +770,11 @@ public int getEdgeKey() { throw new UnsupportedOperationException("Not supported. Edge is empty."); } + @Override + public int getReverseEdgeKey() { + throw new UnsupportedOperationException("Not supported. Edge is empty."); + } + @Override public int getBaseNode() { throw new UnsupportedOperationException("Not supported. Edge is empty."); diff --git a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java index 212f34651cc..36f81f03947 100644 --- a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java @@ -85,9 +85,9 @@ private void freeze() { chBuilder = new CHStorageBuilder(chStore); } - private void addShortcut(int from, int to, int firstOrigEdge, int lastOrigEdge, int skipped1, int skipped2, double weight, boolean reverse) { + private void addShortcut(int from, int to, int firstOrigEdgeKey, int lastOrigEdgeKey, int skipped1, int skipped2, double weight, boolean reverse) { int flags = reverse ? PrepareEncoder.getScBwdDir() : PrepareEncoder.getScFwdDir(); - chBuilder.addShortcutEdgeBased(from, to, flags, weight, skipped1, skipped2, firstOrigEdge, lastOrigEdge); + chBuilder.addShortcutEdgeBased(from, to, flags, weight, skipped1, skipped2, firstOrigEdgeKey, lastOrigEdgeKey); } private void setIdentityLevels() { @@ -231,13 +231,13 @@ public void testFindPathWithTurnCosts_loopShortcutBwdSearch(Fixture f) { f.setIdentityLevels(); // from contracting nodes 1&2 - f.addShortcut(3, 4, 3, 4, 3, 4, 2, true); - f.addShortcut(3, 4, 5, 6, 5, 6, 2, false); + f.addShortcut(3, 4, 6, 8, 3, 4, 2, true); + f.addShortcut(3, 4, 10, 12, 5, 6, 2, false); // from contracting node 3 - f.addShortcut(4, 4, 3, 6, 9, 10, 4, false); + f.addShortcut(4, 4, 6, 13, 9, 10, 4, false); // from contracting node 4 - f.addShortcut(4, 8, 2, 6, 2, 11, 5, true); - f.addShortcut(6, 8, 2, 7, 12, 7, 6, true); + f.addShortcut(4, 8, 4, 12, 2, 11, 5, true); + f.addShortcut(6, 8, 4, 14, 12, 7, 6, true); f.testPathCalculation(0, 5, 9, IntArrayList.from(0, 7, 8, 4, 1, 3, 2, 4, 6, 5)); } @@ -268,13 +268,13 @@ public void testFindPathWithTurnCosts_loopShortcutFwdSearch(Fixture f) { f.setIdentityLevels(); // from contracting nodes 1&2 - f.addShortcut(3, 4, 2, 3, 2, 3, 2, true); - f.addShortcut(3, 4, 4, 5, 4, 5, 2, false); + f.addShortcut(3, 4, 4, 6, 2, 3, 2, true); + f.addShortcut(3, 4, 8, 10, 4, 5, 2, false); // from contracting node 3 - f.addShortcut(4, 4, 2, 5, 9, 10, 4, false); + f.addShortcut(4, 4, 4, 10, 9, 10, 4, false); // from contracting node 4 - f.addShortcut(4, 6, 1, 5, 1, 11, 5, true); - f.addShortcut(6, 7, 1, 6, 12, 6, 6, false); + f.addShortcut(4, 6, 3, 10, 1, 11, 5, true); + f.addShortcut(6, 7, 2, 12, 12, 6, 6, false); f.testPathCalculation(5, 0, 9, IntArrayList.from(5, 6, 4, 1, 3, 2, 4, 7, 8, 0)); } @@ -297,7 +297,7 @@ public void testFindPathWithTurnCosts_directed_single_shortcut(Fixture f) { // only when node 0 is contracted a shortcut is added f.setIdentityLevels(); - f.addShortcut(2, 3, 1, 2, 1, 2, 7, false); + f.addShortcut(2, 3, 2, 4, 1, 2, 7, false); // when we are searching a path to the highest level node, the backward search will not expand any edges f.testPathCalculation(1, 4, 11, IntArrayList.from(1, 2, 0, 3, 4), 8); @@ -326,7 +326,7 @@ public void testFindPathWithTurnCosts_directed_single_shortcut_fwdSearchStopsQui f.setIdentityLevels(); // from contracting node 0 - f.addShortcut(2, 3, 1, 2, 1, 2, 4, false); + f.addShortcut(2, 3, 2, 4, 1, 2, 4, false); f.testPathCalculation(1, 4, 9, IntArrayList.from(1, 2, 0, 3, 4), 6); } @@ -349,8 +349,8 @@ public void testFindPathWithTurnCosts_directed_two_shortcuts(Fixture f) { f.setIdentityLevels(); // contraction of node 0 and 1 each yield a single shortcut - f.addShortcut(1, 4, 2, 3, 2, 3, 6, false); - f.addShortcut(3, 4, 1, 3, 1, 4, 10, false); + f.addShortcut(1, 4, 4, 6, 2, 3, 6, false); + f.addShortcut(3, 4, 2, 6, 1, 4, 10, false); // the turn costs have to be accounted for also when the shortcuts are used f.testPathCalculation(2, 4, 11, IntArrayList.from(2, 3, 1, 0, 4), 8); @@ -435,7 +435,7 @@ public void testFindPath_incomingShortcut(Fixture f) { GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 2).setDistance(9)); f.freeze(); f.setIdentityLevels(); - f.addShortcut(1, 3, 0, 1, 0, 1, 23, false); + f.addShortcut(1, 3, 1, 2, 0, 1, 23, false); f.testPathCalculation(0, 2, 23, IntArrayList.from(0, 3, 2)); } @@ -500,9 +500,9 @@ private void checkUTurnNotBeingUsed(Fixture f, boolean toLowerLevelNode) { // one shortcut when contracting node 3 f.setIdentityLevels(); if (toLowerLevelNode) { - f.addShortcut(nodeB, nodeA, e3toA.getEdge(), e3toB.getEdge(), e3toA.getEdge(), e3toB.getEdge(), 2, true); + f.addShortcut(nodeB, nodeA, e3toA.detach(true).getEdgeKey(), e3toB.getEdgeKey(), e3toA.getEdge(), e3toB.getEdge(), 2, true); } else { - f.addShortcut(nodeA, nodeB, e3toA.getEdge(), e3toB.getEdge(), e3toA.getEdge(), e3toB.getEdge(), 2, false); + f.addShortcut(nodeA, nodeB, e3toA.detach(true).getEdgeKey(), e3toB.getEdgeKey(), e3toA.getEdge(), e3toB.getEdge(), 2, false); } // without u-turns the only 'possible' path 0-3-A-3-B-2 is forbidden @@ -600,8 +600,8 @@ public void testFindPath_shortcutLoopIsRecognizedAsIncomingEdge(Fixture f) { f.freeze(); f.setIdentityLevels(); - // contracting node 0 yields (the only) shortcut - and its a loop - f.addShortcut(2, 2, edge2.getEdge(), edge3.getEdge(), edge2.getEdge(), edge3.getEdge(), 2, false); + // contracting node 0 yields (the only) shortcut - and it's a loop + f.addShortcut(2, 2, edge2.getEdgeKey(), edge3.getEdgeKey(), edge2.getEdge(), edge3.getEdge(), 2, false); // node 2 is the bridge node where the forward and backward searches meet (highest level). since there is a turn restriction // at node 2 we cannot go from 4 to 1 directly, but we need to take the loop at 2 first. when the backward @@ -632,9 +632,9 @@ public void testFindPathWithTurnRestriction_single_loop(Fixture f) { f.setIdentityLevels(); // contracting node 0 - f.addShortcut(1, 4, 1, 2, 1, 2, 4, true); + f.addShortcut(1, 4, 2, 4, 1, 2, 4, true); // contracting node 1 - f.addShortcut(4, 4, 1, 3, 5, 3, 9, false); + f.addShortcut(4, 4, 2, 6, 5, 3, 9, false); f.testPathCalculation(3, 2, 15, IntArrayList.from(3, 4, 0, 1, 4, 2)); } @@ -679,9 +679,9 @@ private void runTestWithSingleLoop(Fixture f, boolean loopInFwdSearch) { f.setRestriction(nodeA, 5, nodeB); f.freeze(); f.setIdentityLevels(); - f.addShortcut(3, 5, 4, 5, 4, 5, 3, false); - f.addShortcut(3, 5, 2, 3, 2, 3, 3, true); - f.addShortcut(5, 5, 2, 5, 9, 8, 6, false); + f.addShortcut(3, 5, 8, 10, 4, 5, 3, false); + f.addShortcut(3, 5, 4, 6, 2, 3, 3, true); + f.addShortcut(5, 5, 4, 10, 9, 8, 6, false); f.testPathCalculation(4, 7, 12, IntArrayList.from(4, nodeA, 5, 2, 3, 1, 5, nodeB, 7)); } @@ -722,15 +722,15 @@ public void testFindPathWithTurnRestriction_double_loop(Fixture f) { f.setIdentityLevels(); // contracting node 0,1,2,3 - f.addShortcut(1, 6, 2, 0, 2, 0, 6, true); - f.addShortcut(3, 6, 3, 4, 3, 4, 8, true); - f.addShortcut(6, 6, 2, 1, 9, 1, 7, false); - f.addShortcut(6, 6, 3, 5, 10, 5, 10, false); + f.addShortcut(1, 6, 4, 0, 2, 0, 6, true); + f.addShortcut(3, 6, 6, 8, 3, 4, 8, true); + f.addShortcut(6, 6, 4, 2, 9, 1, 7, false); + f.addShortcut(6, 6, 6, 10, 10, 5, 10, false); // contracting node 4 and 5 yields no shortcuts // contracting node 6 --> three shortcuts to account for double loop (we nest shortcuts inside each other) - f.addShortcut(6, 7, 6, 1, 6, 11, 8, true); - f.addShortcut(6, 7, 6, 5, 13, 12, 18, true); - f.addShortcut(7, 7, 6, 6, 14, 6, 19, false); + f.addShortcut(6, 7, 12, 2, 6, 11, 8, true); + f.addShortcut(6, 7, 12, 10, 13, 12, 18, true); + f.addShortcut(7, 7, 12, 12, 14, 6, 19, false); f.testPathCalculation(4, 5, 24, IntArrayList.from(4, 7, 6, 0, 1, 6, 2, 3, 6, 7, 5)); f.testPathCalculation(5, 4, 24, IntArrayList.from(5, 7, 6, 0, 1, 6, 2, 3, 6, 7, 4)); @@ -764,15 +764,15 @@ public void testFindPathWithTurnRestriction_two_different_loops(Fixture f) { f.setIdentityLevels(); // contracting node 0 - f.addShortcut(1, 5, 2, 0, 2, 0, 3, true); + f.addShortcut(1, 5, 4, 0, 2, 0, 3, true); // contracting node 1 - f.addShortcut(5, 5, 2, 1, 8, 1, 4, false); + f.addShortcut(5, 5, 4, 2, 8, 1, 4, false); // contracting node 2 & 3 does not yield any shortcuts // contracting node 4 - f.addShortcut(5, 6, 3, 5, 3, 5, 9, false); + f.addShortcut(5, 6, 6, 11, 3, 5, 9, false); // contracting node 5 --> two shortcuts to account for loop (we nest shortcuts inside each other) - f.addShortcut(5, 6, 4, 1, 4, 9, 7, true); - f.addShortcut(6, 6, 4, 4, 11, 4, 10, false); + f.addShortcut(5, 6, 9, 2, 4, 9, 7, true); + f.addShortcut(6, 6, 9, 8, 11, 4, 10, false); // contracting node 6 --> no more shortcuts diff --git a/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java b/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java index 7c2e6532c65..8dfce062197 100644 --- a/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java @@ -111,7 +111,7 @@ public void withShortcuts() { CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); chBuilder.setIdentityLevels(); - chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 20, 0, 1, 0, 1); + chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 20, 0, 1, 0, 2); QueryGraph queryGraph = QueryGraph.create(graph, Collections.emptyList()); QueryRoutingCHGraph queryCHGraph = new QueryRoutingCHGraph(routingCHGraph, queryGraph); @@ -221,7 +221,7 @@ public void withVirtualEdgesAndShortcuts() { CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); chBuilder.setIdentityLevels(); - chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 20, 0, 1, 0, 1); + chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 20, 0, 1, 0, 2); Snap snap = new Snap(50.00, 10.05); snap.setClosestEdge(edge); @@ -297,7 +297,7 @@ public void getEdgeIteratorState() { CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); chBuilder.setIdentityLevels(); - chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 20, 0, 1, 0, 1); + chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 20, 0, 1, 0, 2); Snap snap = new Snap(50.00, 10.05); snap.setClosestEdge(edge); @@ -380,7 +380,7 @@ public void getWeight() { CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); chBuilder.setIdentityLevels(); - chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScDirMask(), 20, 0, 1, 0, 1); + chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScDirMask(), 20, 0, 1, 0, 2); // without query graph RoutingCHEdgeIterator iter = routingCHGraph.createOutEdgeExplorer().setBaseNode(0); @@ -560,7 +560,7 @@ public void getTurnCost() { CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); chBuilder.setIdentityLevels(); - chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 20, 0, 1, 0, 1); + chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 20, 0, 1, 0, 2); // without virtual nodes assertEquals(5, routingCHGraph.getTurnWeight(0, 1, 1)); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java b/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java index 68147065930..40d87e9f46e 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java @@ -265,7 +265,7 @@ public void testAddShortcut_edgeBased_throwsIfNotConfiguredForEdgeBased() { CHConfig chConfig = CHConfig.nodeBased("p1", weighting); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); - assertThrows(IllegalArgumentException.class, () -> chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 10, 0, 1, 0, 1)); + assertThrows(IllegalArgumentException.class, () -> chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 10, 0, 1, 0, 2)); } @Test @@ -284,9 +284,9 @@ public void testAddShortcut_edgeBased() { CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); chBuilder.setIdentityLevels(); - chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 10, 0, 1, 0, 1); - assertEquals(0, chStore.getOrigEdgeFirst(chStore.toShortcutPointer(0))); - assertEquals(1, chStore.getOrigEdgeLast(chStore.toShortcutPointer(0))); + chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 10, 0, 1, 0, 2); + assertEquals(0, chStore.getOrigEdgeKeyFirst(chStore.toShortcutPointer(0))); + assertEquals(2, chStore.getOrigEdgeKeyLast(chStore.toShortcutPointer(0))); } @Test @@ -316,7 +316,7 @@ public void testGetEdgeIterator() { CHStorage store = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(store); chBuilder.setIdentityLevels(); - chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 10, 0, 1, 0, 1); + chBuilder.addShortcutEdgeBased(0, 2, PrepareEncoder.getScFwdDir(), 10, 0, 1, 0, 2); RoutingCHGraph lg = RoutingCHGraphImpl.fromGraph(graph, store, chConfig); @@ -327,8 +327,8 @@ public void testGetEdgeIterator() { assertEquals(2, sc02.getEdge()); assertEquals(0, sc02.getSkippedEdge1()); assertEquals(1, sc02.getSkippedEdge2()); - assertEquals(0, sc02.getOrigEdgeFirst()); - assertEquals(1, sc02.getOrigEdgeLast()); + assertEquals(0, sc02.getOrigEdgeKeyFirst()); + assertEquals(2, sc02.getOrigEdgeKeyLast()); RoutingCHEdgeIteratorState sc20 = lg.getEdgeIteratorState(2, 0); assertNotNull(sc20); @@ -339,7 +339,7 @@ public void testGetEdgeIterator() { // is still edge 0 and the second skipped/last orig edge is edge 1 assertEquals(0, sc20.getSkippedEdge1()); assertEquals(1, sc20.getSkippedEdge2()); - assertEquals(0, sc20.getOrigEdgeFirst()); - assertEquals(1, sc20.getOrigEdgeLast()); + assertEquals(0, sc20.getOrigEdgeKeyFirst()); + assertEquals(2, sc20.getOrigEdgeKeyLast()); } } diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHPreparationGraphTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHPreparationGraphTest.java index 9a4fe0b086c..3edd86c0c79 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHPreparationGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHPreparationGraphTest.java @@ -47,10 +47,10 @@ void basic() { pg.addShortcut(3, 4, 1, 3, 1, 3, 16, 2); pg.disconnect(0); PrepareGraphEdgeIterator iter = pg.createOutEdgeExplorer().setBaseNode(3); - String res = ""; + StringBuilder res = new StringBuilder(); while (iter.next()) { - res += iter.toString() + ","; + res.append(iter).append(","); } - assertEquals("3-4,", res); + assertEquals("3-4 16.0,", res.toString()); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java index cbf710c0731..f98cc3dd108 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java @@ -674,6 +674,7 @@ public void testFindPath_bug() { @Test public void testFindPath_bug2() { + // 1 = 0 - 3 - 2 - 4 GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 3).setDistance(24.001000)); GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(6.087000)); GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(6.067000)); @@ -1146,6 +1147,31 @@ void testBestFwdBwdEntryUpdate() { compareCHQueryWithDijkstra(1, 2); } + @Test + void testEdgeKeyBug() { + // 1 - 2 - 0 - 4 + // \ / + // 3 + GHUtility.setSpeed(60, 60, encoder, graph.edge(0, 3).setDistance(100)); // edgeId=0 + GHUtility.setSpeed(60, 60, encoder, graph.edge(4, 3).setDistance(100)); // edgeId=1 + GHUtility.setSpeed(60, 60, encoder, graph.edge(0, 4).setDistance(100)); // edgeId=2 + GHUtility.setSpeed(60, 60, encoder, graph.edge(1, 2).setDistance(100)); // edgeId=3 + GHUtility.setSpeed(60, 60, encoder, graph.edge(0, 2).setDistance(100)); // edgeId=4 + graph.freeze(); + prepareCH(2, 0, 1, 3, 4); + assertEquals(2, chGraph.getShortcuts()); + RoutingCHEdgeIteratorState chEdge = chGraph.getEdgeIteratorState(6, 4); + assertEquals(3, chEdge.getBaseNode()); + assertEquals(4, chEdge.getAdjNode()); + assertEquals(2, chEdge.getSkippedEdge1()); + assertEquals(0, chEdge.getSkippedEdge2()); + // the first edge is 4-0 (edge 2 against the storage direction) -> key is 2*2+1=5 + assertEquals(5, chEdge.getOrigEdgeKeyFirst()); + // the second is 0-3 (edge 0 in storage direction) -> key is 2*0=0 + assertEquals(0, chEdge.getOrigEdgeKeyLast()); + compareCHQueryWithDijkstra(1, 3); + } + /** * This test runs on a random graph with random turn costs and a predefined (but random) contraction order. * It often produces exotic conditions that are hard to anticipate beforehand. diff --git a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java index 627dd089bb4..56cadb7803b 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java @@ -18,7 +18,6 @@ package com.graphhopper.routing.ch; -import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; @@ -101,8 +100,8 @@ public void testContractNodes_simpleLoop() { contractNodes(5, 6, 3, 2, 9, 1, 8, 4, 7, 0); checkShortcuts( createShortcut(2, 8, edge8to3, edge3to2, 5, false, true), - createShortcut(8, 7, edge8to3.getEdge(), edge2to7.getEdge(), 6, edge2to7.getEdge(), 6, true, false), - createShortcut(7, 7, edge7to8.getEdge(), edge2to7.getEdge(), edge7to8.getEdge(), 7, 8, true, false) + createShortcut(8, 7, edge8to3.getEdgeKey(), edge2to7.getEdgeKey(), 6, edge2to7.getEdge(), 6, true, false), + createShortcut(7, 7, edge7to8.getEdgeKey(), edge2to7.getEdgeKey(), edge7to8.getEdge(), 7, 8, true, false) ); } @@ -131,7 +130,7 @@ public void testContractNodes_necessaryAlternative() { // from contracting node 3: two shortcuts: // 1) in case we come from 1->6 (cant turn left) // 2) in case we come from 2->6 (going via node 0 would be more expensive) - createShortcut(5, 6, e6to0.getEdge(), e3to5.getEdge(), 7, e3to5.getEdge(), 11, false, true), + createShortcut(5, 6, e6to0.getEdgeKey(), e3to5.getEdgeKey(), 7, e3to5.getEdge(), 11, false, true), createShortcut(5, 6, e6to3, e3to5, 3, false, true) ); } @@ -156,7 +155,7 @@ public void testContractNodes_alternativeNecessary_noUTurn() { // from contraction of node 2 // It might look like it is always better to go directly from 4 to 2, but when we come from edge (2->4) // we may not do a u-turn at 4. - createShortcut(3, 4, e0to4.getEdge(), e2to3.getEdge(), 5, e2to3.getEdge(), 10, false, true), + createShortcut(3, 4, e0to4.getEdgeKey(), e2to3.getEdgeKey(), 5, e2to3.getEdge(), 10, false, true), createShortcut(3, 4, e2to4, e2to3, 4, false, true) ); } @@ -171,7 +170,7 @@ public void testContractNodes_bidirectionalLoop() { GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(1)); GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 4).setDistance(2)); final EdgeIteratorState e4to6 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 6).setDistance(2)); - final EdgeIteratorState e3to6 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 3).setDistance(1)); + final EdgeIteratorState e6to3 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 3).setDistance(1)); final EdgeIteratorState e3to4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(1)); final EdgeIteratorState e4to5 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 2).setDistance(2)); @@ -186,12 +185,12 @@ public void testContractNodes_bidirectionalLoop() { contractAllNodesInOrder(); checkShortcuts( // from contraction of node 3 - createShortcut(4, 6, e3to4, e3to6, 6, true, false), - createShortcut(4, 6, e3to6, e3to4, 4, false, true), + createShortcut(4, 6, e3to4.detach(true), e6to3.detach(true), 6, true, false), + createShortcut(4, 6, e6to3, e3to4, 4, false, true), // from contraction of node 4 // two 'parallel' shortcuts to preserve shortest paths to 5 when coming from 4->6 and 3->6 !! - createShortcut(5, 6, e3to6.getEdge(), e4to5.getEdge(), 8, e4to5.getEdge(), 5, false, true), - createShortcut(5, 6, e4to6, e4to5, 3, false, true) + createShortcut(5, 6, e6to3.getEdgeKey(), e4to5.getEdgeKey(), 8, e4to5.getEdge(), 5, false, true), + createShortcut(5, 6, e4to6.detach(true), e4to5, 3, false, true) ); } @@ -321,7 +320,7 @@ public void testContractNode_duplicateOutgoingEdges_differentWeight() { contractNodes(2, 0, 4, 1, 3); // there should be only one shortcut checkShortcuts( - createShortcut(1, 3, 1, 3, 1, 3, 2) + createShortcut(1, 3, 2, 6, 1, 3, 2) ); } @@ -338,7 +337,7 @@ public void testContractNode_duplicateIncomingEdges_differentWeight() { setMaxLevelOnAllNodes(); contractNodes(2, 0, 4, 1, 3); checkShortcuts( - createShortcut(1, 3, 2, 3, 2, 3, 2) + createShortcut(1, 3, 4, 6, 2, 3, 2) ); } @@ -421,8 +420,8 @@ public void testContractNode_twoNormalEdges_bidirectional() { // note that for now we add a shortcut for each direction. using fwd/bwd flags would be more efficient, // but requires a more sophisticated way to determine the 'first' and 'last' original edges at various // places - createShortcut(3, 4, e3to2, e2to4, 12, true, false), - createShortcut(3, 4, e2to4, e3to2, 12, false, true) + createShortcut(3, 4, 2, 4, 1, 2, 12, true, false), + createShortcut(3, 4, 5, 3, 2, 1, 12, false, true) ); } @@ -430,17 +429,17 @@ public void testContractNode_twoNormalEdges_bidirectional() { public void testContractNode_twoNormalEdges_bidirectional_differentCosts() { // 0 -- 3 -- 2 -- 4 -- 1 GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 3).setDistance(1)); - final EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 2).setDistance(3)); + final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 2).setDistance(3)); final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4).setDistance(5)); GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 1).setDistance(1)); - setTurnCost(e2to3, e2to4, 2, 4); - setTurnCost(e2to4, e2to3, 2, 7); + setTurnCost(e3to2, e2to4, 2, 4); + setTurnCost(e2to4, e3to2, 2, 7); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 3, 4); checkShortcuts( - createShortcut(3, 4, e2to3, e2to4, 12, true, false), - createShortcut(3, 4, e2to4, e2to3, 15, false, true) + createShortcut(3, 4, e3to2, e2to4, 12, true, false), + createShortcut(3, 4, e2to4.detach(true), e3to2.detach(true), 15, false, true) ); } @@ -490,7 +489,7 @@ private void runTestWithTurnCostAndLoop(boolean loopHelps) { // the first (this is important for path unpacking) checkShortcuts( createShortcut(2, 3, e3to2, e2to2, 7, false, true), - createShortcut(3, 4, e3to2.getEdge(), e2to4.getEdge(), 5, e2to4.getEdge(), 13, true, false)); + createShortcut(3, 4, e3to2.getEdgeKey(), e2to4.getEdgeKey(), 5, e2to4.getEdge(), 13, true, false)); } else { // taking the loop would be worse, so the path is just 3-2-4 and we only need a single shortcut checkShortcuts( @@ -516,7 +515,7 @@ public void testContractNode_shortcutDoesNotSpanUTurn() { checkShortcuts( // from contracting node 3 createShortcut(4, 7, e7to3, e3to4, 3, false, true), - createShortcut(4, 5, e3to4, e3to5, 3, true, false) + createShortcut(4, 5, e3to4.detach(true), e3to5, 3, true, false) // important! no shortcut from 7 to 5 when contracting node 4, because it includes a u-turn ); } @@ -534,8 +533,8 @@ public void testContractNode_multiple_loops_leftLoopIsBest() { // direct turn is restricted, so we take the left loop -> two extra shortcuts GraphWithTwoLoops g = new GraphWithTwoLoops(2, maxCost, 1, 2, 3, maxCost); g.contractAndCheckShortcuts( - createShortcut(6, 7, g.e7to6.getEdge(), g.e1to6.getEdge(), g.e7to6.getEdge(), g.getScEdge(3), 12, false, true), - createShortcut(7, 8, g.e7to6.getEdge(), g.e6to8.getEdge(), g.getScEdge(4), g.e6to8.getEdge(), 20, true, false) + createShortcut(6, 7, g.e7to6.getEdgeKey(), g.e1to6.getEdgeKey(), g.e7to6.getEdge(), g.getScEdge(3), 12, false, true), + createShortcut(7, 8, g.e7to6.getEdgeKey(), g.e6to8.getEdgeKey(), g.getScEdge(4), g.e6to8.getEdge(), 20, true, false) ); } @@ -544,8 +543,8 @@ public void testContractNode_multiple_loops_rightLoopIsBest() { // direct turn is restricted, going on left loop is expensive, so we take the right loop -> two extra shortcuts GraphWithTwoLoops g = new GraphWithTwoLoops(8, 1, 1, 2, 3, maxCost); g.contractAndCheckShortcuts( - createShortcut(6, 7, g.e7to6.getEdge(), g.e3to6.getEdge(), g.e7to6.getEdge(), g.getScEdge(2), 12, false, true), - createShortcut(7, 8, g.e7to6.getEdge(), g.e6to8.getEdge(), g.getScEdge(4), g.e6to8.getEdge(), 21, true, false) + createShortcut(6, 7, g.e7to6.getEdgeKey(), g.e3to6.getEdgeKey(), g.e7to6.getEdge(), g.getScEdge(2), 12, false, true), + createShortcut(7, 8, g.e7to6.getEdgeKey(), g.e6to8.getEdgeKey(), g.getScEdge(4), g.e6to8.getEdge(), 21, true, false) ); } @@ -554,9 +553,9 @@ public void testContractNode_multiple_loops_leftRightLoopIsBest() { // multiple turns are restricted, it is best to take the left and the right loop -> three extra shortcuts GraphWithTwoLoops g = new GraphWithTwoLoops(3, maxCost, 1, maxCost, 3, maxCost); g.contractAndCheckShortcuts( - createShortcut(6, 7, g.e7to6.getEdge(), g.e1to6.getEdge(), g.e7to6.getEdge(), g.getScEdge(3), 13, false, true), - createShortcut(6, 7, g.e7to6.getEdge(), g.e3to6.getEdge(), g.getScEdge(5), g.getScEdge(2), 24, false, true), - createShortcut(7, 8, g.e7to6.getEdge(), g.e6to8.getEdge(), g.getScEdge(4), g.e6to8.getEdge(), 33, true, false) + createShortcut(6, 7, g.e7to6.getEdgeKey(), g.e1to6.getEdgeKey(), g.e7to6.getEdge(), g.getScEdge(3), 13, false, true), + createShortcut(6, 7, g.e7to6.getEdgeKey(), g.e3to6.getEdgeKey(), g.getScEdge(5), g.getScEdge(2), 24, false, true), + createShortcut(7, 8, g.e7to6.getEdgeKey(), g.e6to8.getEdgeKey(), g.getScEdge(4), g.e6to8.getEdge(), 33, true, false) ); } @@ -565,9 +564,9 @@ public void testContractNode_multiple_loops_rightLeftLoopIsBest() { // multiple turns are restricted, it is best to take the right and the left loop -> three extra shortcuts GraphWithTwoLoops g = new GraphWithTwoLoops(maxCost, 5, 4, 2, maxCost, maxCost); g.contractAndCheckShortcuts( - createShortcut(6, 7, g.e7to6.getEdge(), g.e3to6.getEdge(), g.e7to6.getEdge(), g.getScEdge(2), 16, false, true), - createShortcut(6, 7, g.e7to6.getEdge(), g.e1to6.getEdge(), g.getScEdge(5), g.getScEdge(3), 25, false, true), - createShortcut(7, 8, g.e7to6.getEdge(), g.e6to8.getEdge(), g.getScEdge(4), g.e6to8.getEdge(), 33, true, false) + createShortcut(6, 7, g.e7to6.getEdgeKey(), g.e3to6.getEdgeKey(), g.e7to6.getEdge(), g.getScEdge(2), 16, false, true), + createShortcut(6, 7, g.e7to6.getEdgeKey(), g.e1to6.getEdgeKey(), g.getScEdge(5), g.getScEdge(3), 25, false, true), + createShortcut(7, 8, g.e7to6.getEdgeKey(), g.e6to8.getEdgeKey(), g.getScEdge(4), g.e6to8.getEdge(), 33, true, false) ); } @@ -614,9 +613,9 @@ private void contractAndCheckShortcuts(Shortcut... shortcuts) { HashSet expectedShortcuts = new HashSet<>(); expectedShortcuts.addAll(Arrays.asList( createShortcut(1, 6, e6to0, e0to1, 7, false, true), - createShortcut(6, 6, e6to0.getEdge(), e1to6.getEdge(), getScEdge(0), e1to6.getEdge(), 9, true, false), + createShortcut(6, 6, e6to0.getEdgeKey(), e1to6.getEdgeKey(), getScEdge(0), e1to6.getEdge(), 9, true, false), createShortcut(3, 6, e6to2, e2to3, 3, false, true), - createShortcut(6, 6, e6to2.getEdge(), e3to6.getEdge(), getScEdge(1), e3to6.getEdge(), 10, true, false) + createShortcut(6, 6, e6to2.getEdgeKey(), e3to6.getEdgeKey(), getScEdge(1), e3to6.getEdge(), 10, true, false) )); expectedShortcuts.addAll(Arrays.asList(shortcuts)); checkShortcuts(expectedShortcuts); @@ -721,7 +720,7 @@ public void testContractNode_loopAvoidance_loopNecessary() { final int numEdges = 6; checkShortcuts( createShortcut(1, 2, g.e2to0, g.e0to1, 3, false, true), - createShortcut(2, 2, g.e2to0.getEdge(), g.e1to2.getEdge(), numEdges, g.e1to2.getEdge(), 4, true, false) + createShortcut(2, 2, g.e2to0.getEdgeKey(), g.e1to2.getEdgeKey(), numEdges, g.e1to2.getEdge(), 4, true, false) ); } @@ -882,7 +881,7 @@ public void testContractNode_bidirectional_edge_at_fromNode(boolean edge1to2bidi setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 5, 4, 3); // we might come from (5->1) so we still need a way back to (3->4) -> we need a shortcut - Shortcut expectedShortcuts = createShortcut(1, 3, 1, 2, 1, 2, 2); + Shortcut expectedShortcuts = createShortcut(1, 3, 2, 4, 1, 2, 2); checkShortcuts(expectedShortcuts); } @@ -926,12 +925,12 @@ public void testNodeContraction_directWitness() { contractNodes(2, 6, 3, 5, 4, 0, 8, 10, 11, 1, 7, 9); // note that the shortcut edge ids depend on the insertion order which might change when changing the implementation checkShortcuts( - createShortcut(3, 1, 1, 2, 1, 2, 2, false, true), - createShortcut(1, 9, 1, 8, 1, 8, 2, true, false), - createShortcut(5, 7, 5, 6, 5, 6, 2, true, false), - createShortcut(7, 9, 9, 6, 9, 6, 2, false, true), - createShortcut(4, 1, 1, 3, 12, 3, 3, false, true), - createShortcut(4, 7, 4, 6, 4, 13, 3, true, false) + createShortcut(3, 1, 2, 4, 1, 2, 2, false, true), + createShortcut(1, 9, 2, 16, 1, 8, 2, true, false), + createShortcut(5, 7, 10, 12, 5, 6, 2, true, false), + createShortcut(7, 9, 18, 12, 9, 6, 2, false, true), + createShortcut(4, 1, 2, 6, 12, 3, 3, false, true), + createShortcut(4, 7, 8, 12, 4, 13, 3, true, false) ); } @@ -977,7 +976,7 @@ public void testNodeContraction_letShortcutsWitnessEachOther_twoIn() { setMaxLevelOnAllNodes(); contractNodes(3, 0, 5, 1, 4, 2); checkShortcuts( - createShortcut(4, 2, 2, 3, 2, 3, 2, false, true) + createShortcut(4, 2, 4, 6, 2, 3, 2, false, true) ); } @@ -1001,14 +1000,14 @@ public void testNodeContraction_letShortcutsWitnessEachOther_twoOut() { setMaxLevelOnAllNodes(); contractNodes(2, 0, 5, 1, 4, 3); checkShortcuts( - createShortcut(1, 3, 1, 2, 1, 2, 2) + createShortcut(1, 3, 2, 4, 1, 2, 2) ); } @Test public void testNodeContraction_parallelEdges_onlyOneLoopShortcutNeeded() { + // /--\ // 0 -- 1 -- 2 - // \--/ EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(2)); EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 0).setDistance(4)); GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(5)); @@ -1019,7 +1018,7 @@ public void testNodeContraction_parallelEdges_onlyOneLoopShortcutNeeded() { contractNodes(0, 2, 1); // it is sufficient to be able to travel the 1-0-1 loop in one (the cheaper) direction checkShortcuts( - createShortcut(1, 1, 0, 1, 0, 1, 7) + createShortcut(1, 1, 1, 3, 0, 1, 7) ); } @@ -1049,18 +1048,18 @@ public void testNodeContraction_duplicateEdge_severalLoops() { checkNumShortcuts(11); checkShortcuts( // from node 4 contraction - createShortcut(5, 3, 5, 4, 5, 4, 66, true, false), - createShortcut(5, 3, 4, 5, 4, 5, 66, false, true), - createShortcut(3, 2, 1, 4, 1, 4, 29, false, true), - createShortcut(3, 2, 4, 1, 4, 1, 29, true, false), - createShortcut(5, 2, 1, 5, 1, 5, 75, false, true), - createShortcut(5, 2, 5, 1, 5, 1, 75, true, false), + createShortcut(5, 3, 11, 9, 5, 4, 66, true, false), + createShortcut(5, 3, 8, 10, 4, 5, 66, false, true), + createShortcut(3, 2, 2, 9, 1, 4, 29, false, true), + createShortcut(3, 2, 8, 3, 4, 1, 29, true, false), + createShortcut(5, 2, 2, 10, 1, 5, 75, false, true), + createShortcut(5, 2, 11, 3, 5, 1, 75, true, false), // from node 5 contraction - createShortcut(2, 2, 3, 2, 3, 2, 99, true, false), - createShortcut(2, 2, 3, 1, 3, 6, 134, true, false), - createShortcut(2, 2, 1, 2, 8, 2, 114, true, false), - createShortcut(3, 2, 2, 4, 2, 7, 106, false, true), - createShortcut(3, 2, 4, 2, 9, 2, 105, true, false) + createShortcut(2, 2, 6, 5, 3, 2, 99, true, false), + createShortcut(2, 2, 6, 3, 3, 6, 134, true, false), + createShortcut(2, 2, 2, 5, 8, 2, 114, true, false), + createShortcut(3, 2, 4, 9, 2, 7, 106, false, true), + createShortcut(3, 2, 8, 5, 9, 2, 105, true, false) ); } @@ -1073,9 +1072,9 @@ public void testNodeContraction_tripleConnection() { setMaxLevelOnAllNodes(); contractNodes(1, 0); checkShortcuts( - createShortcut(0, 0, 1, 2, 1, 2, 5.5), - createShortcut(0, 0, 0, 2, 0, 2, 4.5), - createShortcut(0, 0, 0, 1, 0, 1, 3.0) + createShortcut(0, 0, 2, 5, 1, 2, 5.5), + createShortcut(0, 0, 0, 5, 0, 2, 4.5), + createShortcut(0, 0, 0, 3, 0, 1, 3.0) ); } @@ -1117,8 +1116,8 @@ public void testNodeContraction_node_in_loop() { setTurnCost(3, 2, 4, 2); contractNodes(2, 0, 1, 4, 3); checkShortcuts( - createShortcut(4, 3, 3, 2, 3, 2, 6, true, false), - createShortcut(4, 3, 2, 3, 2, 3, 4, false, true) + createShortcut(4, 3, 7, 5, 3, 2, 6, true, false), + createShortcut(4, 3, 4, 6, 2, 3, 4, false, true) ); } @@ -1144,8 +1143,8 @@ public void testFindPath_finiteUTurnCost() { setRestriction(0, 3, 1); contractNodes(4, 0, 1, 2, 3); checkShortcuts( - createShortcut(2, 3, 1, 2, 1, 2, 600, false, true), - createShortcut(3, 3, 1, 1, 1, 1, 260, true, false) + createShortcut(2, 3, 2, 4, 1, 2, 600, false, true), + createShortcut(3, 3, 2, 3, 1, 1, 260, true, false) ); } @@ -1199,7 +1198,7 @@ public void testNodeContraction_minorWeightDeviation() { setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 3, 4); checkShortcuts( - createShortcut(1, 3, 1, 2, 1, 2, 145.847) + createShortcut(1, 3, 2, 4, 1, 2, 145.847) ); } @@ -1216,7 +1215,7 @@ public void testNodeContraction_zeroWeightLoop_loopOnly() { setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 3); checkShortcuts( - createShortcut(1, 3, 1, 2, 1, 2, 2) + createShortcut(1, 3, 2, 4, 1, 2, 2) ); } @@ -1235,7 +1234,7 @@ public void testNodeContraction_zeroWeightLoop_loopAndEdge() { setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 4, 3); checkShortcuts( - createShortcut(1, 3, 1, 2, 1, 2, 2) + createShortcut(1, 3, 2, 4, 1, 2, 2) ); } @@ -1253,7 +1252,7 @@ public void testNodeContraction_zeroWeightLoop_twoLoops() { setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 3); checkShortcuts( - createShortcut(1, 3, 1, 2, 1, 2, 2) + createShortcut(1, 3, 2, 4, 1, 2, 2) ); } @@ -1273,7 +1272,7 @@ public void testNodeContraction_zeroWeightLoop_twoLoopsAndEdge_edgeFirst() { setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 4, 3); checkShortcuts( - createShortcut(1, 3, 1, 2, 1, 2, 2) + createShortcut(1, 3, 2, 4, 1, 2, 2) ); } @@ -1293,7 +1292,7 @@ public void testNodeContraction_zeroWeightLoop_twoLoopsAndEdge_loopsFirst() { setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 4, 3); checkShortcuts( - createShortcut(1, 3, 1, 4, 1, 4, 2) + createShortcut(1, 3, 2, 8, 1, 4, 2) ); } @@ -1317,7 +1316,7 @@ public void testNodeContraction_zeroWeightLoop_manyLoops() { setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 4, 3); checkShortcuts( - createShortcut(1, 3, 3, 5, 3, 5, 2) + createShortcut(1, 3, 6, 10, 3, 5, 2) ); } @@ -1344,8 +1343,8 @@ public void testNodeContraction_zeroWeightLoop_another() { // connects the same nodes and is not a bridge path. this needs special handling in our edge-based witness path // searcher. checkShortcuts( - createShortcut(4, 5, 0, 2, 0, 2, 200, false, true), - createShortcut(4, 5, 2, 0, 2, 0, 200, true, false) + createShortcut(4, 5, 0, 4, 0, 2, 200, false, true), + createShortcut(4, 5, 5, 1, 2, 0, 200, true, false) ); } @@ -1409,8 +1408,8 @@ void issue_2564() { setMaxLevelOnAllNodes(); contractNodes(0, 5, 2, 1, 3, 4); checkShortcuts( - createShortcut(1, 3, 1, 2, 1, 2, 17.497, true, false), - createShortcut(1, 3, 2, 1, 2, 1, 17.497, false, true) + createShortcut(1, 3, 2, 4, 1, 2, 17.497, true, false), + createShortcut(1, 3, 5, 3, 2, 1, 17.497, false, true) ); } @@ -1464,7 +1463,7 @@ private void setTurnCost(int from, int via, int to, double cost) { private void setTurnCost(EdgeIteratorState inEdge, EdgeIteratorState outEdge, int viaNode, double cost) { double cost1 = cost >= maxCost ? Double.POSITIVE_INFINITY : cost; - graph.getTurnCostStorage().set(((EncodedValueLookup) encoder).getDecimalEncodedValue(TurnCost.key("car")), inEdge.getEdge(), viaNode, outEdge.getEdge(), cost1); + graph.getTurnCostStorage().set(encoder.getDecimalEncodedValue(TurnCost.key("car")), inEdge.getEdge(), viaNode, outEdge.getEdge(), cost1); } private EdgeIteratorState getEdge(int from, int to) { @@ -1476,15 +1475,15 @@ private Shortcut createShortcut(int from, int to, EdgeIteratorState edge1, EdgeI } private Shortcut createShortcut(int from, int to, EdgeIteratorState edge1, EdgeIteratorState edge2, double weight, boolean fwd, boolean bwd) { - return createShortcut(from, to, edge1.getEdge(), edge2.getEdge(), edge1.getEdge(), edge2.getEdge(), weight, fwd, bwd); + return createShortcut(from, to, edge1.getEdgeKey(), edge2.getEdgeKey(), edge1.getEdge(), edge2.getEdge(), weight, fwd, bwd); } - private Shortcut createShortcut(int from, int to, int firstOrigEdge, int lastOrigEdge, int skipEdge1, int skipEdge2, double weight) { - return createShortcut(from, to, firstOrigEdge, lastOrigEdge, skipEdge1, skipEdge2, weight, true, false); + private Shortcut createShortcut(int from, int to, int firstOrigEdgeKey, int lastOrigEdgeKey, int skipEdge1, int skipEdge2, double weight) { + return createShortcut(from, to, firstOrigEdgeKey, lastOrigEdgeKey, skipEdge1, skipEdge2, weight, true, false); } - private Shortcut createShortcut(int from, int to, int firstOrigEdge, int lastOrigEdge, int skipEdge1, int skipEdge2, double weight, boolean fwd, boolean bwd) { - return new Shortcut(from, to, firstOrigEdge, lastOrigEdge, skipEdge1, skipEdge2, weight, fwd, bwd); + private Shortcut createShortcut(int from, int to, int firstOrigEdgeKey, int lastOrigEdgeKey, int skipEdge1, int skipEdge2, double weight, boolean fwd, boolean bwd) { + return new Shortcut(from, to, firstOrigEdgeKey, lastOrigEdgeKey, skipEdge1, skipEdge2, weight, fwd, bwd); } /** @@ -1512,7 +1511,7 @@ private Set getCurrentShortcuts() { long ptr = chStore.toShortcutPointer(i); shortcuts.add(new Shortcut( chStore.getNodeA(ptr), chStore.getNodeB(ptr), - chStore.getOrigEdgeFirst(ptr), chStore.getOrigEdgeLast(ptr), + chStore.getOrigEdgeKeyFirst(ptr), chStore.getOrigEdgeKeyLast(ptr), chStore.getSkippedEdge1(ptr), chStore.getSkippedEdge2(ptr), chStore.getWeight(ptr), chStore.getFwdAccess(ptr), chStore.getBwdAccess(ptr) @@ -1532,20 +1531,20 @@ private void setMaxLevelOnAllNodes() { private static class Shortcut { int baseNode; int adjNode; - int firstOrigEdge; - int lastOrigEdge; + int firstOrigEdgeKey; + int lastOrigEdgeKey; double weight; boolean fwd; boolean bwd; int skipEdge1; int skipEdge2; - public Shortcut(int baseNode, int adjNode, int firstOrigEdge, int lastOrigEdge, int skipEdge1, int skipEdge2, double weight, + public Shortcut(int baseNode, int adjNode, int firstOrigEdgeKey, int lastOrigEdgeKey, int skipEdge1, int skipEdge2, double weight, boolean fwd, boolean bwd) { this.baseNode = baseNode; this.adjNode = adjNode; - this.firstOrigEdge = firstOrigEdge; - this.lastOrigEdge = lastOrigEdge; + this.firstOrigEdgeKey = firstOrigEdgeKey; + this.lastOrigEdgeKey = lastOrigEdgeKey; this.weight = weight; this.fwd = fwd; this.bwd = bwd; @@ -1560,8 +1559,8 @@ public boolean equals(Object o) { Shortcut shortcut = (Shortcut) o; return baseNode == shortcut.baseNode && adjNode == shortcut.adjNode && - firstOrigEdge == shortcut.firstOrigEdge && - lastOrigEdge == shortcut.lastOrigEdge && + firstOrigEdgeKey == shortcut.firstOrigEdgeKey && + lastOrigEdgeKey == shortcut.lastOrigEdgeKey && Double.compare(shortcut.weight, weight) == 0 && fwd == shortcut.fwd && bwd == shortcut.bwd && @@ -1571,7 +1570,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(baseNode, adjNode, firstOrigEdge, lastOrigEdge, weight, fwd, bwd, + return Objects.hash(baseNode, adjNode, firstOrigEdgeKey, lastOrigEdgeKey, weight, fwd, bwd, skipEdge1, skipEdge2); } @@ -1580,8 +1579,8 @@ public String toString() { return "Shortcut{" + "baseNode=" + baseNode + ", adjNode=" + adjNode + - ", firstOrigEdge=" + firstOrigEdge + - ", lastOrigEdge=" + lastOrigEdge + + ", firstOrigEdgeKey=" + firstOrigEdgeKey + + ", lastOrigEdgeKey=" + lastOrigEdgeKey + ", weight=" + weight + ", fwd=" + fwd + ", bwd=" + bwd + diff --git a/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java b/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java index 6503e73b47d..57ec089b0f1 100644 --- a/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java @@ -686,7 +686,6 @@ public void testInternalAPIOriginalEdgeKey() { EdgeExplorer explorer = g.createEdgeExplorer(); EdgeIterator iter = explorer.setBaseNode(1); assertTrue(iter.next()); - int origEdgeId = iter.getEdge(); Snap res = createLocationResult(2, 1.5, iter, 1, PILLAR); QueryGraph queryGraph = lookup(res); @@ -696,14 +695,14 @@ public void testInternalAPIOriginalEdgeKey() { EdgeExplorer qGraphExplorer = queryGraph.createEdgeExplorer(); iter = qGraphExplorer.setBaseNode(3); assertTrue(iter.next()); + assertEquals(2, iter.getEdge()); assertEquals(0, iter.getAdjNode()); - assertEquals(GHUtility.createEdgeKey(1, 0, origEdgeId, false), - ((VirtualEdgeIteratorState) queryGraph.getEdgeIteratorState(iter.getEdge(), 0)).getOriginalEdgeKey()); + assertEquals(3, ((VirtualEdgeIteratorState) queryGraph.getEdgeIteratorState(iter.getEdge(), 0)).getOriginalEdgeKey()); assertTrue(iter.next()); + assertEquals(3, iter.getEdge()); assertEquals(1, iter.getAdjNode()); - assertEquals(GHUtility.createEdgeKey(0, 1, origEdgeId, false), - ((VirtualEdgeIteratorState) queryGraph.getEdgeIteratorState(iter.getEdge(), 1)).getOriginalEdgeKey()); + assertEquals(2, ((VirtualEdgeIteratorState) queryGraph.getEdgeIteratorState(iter.getEdge(), 1)).getOriginalEdgeKey()); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java index 053d1997371..1e7434e6de9 100644 --- a/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java @@ -49,7 +49,7 @@ public void testAccept_fwdLoopShortcut_acceptedByInExplorer() { CHStorage chStore = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); chBuilder.setIdentityLevels(); - chBuilder.addShortcutEdgeBased(0, 0, PrepareEncoder.getScFwdDir(), 5, 0, 2, 0, 2); + chBuilder.addShortcutEdgeBased(0, 0, PrepareEncoder.getScFwdDir(), 5, 0, 2, 0, 5); RoutingCHGraph chGraph = RoutingCHGraphImpl.fromGraph(graph, chStore, chConfig); RoutingCHEdgeExplorer outExplorer = chGraph.createOutEdgeExplorer(); RoutingCHEdgeExplorer inExplorer = chGraph.createInEdgeExplorer(); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java index b853abe44c8..962e5aa3749 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java @@ -55,7 +55,7 @@ public void testMinWeightHasSameUnitAs_getWeight() { public void testWeightWrongHeading() { Weighting instance = new FastestWeighting(encoder, new PMap().putObject(Parameters.Routing.HEADING_PENALTY, 100)); - VirtualEdgeIteratorState virtEdge = new VirtualEdgeIteratorState(0, GHUtility.createEdgeKey(1, false), 1, 2, 10, + VirtualEdgeIteratorState virtEdge = new VirtualEdgeIteratorState(0, GHUtility.createEdgeKey(1, false, false), 1, 2, 10, GHUtility.setSpeed(10, 0, encoder, encodingManager.createEdgeFlags()), "test", Helper.createPointList(51, 0, 51, 1), false); double time = instance.calcEdgeWeight(virtEdge, false); diff --git a/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java b/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java index e05064df780..4abf63ef337 100644 --- a/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java +++ b/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java @@ -82,12 +82,12 @@ private void setTurnCost(int fromEdge, int viaNode, int toEdge, double cost) { graph.getTurnCostStorage().set(((EncodedValueLookup) encodingManager).getDecimalEncodedValue(TurnCost.key(encoder.toString())), fromEdge, viaNode, toEdge, cost); } - private void shortcut(int baseNode, int adjNode, int skip1, int skip2, int origFirst, int origLast, boolean reverse) { + private void shortcut(int baseNode, int adjNode, int skip1, int skip2, int origKeyFirst, int origKeyLast, boolean reverse) { // shortcut weight/distance is not important for us here double weight = 1; int flags = reverse ? PrepareEncoder.getScFwdDir() : PrepareEncoder.getScBwdDir(); if (edgeBased) { - chBuilder.addShortcutEdgeBased(baseNode, adjNode, flags, weight, skip1, skip2, origFirst, origLast); + chBuilder.addShortcutEdgeBased(baseNode, adjNode, flags, weight, skip1, skip2, origKeyFirst, origKeyLast); } else { chBuilder.addShortcutNodeBased(baseNode, adjNode, flags, weight, skip1, skip2); } @@ -119,11 +119,11 @@ public void testUnpacking(Fixture f) { f.freeze(); f.setCHLevels(1, 3, 5, 4, 2, 0, 6); - f.shortcut(4, 2, 2, 3, 2, 3, true); - f.shortcut(4, 6, 4, 5, 4, 5, false); - f.shortcut(2, 0, 0, 1, 0, 1, true); - f.shortcut(2, 6, 6, 7, 2, 5, false); - f.shortcut(0, 6, 8, 9, 0, 5, false); + f.shortcut(4, 2, 2, 3, 4, 6, true); + f.shortcut(4, 6, 4, 5, 8, 10, false); + f.shortcut(2, 0, 0, 1, 0, 2, true); + f.shortcut(2, 6, 6, 7, 4, 10, false); + f.shortcut(0, 6, 8, 9, 0, 10, false); { // unpack the shortcut 0->6, traverse original edges in 'forward' order (from node 0 to 6) @@ -207,11 +207,11 @@ public void loopShortcut(Fixture f) { f.freeze(); f.setCHLevels(2, 4, 3, 1, 5, 0); - f.shortcut(3, 1, 1, 2, 1, 2, true); - f.shortcut(3, 1, 3, 4, 3, 4, false); - f.shortcut(1, 1, 6, 7, 1, 4, false); - f.shortcut(1, 0, 0, 8, 0, 4, true); - f.shortcut(5, 0, 9, 5, 0, 5, true); + f.shortcut(3, 1, 1, 2, 2, 4, true); + f.shortcut(3, 1, 3, 4, 6, 8, false); + f.shortcut(1, 1, 6, 7, 2, 8, false); + f.shortcut(1, 0, 0, 8, 0, 8, true); + f.shortcut(5, 0, 9, 5, 0, 10, true); { // unpack the shortcut 0->5, traverse original edges in 'forward' order (from node 0 to 5) @@ -301,11 +301,11 @@ public void withTurnWeighting(Fixture f) { f.setTurnCost(edge0.getEdge(), 0, PREV_EDGE, 1.0); f.setCHLevels(1, 3, 5, 4, 2, 0, 6); - f.shortcut(4, 2, 2, 3, 2, 3, true); - f.shortcut(4, 6, 4, 5, 4, 5, false); - f.shortcut(2, 0, 0, 1, 0, 1, true); - f.shortcut(2, 6, 6, 7, 2, 5, false); - f.shortcut(0, 6, 8, 9, 0, 5, false); + f.shortcut(4, 2, 2, 3, 4, 6, true); + f.shortcut(4, 6, 4, 5, 8, 10, false); + f.shortcut(2, 0, 0, 1, 0, 2, true); + f.shortcut(2, 6, 6, 7, 4, 10, false); + f.shortcut(0, 6, 8, 9, 0, 10, false); { // unpack the shortcut 0->6, traverse original edges in 'forward' order (from node 0 to 6) diff --git a/core/src/test/java/com/graphhopper/util/GHUtilityTest.java b/core/src/test/java/com/graphhopper/util/GHUtilityTest.java index 362bdfa39d1..489d89ab0e5 100644 --- a/core/src/test/java/com/graphhopper/util/GHUtilityTest.java +++ b/core/src/test/java/com/graphhopper/util/GHUtilityTest.java @@ -123,20 +123,10 @@ public void testSortDirected() { @Test public void testEdgeStuff() { - assertEquals(6, GHUtility.createEdgeKey(1, 2, 3, false)); - assertEquals(7, GHUtility.createEdgeKey(2, 1, 3, false)); - assertEquals(7, GHUtility.createEdgeKey(1, 2, 3, true)); - assertEquals(6, GHUtility.createEdgeKey(2, 1, 3, true)); - - assertEquals(8, GHUtility.createEdgeKey(1, 2, 4, false)); - assertEquals(9, GHUtility.createEdgeKey(2, 1, 4, false)); - - assertEquals(6, GHUtility.createEdgeKey(1, 1, 3, false)); - assertEquals(6, GHUtility.createEdgeKey(1, 1, 3, true)); - - assertTrue(GHUtility.isSameEdgeKeys(GHUtility.createEdgeKey(1, 2, 4, false), GHUtility.createEdgeKey(1, 2, 4, false))); - assertTrue(GHUtility.isSameEdgeKeys(GHUtility.createEdgeKey(2, 1, 4, false), GHUtility.createEdgeKey(1, 2, 4, false))); - assertFalse(GHUtility.isSameEdgeKeys(GHUtility.createEdgeKey(1, 2, 4, false), GHUtility.createEdgeKey(1, 2, 5, false))); + assertEquals(2, GHUtility.createEdgeKey(1, false, false)); + assertEquals(2, GHUtility.createEdgeKey(1, true, false)); + assertEquals(2, GHUtility.createEdgeKey(1, true, true)); + assertEquals(3, GHUtility.createEdgeKey(1, false, true)); } @Test diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java index ebaa70cae03..f77482dd71b 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java @@ -166,7 +166,7 @@ public Response match( for (EdgeMatch em : matchResult.getEdgeMatches()) { EdgeIteratorState edge = em.getEdgeState(); // encode edges as traversal keys which includes orientation, decode simply by multiplying with 0.5 - traversalKeylist.add(GHUtility.createEdgeKey(edge.getBaseNode(), edge.getAdjNode(), edge.getEdge(), false)); + traversalKeylist.add(edge.getEdgeKey()); } map.putPOJO("traversal_keys", traversalKeylist); } From f3d58ababc2f95a259666f67cd088fe65926db2e Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 27 May 2022 16:43:52 +0200 Subject: [PATCH 023/389] Add comment about slow non-CH alternatives --- .../src/main/java/com/graphhopper/routing/AlternativeRoute.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java index 900f0362060..d333bd23e1a 100644 --- a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java +++ b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java @@ -55,6 +55,8 @@ * * * + * Note: This algorithm is quite slow and alternatives are only really practical in combination with CH, see #2566 + * * @author Peter Karich */ public class AlternativeRoute implements RoutingAlgorithm { From 62017f142d27dc7da964d353bbf0ce1405ae806a Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Mon, 30 May 2022 10:17:23 +0200 Subject: [PATCH 024/389] Remove outdated/wrong comments --- .../application/MapMatchingTest.java | 34 ++----------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/web/src/test/java/com/graphhopper/application/MapMatchingTest.java b/web/src/test/java/com/graphhopper/application/MapMatchingTest.java index b214ed0dc6f..a00e8e3cc73 100644 --- a/web/src/test/java/com/graphhopper/application/MapMatchingTest.java +++ b/web/src/test/java/com/graphhopper/application/MapMatchingTest.java @@ -33,7 +33,6 @@ import com.graphhopper.util.shapes.GHPoint; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -145,18 +144,9 @@ public void testDoWork(PMap hints) { assertEquals(142, mr.getEdgeMatches().size()); } - /** - * This test is to check behavior over large separated routes: it should - * work if the user sets the maxVisitedNodes large enough. Input path: - * https://graphhopper.com/maps/?point=51.23%2C12.18&point=51.45%2C12.59&layer=Lyrk - *

- * Update: Seems to me that this test only tests a long route, not one with - * distant input points. createRandomGPXEntries currently creates very close input points. - * The length of the route doesn't seem to matter. - */ @ParameterizedTest @ArgumentsSource(FixtureProvider.class) - public void testDistantPoints(PMap hints) { + public void testLongTrackWithLotsOfPoints(PMap hints) { // OK with 1000 visited nodes: MapMatching mapMatching = new MapMatching(graphHopper, hints); ResponsePath route = graphHopper.route(new GHRequest( @@ -169,22 +159,8 @@ public void testDistantPoints(PMap hints) { assertEquals(route.getDistance(), mr.getMatchLength(), 2); // GraphHopper travel times aren't exactly additive assertThat(Math.abs(route.getTime() - mr.getMatchMillis()), is(lessThan(1000L))); - - // not OK when we only allow a small number of visited nodes: - PMap opts = new PMap(hints).putObject(Parameters.Routing.MAX_VISITED_NODES, 1); - mapMatching = new MapMatching(graphHopper, opts); - try { - mr = mapMatching.match(inputGPXEntries); - fail("Expected sequence to be broken due to maxVisitedNodes being too small"); - } catch (RuntimeException e) { - assertTrue(e.getMessage().startsWith("Sequence is broken for submitted track")); - } } - /** - * This test is to check behavior over short tracks. GPX input: - * https://graphhopper.com/maps/?point=51.342422%2C12.3613358&point=51.3423281%2C12.3613358&layer=Lyrk - */ @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testClosePoints(PMap hints) { @@ -202,15 +178,9 @@ public void testClosePoints(PMap hints) { assertThat(Math.abs(route.getTime() - mr.getMatchMillis()), is(lessThan(1000L))); } - /** - * This test is to check what happens when two GPX entries are on one edge - * which is longer than 'separatedSearchDistance' - which is always 66m. GPX - * input: - * https://graphhopper.com/maps/?point=51.359723%2C12.360108&point=51.358748%2C12.358798&point=51.358001%2C12.357597&point=51.358709%2C12.356511&layer=Lyrk - */ @ParameterizedTest @ArgumentsSource(FixtureProvider.class) - public void testSmallSeparatedSearchDistance(PMap hints) throws IOException { + public void testTour3WithLongEdge(PMap hints) throws IOException { Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/tour3-with-long-edge.gpx"), Gpx.class); MapMatching mapMatching = new MapMatching(graphHopper, hints); mapMatching.setMeasurementErrorSigma(20); From 9545a6bc145e12315d985daf504fa01d4032de88 Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Mon, 30 May 2022 12:56:35 +0200 Subject: [PATCH 025/389] Add a mapmatching test --- .../com/graphhopper/maps/map-matching/js/demo.js | 4 +--- .../com/graphhopper/application/MapMatchingTest.java | 12 +++++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/map-matching/js/demo.js b/web-bundle/src/main/resources/com/graphhopper/maps/map-matching/js/demo.js index 4915624c29f..bb1821adc62 100644 --- a/web-bundle/src/main/resources/com/graphhopper/maps/map-matching/js/demo.js +++ b/web-bundle/src/main/resources/com/graphhopper/maps/map-matching/js/demo.js @@ -99,7 +99,6 @@ GraphHopperMapMatching = function (args) { this.vehicle = "car"; this.gps_accuracy = 20; this.data_type = "json"; - this.max_visited_nodes = 3000; graphhopper.util.copyProperties(args, this); }; @@ -112,8 +111,7 @@ GraphHopperMapMatching.prototype.doRequest = function (content, callback, reqArg var url = args.host + args.basePath + "?vehicle=" + args.vehicle + "&gps_accuracy=" + args.gps_accuracy - + "&type=" + args.data_type - + "&max_visited_nodes=" + args.max_visited_nodes; + + "&type=" + args.data_type; if (args.key) url += "&key=" + args.key; diff --git a/web/src/test/java/com/graphhopper/application/MapMatchingTest.java b/web/src/test/java/com/graphhopper/application/MapMatchingTest.java index a00e8e3cc73..4bd10de14cb 100644 --- a/web/src/test/java/com/graphhopper/application/MapMatchingTest.java +++ b/web/src/test/java/com/graphhopper/application/MapMatchingTest.java @@ -147,7 +147,6 @@ public void testDoWork(PMap hints) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testLongTrackWithLotsOfPoints(PMap hints) { - // OK with 1000 visited nodes: MapMatching mapMatching = new MapMatching(graphHopper, hints); ResponsePath route = graphHopper.route(new GHRequest( new GHPoint(51.23, 12.18), @@ -161,6 +160,17 @@ public void testLongTrackWithLotsOfPoints(PMap hints) { assertThat(Math.abs(route.getTime() - mr.getMatchMillis()), is(lessThan(1000L))); } + @ParameterizedTest + @ArgumentsSource(FixtureProvider.class) + public void testLongTrackWithTwoPoints(PMap hints) { + MapMatching mapMatching = new MapMatching(graphHopper, hints); + List inputGPXEntries = Arrays.asList( + new Observation(new GHPoint(51.23, 12.18)), + new Observation(new GHPoint(51.45, 12.59))); + MatchResult mr = mapMatching.match(inputGPXEntries); + assertEquals(57553.0, mr.getMatchLength(), 1.0); + } + @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testClosePoints(PMap hints) { From be7b2476aaff55c7c266fd517c8cf2c37ae91b43 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 30 May 2022 16:35:34 +0200 Subject: [PATCH 026/389] Remove 'shared' encoded values with $ sign in name (#2585) * remove OSMAccessParser * removed $ from encoded values * no if clause necessary * fix changelog --- CHANGELOG.md | 1 + .../java/com/graphhopper/GraphHopper.java | 7 +- .../routing/util/EncodingManager.java | 64 +++---- .../util/parsers/DefaultTagParserFactory.java | 4 - .../routing/util/parsers/OSMAccessParser.java | 160 ------------------ .../routing/util/EncodingManagerTest.java | 7 +- .../custom/CustomModelParserTest.java | 2 +- .../weighting/custom/CustomWeightingTest.java | 2 +- 8 files changed, 29 insertions(+), 218 deletions(-) delete mode 100644 core/src/main/java/com/graphhopper/routing/util/parsers/OSMAccessParser.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d4dcb419be..1f6826f9c26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### 6.0 [not yet released] +- replaced car$access with car_access (and same for $average_speed and $priority) - don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) - faster flexible routing, especially in conjunction with turn costs (#2571) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 54bdfe0ce05..bfa74358071 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -594,12 +594,7 @@ private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String en flagEncodersMap.forEach((name, encoderStr) -> { VehicleTagParser vehicleTagParser = vehicleTagParserFactory.createParser(encodingManager, name, new PMap(encoderStr)); vehicleTagParser.init(dateRangeParser); - if (vehicleTagParser instanceof RoadsTagParser) { - if (encodingManager.hasEncodedValue("car_access") && !encodedValueStrings.contains("car_access")) - osmParsers.addWayTagParser(new OSMAccessParser(encodingManager.getBooleanEncodedValue("car_access"), encodingManager.getBooleanEncodedValue(Roundabout.KEY), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR), TransportationMode.CAR)); - if (encodingManager.hasEncodedValue("bike_access") && !encodedValueStrings.contains("bike_access")) - osmParsers.addWayTagParser(new OSMAccessParser(encodingManager.getBooleanEncodedValue("bike_access"), encodingManager.getBooleanEncodedValue(Roundabout.KEY), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.BIKE), TransportationMode.BIKE)); - } else if (vehicleTagParser instanceof BikeCommonTagParser) { + if (vehicleTagParser instanceof BikeCommonTagParser) { if (encodingManager.hasEncodedValue(BikeNetwork.KEY)) osmParsers.addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(encodingManager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig)); if (encodingManager.hasEncodedValue(GetOffBike.KEY)) diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java index c37e3a2d591..eece47905a3 100644 --- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java +++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java @@ -136,40 +136,34 @@ public EncodingManager build() { check(); for (EncodedValue ev : encodedValueMap.values()) { - em.addEncodedValue(ev, false); + em.addEncodedValue(ev); } if (!em.hasEncodedValue(Roundabout.KEY)) - em.addEncodedValue(Roundabout.create(), false); + em.addEncodedValue(Roundabout.create()); if (!em.hasEncodedValue(RoadClass.KEY)) - em.addEncodedValue(new EnumEncodedValue<>(RoadClass.KEY, RoadClass.class), false); + em.addEncodedValue(new EnumEncodedValue<>(RoadClass.KEY, RoadClass.class)); if (!em.hasEncodedValue(RoadClassLink.KEY)) - em.addEncodedValue(new SimpleBooleanEncodedValue(RoadClassLink.KEY), false); + em.addEncodedValue(new SimpleBooleanEncodedValue(RoadClassLink.KEY)); if (!em.hasEncodedValue(RoadEnvironment.KEY)) - em.addEncodedValue(new EnumEncodedValue<>(RoadEnvironment.KEY, RoadEnvironment.class), false); + em.addEncodedValue(new EnumEncodedValue<>(RoadEnvironment.KEY, RoadEnvironment.class)); if (!em.hasEncodedValue(MaxSpeed.KEY)) - em.addEncodedValue(MaxSpeed.create(), false); + em.addEncodedValue(MaxSpeed.create()); if (!em.hasEncodedValue(RoadAccess.KEY)) { - em.addEncodedValue(new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class), false); + em.addEncodedValue(new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class)); } for (VehicleEncodedValues encoder : flagEncoderMap.values()) { - if (encoder.getName().equals("roads")) { - // TODO Later these EncodedValues can be added independently of RoadsFlagEncoder. Maybe add a foot_access and hgv_access? and remove the others "xy$access" - if (!em.hasEncodedValue("car_access")) - em.addEncodedValue(new SimpleBooleanEncodedValue("car_access", true), false); - if (!em.hasEncodedValue("bike_access")) - em.addEncodedValue(new SimpleBooleanEncodedValue("bike_access", true), false); - } else if (encoder.getName().contains("bike") || encoder.getName().contains("mtb")) { + if (encoder.getName().contains("bike") || encoder.getName().contains("mtb")) { if (!em.hasEncodedValue(RouteNetwork.key("bike"))) - em.addEncodedValue(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class), false); + em.addEncodedValue(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)); if (!em.hasEncodedValue(GetOffBike.KEY)) - em.addEncodedValue(GetOffBike.create(), false); + em.addEncodedValue(GetOffBike.create()); if (!em.hasEncodedValue(Smoothness.KEY)) - em.addEncodedValue(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class), false); + em.addEncodedValue(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)); } else if (encoder.getName().contains("foot") || encoder.getName().contains("hike") || encoder.getName().contains("wheelchair")) { if (!em.hasEncodedValue(RouteNetwork.key("foot"))) - em.addEncodedValue(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class), false); + em.addEncodedValue(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)); } } @@ -211,8 +205,9 @@ private void addEncoder(VehicleEncodedValues encoder) { encoder.setEncodedValueLookup(this); List list = new ArrayList<>(); encoder.createEncodedValues(list); - for (EncodedValue ev : list) - addEncodedValue(ev, true); + for (EncodedValue ev : list) { + addEncodedValue(ev); + } list = new ArrayList<>(); encoder.createTurnCostEncodedValues(list); for (EncodedValue ev : list) @@ -220,14 +215,9 @@ private void addEncoder(VehicleEncodedValues encoder) { edgeEncoders.add(encoder); } - private void addEncodedValue(EncodedValue ev, boolean withNamespace) { - String normalizedKey = ev.getName().replaceAll(SPECIAL_SEPARATOR, "_"); - if (hasEncodedValue(normalizedKey)) - throw new IllegalStateException("EncodedValue " + ev.getName() + " collides with " + normalizedKey); - if (!withNamespace && !isSharedEncodedValues(ev)) - throw new IllegalArgumentException("EncodedValue " + ev.getName() + " must not contain namespace character '" + SPECIAL_SEPARATOR + "'"); - if (withNamespace && isSharedEncodedValues(ev)) - throw new IllegalArgumentException("EncodedValue " + ev.getName() + " must contain namespace character '" + SPECIAL_SEPARATOR + "'"); + private void addEncodedValue(EncodedValue ev) { + if (hasEncodedValue(ev.getName())) + throw new IllegalStateException("EncodedValue " + ev.getName() + " collides with " + ev.getName()); ev.init(edgeConfig); encodedValueMap.put(ev.getName(), ev); } @@ -303,9 +293,6 @@ public String toFlagEncodersAsString() { public String toEncodedValuesAsString() { StringBuilder str = new StringBuilder(); for (EncodedValue ev : encodedValueMap.values()) { - if (!isSharedEncodedValues(ev)) - continue; - if (str.length() > 0) str.append(","); @@ -404,12 +391,6 @@ public T getEncodedValue(String key, Class encodedVa return (T) ev; } - private static final String SPECIAL_SEPARATOR = "$"; - - private static boolean isSharedEncodedValues(EncodedValue ev) { - return isValidEncodedValue(ev.getName()) && !ev.getName().contains(SPECIAL_SEPARATOR); - } - /** * All EncodedValue names that are created from a FlagEncoder should use this method to mark them as * "none-shared" across the other FlagEncoders. @@ -419,7 +400,7 @@ public static String getKey(FlagEncoder encoder, String str) { } public static String getKey(String prefix, String str) { - return prefix + SPECIAL_SEPARATOR + str; + return prefix + "_" + str; } // copied from janino @@ -449,13 +430,10 @@ public static boolean isValidEncodedValue(String name) { // first character must be a lower case letter if (name.isEmpty() || !isLowerLetter(name.charAt(0)) || KEYWORDS.contains(name)) return false; - int dollarCount = 0, underscoreCount = 0; + int underscoreCount = 0; for (int i = 1; i < name.length(); i++) { char c = name.charAt(i); - if (c == '$') { - if (dollarCount > 0) return false; - dollarCount++; - } else if (c == '_') { + if (c == '_') { if (underscoreCount > 0) return false; underscoreCount++; } else if (!isLowerLetter(c) && !isNumber(c)) { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java index eb5b1be0fec..74b92d3a48d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java @@ -39,10 +39,6 @@ else if (name.equals(RoadEnvironment.KEY)) return new OSMRoadEnvironmentParser(lookup.getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class)); else if (name.equals(RoadAccess.KEY)) return new OSMRoadAccessParser(lookup.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR)); - else if (name.equals("car_access")) - return new OSMAccessParser(lookup.getBooleanEncodedValue("car_access"), lookup.getBooleanEncodedValue(Roundabout.KEY), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR), TransportationMode.CAR); - else if (name.equals("bike_access")) - return new OSMAccessParser(lookup.getBooleanEncodedValue("bike_access"), lookup.getBooleanEncodedValue(Roundabout.KEY), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.BIKE), TransportationMode.BIKE); else if (name.equals(MaxSpeed.KEY)) return new OSMMaxSpeedParser(lookup.getDecimalEncodedValue(MaxSpeed.KEY)); else if (name.equals(MaxWeight.KEY)) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMAccessParser.java deleted file mode 100644 index a61728d73d0..00000000000 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMAccessParser.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.routing.util.parsers; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.RoadAccess; -import com.graphhopper.routing.util.TransportationMode; -import com.graphhopper.routing.util.countryrules.CountryRule; -import com.graphhopper.storage.IntsRef; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import static com.graphhopper.routing.ev.RoadAccess.YES; - -// TODO rename to car_restricted or car_allowed? -// if car_allowed == false -// if car_access == false -public class OSMAccessParser implements TagParser { - - private final BooleanEncodedValue accessEnc; - private final List restrictions; - private final TransportationMode transportationMode; - private final Set restrictedValues = new HashSet<>(10); - private final Set oneways = new HashSet<>(5); - private final HashSet oppositeLanes = new HashSet<>(); - private final BooleanEncodedValue roundaboutEnc; - - private final Set intendedValues = new HashSet<>(5); - - public OSMAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc, List restrictions, TransportationMode transportationMode) { - this.roundaboutEnc = roundaboutEnc; - this.accessEnc = accessEnc; - this.restrictions = restrictions; - this.transportationMode = transportationMode; - - restrictedValues.add("agricultural"); - restrictedValues.add("forestry"); - restrictedValues.add("no"); - restrictedValues.add("restricted"); - restrictedValues.add("delivery"); - restrictedValues.add("military"); - restrictedValues.add("emergency"); - restrictedValues.add("private"); - - oneways.add("yes"); - oneways.add("true"); - oneways.add("1"); - oneways.add("-1"); - - intendedValues.add("yes"); - intendedValues.add("designated"); - intendedValues.add("official"); - intendedValues.add("permissive"); - - oppositeLanes.add("opposite"); - oppositeLanes.add("opposite_lane"); - oppositeLanes.add("opposite_track"); - } - - @Override - public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { - RoadAccess accessValue = YES; - RoadAccess tmpAccessValue; - for (String restriction : restrictions) { - tmpAccessValue = RoadAccess.find(way.getTag(restriction, "yes")); - if (tmpAccessValue != null && tmpAccessValue.ordinal() > accessValue.ordinal()) { - accessValue = tmpAccessValue; - } - } - - CountryRule countryRule = way.getTag("country_rule", null); - if (countryRule != null) - accessValue = countryRule.getAccess(way, transportationMode, accessValue); - - boolean access = accessValue != RoadAccess.NO; - accessEnc.setBool(false, edgeFlags, access); - - if (access) { - boolean isRoundabout = roundaboutEnc.getBool(false, edgeFlags); - if (transportationMode.isMotorVehicle() && (isOneway(way) || isRoundabout)) { - if (isForwardOneway(way)) - accessEnc.setBool(false, edgeFlags, true); - if (isBackwardOneway(way)) - accessEnc.setBool(true, edgeFlags, true); - } else if (transportationMode == TransportationMode.BIKE - && (isBikeOneway(way) || isRoundabout && !way.hasTag("oneway:bicycle", "no") - && !way.hasTag("cycleway", oppositeLanes) - && !way.hasTag("cycleway:left", oppositeLanes) - && !way.hasTag("cycleway:right", oppositeLanes) - && !way.hasTag("cycleway:left:oneway", "-1") - && !way.hasTag("cycleway:right:oneway", "-1"))) { - boolean isBackward = way.hasTag("oneway", "-1") - || way.hasTag("oneway:bicycle", "-1") - || way.hasTag("vehicle:forward", restrictedValues) - || way.hasTag("bicycle:forward", restrictedValues); - accessEnc.setBool(isBackward, edgeFlags, true); - } else { - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); - } - } - - return edgeFlags; - } - - /** - * make sure that isOneway is called before - */ - protected boolean isBackwardOneway(ReaderWay way) { - return way.hasTag("oneway", "-1") - || way.hasTag("vehicle:forward", restrictedValues) - || way.hasTag("motor_vehicle:forward", restrictedValues); - } - - /** - * make sure that isOneway is called before - */ - protected boolean isForwardOneway(ReaderWay way) { - return !way.hasTag("oneway", "-1") - && !way.hasTag("vehicle:forward", restrictedValues) - && !way.hasTag("motor_vehicle:forward", restrictedValues); - } - - protected boolean isOneway(ReaderWay way) { - return way.hasTag("oneway", oneways) - || way.hasTag("vehicle:backward", restrictedValues) - || way.hasTag("vehicle:forward", restrictedValues) - || way.hasTag("motor_vehicle:backward", restrictedValues) - || way.hasTag("motor_vehicle:forward", restrictedValues); - } - - - boolean isBikeOneway(ReaderWay way) { - return way.hasTag("oneway", oneways) && !way.hasTag("oneway", "-1") && !way.hasTag("bicycle:backward", intendedValues) - || way.hasTag("oneway", "-1") && !way.hasTag("bicycle:forward", intendedValues) - || way.hasTag("oneway:bicycle", oneways) - || way.hasTag("vehicle:backward", restrictedValues) && !way.hasTag("bicycle:forward", intendedValues) - || way.hasTag("vehicle:forward", restrictedValues) && !way.hasTag("bicycle:backward", intendedValues) - || way.hasTag("bicycle:forward", restrictedValues) - || way.hasTag("bicycle:backward", restrictedValues); - } -} diff --git a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java index 8f2f1430893..e3c55adb50f 100644 --- a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java @@ -75,12 +75,13 @@ public void testSupportFords() { @Test public void validEV() { - for (String str : Arrays.asList("blup_test", "test", "test12", "tes$0", "car_test_test", "small_car$average_speed")) { + for (String str : Arrays.asList("blup_test", "test", "test12", "car_test_test")) { assertTrue(EncodingManager.isValidEncodedValue(str), str); } - for (String str : Arrays.asList("Test", "12test", "test|3", "car__test", "blup_te.st_", "car___test", "car$$access", - "test{34", "truck__average_speed", "blup.test", "test,21", "täst", "blup.two.three", "blup..test")) { + for (String str : Arrays.asList("Test", "12test", "test|3", "car__test", "small_car$average_speed", "tes$0", + "blup_te.st_", "car___test", "car$$access", "test{34", "truck__average_speed", "blup.test", "test,21", + "täst", "blup.two.three", "blup..test")) { assertFalse(EncodingManager.isValidEncodedValue(str), str); } diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java index 5e942283bcb..79aefa7a3b1 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java @@ -114,7 +114,7 @@ public void testBrackets() { set(roadClassEnc, SECONDARY).set(avgSpeedEnc, 40); CustomModel customModel = new CustomModel(); - customModel.addToPriority(If("(road_class == PRIMARY || car$access == true) && car$average_speed > 50", MULTIPLY, 0.9)); + customModel.addToPriority(If("(road_class == PRIMARY || car_access == true) && car_average_speed > 50", MULTIPLY, 0.9)); CustomWeighting.Parameters parameters = CustomModelParser.createWeightingParameters(customModel, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null); assertEquals(0.9, parameters.getEdgeToPriorityMapping().get(primary, false), 0.01); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index 95726f9dc02..990411127f7 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -202,7 +202,7 @@ public void testCarAccess() { EdgeIteratorState edge50 = graph.edge(1, 2).setDistance(10).set(avSpeedEnc, 50).set(accessEnc, true, true); CustomModel vehicleModel = new CustomModel(); - vehicleModel.addToPriority(If("car$average_speed > 40", MULTIPLY, 0.5)); + vehicleModel.addToPriority(If("car_average_speed > 40", MULTIPLY, 0.5)); assertEquals(1.60, createWeighting(vehicleModel).calcEdgeWeight(edge40, false), 0.01); assertEquals(2.14, createWeighting(vehicleModel).calcEdgeWeight(edge50, false), 0.01); From 56cd9ae0171493b50528110ab83f0f295fe616df Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 1 Jun 2022 11:58:04 +0200 Subject: [PATCH 027/389] downgrade todonow --- .../com/graphhopper/routing/subnetwork/EdgeBasedTarjanSCC.java | 2 +- .../java/com/graphhopper/routing/util/BikeTagParserTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/subnetwork/EdgeBasedTarjanSCC.java b/core/src/main/java/com/graphhopper/routing/subnetwork/EdgeBasedTarjanSCC.java index 1819a8edc95..eef48a6d167 100644 --- a/core/src/main/java/com/graphhopper/routing/subnetwork/EdgeBasedTarjanSCC.java +++ b/core/src/main/java/com/graphhopper/routing/subnetwork/EdgeBasedTarjanSCC.java @@ -455,7 +455,7 @@ public void set(int key, int value) { @Override public void minTo(int key, int value) { - // todonow: optimize + // todo: optimize with map.indexOf(key) etc map.put(key, Math.min(map.getOrDefault(key, -1), value)); } diff --git a/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java index 929aa7c9099..d0709df488b 100644 --- a/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java @@ -597,7 +597,7 @@ public void testMaxSpeed() { way = new ReaderWay(1); way.setTag("highway", "residential"); way.setTag("maxspeed", "15"); - // todonow!! speed is larger than maxspeed + // todo: speed is larger than maxspeed tag due to rounding and storable max speed is 30 assertPriorityAndSpeed(PREFER.getValue(), 16, way); } From 8e8f21e600cb3fba245ee92222cd4b9a4bb3b270 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 1 Jun 2022 12:26:58 +0200 Subject: [PATCH 028/389] Matrix client improvements (#2587) * tmp * fix tests * update okhttp to 4.9.3 * fixes regarding code review Co-authored-by: easbar --- CHANGELOG.md | 1 + client-hc/pom.xml | 2 +- .../java/com/graphhopper/api/GHMRequest.java | 202 ++++++------------ .../api/GHMatrixAbstractRequester.java | 32 ++- .../api/GHMatrixBatchRequester.java | 16 +- .../api/GHMatrixSyncRequester.java | 17 +- .../graphhopper/api/GraphHopperMatrixWeb.java | 3 - .../api/AbstractGHMatrixWebTester.java | 58 ++--- .../java/com/graphhopper/api/Examples.java | 38 ++-- .../com/graphhopper/api/GHMRequestTest.java | 41 ---- .../graphhopper/api/GraphHopperWebTest.java | 10 +- 11 files changed, 167 insertions(+), 253 deletions(-) delete mode 100644 client-hc/src/test/java/com/graphhopper/api/GHMRequestTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f6826f9c26..852bfdc172c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### 6.0 [not yet released] +- the Matrix client changed and users have to adapt the usage, see #2587 - replaced car$access with car_access (and same for $average_speed and $priority) - don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) - faster flexible routing, especially in conjunction with turn costs (#2571) diff --git a/client-hc/pom.xml b/client-hc/pom.xml index 982b8c7e385..274b00df454 100644 --- a/client-hc/pom.xml +++ b/client-hc/pom.xml @@ -41,7 +41,7 @@ com.squareup.okhttp3 okhttp - 3.14.9 + 4.9.3 org.slf4j diff --git a/client-hc/src/main/java/com/graphhopper/api/GHMRequest.java b/client-hc/src/main/java/com/graphhopper/api/GHMRequest.java index 8f33406c502..3868f9a7cf9 100644 --- a/client-hc/src/main/java/com/graphhopper/api/GHMRequest.java +++ b/client-hc/src/main/java/com/graphhopper/api/GHMRequest.java @@ -1,90 +1,55 @@ package com.graphhopper.api; +import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonProperty; -import com.graphhopper.GHRequest; -import com.graphhopper.util.Helper; +import com.graphhopper.util.PMap; import com.graphhopper.util.shapes.GHPoint; -import java.util.ArrayList; -import java.util.HashSet; +import java.util.Collections; import java.util.List; -import java.util.Set; /** * @author Peter Karich */ -public class GHMRequest extends GHRequest { - +public class GHMRequest { + private String profile; + private List points; private List fromPoints; private List toPoints; + + private List pointHints; private List fromPointHints; private List toPointHints; + + private List curbsides; private List fromCurbsides; private List toCurbsides; - private int called = 0; - boolean identicalLists = true; - private final Set outArrays = new HashSet<>(5); - private boolean failFast = true; - public GHMRequest() { - this(10); - } - - public GHMRequest(int size) { - super(0); - fromPoints = new ArrayList<>(size); - toPoints = new ArrayList<>(size); - fromPointHints = new ArrayList<>(size); - toPointHints = new ArrayList<>(size); - fromCurbsides = new ArrayList<>(size); - toCurbsides = new ArrayList<>(size); - } + private List snapPreventions; + private final PMap hints = new PMap(); + private List outArrays = Collections.EMPTY_LIST; + private boolean failFast = true; - /** - * Currently: weights, times, distances and paths possible. Where paths is - * the most expensive to calculate and limited to maximum 10*10 points (via - * API end point). - */ - public GHMRequest addOutArray(String type) { - outArrays.add(type); + public GHMRequest setProfile(String profile) { + this.profile = profile; return this; } - public Set getOutArrays() { - return outArrays; + public String getProfile() { + return profile; } - public GHMRequest addAllPoints(List points) { - for (GHPoint p : points) { - addPoint(p); - } + public GHMRequest setPoints(List points) { + this.points = points; return this; } - /** - * This methods adds the coordinate as 'from' and 'to' to the request. - */ - @Override - public GHMRequest addPoint(GHPoint point) { - fromPoints.add(point); - toPoints.add(point); - return this; - } - - @Override public List getPoints() { - throw new IllegalStateException("use getFromPoints or getToPoints"); - } - - public GHMRequest addFromPoint(GHPoint point) { - fromPoints.add(point); - identicalLists = false; - return this; + return points; } - public GHMRequest setFromPoints(List points) { - fromPoints = points; - identicalLists = false; + public GHMRequest setFromPoints(List fromPoints) { + this.fromPoints = fromPoints; return this; } @@ -92,15 +57,8 @@ public List getFromPoints() { return fromPoints; } - public GHMRequest addToPoint(GHPoint point) { - toPoints.add(point); - identicalLists = false; - return this; - } - - public GHMRequest setToPoints(List points) { - toPoints = points; - identicalLists = false; + public GHMRequest setToPoints(List toPoints) { + this.toPoints = toPoints; return this; } @@ -108,26 +66,17 @@ public List getToPoints() { return toPoints; } - @Override - public GHRequest setPointHints(List pointHints) { - setToPointHints(pointHints); - this.fromPointHints = this.toPointHints; + public GHMRequest setPointHints(List pointHints) { + this.pointHints = pointHints; return this; } - @Override public List getPointHints() { - throw new IllegalStateException("Use getFromPointHints or getToPointHints"); - } - - public GHRequest addFromPointHint(String pointHint) { - this.fromPointHints.add(pointHint); - return this; + return pointHints; } - public GHRequest setFromPointHints(List pointHints) { - // create new array as we modify pointHints in compactPointHints - this.fromPointHints = new ArrayList<>(pointHints); + public GHMRequest setFromPointHints(List fromPointHints) { + this.fromPointHints = fromPointHints; return this; } @@ -135,14 +84,8 @@ public List getFromPointHints() { return fromPointHints; } - public GHRequest addToPointHint(String pointHint) { - this.toPointHints.add(pointHint); - return this; - } - - public GHRequest setToPointHints(List pointHints) { - // create new array as we modify pointHints in compactPointHints - this.toPointHints = new ArrayList<>(pointHints); + public GHMRequest setToPointHints(List toPointHints) { + this.toPointHints = toPointHints; return this; } @@ -150,13 +93,17 @@ public List getToPointHints() { return toPointHints; } - public GHMRequest addFromCurbside(String curbside) { - fromCurbsides.add(curbside); + public GHMRequest setCurbsides(List curbsides) { + this.curbsides = curbsides; return this; } - public GHMRequest setFromCurbsides(List curbsides) { - fromCurbsides = curbsides; + public List getCurbsides() { + return curbsides; + } + + public GHMRequest setFromCurbsides(List fromCurbsides) { + this.fromCurbsides = fromCurbsides; return this; } @@ -164,30 +111,45 @@ public List getFromCurbsides() { return fromCurbsides; } - public GHMRequest addToCurbside(String curbside) { - toCurbsides.add(curbside); + public GHMRequest setToCurbsides(List toCurbsides) { + this.toCurbsides = toCurbsides; return this; } - public GHMRequest setToCurbsides(List curbsides) { - toCurbsides = curbsides; + public List getToCurbsides() { + return toCurbsides; + } + + public GHMRequest setSnapPreventions(List snapPreventions) { + this.snapPreventions = snapPreventions; return this; } - public List getToCurbsides() { - return toCurbsides; + public List getSnapPreventions() { + return snapPreventions; } - @Override - public GHRequest setCurbsides(List curbsides) { - fromCurbsides = curbsides; - toCurbsides = curbsides; + // a good trick to serialize unknown properties into the HintsMap + @JsonAnySetter + public GHMRequest putHint(String fieldName, Object value) { + hints.putObject(fieldName, value); return this; } - @Override - public List getCurbsides() { - throw new IllegalStateException("Use getFromCurbsides or getToCurbsides"); + public PMap getHints() { + return hints; + } + + /** + * Possible values are 'weights', 'times', 'distances' + */ + public GHMRequest setOutArrays(List outArrays) { + this.outArrays = outArrays; + return this; + } + + public List getOutArrays() { + return outArrays; } /** @@ -202,32 +164,4 @@ public boolean getFailFast() { return failFast; } - /** - * This method clears the point hint lists if they only contain empty values. Often point hints are added although the - * strings are empty. But because they could be used as placeholder we do not know earlier if they are meaningless. - */ - void compactPointHints() { - if (called > 0) - throw new IllegalStateException("cannot call more than once"); - called++; - boolean clear = true; - for (String hint : toPointHints) { - if (!Helper.isEmpty(hint)) { - clear = false; - break; - } - } - if (clear) - toPointHints.clear(); - - clear = true; - for (String hint : fromPointHints) { - if (!Helper.isEmpty(hint)) { - clear = false; - break; - } - } - if (clear) - fromPointHints.clear(); - } } diff --git a/client-hc/src/main/java/com/graphhopper/api/GHMatrixAbstractRequester.java b/client-hc/src/main/java/com/graphhopper/api/GHMatrixAbstractRequester.java index f90e0375425..d859cbcfc5f 100644 --- a/client-hc/src/main/java/com/graphhopper/api/GHMatrixAbstractRequester.java +++ b/client-hc/src/main/java/com/graphhopper/api/GHMatrixAbstractRequester.java @@ -79,17 +79,28 @@ public OkHttpClient getDownloader() { return downloader; } - protected Collection createOutArrayList(GHMRequest ghRequest) { - return ghRequest.getOutArrays().isEmpty() ? Collections.singletonList("weights") : ghRequest.getOutArrays(); - } + protected JsonNode createPostRequest(GHMRequest ghRequest) { + if (ghRequest.getHints().getObject("profile", null) != null) + throw new IllegalArgumentException("use setProfile instead of hint 'profile'"); + if (ghRequest.getHints().getObject("fail_fast", null) != null) + throw new IllegalArgumentException("use setFailFast instead of hint 'fail_fast'"); - protected JsonNode createPostRequest(GHMRequest ghRequest, Collection outArraysList) { ObjectNode requestJson = objectMapper.createObjectNode(); - if (ghRequest.identicalLists) { - putPoints(requestJson, "points", ghRequest.getFromPoints()); - putStrings(requestJson, "point_hints", ghRequest.getFromPointHints()); - putStrings(requestJson, "curbsides", ghRequest.getFromCurbsides()); + if (ghRequest.getPoints() != null) { + if (ghRequest.getFromPoints() != null) + throw new IllegalArgumentException("if points are set do not use setFromPoints"); + if (ghRequest.getToPoints() != null) + throw new IllegalArgumentException("if points are set do not use setToPoints"); + + putPoints(requestJson, "points", ghRequest.getPoints()); + putStrings(requestJson, "point_hints", ghRequest.getPointHints()); + putStrings(requestJson, "curbsides", ghRequest.getCurbsides()); } else { + if (ghRequest.getFromPoints() == null) + throw new IllegalArgumentException("if points are not set you have to use setFromPoints but was null"); + if (ghRequest.getToPoints() == null) + throw new IllegalArgumentException("if points are not set you have to use setToPoints but was null"); + putPoints(requestJson, "from_points", ghRequest.getFromPoints()); putStrings(requestJson, "from_point_hints", ghRequest.getFromPointHints()); @@ -101,8 +112,7 @@ protected JsonNode createPostRequest(GHMRequest ghRequest, Collection ou } putStrings(requestJson, "snap_preventions", ghRequest.getSnapPreventions()); - putStrings(requestJson, "out_arrays", outArraysList); - // requestJson.put("elevation", ghRequest.getHints().getBool("elevation", false)); + putStrings(requestJson, "out_arrays", ghRequest.getOutArrays()); requestJson.put("fail_fast", ghRequest.getFailFast()); Map hintsMap = ghRequest.getHints().toMap(); @@ -309,7 +319,7 @@ protected String postJson(String url, JsonNode data) throws IOException { } private void putStrings(ObjectNode requestJson, String name, Collection stringList) { - if (stringList.isEmpty()) + if (stringList == null || stringList.isEmpty()) return; ArrayNode outList = objectMapper.createArrayNode(); for (String str : stringList) { diff --git a/client-hc/src/main/java/com/graphhopper/api/GHMatrixBatchRequester.java b/client-hc/src/main/java/com/graphhopper/api/GHMatrixBatchRequester.java index 318cbe320ed..4c10e85d1d6 100644 --- a/client-hc/src/main/java/com/graphhopper/api/GHMatrixBatchRequester.java +++ b/client-hc/src/main/java/com/graphhopper/api/GHMatrixBatchRequester.java @@ -71,15 +71,15 @@ public GHMatrixBatchRequester setSleepAfterGET(long sleepAfterGETMillis) { @Override public MatrixResponse route(GHMRequest ghRequest) { - Collection outArraysList = createOutArrayList(ghRequest); - JsonNode requestJson = createPostRequest(ghRequest, outArraysList); + JsonNode requestJson = createPostRequest(ghRequest); - boolean withTimes = outArraysList.contains("times"); - boolean withDistances = outArraysList.contains("distances"); - boolean withWeights = outArraysList.contains("weights"); + boolean withTimes = ghRequest.getOutArrays().contains("times"); + boolean withDistances = ghRequest.getOutArrays().contains("distances"); + boolean withWeights = ghRequest.getOutArrays().contains("weights"); final MatrixResponse matrixResponse = new MatrixResponse( - ghRequest.getFromPoints().size(), - ghRequest.getToPoints().size(), withTimes, withDistances, withWeights); + ghRequest.getPoints() == null ? ghRequest.getFromPoints().size() : ghRequest.getPoints().size(), + ghRequest.getPoints() == null ? ghRequest.getToPoints().size() : ghRequest.getPoints().size(), + withTimes, withDistances, withWeights); try { String postUrl = buildURLNoHints("/calculate", ghRequest); String postResponseStr = postJson(postUrl, requestJson); @@ -131,7 +131,7 @@ public MatrixResponse route(GHMRequest ghRequest) { if ("finished".equals(status)) { JsonNode solution = getResponseJson.get("solution"); - matrixResponse.addErrors(readUsableEntityError(outArraysList, solution)); + matrixResponse.addErrors(readUsableEntityError(ghRequest.getOutArrays(), solution)); if (!matrixResponse.hasErrors()) fillResponseFromJson(matrixResponse, solution, ghRequest.getFailFast()); diff --git a/client-hc/src/main/java/com/graphhopper/api/GHMatrixSyncRequester.java b/client-hc/src/main/java/com/graphhopper/api/GHMatrixSyncRequester.java index 5b037943e4d..7f997cecd42 100644 --- a/client-hc/src/main/java/com/graphhopper/api/GHMatrixSyncRequester.java +++ b/client-hc/src/main/java/com/graphhopper/api/GHMatrixSyncRequester.java @@ -5,7 +5,6 @@ import okhttp3.OkHttpClient; import java.io.IOException; -import java.util.Collection; import java.util.concurrent.TimeUnit; /** @@ -29,15 +28,15 @@ public GHMatrixSyncRequester(String serviceUrl, OkHttpClient client, boolean doR @Override public MatrixResponse route(GHMRequest ghRequest) { - Collection outArraysList = createOutArrayList(ghRequest); - JsonNode requestJson = createPostRequest(ghRequest, outArraysList); + JsonNode requestJson = createPostRequest(ghRequest); - boolean withTimes = outArraysList.contains("times"); - boolean withDistances = outArraysList.contains("distances"); - boolean withWeights = outArraysList.contains("weights"); + boolean withTimes = ghRequest.getOutArrays().contains("times"); + boolean withDistances = ghRequest.getOutArrays().contains("distances"); + boolean withWeights = ghRequest.getOutArrays().contains("weights"); final MatrixResponse matrixResponse = new MatrixResponse( - ghRequest.getFromPoints().size(), - ghRequest.getToPoints().size(), withTimes, withDistances, withWeights); + ghRequest.getPoints() == null ? ghRequest.getFromPoints().size() : ghRequest.getPoints().size(), + ghRequest.getPoints() == null ? ghRequest.getToPoints().size() : ghRequest.getPoints().size(), + withTimes, withDistances, withWeights); try { String postUrl = buildURLNoHints("/", ghRequest); @@ -49,7 +48,7 @@ public MatrixResponse route(GHMRequest ghRequest) { matrixResponse.addErrors(ResponsePathDeserializer.readErrors(objectMapper, responseJson)); if (!matrixResponse.hasErrors()) - matrixResponse.addErrors(readUsableEntityError(outArraysList, responseJson)); + matrixResponse.addErrors(readUsableEntityError(ghRequest.getOutArrays(), responseJson)); if (!matrixResponse.hasErrors()) fillResponseFromJson(matrixResponse, responseJson, ghRequest.getFailFast()); diff --git a/client-hc/src/main/java/com/graphhopper/api/GraphHopperMatrixWeb.java b/client-hc/src/main/java/com/graphhopper/api/GraphHopperMatrixWeb.java index 3a19a092647..90c4c0e222a 100644 --- a/client-hc/src/main/java/com/graphhopper/api/GraphHopperMatrixWeb.java +++ b/client-hc/src/main/java/com/graphhopper/api/GraphHopperMatrixWeb.java @@ -38,9 +38,6 @@ public GraphHopperMatrixWeb setKey(String key) { public MatrixResponse route(GHMRequest request) { if (!Helper.isEmpty(key)) request.getHints().putObject(KEY, key); - if (!request.getPathDetails().isEmpty()) - throw new IllegalArgumentException("Path details are not supported for the Matrix API"); - request.compactPointHints(); return requester.route(request); } } diff --git a/client-hc/src/test/java/com/graphhopper/api/AbstractGHMatrixWebTester.java b/client-hc/src/test/java/com/graphhopper/api/AbstractGHMatrixWebTester.java index 85dc064988e..dbfba7429d6 100644 --- a/client-hc/src/test/java/com/graphhopper/api/AbstractGHMatrixWebTester.java +++ b/client-hc/src/test/java/com/graphhopper/api/AbstractGHMatrixWebTester.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; +import java.util.Arrays; import java.util.Collections; import static org.junit.jupiter.api.Assertions.*; @@ -27,10 +28,13 @@ public abstract class AbstractGHMatrixWebTester { public static GHMRequest createRequest() { GHMRequest req = new GHMRequest(); - req.addPoint(new GHPoint(51.534377, -0.087891)); - req.addPoint(new GHPoint(51.467697, -0.090637)); - req.addPoint(new GHPoint(51.521241, -0.171833)); - req.addPoint(new GHPoint(51.473685, -0.211487)); + req.setPoints(Arrays.asList( + new GHPoint(51.534377, -0.087891), + new GHPoint(51.467697, -0.090637), + new GHPoint(51.521241, -0.171833), + new GHPoint(51.473685, -0.211487) + )); + req.setOutArrays(Arrays.asList("weights")); return req; } @@ -70,11 +74,11 @@ public void testReadingMatrixConnectionsNotFound_noFailFast() throws IOException GraphHopperMatrixWeb matrixWeb = createMatrixClient(ghMatrix); GHMRequest req = new GHMRequest(); - req.addPoint(new GHPoint(0, 1)); - req.addPoint(new GHPoint(2, 3)); - req.addOutArray("weights"); - req.addOutArray("distances"); - req.addOutArray("times"); + req.setPoints(Arrays.asList( + new GHPoint(0, 1), + new GHPoint(2, 3) + )); + req.setOutArrays(Arrays.asList("weights", "distances", "times")); req.setFailFast(false); MatrixResponse rsp = matrixWeb.route(req); @@ -99,12 +103,12 @@ public void testReadingMatrixPointsNotFound_noFailFast() throws IOException { GraphHopperMatrixWeb matrixWeb = createMatrixClient(ghMatrix); GHMRequest req = new GHMRequest(); - req.addPoint(new GHPoint(0, 1)); - req.addPoint(new GHPoint(2, 3)); - req.addPoint(new GHPoint(4, 5)); - req.addOutArray("weights"); - req.addOutArray("distances"); - req.addOutArray("times"); + req.setPoints(Arrays.asList( + new GHPoint(0, 1), + new GHPoint(2, 3), + new GHPoint(4, 5) + )); + req.setOutArrays(Arrays.asList("weights", "distances", "times")); req.setFailFast(false); MatrixResponse rsp = matrixWeb.route(req); @@ -164,9 +168,7 @@ public void testReadingWeights_TimesAndDistances() throws IOException { GraphHopperMatrixWeb matrixWeb = createMatrixClient(ghMatrix); GHMRequest req = createRequest(); - req.addOutArray("weights"); - req.addOutArray("distances"); - req.addOutArray("times"); + req.setOutArrays(Arrays.asList("weights", "distances", "times")); MatrixResponse rsp = matrixWeb.route(req); assertFalse(rsp.hasErrors()); @@ -183,19 +185,25 @@ public void testReadingWeights_TimesAndDistances() throws IOException { } @Test - public void noVehicleWhenNotSpecified() { + public void noProfileWhenNotSpecified() { GHMatrixBatchRequester requester = new GHMatrixBatchRequester("url"); - JsonNode json = requester.createPostRequest(new GHMRequest(5), Collections.singletonList("weights")); - assertEquals("{\"out_arrays\":[\"weights\"],\"fail_fast\":true}", json.toString()); + JsonNode json = requester.createPostRequest(new GHMRequest().setOutArrays(Collections.singletonList("weights")).setPoints(Arrays.asList(new GHPoint(11, 12)))); + assertEquals("{\"points\":[[12.0,11.0]],\"out_arrays\":[\"weights\"],\"fail_fast\":true}", json.toString()); } @Test public void hasHintsWhenSpecified() { GHMatrixAbstractRequester requester = createRequester("url"); - GHMRequest ghmRequest = new GHMRequest(5); - ghmRequest.putHint("vehicle", "my_car").putHint("profile", "my_profile"); - JsonNode json = requester.createPostRequest(ghmRequest, Collections.singletonList("weights")); - assertEquals("{\"out_arrays\":[\"weights\"],\"fail_fast\":true,\"vehicle\":\"my_car\",\"profile\":\"my_profile\"}", json.toString()); + GHMRequest ghmRequest = new GHMRequest(); + ghmRequest.putHint("some_property", "value"); + ghmRequest.setOutArrays(Collections.singletonList("weights")); + ghmRequest.setPoints(Arrays.asList(new GHPoint(11, 12))); + JsonNode json = requester.createPostRequest(ghmRequest); + assertEquals("{\"points\":[[12.0,11.0]],\"out_arrays\":[\"weights\"],\"fail_fast\":true,\"some_property\":\"value\"}", json.toString()); + + ghmRequest.putHint("profile", "car"); + Exception ex = assertThrows(IllegalArgumentException.class, () -> requester.createPostRequest(ghmRequest)); + assertTrue(ex.getMessage().contains("use setProfile"), ex.getMessage()); } public static String readFile(Reader simpleReader) throws IOException { diff --git a/client-hc/src/test/java/com/graphhopper/api/Examples.java b/client-hc/src/test/java/com/graphhopper/api/Examples.java index be26b50199e..ae4a9f706c0 100644 --- a/client-hc/src/test/java/com/graphhopper/api/Examples.java +++ b/client-hc/src/test/java/com/graphhopper/api/Examples.java @@ -36,8 +36,8 @@ public void routing() { GHRequest req = new GHRequest(). addPoint(new GHPoint(49.6724, 11.3494)). addPoint(new GHPoint(49.6550, 11.4180)); - // Set vehicle like car, bike, foot, ... - req.putHint("vehicle", "bike"); + // Set profile like car, bike, foot, ... + req.setProfile("bike"); // Optionally enable/disable elevation in output PointList, currently bike and foot support elevation, default is false req.putHint("elevation", false); // Optionally enable/disable turn instruction information, defaults is true @@ -92,23 +92,29 @@ public void matrix() { matrixClient.setKey(apiKey); GHMRequest ghmRequest = new GHMRequest(); - ghmRequest.addOutArray("distances"); - ghmRequest.addOutArray("times"); - ghmRequest.putHint("vehicle", "car"); - - // init points for a symmetric matrix - // List allPoints = Arrays.asList(new GHPoint(49.6724, 11.3494), new GHPoint(49.6550, 11.4180)); - // ghmRequest.addAllPoints(allPoints); + ghmRequest.setOutArrays(Arrays.asList("distances", "times")); + ghmRequest.setProfile("car"); + + // Option 1: init points for a symmetric matrix + List allPoints = Arrays.asList(new GHPoint(49.6724, 11.3494), new GHPoint(49.6550, 11.4180)); + ghmRequest.setPoints(allPoints); + MatrixResponse responseSymm = matrixClient.route(ghmRequest); + if (responseSymm.hasErrors()) + throw new RuntimeException(responseSymm.getErrors().toString()); + // get time from first to second point: + // System.out.println(response.getTime(0, 1)); + // Option 2: for an asymmetric matrix do: + ghmRequest = new GHMRequest(); + ghmRequest.setOutArrays(Arrays.asList("distances", "times")); + ghmRequest.setProfile("car"); + ghmRequest.setFromPoints(Arrays.asList(new GHPoint(49.6724, 11.3494))); // or init e.g. a one-to-many matrix: - ghmRequest.addFromPoint(new GHPoint(49.6724, 11.3494)); - for (GHPoint to : Arrays.asList(new GHPoint(49.6724, 11.3494), new GHPoint(49.6550, 11.4180))) { - ghmRequest.addToPoint(to); - } + ghmRequest.setToPoints(Arrays.asList(new GHPoint(49.6724, 11.3494), new GHPoint(49.6550, 11.4180))); - MatrixResponse response = matrixClient.route(ghmRequest); - if (response.hasErrors()) - throw new RuntimeException(response.getErrors().toString()); + MatrixResponse responseAsymm = matrixClient.route(ghmRequest); + if (responseAsymm.hasErrors()) + throw new RuntimeException(responseAsymm.getErrors().toString()); // get time from first to second point: // System.out.println(response.getTime(0, 1)); diff --git a/client-hc/src/test/java/com/graphhopper/api/GHMRequestTest.java b/client-hc/src/test/java/com/graphhopper/api/GHMRequestTest.java deleted file mode 100644 index 1c374bd593d..00000000000 --- a/client-hc/src/test/java/com/graphhopper/api/GHMRequestTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.graphhopper.api; - -import com.graphhopper.util.shapes.GHPoint; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class GHMRequestTest { - @Test - public void testCompact() { - GHMRequest request = new GHMRequest(); - for (int i = 0; i < 3; i++) { - request.addFromPoint(new GHPoint()); - request.addFromPointHint(""); - } - - request.addToPoint(new GHPoint()); - request.addToPointHint(""); - - request.compactPointHints(); - assertTrue(request.getToPointHints().isEmpty()); - assertTrue(request.getFromPointHints().isEmpty()); - } - - @Test - public void testCompact2() { - GHMRequest request = new GHMRequest(); - for (int i = 0; i < 3; i++) { - request.addFromPoint(new GHPoint()); - request.addFromPointHint(""); - } - - request.addToPoint(new GHPoint()); - request.addToPointHint("x"); - - request.compactPointHints(); - assertFalse(request.getToPointHints().isEmpty()); - assertTrue(request.getFromPointHints().isEmpty()); - } -} \ No newline at end of file diff --git a/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java b/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java index 115f7bcccc9..6c3d8cbe02e 100644 --- a/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java +++ b/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java @@ -33,14 +33,14 @@ public class GraphHopperWebTest { public void testGetClientForRequest(boolean usePost) { GraphHopperWeb gh = new GraphHopperWeb(null).setPostRequest(usePost); GHRequest req = new GHRequest(new GHPoint(42.509225, 1.534728), new GHPoint(42.512602, 1.551558)). - putHint("vehicle", "car"); + setProfile("car"); req.putHint(GraphHopperWeb.TIMEOUT, 5); assertEquals(5, gh.getClientForRequest(req).connectTimeoutMillis()); } @Test - public void vehicleIncludedAsGiven() { + public void profileIncludedAsGiven() { GraphHopperWeb hopper = new GraphHopperWeb("https://localhost:8000/route"); // no vehicle -> no vehicle assertEquals("https://localhost:8000/route?profile=&type=json&instructions=true&points_encoded=true" + @@ -48,9 +48,9 @@ public void vehicleIncludedAsGiven() { hopper.createGetRequest(new GHRequest()).url().toString()); // vehicle given -> vehicle used in url - assertEquals("https://localhost:8000/route?profile=my_profile&type=json&instructions=true&points_encoded=true" + - "&calc_points=true&algorithm=&locale=en_US&elevation=false&optimize=false&vehicle=my_car", - hopper.createGetRequest(new GHRequest().putHint("vehicle", "my_car").setProfile("my_profile")).url().toString()); + assertEquals("https://localhost:8000/route?profile=my_car&type=json&instructions=true&points_encoded=true" + + "&calc_points=true&algorithm=&locale=en_US&elevation=false&optimize=false", + hopper.createGetRequest(new GHRequest().setProfile("my_car")).url().toString()); } @Test From 677b10a4a6bf3d28a33cef945244e0ddb269593b Mon Sep 17 00:00:00 2001 From: otbutz Date: Thu, 2 Jun 2022 10:13:48 +0200 Subject: [PATCH 029/389] European toll fallback rules (#2450) Co-authored-by: Thomas Butz --- .../util/countryrules/CountryRule.java | 2 +- .../util/countryrules/CountryRuleFactory.java | 50 +++++++++++++++++++ .../europe/AlbaniaCountryRule.java | 35 +++++++++++++ .../europe/AndorraCountryRule.java | 35 +++++++++++++ .../{ => europe}/AustriaCountryRule.java | 7 +-- .../europe/BelarusCountryRule.java | 41 +++++++++++++++ .../europe/BelgiumCountryRule.java | 43 ++++++++++++++++ .../europe/BosniaHerzegovinaCountryRule.java | 25 ++++++++++ .../europe/BulgariaCountryRule.java | 43 ++++++++++++++++ .../europe/CroatiaCountryRule.java | 43 ++++++++++++++++ .../europe/CzechiaCountryRule.java | 43 ++++++++++++++++ .../europe/DenmarkCountryRule.java | 43 ++++++++++++++++ .../europe/EstoniaCountryRule.java | 41 +++++++++++++++ .../europe/FaroeIslandsCountryRule.java | 35 +++++++++++++ .../europe/FinlandCountryRule.java | 35 +++++++++++++ .../europe/FranceCountryRule.java | 43 ++++++++++++++++ .../{ => europe}/GermanyCountryRule.java | 7 +-- .../europe/GibraltarCountryRule.java | 35 +++++++++++++ .../europe/GreeceCountryRule.java | 41 +++++++++++++++ .../europe/GuernseyCountryRule.java | 35 +++++++++++++ .../europe/HungaryCountryRule.java | 49 ++++++++++++++++++ .../europe/IcelandCountryRule.java | 35 +++++++++++++ .../europe/IrelandCountryRule.java | 25 ++++++++++ .../europe/IsleOfManCountryRule.java | 35 +++++++++++++ .../countryrules/europe/ItalyCountryRule.java | 43 ++++++++++++++++ .../europe/JerseyCountryRule.java | 35 +++++++++++++ .../europe/LatviaCountryRule.java | 41 +++++++++++++++ .../europe/LiechtensteinCountryRule.java | 35 +++++++++++++ .../europe/LithuaniaCountryRule.java | 41 +++++++++++++++ .../europe/LuxembourgCountryRule.java | 43 ++++++++++++++++ .../countryrules/europe/MaltaCountryRule.java | 35 +++++++++++++ .../europe/MoldovaCountryRule.java | 25 ++++++++++ .../europe/MonacoCountryRule.java | 35 +++++++++++++ .../europe/MontenegroCountryRule.java | 25 ++++++++++ .../europe/NetherlandsCountryRule.java | 43 ++++++++++++++++ .../europe/NorthMacedoniaCountryRule.java | 25 ++++++++++ .../europe/NorwayCountryRule.java | 25 ++++++++++ .../europe/PolandCountryRule.java | 43 ++++++++++++++++ .../europe/PortugalCountryRule.java | 43 ++++++++++++++++ .../europe/RomaniaCountryRule.java | 43 ++++++++++++++++ .../europe/RomaniaSpatialRule.java | 48 ++++++++++++++++++ .../europe/RussiaCountryRule.java | 25 ++++++++++ .../europe/SanMarinoCountryRule.java | 35 +++++++++++++ .../europe/SerbiaCountryRule.java | 43 ++++++++++++++++ .../europe/SlovakiaCountryRule.java | 47 +++++++++++++++++ .../europe/SloveniaCountryRule.java | 47 +++++++++++++++++ .../countryrules/europe/SpainCountryRule.java | 43 ++++++++++++++++ .../europe/SwedenCountryRule.java | 43 ++++++++++++++++ .../europe/SwitzerlandCountryRule.java | 50 +++++++++++++++++++ .../europe/UkraineCountryRule.java | 35 +++++++++++++ .../europe/UnitedKingdomCountryRule.java | 25 ++++++++++ .../europe/VaticanCityCountryRule.java | 35 +++++++++++++ .../routing/util/parsers/OSMTollParser.java | 3 +- .../util/countryrules/CountryRuleTest.java | 3 ++ 54 files changed, 1879 insertions(+), 9 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AlbaniaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AndorraCountryRule.java rename core/src/main/java/com/graphhopper/routing/util/countryrules/{ => europe}/AustriaCountryRule.java (92%) create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelarusCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelgiumCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BosniaHerzegovinaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BulgariaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CroatiaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CzechiaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/DenmarkCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/EstoniaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FaroeIslandsCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FinlandCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FranceCountryRule.java rename core/src/main/java/com/graphhopper/routing/util/countryrules/{ => europe}/GermanyCountryRule.java (93%) create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GibraltarCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GreeceCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GuernseyCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/HungaryCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IcelandCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IrelandCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IsleOfManCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/ItalyCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/JerseyCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LatviaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LiechtensteinCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LithuaniaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LuxembourgCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MaltaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MoldovaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MonacoCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MontenegroCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NetherlandsCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NorthMacedoniaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NorwayCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PolandCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PortugalCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaSpatialRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RussiaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SanMarinoCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SerbiaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SlovakiaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SloveniaCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SpainCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwedenCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwitzerlandCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UkraineCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UnitedKingdomCountryRule.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/countryrules/europe/VaticanCityCountryRule.java diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRule.java index cf67f15761a..24f544eb737 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRule.java @@ -35,7 +35,7 @@ default RoadAccess getAccess(ReaderWay readerWay, TransportationMode transportat return currentRoadAccess; } - default Toll getToll(ReaderWay readerWay, TransportationMode transportationMode, Toll currentToll) { + default Toll getToll(ReaderWay readerWay, Toll currentToll) { return currentToll; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRuleFactory.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRuleFactory.java index 7a68a6dbfd1..f9ed9e7f0fb 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRuleFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/CountryRuleFactory.java @@ -25,14 +25,64 @@ import java.util.Map; import com.graphhopper.routing.ev.Country; +import com.graphhopper.routing.util.countryrules.europe.*; public class CountryRuleFactory { private final Map rules = new EnumMap<>(Country.class); public CountryRuleFactory() { + + // Europe + rules.put(ALB, new AlbaniaCountryRule()); + rules.put(AND, new AndorraCountryRule()); rules.put(AUT, new AustriaCountryRule()); + rules.put(BEL, new BelgiumCountryRule()); + rules.put(BGR, new BulgariaCountryRule()); + rules.put(BIH, new BosniaHerzegovinaCountryRule()); + rules.put(BLR, new BelarusCountryRule()); + rules.put(CHE, new SwitzerlandCountryRule()); + rules.put(CZE, new CzechiaCountryRule()); rules.put(DEU, new GermanyCountryRule()); + rules.put(DNK, new DenmarkCountryRule()); + rules.put(ESP, new SpainCountryRule()); + rules.put(EST, new EstoniaCountryRule()); + rules.put(FIN, new FinlandCountryRule()); + rules.put(FRA, new FranceCountryRule()); + rules.put(FRO, new FaroeIslandsCountryRule()); + rules.put(GGY, new GuernseyCountryRule()); + rules.put(GIB, new GibraltarCountryRule()); + rules.put(GBR, new UnitedKingdomCountryRule()); + rules.put(GRC, new GreeceCountryRule()); + rules.put(HRV, new CroatiaCountryRule()); + rules.put(HUN, new HungaryCountryRule()); + rules.put(IMN, new IsleOfManCountryRule()); + rules.put(IRL, new IrelandCountryRule()); + rules.put(ISL, new IcelandCountryRule()); + rules.put(ITA, new ItalyCountryRule()); + rules.put(JEY, new JerseyCountryRule()); + rules.put(LIE, new LiechtensteinCountryRule()); + rules.put(LTU, new LithuaniaCountryRule()); + rules.put(LUX, new LuxembourgCountryRule()); + rules.put(LVA, new LatviaCountryRule()); + rules.put(MCO, new MonacoCountryRule()); + rules.put(MDA, new MoldovaCountryRule()); + rules.put(MKD, new NorthMacedoniaCountryRule()); + rules.put(MLT, new MaltaCountryRule()); + rules.put(MNE, new MontenegroCountryRule()); + rules.put(NLD, new NetherlandsCountryRule()); + rules.put(NOR, new NorwayCountryRule()); + rules.put(POL, new PolandCountryRule()); + rules.put(PRT, new PortugalCountryRule()); + rules.put(ROU, new RomaniaCountryRule()); + rules.put(RUS, new RussiaCountryRule()); + rules.put(SMR, new SanMarinoCountryRule()); + rules.put(SRB, new SerbiaCountryRule()); + rules.put(SVK, new SlovakiaCountryRule()); + rules.put(SVN, new SloveniaCountryRule()); + rules.put(SWE, new SwedenCountryRule()); + rules.put(UKR, new UkraineCountryRule()); + rules.put(VAT, new VaticanCityCountryRule()); } public CountryRule getCountryRule(Country country) { diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AlbaniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AlbaniaCountryRule.java new file mode 100644 index 00000000000..4201501ae82 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AlbaniaCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class AlbaniaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AndorraCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AndorraCountryRule.java new file mode 100644 index 00000000000..2de857f7aa1 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AndorraCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class AndorraCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/AustriaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AustriaCountryRule.java similarity index 92% rename from core/src/main/java/com/graphhopper/routing/util/countryrules/AustriaCountryRule.java rename to core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AustriaCountryRule.java index 64b0a73e87f..6fb3accdb9a 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/AustriaCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/AustriaCountryRule.java @@ -16,13 +16,14 @@ * limitations under the License. */ -package com.graphhopper.routing.util.countryrules; +package com.graphhopper.routing.util.countryrules.europe; import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.RoadAccess; import com.graphhopper.routing.ev.RoadClass; import com.graphhopper.routing.ev.Toll; import com.graphhopper.routing.util.TransportationMode; +import com.graphhopper.routing.util.countryrules.CountryRule; public class AustriaCountryRule implements CountryRule { @@ -74,8 +75,8 @@ public RoadAccess getAccess(ReaderWay readerWay, TransportationMode transportati } @Override - public Toll getToll(ReaderWay readerWay, TransportationMode transportationMode, Toll currentToll) { - if (!transportationMode.isMotorVehicle() || currentToll != Toll.MISSING) { + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { return currentToll; } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelarusCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelarusCountryRule.java new file mode 100644 index 00000000000..9b3b11dc837 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelarusCountryRule.java @@ -0,0 +1,41 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class BelarusCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (roadClass == RoadClass.MOTORWAY) { + return Toll.HGV; + } + + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelgiumCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelgiumCountryRule.java new file mode 100644 index 00000000000..ba9b30ac1f2 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BelgiumCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Belgian roads + * + * @author Thomas Butz + */ +public class BelgiumCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BosniaHerzegovinaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BosniaHerzegovinaCountryRule.java new file mode 100644 index 00000000000..4b3fbe23bcb --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BosniaHerzegovinaCountryRule.java @@ -0,0 +1,25 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class BosniaHerzegovinaCountryRule implements CountryRule { + +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BulgariaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BulgariaCountryRule.java new file mode 100644 index 00000000000..a8e642a4554 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/BulgariaCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Bulgarian roads + * + * @author Thomas Butz + */ +public class BulgariaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CroatiaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CroatiaCountryRule.java new file mode 100644 index 00000000000..948eb5a4283 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CroatiaCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Croatian roads + * + * @author Thomas Butz + */ +public class CroatiaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CzechiaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CzechiaCountryRule.java new file mode 100644 index 00000000000..a29e23d929d --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/CzechiaCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for the roads of the Czech Republic. + * + * @author Thomas Butz + */ +public class CzechiaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/DenmarkCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/DenmarkCountryRule.java new file mode 100644 index 00000000000..177cdaab890 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/DenmarkCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Polish roads + * + * @author Thomas Butz + */ +public class DenmarkCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/EstoniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/EstoniaCountryRule.java new file mode 100644 index 00000000000..3d00d7278dd --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/EstoniaCountryRule.java @@ -0,0 +1,41 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class EstoniaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK || roadClass == RoadClass.PRIMARY) { + return Toll.HGV; + } + + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FaroeIslandsCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FaroeIslandsCountryRule.java new file mode 100644 index 00000000000..3838ba68d67 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FaroeIslandsCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class FaroeIslandsCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FinlandCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FinlandCountryRule.java new file mode 100644 index 00000000000..687cfa95428 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FinlandCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class FinlandCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FranceCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FranceCountryRule.java new file mode 100644 index 00000000000..e35f2977e23 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/FranceCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for French roads + * + * @author Thomas Butz + */ +public class FranceCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/GermanyCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GermanyCountryRule.java similarity index 93% rename from core/src/main/java/com/graphhopper/routing/util/countryrules/GermanyCountryRule.java rename to core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GermanyCountryRule.java index 49a9d01aa39..35a59490ea8 100644 --- a/core/src/main/java/com/graphhopper/routing/util/countryrules/GermanyCountryRule.java +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GermanyCountryRule.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package com.graphhopper.routing.util.countryrules; +package com.graphhopper.routing.util.countryrules.europe; import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.MaxSpeed; @@ -24,6 +24,7 @@ import com.graphhopper.routing.ev.RoadClass; import com.graphhopper.routing.ev.Toll; import com.graphhopper.routing.util.TransportationMode; +import com.graphhopper.routing.util.countryrules.CountryRule; /** * @author Robin Boldt @@ -82,8 +83,8 @@ public RoadAccess getAccess(ReaderWay readerWay, TransportationMode transportati } @Override - public Toll getToll(ReaderWay readerWay, TransportationMode transportationMode, Toll currentToll) { - if (!transportationMode.isMotorVehicle() || currentToll != Toll.MISSING) { + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { return currentToll; } diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GibraltarCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GibraltarCountryRule.java new file mode 100644 index 00000000000..adfbcf0b741 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GibraltarCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class GibraltarCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GreeceCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GreeceCountryRule.java new file mode 100644 index 00000000000..4d28cbc0872 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GreeceCountryRule.java @@ -0,0 +1,41 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class GreeceCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (roadClass == RoadClass.MOTORWAY) { + return Toll.ALL; + } + + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GuernseyCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GuernseyCountryRule.java new file mode 100644 index 00000000000..6c5e5e47dd9 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/GuernseyCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class GuernseyCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/HungaryCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/HungaryCountryRule.java new file mode 100644 index 00000000000..6e288bda384 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/HungaryCountryRule.java @@ -0,0 +1,49 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Hungarian roads + * + * @author Thomas Butz + */ +public class HungaryCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + switch (roadClass) { + case MOTORWAY: + return Toll.ALL; + case TRUNK: + case PRIMARY: + return Toll.HGV; + default: + return currentToll; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IcelandCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IcelandCountryRule.java new file mode 100644 index 00000000000..1342e71da7c --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IcelandCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class IcelandCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IrelandCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IrelandCountryRule.java new file mode 100644 index 00000000000..105162ec406 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IrelandCountryRule.java @@ -0,0 +1,25 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class IrelandCountryRule implements CountryRule { + +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IsleOfManCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IsleOfManCountryRule.java new file mode 100644 index 00000000000..cb391439a6c --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/IsleOfManCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class IsleOfManCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/ItalyCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/ItalyCountryRule.java new file mode 100644 index 00000000000..ba70969f299 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/ItalyCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Italian roads + * + * @author Thomas Butz + */ +public class ItalyCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/JerseyCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/JerseyCountryRule.java new file mode 100644 index 00000000000..c3220b4a9eb --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/JerseyCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class JerseyCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LatviaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LatviaCountryRule.java new file mode 100644 index 00000000000..e55b9e7d0a9 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LatviaCountryRule.java @@ -0,0 +1,41 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class LatviaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK || roadClass == RoadClass.PRIMARY) { + return Toll.HGV; + } + + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LiechtensteinCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LiechtensteinCountryRule.java new file mode 100644 index 00000000000..d7e636b6578 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LiechtensteinCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class LiechtensteinCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LithuaniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LithuaniaCountryRule.java new file mode 100644 index 00000000000..66d1f6499d8 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LithuaniaCountryRule.java @@ -0,0 +1,41 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class LithuaniaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK || roadClass == RoadClass.PRIMARY) { + return Toll.HGV; + } + + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LuxembourgCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LuxembourgCountryRule.java new file mode 100644 index 00000000000..19b6b9f7883 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/LuxembourgCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Luxembourgish roads + * + * @author Thomas Butz + */ +public class LuxembourgCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MaltaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MaltaCountryRule.java new file mode 100644 index 00000000000..88a3ae03cc5 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MaltaCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class MaltaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MoldovaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MoldovaCountryRule.java new file mode 100644 index 00000000000..c5e4beddfce --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MoldovaCountryRule.java @@ -0,0 +1,25 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class MoldovaCountryRule implements CountryRule { + +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MonacoCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MonacoCountryRule.java new file mode 100644 index 00000000000..277137176f6 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MonacoCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class MonacoCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MontenegroCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MontenegroCountryRule.java new file mode 100644 index 00000000000..e505b0b5c1e --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/MontenegroCountryRule.java @@ -0,0 +1,25 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class MontenegroCountryRule implements CountryRule { + +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NetherlandsCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NetherlandsCountryRule.java new file mode 100644 index 00000000000..2d8aa038b05 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NetherlandsCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Netherlands roads + * + * @author Thomas Butz + */ +public class NetherlandsCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NorthMacedoniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NorthMacedoniaCountryRule.java new file mode 100644 index 00000000000..ffb94a76356 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NorthMacedoniaCountryRule.java @@ -0,0 +1,25 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class NorthMacedoniaCountryRule implements CountryRule { + +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NorwayCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NorwayCountryRule.java new file mode 100644 index 00000000000..c670d9af40a --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/NorwayCountryRule.java @@ -0,0 +1,25 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class NorwayCountryRule implements CountryRule { + +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PolandCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PolandCountryRule.java new file mode 100644 index 00000000000..fb26f885f38 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PolandCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Polish roads + * + * @author Thomas Butz + */ +public class PolandCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PortugalCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PortugalCountryRule.java new file mode 100644 index 00000000000..8f3c6c85b76 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/PortugalCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Portuguese roads + * + * @author Thomas Butz + */ +public class PortugalCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaCountryRule.java new file mode 100644 index 00000000000..cb310251e1f --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Croatian roads + * + * @author Thomas Butz + */ +public class RomaniaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (roadClass == RoadClass.MOTORWAY || roadClass == RoadClass.TRUNK) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaSpatialRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaSpatialRule.java new file mode 100644 index 00000000000..efa447f344c --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RomaniaSpatialRule.java @@ -0,0 +1,48 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Romanian roads + * + * @author Thomas Butz + */ +public class RomaniaSpatialRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + switch (roadClass) { + case MOTORWAY: + case TRUNK: + case PRIMARY: + return Toll.ALL; + default: + return currentToll; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RussiaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RussiaCountryRule.java new file mode 100644 index 00000000000..11776a22080 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/RussiaCountryRule.java @@ -0,0 +1,25 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class RussiaCountryRule implements CountryRule { + +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SanMarinoCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SanMarinoCountryRule.java new file mode 100644 index 00000000000..ec4ae43c31c --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SanMarinoCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class SanMarinoCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SerbiaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SerbiaCountryRule.java new file mode 100644 index 00000000000..5ced7eac829 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SerbiaCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Serbian roads + * + * @author Thomas Butz + */ +public class SerbiaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SlovakiaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SlovakiaCountryRule.java new file mode 100644 index 00000000000..be03fe0da76 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SlovakiaCountryRule.java @@ -0,0 +1,47 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Slovakian roads + * + * @author Thomas Butz + */ +public class SlovakiaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + switch (roadClass) { + case MOTORWAY: + case TRUNK: + return Toll.ALL; + default: + return currentToll; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SloveniaCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SloveniaCountryRule.java new file mode 100644 index 00000000000..5bfcc699222 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SloveniaCountryRule.java @@ -0,0 +1,47 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Slovenian roads + * + * @author Thomas Butz + */ +public class SloveniaCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + switch (roadClass) { + case MOTORWAY: + case TRUNK: + return Toll.ALL; + default: + return currentToll; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SpainCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SpainCountryRule.java new file mode 100644 index 00000000000..727b06b22f9 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SpainCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Spanish roads + * + * @author Thomas Butz + */ +public class SpainCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.ALL; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwedenCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwedenCountryRule.java new file mode 100644 index 00000000000..4d303b2f246 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwedenCountryRule.java @@ -0,0 +1,43 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Swedish roads + * + * @author Thomas Butz + */ +public class SwedenCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (RoadClass.MOTORWAY == roadClass) + return Toll.HGV; + return currentToll; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwitzerlandCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwitzerlandCountryRule.java new file mode 100644 index 00000000000..04745249df7 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/SwitzerlandCountryRule.java @@ -0,0 +1,50 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +/** + * Defines the default rules for Swiss roads + * + * @author Thomas Butz + */ +public class SwitzerlandCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + RoadClass roadClass = RoadClass.find(readerWay.getTag("highway", "")); + if (currentToll != null) + return currentToll; + + switch (roadClass) { + case MOTORWAY: + case TRUNK: + return Toll.ALL; + default: + return currentToll; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UkraineCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UkraineCountryRule.java new file mode 100644 index 00000000000..acbed2fb5b0 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UkraineCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class UkraineCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UnitedKingdomCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UnitedKingdomCountryRule.java new file mode 100644 index 00000000000..5bc7e4e5856 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/UnitedKingdomCountryRule.java @@ -0,0 +1,25 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class UnitedKingdomCountryRule implements CountryRule { + +} diff --git a/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/VaticanCityCountryRule.java b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/VaticanCityCountryRule.java new file mode 100644 index 00000000000..1c1e7f50af0 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/countryrules/europe/VaticanCityCountryRule.java @@ -0,0 +1,35 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util.countryrules.europe; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Toll; +import com.graphhopper.routing.util.countryrules.CountryRule; + +public class VaticanCityCountryRule implements CountryRule { + + @Override + public Toll getToll(ReaderWay readerWay, Toll currentToll) { + if (currentToll != Toll.MISSING) { + return currentToll; + } + + return Toll.NO; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java index d784af6e107..2e808820ac1 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTollParser.java @@ -20,7 +20,6 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.Toll; -import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.routing.util.countryrules.CountryRule; import com.graphhopper.storage.IntsRef; @@ -52,7 +51,7 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef rel CountryRule countryRule = readerWay.getTag("country_rule", null); if (countryRule != null) - toll = countryRule.getToll(readerWay, TransportationMode.CAR, toll); + toll = countryRule.getToll(readerWay, toll); tollEnc.setEnum(false, edgeFlags, toll); diff --git a/core/src/test/java/com/graphhopper/routing/util/countryrules/CountryRuleTest.java b/core/src/test/java/com/graphhopper/routing/util/countryrules/CountryRuleTest.java index 7585fd9322f..274dcfd5f67 100644 --- a/core/src/test/java/com/graphhopper/routing/util/countryrules/CountryRuleTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/countryrules/CountryRuleTest.java @@ -20,6 +20,9 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.RoadAccess; import com.graphhopper.routing.util.TransportationMode; +import com.graphhopper.routing.util.countryrules.europe.AustriaCountryRule; +import com.graphhopper.routing.util.countryrules.europe.GermanyCountryRule; + import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; From 837eb7443cfa2a41942c29aa1edca176b403199a Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 2 Jun 2022 19:12:25 +0200 Subject: [PATCH 030/389] use for loop in PathDetailsBuilderFactory as discussed in #2585 (#2589) --- .../details/PathDetailsBuilderFactory.java | 43 +++++++------------ 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java index 910d99ca0e0..c3e0849c0a5 100644 --- a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java +++ b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java @@ -21,10 +21,8 @@ import com.graphhopper.routing.weighting.Weighting; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.util.Parameters.Details.*; /** @@ -58,32 +56,21 @@ public List createPathDetailsBuilders(List requested if (requestedPathDetails.contains(DISTANCE)) builders.add(new DistanceDetails()); - for (String checkSuffix : requestedPathDetails) { - if (checkSuffix.endsWith(getKey("", "priority")) && evl.hasEncodedValue(checkSuffix)) - builders.add(new DecimalDetails(checkSuffix, evl.getDecimalEncodedValue(checkSuffix))); - } - - for (String key : Arrays.asList(MaxSpeed.KEY, MaxWidth.KEY, MaxHeight.KEY, MaxWeight.KEY, - MaxAxleLoad.KEY, MaxLength.KEY)) { - if (requestedPathDetails.contains(key) && evl.hasEncodedValue(key)) - builders.add(new DecimalDetails(key, evl.getDecimalEncodedValue(key))); - } - - for (String key : Arrays.asList(Roundabout.KEY, RoadClassLink.KEY, GetOffBike.KEY, "car_access", "bike_access")) { - if (requestedPathDetails.contains(key) && evl.hasEncodedValue(key)) - builders.add(new BooleanDetails(key, evl.getBooleanEncodedValue(key))); - } - - for (String key : Arrays.asList(RoadClass.KEY, RoadEnvironment.KEY, Surface.KEY, Smoothness.KEY, RoadAccess.KEY, - BikeNetwork.KEY, FootNetwork.KEY, Toll.KEY, TrackType.KEY, Hazmat.KEY, HazmatTunnel.KEY, - HazmatWater.KEY, Country.KEY)) { - if (requestedPathDetails.contains(key) && evl.hasEncodedValue(key)) - builders.add(new EnumDetails<>(key, evl.getEnumEncodedValue(key, Enum.class))); - } - - for (String key : Arrays.asList(MtbRating.KEY, HikeRating.KEY, HorseRating.KEY, Lanes.KEY)) { - if (requestedPathDetails.contains(key) && evl.hasEncodedValue(key)) - builders.add(new IntDetails(key, evl.getIntEncodedValue(key))); + for (String pathDetail : requestedPathDetails) { + if (!evl.hasEncodedValue(pathDetail)) continue; // path details like "time" won't be found + + EncodedValue ev = evl.getEncodedValue(pathDetail, EncodedValue.class); + if (ev instanceof DecimalEncodedValue) + builders.add(new DecimalDetails(pathDetail, (DecimalEncodedValue) ev)); + else if (ev instanceof BooleanEncodedValue) + builders.add(new BooleanDetails(pathDetail, (BooleanEncodedValue) ev)); + else if (ev instanceof EnumEncodedValue) + builders.add(new EnumDetails<>(pathDetail, (EnumEncodedValue) ev)); + else if (ev instanceof StringEncodedValue) + builders.add(new StringDetails(pathDetail, (StringEncodedValue) ev)); + else if (ev instanceof IntEncodedValue) + builders.add(new IntDetails(pathDetail, (IntEncodedValue) ev)); + else throw new IllegalArgumentException("unknown EncodedValue class " + ev.getClass().getName()); } if (requestedPathDetails.size() != builders.size()) { From 0ddded8d6d3c5bc311fe72cc4460a8bae0cb70fb Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 3 Jun 2022 09:44:05 +0200 Subject: [PATCH 031/389] Fix: Put back block_private and block_fords for racingbike, this got lost in #2561 --- .../routing/util/RacingBikeTagParser.java | 2 ++ .../util/AbstractBikeTagParserTester.java | 20 +++++++++++++++++-- .../util/Bike2WeightTagParserTest.java | 4 ++-- .../routing/util/BikeTagParserTest.java | 4 ++-- .../util/MountainBikeTagParserTest.java | 4 ++-- .../routing/util/RacingBikeTagParserTest.java | 4 ++-- 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java index 68b678fe698..c94a578f260 100644 --- a/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java @@ -45,6 +45,8 @@ public RacingBikeTagParser(EncodedValueLookup lookup, PMap properties) { lookup.getBooleanEncodedValue(Roundabout.KEY), lookup.hasEncodedValue(TurnCost.key("racingbike")) ? lookup.getDecimalEncodedValue(TurnCost.key("racingbike")) : null ); + blockPrivate(properties.getBool("block_private", true)); + blockFords(properties.getBool("block_fords", false)); } protected RacingBikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, diff --git a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java index 73078448b2c..35a6d243c68 100644 --- a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java @@ -23,6 +23,7 @@ import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; +import com.graphhopper.util.PMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -49,7 +50,7 @@ public void setUp() { encodingManager = createEncodingManager(); if (encodingManager.fetchEdgeEncoders().size() > 1) fail("currently we assume there is only one encoder per test"); - parser = createBikeTagParser(encodingManager); + parser = createBikeTagParser(encodingManager, new PMap("block_fords=true")); osmParsers = createOSMParsers(parser, encodingManager); roundaboutEnc = encodingManager.getBooleanEncodedValue(Roundabout.KEY); priorityEnc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(parser.getName(), "priority")); @@ -58,7 +59,7 @@ public void setUp() { protected abstract EncodingManager createEncodingManager(); - protected abstract BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup); + protected abstract BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup, PMap pMap); protected abstract OSMParsers createOSMParsers(BikeCommonTagParser parser, EncodedValueLookup lookup); @@ -495,4 +496,19 @@ public void testFerries() { way.setTag("foot", "yes"); assertTrue(parser.getAccess(way).canSkip()); } + + @Test + void privateAndFords() { + // defaults: do not block fords, block private + BikeCommonTagParser bike = createBikeTagParser(encodingManager, new PMap()); + assertFalse(bike.isBlockFords()); + assertTrue(bike.restrictedValues.contains("private")); + assertFalse(bike.intendedValues.contains("private")); + + // block fords, unblock private + bike = createBikeTagParser(encodingManager, new PMap("block_fords=true|block_private=false")); + assertTrue(bike.isBlockFords()); + assertFalse(bike.restrictedValues.contains("private")); + assertTrue(bike.intendedValues.contains("private")); + } } diff --git a/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java index bfb188d1b13..31fd7825cbc 100644 --- a/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java @@ -42,8 +42,8 @@ protected EncodingManager createEncodingManager() { } @Override - protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup) { - Bike2WeightTagParser parser = new Bike2WeightTagParser(lookup, new PMap("block_fords=true")); + protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup, PMap pMap) { + Bike2WeightTagParser parser = new Bike2WeightTagParser(lookup, pMap); parser.init(new DateRangeParser()); return parser; } diff --git a/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java index d0709df488b..96274c7daaa 100644 --- a/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java @@ -47,8 +47,8 @@ protected EncodingManager createEncodingManager() { } @Override - protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup) { - BikeTagParser parser = new BikeTagParser(lookup, new PMap("block_fords=true")); + protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup, PMap pMap) { + BikeTagParser parser = new BikeTagParser(lookup, pMap); parser.init(new DateRangeParser()); return parser; } diff --git a/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java index 9a4059fb9fb..e366ee00edf 100644 --- a/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java @@ -41,8 +41,8 @@ protected EncodingManager createEncodingManager() { } @Override - protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup) { - MountainBikeTagParser parser = new MountainBikeTagParser(lookup, new PMap("block_fords=true")); + protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup, PMap pMap) { + MountainBikeTagParser parser = new MountainBikeTagParser(lookup, pMap); parser.init(new DateRangeParser()); return parser; } diff --git a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java index cba2ce60dfb..13fd75b9c4b 100644 --- a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java @@ -44,8 +44,8 @@ protected EncodingManager createEncodingManager() { } @Override - protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup) { - RacingBikeTagParser parser = new RacingBikeTagParser(lookup, new PMap("block_fords=true")); + protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup, PMap pMap) { + RacingBikeTagParser parser = new RacingBikeTagParser(lookup, pMap); parser.init(new DateRangeParser()); return parser; } From 4da856b10e2bf13c431773be20aec23349ee455f Mon Sep 17 00:00:00 2001 From: Andi Date: Fri, 3 Jun 2022 13:02:21 +0200 Subject: [PATCH 032/389] Make motor vehicle and hgv properties configurable for roads encoder (#2594) --- .../graphhopper/routing/util/DefaultFlagEncoderFactory.java | 2 +- .../java/com/graphhopper/routing/util/FlagEncoders.java | 4 ++-- .../com/graphhopper/routing/util/VehicleEncodedValues.java | 6 ++++-- .../test/java/com/graphhopper/util/InstructionListTest.java | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java index 517b91f36ea..4bbc8526cdf 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java @@ -28,7 +28,7 @@ public class DefaultFlagEncoderFactory implements FlagEncoderFactory { @Override public FlagEncoder createFlagEncoder(String name, PMap configuration) { if (name.equals(ROADS)) - return FlagEncoders.createRoads(); + return FlagEncoders.createRoads(configuration); if (name.equals(CAR)) return FlagEncoders.createCar(configuration); diff --git a/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java b/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java index 5be8e989ac4..4437e9f1056 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java +++ b/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java @@ -79,7 +79,7 @@ public static FlagEncoder createMountainBike(PMap properties) { return VehicleEncodedValues.mountainbike(properties); } - public static FlagEncoder createRoads() { - return VehicleEncodedValues.roads(); + public static FlagEncoder createRoads(PMap properties) { + return VehicleEncodedValues.roads(properties); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index 8ef954dc7fa..868d781f210 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -135,7 +135,7 @@ public static VehicleEncodedValues motorcycle(PMap properties) { return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, curvatureEnc, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), true, false); } - public static VehicleEncodedValues roads() { + public static VehicleEncodedValues roads(PMap properties) { String name = "roads"; int speedBits = 7; double speedFactor = 2; @@ -144,7 +144,9 @@ public static VehicleEncodedValues roads() { BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, speedEnc.getNextStorableValue(ROADS_MAX_SPEED), true, false); + boolean isMotorVehicle = properties.getBool("is_motor_vehicle", true); + boolean isHGV = properties.getBool("is_hgv", false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, speedEnc.getNextStorableValue(ROADS_MAX_SPEED), isMotorVehicle, isHGV); } public VehicleEncodedValues(String name, BooleanEncodedValue accessEnc, DecimalEncodedValue avgSpeedEnc, diff --git a/core/src/test/java/com/graphhopper/util/InstructionListTest.java b/core/src/test/java/com/graphhopper/util/InstructionListTest.java index be889df036d..68be9c18bc8 100644 --- a/core/src/test/java/com/graphhopper/util/InstructionListTest.java +++ b/core/src/test/java/com/graphhopper/util/InstructionListTest.java @@ -424,7 +424,7 @@ public void testInstructionIfSlightTurnForCustomProfile() { @Test public void testInstructionWithHighlyCustomProfileWithRoadsBase() { - FlagEncoder roads = FlagEncoders.createRoads(); + FlagEncoder roads = FlagEncoders.createRoads(new PMap()); EncodingManager tmpEM = EncodingManager.create(roads); EnumEncodedValue rcEV = tmpEM.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BaseGraph g = new BaseGraph.Builder(tmpEM).create(); From fb39266ce2ab2fa87eb11956d09bddf8cedee25b Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 7 Jun 2022 23:02:48 +0200 Subject: [PATCH 033/389] Disable edge+alt measurements, they take too long --- .../java/com/graphhopper/tools/Measurement.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tools/src/main/java/com/graphhopper/tools/Measurement.java b/tools/src/main/java/com/graphhopper/tools/Measurement.java index c836e91af3f..9d744cdd888 100644 --- a/tools/src/main/java/com/graphhopper/tools/Measurement.java +++ b/tools/src/main/java/com/graphhopper/tools/Measurement.java @@ -202,9 +202,10 @@ protected void importOSM() { measureRouting(hopper, new QuerySettings("routing_edge", count / 20, isCH, isLM). withInstructions().edgeBased()); // unfortunately alt routes are so slow that we cannot really afford many iterations - measureRouting(hopper, new QuerySettings("routing_edge_alt", count / 1000, isCH, isLM). - edgeBased().alternative() - ); + // actually it is just too slow so we skip it for now +// measureRouting(hopper, new QuerySettings("routing_edge_alt", count / 1000, isCH, isLM). +// edgeBased().alternative() +// ); } if (!blockAreaStr.isEmpty()) measureRouting(hopper, new QuerySettings("routing_block_area", count / 20, isCH, isLM). @@ -224,8 +225,9 @@ protected void importOSM() { if (args.getBool("measurement.lm.edge_based", encoder.supportsTurnCosts())) { measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_edge", count / 20, isCH, isLM). withInstructions().activeLandmarks(activeLMCount).edgeBased()); - measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_alt_edge", count / 1000, isCH, isLM). - activeLandmarks(activeLMCount).edgeBased().alternative()); + // this is too slow +// measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_alt_edge", count / 1000, isCH, isLM). +// activeLandmarks(activeLMCount).edgeBased().alternative()); } }); @@ -245,7 +247,7 @@ protected void importOSM() { gcAndWait(); measureRouting(hopper, new QuerySettings("routingCH", count, isCH, isLM). withInstructions().sod()); - measureRouting(hopper, new QuerySettings("routingCH_alt", count / 10, isCH, isLM). + measureRouting(hopper, new QuerySettings("routingCH_alt", count / 100, isCH, isLM). withInstructions().sod().alternative()); measureRouting(hopper, new QuerySettings("routingCH_with_hints", count, isCH, isLM). withInstructions().sod().withPointHints()); @@ -265,7 +267,7 @@ protected void importOSM() { if (edgeBasedCH != null) { measureRouting(hopper, new QuerySettings("routingCH_edge", count, isCH, isLM). edgeBased().withInstructions()); - measureRouting(hopper, new QuerySettings("routingCH_edge_alt", count / 10, isCH, isLM). + measureRouting(hopper, new QuerySettings("routingCH_edge_alt", count / 100, isCH, isLM). edgeBased().withInstructions().alternative()); measureRouting(hopper, new QuerySettings("routingCH_edge_no_instr", count, isCH, isLM). edgeBased()); From 0709eaf6f78e3e47b0f6d35312cf6c8ea62ec23f Mon Sep 17 00:00:00 2001 From: Andi Date: Wed, 8 Jun 2022 20:36:47 +0200 Subject: [PATCH 034/389] Use separate deleted flag for SPTEntry, prevent exception when calculating routes with non-feasible approximator (#2600) Also revert epsilon=0.9 'fix' in map matching now that we know what is going on --- .../com/graphhopper/routing/SPTEntry.java | 5 +- .../routing/AStarBidirectionTest.java | 118 ++++++++++++++++++ .../com/graphhopper/matching/MapMatching.java | 2 - 3 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java diff --git a/core/src/main/java/com/graphhopper/routing/SPTEntry.java b/core/src/main/java/com/graphhopper/routing/SPTEntry.java index 7705a452601..db0871c2b73 100644 --- a/core/src/main/java/com/graphhopper/routing/SPTEntry.java +++ b/core/src/main/java/com/graphhopper/routing/SPTEntry.java @@ -30,6 +30,7 @@ public class SPTEntry implements Comparable { public int adjNode; public double weight; public SPTEntry parent; + public boolean deleted; public SPTEntry(int node, double weight) { this(EdgeIterator.NO_EDGE, node, weight, null); @@ -43,11 +44,11 @@ public SPTEntry(int edgeId, int adjNode, double weight, SPTEntry parent) { } public void setDeleted() { - adjNode = Integer.MIN_VALUE; + deleted = true; } public boolean isDeleted() { - return adjNode == Integer.MIN_VALUE; + return deleted; } /** diff --git a/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java b/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java new file mode 100644 index 00000000000..35952874b6d --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java @@ -0,0 +1,118 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing; + +import com.carrotsearch.hppc.IntArrayList; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.util.FlagEncoders; +import com.graphhopper.routing.util.TraversalMode; +import com.graphhopper.routing.weighting.ShortestWeighting; +import com.graphhopper.routing.weighting.WeightApproximator; +import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.storage.BaseGraph; +import com.graphhopper.util.GHUtility; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class AStarBidirectionTest { + @Test + void infeasibleApproximator_noException() { + FlagEncoder encoder = FlagEncoders.createCar(); + EncodingManager em = EncodingManager.create(encoder); + // An infeasible approximator means that the weight of the entries polled from the priority queue does not + // increase monotonically. Here we deliberately choose the approximations and edge distances such that the fwd + // search first explores the 0-1-2-3-4 branch, then polls node 10 which causes an update for node 2, but the + // search stops before node 2 is polled again such that nodes 3 and 4 cannot be updated, because the bwd search + // already arrived and the stopping criterion is fulfilled. Node 2 still remains in the queue at this point. + // This means the resulting path contains the invalid search tree branch 2(old)-3-4 and is not the shortest path, + // because the SPTEntry for node 3 still points to the outdated/deleted entry for node 2. + // We do not expect an exception, though, because for an infeasible approximator we cannot expect optimal paths. + // 0-1----2-3-4----5-6-7-8-9 + // \ / + // 10 + BaseGraph graph = new BaseGraph.Builder(em).create(); + GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(100)); + // the distance 1-2 is longer than 1-10-2 + // we deliberately use 2-1 as storage direction, even though the edge points from 1 to 2, because this way + // we can reproduce the 'Calculating time should not require to read speed from edge in wrong direction' error + // from #2600 + graph.edge(2, 1).setDistance(300).set(encoder.getAccessEnc(), false, true).set(encoder.getAverageSpeedEnc(), 60); + GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(100)); + GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(100)); + // distance 4-5 is very long + GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(10_000)); + GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(100)); + GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 7).setDistance(100)); + GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 8).setDistance(100)); + GHUtility.setSpeed(60, true, false, encoder, graph.edge(8, 9).setDistance(100)); + GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 10).setDistance(100)); + GHUtility.setSpeed(60, true, false, encoder, graph.edge(10, 2).setDistance(100)); + + Weighting weighting = new ShortestWeighting(encoder); + AStarBidirection algo = new AStarBidirection(graph, weighting, TraversalMode.NODE_BASED); + algo.setApproximation(new InfeasibleApproximator()); + Path path = algo.calcPath(0, 9); + // the path is not the shortest path, but the suboptimal one we get for this approximator + assertEquals(11_000, path.getDistance()); + assertEquals(IntArrayList.from(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), path.calcNodes()); + + // this returns the correct path + Dijkstra dijkstra = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED); + Path optimalPath = dijkstra.calcPath(0, 9); + assertEquals(10_900, optimalPath.getDistance()); + assertEquals(IntArrayList.from(0, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9), optimalPath.calcNodes()); + } + + private static class InfeasibleApproximator implements WeightApproximator { + int to; + + @Override + public double approximate(int currentNode) { + // we only consider the fwd search (going to 9). for the bwd search we simply approximate 0 + if (to != 9) + return 0; + // we use a super-simple approximator that just returns 0 for all nodes but one. for node 10 we use + // a 'better' approximation that is still off. it is certainly not an over-approximation, because of the + // long edge 4-5, but it makes the approximator infeasible, because + // d(10, 2) + h(2) = 100 + 0 = 100 and h(10) = 1000, so it does not hold that d(10, 2) + h(2) >= h(10) + if (currentNode == 10) + return 1000; + else + return 0; + } + + @Override + public void setTo(int to) { + this.to = to; + } + + @Override + public WeightApproximator reverse() { + // the reverse approximator is a different object (different 'to' field), but runs the same code + return new InfeasibleApproximator(); + } + + @Override + public double getSlack() { + return 0; + } + } +} \ No newline at end of file diff --git a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java index caa3f1b170f..44d784ddd34 100644 --- a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java +++ b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java @@ -400,8 +400,6 @@ protected void initCollections(int size) { }; int activeLM = Math.min(8, landmarks.getLandmarkCount()); LMApproximator lmApproximator = LMApproximator.forLandmarks(queryGraph, landmarks, activeLM); - // todo: we use 0.9, because of some LM bug we do not understand yet - lmApproximator.setEpsilon(0.9); algo.setApproximation(lmApproximator); algo.setMaxVisitedNodes(maxVisitedNodes); router = algo; From 911be20abf3b7905f0cfd531160a3e8463009838 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 8 Jun 2022 22:13:43 +0200 Subject: [PATCH 035/389] LMApproximator: Align variable names with equation numbers --- .../com/graphhopper/routing/lm/LMApproximator.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/lm/LMApproximator.java b/core/src/main/java/com/graphhopper/routing/lm/LMApproximator.java index 4a6ace35c63..73fc83f3438 100644 --- a/core/src/main/java/com/graphhopper/routing/lm/LMApproximator.java +++ b/core/src/main/java/com/graphhopper/routing/lm/LMApproximator.java @@ -153,16 +153,14 @@ private int approximateForLandmark(int i, int v) { // // ...and we can get the right-hand sides of III) and IV) by multiplying those of II) and I) by -1. - int rhs1Int = weightsFromActiveLandmarksToT[i] - lms.getFromWeight(activeLandmarkIndices[i], v); - int rhs2Int = lms.getToWeight(activeLandmarkIndices[i], v) - weightsFromTToActiveLandmarks[i]; + int rhs1Int = lms.getToWeight(activeLandmarkIndices[i], v) - weightsFromTToActiveLandmarks[i]; + int rhs2Int = weightsFromActiveLandmarksToT[i] - lms.getFromWeight(activeLandmarkIndices[i], v); - int resultInt; if (reverse) { - resultInt = Math.max(-rhs2Int, -rhs1Int); - } else { - resultInt = Math.max(rhs1Int, rhs2Int); + rhs1Int *= -1; + rhs2Int *= -1; } - return resultInt; + return Math.max(rhs1Int, rhs2Int); } @Override From cc874c050eeb7b526e6e80514f85f71ea2ae745d Mon Sep 17 00:00:00 2001 From: Robin Date: Sat, 11 Jun 2022 09:39:22 +0200 Subject: [PATCH 036/389] Log map-matching took value in ms instead of seconds (#2591) Co-authored-by: Andi --- core/src/main/java/com/graphhopper/util/StopWatch.java | 7 +++++++ .../graphhopper/jackson/ResponsePathSerializer.java | 2 +- .../com/graphhopper/resources/MapMatchingResource.java | 10 +++++----- .../java/com/graphhopper/resources/RouteResource.java | 8 ++++---- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/graphhopper/util/StopWatch.java b/core/src/main/java/com/graphhopper/util/StopWatch.java index e4baa7bdb7b..23a6cd99bd7 100644 --- a/core/src/main/java/com/graphhopper/util/StopWatch.java +++ b/core/src/main/java/com/graphhopper/util/StopWatch.java @@ -81,6 +81,13 @@ public long getMillis() { return elapsedNanos / 1_000_000; } + /** + * returns the elapsed time in ms but includes the fraction as well to get a precise value + */ + public double getMillisDouble() { + return elapsedNanos / 1_000_000.0; + } + public long getNanos() { return elapsedNanos; } diff --git a/web-api/src/main/java/com/graphhopper/jackson/ResponsePathSerializer.java b/web-api/src/main/java/com/graphhopper/jackson/ResponsePathSerializer.java index 36337355e55..7c1021be73f 100644 --- a/web-api/src/main/java/com/graphhopper/jackson/ResponsePathSerializer.java +++ b/web-api/src/main/java/com/graphhopper/jackson/ResponsePathSerializer.java @@ -86,7 +86,7 @@ private static void encodeNumber(StringBuilder sb, int num) { sb.append((char) (num)); } - public static ObjectNode jsonObject(GHResponse ghRsp, boolean enableInstructions, boolean calcPoints, boolean enableElevation, boolean pointsEncoded, float took) { + public static ObjectNode jsonObject(GHResponse ghRsp, boolean enableInstructions, boolean calcPoints, boolean enableElevation, boolean pointsEncoded, double took) { ObjectNode json = JsonNodeFactory.instance.objectNode(); json.putPOJO("hints", ghRsp.getHints().toMap()); final ObjectNode info = json.putObject("info"); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java index f77482dd71b..e9c819df69d 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java @@ -118,15 +118,15 @@ public Response match( MatchResult matchResult = matching.match(measurements); // TODO: Request logging and timing should perhaps be done somewhere outside - float took = sw.stop().getSeconds(); + double took = sw.stop().getMillisDouble(); String infoStr = request.getRemoteAddr() + " " + request.getLocale() + " " + request.getHeader("User-Agent"); - String logStr = request.getQueryString() + ", " + infoStr + ", took:" + took + "s, entries:" + measurements.size() + + String logStr = request.getQueryString() + ", " + infoStr + ", took:" + String.format("%.1f", took) + "ms, entries:" + measurements.size() + ", profile: " + profile + ", " + weightingVehicleLogStr; logger.info(logStr); if ("extended_json".equals(outType)) { return Response.ok(convertToTree(matchResult, enableElevation, pointsEncoded)). - header("X-GH-Took", "" + Math.round(took * 1000)). + header("X-GH-Took", "" + Math.round(took)). build(); } else { Translation tr = trMap.getWithFallBack(Helper.getLocale(localeStr)); @@ -150,7 +150,7 @@ public Response match( .map(Date::getTime) .orElse(System.currentTimeMillis()); return Response.ok(GpxConversions.createGPX(rsp.getBest().getInstructions(), gpx.trk.get(0).name != null ? gpx.trk.get(0).name : "", time, enableElevation, withRoute, withTrack, false, Constants.VERSION, tr), "application/gpx+xml"). - header("X-GH-Took", "" + Math.round(took * 1000)). + header("X-GH-Took", "" + Math.round(took)). build(); } else { ObjectNode map = ResponsePathSerializer.jsonObject(rsp, instructions, calcPoints, enableElevation, pointsEncoded, took); @@ -171,7 +171,7 @@ public Response match( map.putPOJO("traversal_keys", traversalKeylist); } return Response.ok(map). - header("X-GH-Took", "" + Math.round(took * 1000)). + header("X-GH-Took", "" + Math.round(took)). build(); } } diff --git a/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java b/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java index d280486ad9b..a9b71a152f6 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java @@ -129,10 +129,10 @@ public Response doGet( GHResponse ghResponse = graphHopper.route(request); - long took = sw.stop().getNanos() / 1_000_000; + double took = sw.stop().getMillisDouble(); String infoStr = httpReq.getRemoteAddr() + " " + httpReq.getLocale() + " " + httpReq.getHeader("User-Agent"); String logStr = httpReq.getQueryString() + " " + infoStr + " " + points + ", took: " - + String.format("%.1f", (double) took) + "ms, algo: " + algoStr + ", profile: " + profileName + ", " + weightingVehicleLogStr; + + String.format("%.1f", took) + "ms, algo: " + algoStr + ", profile: " + profileName + ", " + weightingVehicleLogStr; if (ghResponse.hasErrors()) { logger.error(logStr + ", errors:" + ghResponse.getErrors()); @@ -180,14 +180,14 @@ public Response doPost(@NotNull GHRequest request, @Context HttpServletRequest h boolean calcPoints = request.getHints().getBool(CALC_POINTS, true); boolean pointsEncoded = request.getHints().getBool("points_encoded", true); - long took = sw.stop().getNanos() / 1_000_000; + double took = sw.stop().getMillisDouble(); String infoStr = httpReq.getRemoteAddr() + " " + httpReq.getLocale() + " " + httpReq.getHeader("User-Agent"); String queryString = httpReq.getQueryString() == null ? "" : (httpReq.getQueryString() + " "); // todo: vehicle/weighting will always be empty at this point... String weightingVehicleLogStr = "weighting: " + request.getHints().getString("weighting", "") + ", vehicle: " + request.getHints().getString("vehicle", ""); String logStr = queryString + infoStr + " " + request.getPoints().size() + ", took: " - + String.format("%.1f", (double) took) + " ms, algo: " + request.getAlgorithm() + ", profile: " + request.getProfile() + + String.format("%.1f", took) + " ms, algo: " + request.getAlgorithm() + ", profile: " + request.getProfile() + ", " + weightingVehicleLogStr + ", custom_model: " + request.getCustomModel(); From 284acd194017f812bbb2c42c1afa707653eada9b Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 13 Jun 2022 14:13:14 +0200 Subject: [PATCH 037/389] rename StringIndex to EdgeKVStorage in preparation for #2597 --- .../{StringIndex.java => EdgeKVStorage.java} | 6 ++-- .../com/graphhopper/storage/BaseGraph.java | 30 ++++++++-------- ...gIndexTest.java => EdgeKVStorageTest.java} | 36 +++++++++---------- 3 files changed, 36 insertions(+), 36 deletions(-) rename core/src/main/java/com/graphhopper/search/{StringIndex.java => EdgeKVStorage.java} (98%) rename core/src/test/java/com/graphhopper/search/{StringIndexTest.java => EdgeKVStorageTest.java} (90%) diff --git a/core/src/main/java/com/graphhopper/search/StringIndex.java b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java similarity index 98% rename from core/src/main/java/com/graphhopper/search/StringIndex.java rename to core/src/main/java/com/graphhopper/search/EdgeKVStorage.java index 1b5a720285d..f3fe98da3cf 100644 --- a/core/src/main/java/com/graphhopper/search/StringIndex.java +++ b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java @@ -29,7 +29,7 @@ /** * @author Peter Karich */ -public class StringIndex { +public class EdgeKVStorage { private static final long EMPTY_POINTER = 0, START_POINTER = 1; // Store the key index in 2 bytes. Use negative values for marking the value as duplicate. static final int MAX_UNIQUE_KEYS = (1 << 15); @@ -55,7 +55,7 @@ public class StringIndex { /** * Specify a larger cacheSize to reduce disk usage. Note that this increases the memory usage of this object. */ - public StringIndex(Directory dir, final int cacheSize, final int segmentSize) { + public EdgeKVStorage(Directory dir, final int cacheSize, final int segmentSize) { keys = dir.create("string_index_keys", segmentSize); vals = dir.create("string_index_vals", segmentSize); smallCache = new LinkedHashMap(cacheSize, 0.75f, true) { @@ -66,7 +66,7 @@ protected boolean removeEldestEntry(Map.Entry entry) { }; } - public StringIndex create(long initBytes) { + public EdgeKVStorage create(long initBytes) { keys.create(initBytes); vals.create(initBytes); // add special empty case to have a reliable duplicate detection via negative keyIndex diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index e33d3c6553b..d224144b60a 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -22,7 +22,7 @@ import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.search.StringIndex; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; @@ -46,7 +46,7 @@ public class BaseGraph implements Graph, Closeable { private final static String STRING_IDX_NAME_KEY = "name"; final BaseGraphNodesAndEdges store; final NodeAccess nodeAccess; - final StringIndex stringIndex; + final EdgeKVStorage edgeKVStorage; // can be null if turn costs are not supported final TurnCostStorage turnCostStorage; final BitUtil bitUtil; @@ -62,7 +62,7 @@ public BaseGraph(Directory dir, int intsForFlags, boolean withElevation, boolean this.dir = dir; this.bitUtil = BitUtil.LITTLE; this.wayGeometry = dir.create("geometry", segmentSize); - this.stringIndex = new StringIndex(dir, 1000, segmentSize); + this.edgeKVStorage = new EdgeKVStorage(dir, 1000, segmentSize); this.store = new BaseGraphNodesAndEdges(dir, intsForFlags, withElevation, withTurnCosts, segmentSize); this.nodeAccess = new GHNodeAccess(store); this.segmentSize = segmentSize; @@ -159,7 +159,7 @@ public BaseGraph create(long initSize) { initSize = Math.min(initSize, 2000); wayGeometry.create(initSize); - stringIndex.create(initSize); + edgeKVStorage.create(initSize); if (supportsTurnCosts()) { turnCostStorage.create(initSize); } @@ -171,7 +171,7 @@ public BaseGraph create(long initSize) { String toDetailsString() { return store.toDetailsString() + ", " - + "name:(" + stringIndex.getCapacity() / Helper.MB + "MB), " + + "name:(" + edgeKVStorage.getCapacity() / Helper.MB + "MB), " + "geo:" + nf(maxGeoRef) + "(" + wayGeometry.getCapacity() / Helper.MB + "MB)"; } @@ -184,8 +184,8 @@ void flushAndCloseGeometryAndNameStorage() { wayGeometry.flush(); wayGeometry.close(); - stringIndex.flush(); - stringIndex.close(); + edgeKVStorage.flush(); + edgeKVStorage.close(); } public void flush() { @@ -194,8 +194,8 @@ public void flush() { wayGeometry.flush(); } - if (!stringIndex.isClosed()) - stringIndex.flush(); + if (!edgeKVStorage.isClosed()) + edgeKVStorage.flush(); store.flush(); if (supportsTurnCosts()) { @@ -207,8 +207,8 @@ public void flush() { public void close() { if (!wayGeometry.isClosed()) wayGeometry.close(); - if (!stringIndex.isClosed()) - stringIndex.close(); + if (!edgeKVStorage.isClosed()) + edgeKVStorage.close(); store.close(); if (supportsTurnCosts()) { turnCostStorage.close(); @@ -216,7 +216,7 @@ public void close() { } public long getCapacity() { - return store.getCapacity() + stringIndex.getCapacity() + return store.getCapacity() + edgeKVStorage.getCapacity() + wayGeometry.getCapacity() + (supportsTurnCosts() ? turnCostStorage.getCapacity() : 0); } @@ -233,7 +233,7 @@ public void loadExisting() { if (!wayGeometry.loadExisting()) throw new IllegalStateException("Cannot load geometry. corrupt file or directory? " + dir); - if (!stringIndex.loadExisting()) + if (!edgeKVStorage.loadExisting()) throw new IllegalStateException("Cannot load name index. corrupt file or directory? " + dir); if (supportsTurnCosts() && !turnCostStorage.loadExisting()) @@ -460,7 +460,7 @@ static int getPointListLength(int pillarNodes, FetchMode mode) { } private void setName(long edgePointer, String name) { - int stringIndexRef = (int) stringIndex.add(Collections.singletonMap(STRING_IDX_NAME_KEY, name)); + int stringIndexRef = (int) edgeKVStorage.add(Collections.singletonMap(STRING_IDX_NAME_KEY, name)); if (stringIndexRef < 0) throw new IllegalStateException("Too many names are stored, currently limited to int pointer"); store.setNameRef(edgePointer, stringIndexRef); @@ -956,7 +956,7 @@ public int getReverseEdgeKey() { @Override public String getName() { int stringIndexRef = store.getNameRef(edgePointer); - String name = baseGraph.stringIndex.get(stringIndexRef, STRING_IDX_NAME_KEY); + String name = baseGraph.edgeKVStorage.get(stringIndexRef, STRING_IDX_NAME_KEY); // preserve backward compatibility (returns null if not explicitly set) return name == null ? "" : name; } diff --git a/core/src/test/java/com/graphhopper/search/StringIndexTest.java b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java similarity index 90% rename from core/src/test/java/com/graphhopper/search/StringIndexTest.java rename to core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java index 7c983a436e5..2d83fb093ac 100644 --- a/core/src/test/java/com/graphhopper/search/StringIndexTest.java +++ b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java @@ -9,13 +9,13 @@ import java.io.File; import java.util.*; -import static com.graphhopper.search.StringIndex.MAX_UNIQUE_KEYS; +import static com.graphhopper.search.EdgeKVStorage.MAX_UNIQUE_KEYS; import static org.junit.jupiter.api.Assertions.*; -public class StringIndexTest { +public class EdgeKVStorageTest { - private StringIndex create() { - return new StringIndex(new RAMDirectory(), 1000, -1).create(1000); + private EdgeKVStorage create() { + return new EdgeKVStorage(new RAMDirectory(), 1000, -1).create(1000); } Map createMap(String... strings) { @@ -30,7 +30,7 @@ Map createMap(String... strings) { @Test public void putSame() { - StringIndex index = create(); + EdgeKVStorage index = create(); long aPointer = index.add(createMap("a", "same name", "b", "same name")); assertNull(index.get(aPointer, "")); @@ -45,7 +45,7 @@ public void putSame() { @Test public void putAB() { - StringIndex index = create(); + EdgeKVStorage index = create(); long aPointer = index.add(createMap("a", "a name", "b", "b name")); assertNull(index.get(aPointer, "")); @@ -55,7 +55,7 @@ public void putAB() { @Test public void putEmpty() { - StringIndex index = create(); + EdgeKVStorage index = create(); assertEquals(1, index.add(createMap("", ""))); assertEquals(5, index.add(createMap("", null))); assertEquals(9, index.add(createMap(null, null))); @@ -66,7 +66,7 @@ public void putEmpty() { @Test public void putMany() { - StringIndex index = create(); + EdgeKVStorage index = create(); long aPointer = 0, tmpPointer = 0; for (int i = 0; i < 10000; i++) { @@ -85,7 +85,7 @@ public void putMany() { @Test public void putManyKeys() { - StringIndex index = create(); + EdgeKVStorage index = create(); // one key is already stored => empty key for (int i = 1; i < MAX_UNIQUE_KEYS; i++) { index.add(createMap("a" + i, "a name")); @@ -99,7 +99,7 @@ public void putManyKeys() { @Test public void putDuplicate() { - StringIndex index = create(); + EdgeKVStorage index = create(); long aPointer = index.add(createMap("a", "longer name", "b", "longer name")); long bPointer = index.add(createMap("c", "longer other name")); // value storage: 1 byte for count, 2 bytes for keyIndex and 4 bytes for delta of dup_marker and 3 bytes (keyIndex + length for "longer name") @@ -124,7 +124,7 @@ public void putDuplicate() { @Test public void testNoErrorOnLargeName() { - StringIndex index = create(); + EdgeKVStorage index = create(); // 127 => bytes.length == 254 String str = ""; for (int i = 0; i < 127; i++) { @@ -136,7 +136,7 @@ public void testNoErrorOnLargeName() { @Test public void testTooLongNameNoError() { - StringIndex index = create(); + EdgeKVStorage index = create(); index.throwExceptionIfTooLong = true; try { index.add(createMap("", "Бухарестская улица (http://ru.wikipedia.org/wiki/%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))")); @@ -164,12 +164,12 @@ public void testFlush() { String location = "./target/stringindex-store"; Helper.removeDir(new File(location)); - StringIndex index = new StringIndex(new RAMDirectory(location, true).create(), 1000, -1).create(1000); + EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create(), 1000, -1).create(1000); long pointer = index.add(createMap("", "test")); index.flush(); index.close(); - index = new StringIndex(new RAMDirectory(location, true), 1000, -1); + index = new EdgeKVStorage(new RAMDirectory(location, true), 1000, -1); assertTrue(index.loadExisting()); assertEquals("test", index.get(pointer, "")); // make sure bytePointer is correctly set after loadExisting @@ -185,7 +185,7 @@ public void testLoadKeys() { String location = "./target/stringindex-store"; Helper.removeDir(new File(location)); - StringIndex index = new StringIndex(new RAMDirectory(location, true).create(), 1000, -1).create(1000); + EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create(), 1000, -1).create(1000); long pointerA = index.add(createMap("c", "test value")); assertEquals(2, index.getKeys().size()); long pointerB = index.add(createMap("a", "value", "b", "another value")); @@ -194,7 +194,7 @@ public void testLoadKeys() { index.flush(); index.close(); - index = new StringIndex(new RAMDirectory(location, true), 1000, -1); + index = new EdgeKVStorage(new RAMDirectory(location, true), 1000, -1); assertTrue(index.loadExisting()); assertEquals("[, c, a, b]", index.getKeys().toString()); assertEquals("test value", index.get(pointerA, "c")); @@ -211,7 +211,7 @@ public void testLoadKeys() { @Test public void testEmptyKey() { - StringIndex index = create(); + EdgeKVStorage index = create(); long pointerA = index.add(createMap("", "test value")); long pointerB = index.add(createMap("a", "value", "b", "another value")); @@ -226,7 +226,7 @@ public void testEmptyKey() { public void testRandom() { long seed = new Random().nextLong(); try { - StringIndex index = create(); + EdgeKVStorage index = create(); Random random = new Random(seed); List keys = createRandomList(random, "_key", 1000); List values = createRandomList(random, "_value", 5000); From eb7102b21f69a8d07cd52900b1d2fc3247f166e5 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 13 Jun 2022 17:57:30 +0200 Subject: [PATCH 038/389] windows does not need a separate documentation due to WSL (#2599) * windows does not need a separate documentation due to WSL * link to install steps directly --- docs/core/quickstart-from-source.md | 22 +++++++++------------- docs/core/windows-setup.md | 11 ----------- docs/index.md | 5 +++-- 3 files changed, 12 insertions(+), 26 deletions(-) delete mode 100644 docs/core/windows-setup.md diff --git a/docs/core/quickstart-from-source.md b/docs/core/quickstart-from-source.md index 1ff65f1cd1f..896a663456b 100644 --- a/docs/core/quickstart-from-source.md +++ b/docs/core/quickstart-from-source.md @@ -1,35 +1,31 @@ # GraphHopper - Quick Start Guide for Developers -[Watch this video](https://www.youtube.com/watch?v=HBVe_E5j0TM) for a simple introduction. - ## Try out -For a start which requires only the JRE have a look [here](../web/quickstart.md). -Windows users will need Cygwin - find more details [here](./windows-setup.md). +To build the GraphHopper jar from the Java sources you need to install `git` and [a recent JDK](https://adoptium.net). -To proceed install `git` and `openjdk8` or `openjdk11`. Get the a jdk from your package manager, -[AdoptOpenJDK](https://adoptopenjdk.net/) or [Red Hat](https://github.com/ojdkbuild/ojdkbuild/releases). +(For a simpler start consider the pre-built jar and the documentation [here](../web/quickstart.md)). -Then create the jar from sources via: +Now create the jar from sources via: ```bash -# first download some road data -wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf # now get the source code and create the jar in web/target git clone git://github.com/graphhopper/graphhopper.git cd graphhopper git checkout master # if you prefer a less moving branch you can use e.g. 4.x mvn clean install -DskipTests -# start GraphHopper +# start GraphHopper and before download the road data +wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf java -Ddw.graphhopper.datareader.file=berlin-latest.osm.pbf -jar web/target/graphhopper-web-*.jar server config-example.yml # This does mainly 3 things: # - it creates routable files for graphhopper in the folder graph-data (see the config.yml) -# - it creates data for a special routing algorithm to dramatically improve query speed. It skips this and the previous step if these files are already present. -# - it starts the web service to service the UI and also the many endpoints like /route +# - it creates data for a special routing algorithm to improve query speed. (this and the previous step is skipped, if the graph-data folder is already present) +# - it starts the web service to service the UI and endpoints like /route # After 'Server - Started' appears go to http://localhost:8989/ and you should see something similar to GraphHopper Maps: https://graphhopper.com/maps/ ``` -To use a different area make sure you use a different folder instead of graph-data or remove this. +To use a different geographical area make sure you use a different folder instead of graph-data or remove this +and download the appropriate PBF file. For larger maps you need to add some parameters to the JVM: `java -Xmx10g -Xms10g ...`. See [the deployment section](deploy.md) for more details. diff --git a/docs/core/windows-setup.md b/docs/core/windows-setup.md deleted file mode 100644 index 2ebd63877d9..00000000000 --- a/docs/core/windows-setup.md +++ /dev/null @@ -1,11 +0,0 @@ -# Windows Setup from Source - -Download [cygwin](http://www.cygwin.com/) and click on the setup where you need to select wget, git and unzip. - -Now you can choose to either [install GraphHopper](../web/quickstart.md) or if you plan to customize the source code [install it from source](./quickstart-from-source.md). - -After that graphhopper web should start. After this open [http://localhost:8989/](http://localhost:8989/) in your browser. - -### Troubleshooting - * Make sure you have the latest JDK installed and not only the JRE - * Using cygwin you might need to call java via /cygdrive/c/Programme/Java/jdk1.8.0_77/bin/java \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index c186a3ac6a7..8dbded05c2c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,7 +18,7 @@ For bugs see our contribute section below. ## Installation -Install the web demo 'GraphHopper Maps' with [this user installation guide](./web/quickstart.md) on your +Install the web demo 'GraphHopper Maps' with [this user installation guide](../README.md#installation) on your machine. This will also install a web API that can be used in many programming languages. * [Routing API](./web/api-doc.md): Documentation of the Web API to communicate with any GraphHopper server via http. @@ -79,7 +79,8 @@ See the necessary changes for modern iOS and GraphHopper 1.0 in [this pull reque #### Windows -Documentation about how to get an GraphHopper instance running on windows via cygwin is available [here](./core/windows-setup.md). +Install the Windows Subsystem for Linux (WSL) or cygwin and follow the +[normal installation steps](../README.md#installation). #### Eclipse From e61b7a0cb1711d082c7147f1dc71eb270c8f8387 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 15 Jun 2022 09:32:46 +0200 Subject: [PATCH 039/389] EdgeKVStorage: store more than Strings (#2597) * copied code and tests from byteindex branch * a bit more docu and tests * behaviour change: throw exception if string is too long and so cut string before storing way_name * renamed StringIndex -> EdgeKVStorage * more consistent: reject null values for all cases * include lost changes again * ensure same version of storage is used * changes from review * fix variable names for key handling * comments to javadoc * better 'compression' in case of identical map with byte[] array * throw exception earlier --- CHANGELOG.md | 1 + .../java/com/graphhopper/GraphHopper.java | 2 +- .../com/graphhopper/reader/osm/OSMReader.java | 3 +- .../com/graphhopper/search/EdgeKVStorage.java | 412 ++++++++++++------ .../com/graphhopper/storage/BaseGraph.java | 16 +- .../storage/GraphHopperStorage.java | 4 +- .../java/com/graphhopper/util/Constants.java | 4 +- .../graphhopper/search/EdgeKVStorageTest.java | 195 +++++++-- .../storage/AbstractGraphStorageTester.java | 2 +- .../java/com/graphhopper/util/Helper.java | 8 + 10 files changed, 455 insertions(+), 192 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 852bfdc172c..b981d1b18f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### 6.0 [not yet released] +- StringIndex is now EdgeKVStorage and can store e.g. byte arrays. String values needs to be limited to 255 bytes before storing them. See #2597 - the Matrix client changed and users have to adapt the usage, see #2587 - replaced car$access with car_access (and same for $average_speed and $priority) - don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index bfa74358071..99fae58918b 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -994,7 +994,7 @@ protected void postProcessing(boolean closeEarly) { if (closeEarly) { boolean includesCustomProfiles = profilesByName.values().stream().anyMatch(p -> p instanceof CustomProfile); if (!includesCustomProfiles) - // when there are custom profiles we must not close way geometry or StringIndex, because + // when there are custom profiles we must not close way geometry or EdgeKVStorage, because // they might be needed to evaluate the custom weightings for the following preparations ghStorage.flushAndCloseGeometryAndNameStorage(); } diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index a4893df8c18..76b7ff0aaf7 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -332,7 +332,8 @@ protected void addEdge(int fromIndex, int toIndex, PointList pointList, ReaderWa if (edgeFlags.isEmpty()) return; - String name = way.getTag("way_name", ""); + // the storage does not accept too long strings + String name = Helper.cutString(way.getTag("way_name", ""), 255); EdgeIteratorState edge = baseGraph.edge(fromIndex, toIndex).setDistance(distance).setFlags(edgeFlags).setName(name); // If the entire way is just the first and last point, do not waste space storing an empty way geometry diff --git a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java index f3fe98da3cf..4aeca75e415 100644 --- a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java +++ b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java @@ -25,42 +25,83 @@ import com.graphhopper.util.Helper; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; /** + * This class stores key-value pairs in an append-only manner. + * * @author Peter Karich */ public class EdgeKVStorage { + private static final long EMPTY_POINTER = 0, START_POINTER = 1; // Store the key index in 2 bytes. Use negative values for marking the value as duplicate. static final int MAX_UNIQUE_KEYS = (1 << 15); // Store string value as byte array and store the length into 1 byte private static final int MAX_LENGTH = (1 << 8) - 1; - boolean throwExceptionIfTooLong = false; + + // It stores the mapping of "key to index" in the keys DataAccess. E.g. if your first key is "some" then we will + // store the mapping "1->some" there (the 0th index is skipped on purpose). As this map is 'small' the keys + // DataAccess is only used for long term storage, i.e. only in loadExisting and flush. For add and getAll we use + // keyToIndex, indexToClass and indexToClass. private final DataAccess keys; - // storage layout per entry: - // 1 byte | 2 bytes | 1 byte | x | 2 bytes | 1 byte | x | 2 bytes (dup example) | 4 bytes | ... - // vals count| key_idx_0| val_length_0| val_0| key_idx_1| val_length_1| val_1| -key_idx_2 | delta_2 | key_idx_3 | val_length_3 | val_3 - // Drawback: we need to loop through the entries to get the start of val_x. - // Note, that we detect duplicate values via smallCache and then use the negative key index as 'duplicate' marker. - // We then store only the delta (signed int) instead the absolute unsigned long value to reduce memory usage when duplicate entries. + + // The storage layout in the vals DataAccess for one Map of key-value pairs. For example the map: + // map = new HashMap(); map.put("some", "value"); map.put("some2", "value2"); is added via the method add, then we store: + // 2 (the size of the Map, 1 byte) + // --- now the first key-value pair: + // 1 (the keys index for "some", 2 byte) + // 4 (the length of the bytes from "some") + // "some" (the bytes from "some") + // --- second key-value pair: + // 2 (the keys index for "some2") + // 5 (the length of the bytes from "some2") + // "some2" (the bytes from "some2") + + // So more generic: the values could be of dynamic length, fixed length like int or be duplicates: + // vals count (1 byte) + // --- 1. key-value pair (store String or byte[] with dynamic length) + // key_idx_0 (2 byte) + // val_length_0 (1 byte) + // val_0 (x bytes) + // --- 2. key-value pair (store int with fixed length) + // key_idx_1 (2 byte) + // int (4 byte) + // --- 3. key-value pair (store duplicate, then key is negative and the value is a pointer to the actual value (relative to the current pointer) + // -key_idx_2 (2 byte) + // delta_pointer_2 (4 byte) + // + // Note: + // 1. The key strings are limited to 32767 unique values (see MAX_UNIQUE_KEYS). A dynamic value has a maximum byte length of 255. + // 2. Every key can store values only of the same type + // 3. We need to loop through X entries to get the start val_x. + // 4. We detect duplicate values for byte[] and String values via smallCache and then use the negative key index as + // 'duplicate' marker. We then store only the delta (signed int) instead of the absolute unsigned long value to + // reduce memory usage when there are duplicate values. private final DataAccess vals; - // array.indexOf could be faster than hashmap.get if not too many keys or even sort keys and use binarySearch - private final Map keysInMem = new LinkedHashMap<>(); - private final List keyList = new ArrayList<>(); - private final Map smallCache; + private final Map keyToIndex = new HashMap<>(); + private final List> indexToClass = new ArrayList<>(); + private final List indexToKey = new ArrayList<>(); + private final Map smallCache; + private final BitUtil bitUtil = BitUtil.LITTLE; private long bytePointer = START_POINTER; private long lastEntryPointer = -1; - private Map lastEntryMap; + private Map lastEntryMap; + + public EdgeKVStorage(Directory dir) { + this(dir, 1000); + } /** * Specify a larger cacheSize to reduce disk usage. Note that this increases the memory usage of this object. */ - public EdgeKVStorage(Directory dir, final int cacheSize, final int segmentSize) { - keys = dir.create("string_index_keys", segmentSize); - vals = dir.create("string_index_vals", segmentSize); - smallCache = new LinkedHashMap(cacheSize, 0.75f, true) { + public EdgeKVStorage(Directory dir, final int cacheSize) { + keys = dir.create("edgekv_keys", 10 * 1024); + vals = dir.create("edgekv_vals"); + + smallCache = new LinkedHashMap(cacheSize, 0.75f, true) { @Override - protected boolean removeEldestEntry(Map.Entry entry) { + protected boolean removeEldestEntry(Map.Entry entry) { return size() > cacheSize; } }; @@ -70,20 +111,18 @@ public EdgeKVStorage create(long initBytes) { keys.create(initBytes); vals.create(initBytes); // add special empty case to have a reliable duplicate detection via negative keyIndex - keysInMem.put("", 0); - keyList.add(""); + keyToIndex.put("", 0); + indexToKey.add(""); + indexToClass.add(String.class); return this; } public boolean loadExisting() { if (vals.loadExisting()) { - if (!keys.loadExisting()) - throw new IllegalStateException("Loaded values but cannot load keys"); - int stringIndexKeysVersion = keys.getHeader(0); - int stringIndexValsVersion = vals.getHeader(0); - GHUtility.checkDAVersion(keys.getName(), Constants.VERSION_STRING_IDX, stringIndexKeysVersion); - GHUtility.checkDAVersion(vals.getName(), Constants.VERSION_STRING_IDX, stringIndexValsVersion); - bytePointer = BitUtil.LITTLE.combineIntsToLong(vals.getHeader(4), vals.getHeader(8)); + if (!keys.loadExisting()) throw new IllegalStateException("Loaded values but cannot load keys"); + bytePointer = bitUtil.combineIntsToLong(vals.getHeader(0), vals.getHeader(4)); + GHUtility.checkDAVersion(vals.getName(), Constants.VERSION_EDGEKV_STORAGE, vals.getHeader(8)); + GHUtility.checkDAVersion(keys.getName(), Constants.VERSION_EDGEKV_STORAGE, keys.getHeader(0)); // load keys into memory int count = keys.getShort(0); @@ -91,13 +130,19 @@ public boolean loadExisting() { for (int i = 0; i < count; i++) { int keyLength = keys.getShort(keyBytePointer); keyBytePointer += 2; - byte[] keyBytes = new byte[keyLength]; keys.getBytes(keyBytePointer, keyBytes, keyLength); String valueStr = new String(keyBytes, Helper.UTF_CS); - keysInMem.put(valueStr, keysInMem.size()); - keyList.add(valueStr); keyBytePointer += keyLength; + + keyToIndex.put(valueStr, keyToIndex.size()); + indexToKey.add(valueStr); + + int shortClassNameLength = 1; + byte[] classBytes = new byte[shortClassNameLength]; + keys.getBytes(keyBytePointer, classBytes, shortClassNameLength); + keyBytePointer += shortClassNameLength; + indexToClass.add(shortNameToClass(new String(classBytes, Helper.UTF_CS))); } return true; } @@ -105,24 +150,32 @@ public boolean loadExisting() { return false; } - Set getKeys() { - return keysInMem.keySet(); + Collection getKeys() { + return indexToKey; } /** - * This method writes the specified key-value pairs into the storage. + * This method writes the specified entryMap (key-value pairs) into the storage. Please note that null keys or null + * values are rejected. The Class of a value can be only: byte[], String, int, long, float or double + * (or more precisely, their wrapper equivalent). For all other types an exception is thrown. The first call of add + * assigns a Class to every key in the Map and future calls of add will throw an exception if this Class differs. * - * @return entryPointer to later fetch the entryMap via get + * @return entryPointer with which you can later fetch the entryMap via the get or getAll method */ - public long add(Map entryMap) { - if (entryMap.isEmpty()) - return EMPTY_POINTER; + public long add(final Map entryMap) { + if (entryMap == null) throw new IllegalArgumentException("specified Map must not be null"); + if (entryMap.isEmpty()) return EMPTY_POINTER; else if (entryMap.size() > 200) throw new IllegalArgumentException("Cannot store more than 200 entries per entry"); - // This is a very important compressing mechanism due to the nature of OSM. Make this faster via precalculated hastcodes? - if (entryMap.equals(lastEntryMap)) - return lastEntryPointer; + // This is a very important "compression" mechanism because one OSM way is split into multiple edges and so we + // can often re-use the serialized key-value pairs of the previous edge. + if (isEquals(entryMap, lastEntryMap)) return lastEntryPointer; + + // If the Class of a value is unknown it should already fail here, before we modify internal data. (see #2597#discussion_r896469840) + for (Map.Entry entry : entryMap.entrySet()) + if (keyToIndex.get(entry.getKey()) != null) + getBytesForValue(indexToClass.get(keyToIndex.get(entry.getKey())), entry.getValue()); lastEntryMap = entryMap; lastEntryPointer = bytePointer; @@ -132,24 +185,38 @@ else if (entryMap.size() > 200) vals.ensureCapacity(currentPointer + 1); vals.setByte(currentPointer, (byte) entryMap.size()); currentPointer += 1; - for (Map.Entry entry : entryMap.entrySet()) { - String key = entry.getKey(), value = entry.getValue(); - Integer keyIndex = keysInMem.get(key); + for (Map.Entry entry : entryMap.entrySet()) { + String key = entry.getKey(); + if (key == null) throw new IllegalArgumentException("key cannot be null"); + Object value = entry.getValue(); + if (value == null) throw new IllegalArgumentException("value for key " + key + " cannot be null"); + Integer keyIndex = keyToIndex.get(key); + Class clazz; if (keyIndex == null) { - keyIndex = keysInMem.size(); + keyIndex = keyToIndex.size(); if (keyIndex >= MAX_UNIQUE_KEYS) throw new IllegalArgumentException("Cannot store more than " + MAX_UNIQUE_KEYS + " unique keys"); - keysInMem.put(key, keyIndex); - keyList.add(key); + keyToIndex.put(key, keyIndex); + indexToKey.add(key); + indexToClass.add(clazz = value.getClass()); + } else { + clazz = indexToClass.get(keyIndex); + if (clazz != value.getClass()) + throw new IllegalArgumentException("Class of value for key " + key + " must be " + clazz.getSimpleName() + " but was " + value.getClass().getSimpleName()); } - if (value == null || value.isEmpty()) { - vals.ensureCapacity(currentPointer + 3); - vals.setShort(currentPointer, keyIndex.shortValue()); - // ensure that also in case of MMap value is set to 0 - vals.setByte(currentPointer + 2, (byte) 0); - currentPointer += 3; - } else { + boolean hasDynLength = hasDynLength(clazz); + if (hasDynLength) { + // optimization for empty string or empty byte array + if (clazz.equals(String.class) && ((String) value).isEmpty() || clazz.equals(byte[].class) && ((byte[]) value).length == 0) { + vals.ensureCapacity(currentPointer + 3); + vals.setShort(currentPointer, keyIndex.shortValue()); + // ensure that also in case of MMap value is set to 0 + vals.setByte(currentPointer + 2, (byte) 0); + currentPointer += 3; + continue; + } + Long existingRef = smallCache.get(value); if (existingRef != null) { long delta = lastEntryPointer - existingRef; @@ -159,7 +226,7 @@ else if (entryMap.size() > 200) currentPointer += 2; // do not store valueBytes.length as we know it already: it is 4! byte[] valueBytes = new byte[4]; - BitUtil.LITTLE.fromInt(valueBytes, (int) delta); + bitUtil.fromInt(valueBytes, (int) delta); vals.setBytes(currentPointer, valueBytes, valueBytes.length); currentPointer += valueBytes.length; continue; @@ -167,157 +234,241 @@ else if (entryMap.size() > 200) smallCache.remove(value); } } + } - byte[] valueBytes = getBytesForString("Value for key" + key, value); - // only cache value if storing via duplicate marker is valuable (the delta costs 4 bytes minus 1 due to omitted valueBytes.length storage) - if (valueBytes.length > 3) - smallCache.put(value, currentPointer); - - vals.ensureCapacity(currentPointer + 2 + 1 + valueBytes.length); - vals.setShort(currentPointer, keyIndex.shortValue()); - currentPointer += 2; + final byte[] valueBytes = getBytesForValue(clazz, value); + // only cache value if storing via duplicate marker is valuable (the delta costs 4 bytes minus 1 due to omitted valueBytes.length storage) + if (hasDynLength && valueBytes.length > 3) smallCache.put(value, currentPointer); + vals.ensureCapacity(currentPointer + 2 + 1 + valueBytes.length); + vals.setShort(currentPointer, keyIndex.shortValue()); + currentPointer += 2; + if (hasDynLength) { vals.setByte(currentPointer, (byte) valueBytes.length); currentPointer++; - vals.setBytes(currentPointer, valueBytes, valueBytes.length); - currentPointer += valueBytes.length; } + vals.setBytes(currentPointer, valueBytes, valueBytes.length); + currentPointer += valueBytes.length; } + // System.out.println(lastEntryPointer + " " + entryMap); bytePointer = currentPointer; return lastEntryPointer; } - public Map getAll(final long entryPointer) { + private boolean isEquals(Map entryMap, Map lastEntryMap) { + if (lastEntryMap != null && entryMap.size() == lastEntryMap.size()) { + for (Map.Entry entry : entryMap.entrySet()) { + Object val = entry.getValue(); + if (val == null) + throw new IllegalArgumentException("value for key " + entry.getKey() + " cannot be null"); + Object lastVal = lastEntryMap.get(entry.getKey()); + if (val instanceof byte[] && lastVal instanceof byte[] && Arrays.equals((byte[]) lastVal, (byte[]) val) + || val.equals(lastVal)) continue; + return false; + } + return true; + } + return false; + } + + public Map getAll(final long entryPointer) { if (entryPointer < 0) - throw new IllegalStateException("Pointer to access StringIndex cannot be negative:" + entryPointer); + throw new IllegalStateException("Pointer to access EdgeKVStorage cannot be negative:" + entryPointer); - if (entryPointer == EMPTY_POINTER) - return Collections.emptyMap(); + if (entryPointer == EMPTY_POINTER) return Collections.emptyMap(); int keyCount = vals.getByte(entryPointer) & 0xFF; - if (keyCount == 0) - return Collections.emptyMap(); + if (keyCount == 0) return Collections.emptyMap(); - Map map = new LinkedHashMap<>(keyCount); + Map map = new HashMap<>(keyCount); long tmpPointer = entryPointer + 1; + AtomicInteger sizeOfObject = new AtomicInteger(); for (int i = 0; i < keyCount; i++) { int currentKeyIndex = vals.getShort(tmpPointer); tmpPointer += 2; + Object object; if (currentKeyIndex < 0) { + // deserialize duplicate currentKeyIndex = -currentKeyIndex; byte[] valueBytes = new byte[4]; vals.getBytes(tmpPointer, valueBytes, valueBytes.length); tmpPointer += 4; - long dupPointer = entryPointer - BitUtil.LITTLE.toInt(valueBytes); + long dupPointer = entryPointer - bitUtil.toInt(valueBytes); dupPointer += 2; if (dupPointer > bytePointer) throw new IllegalStateException("dup marker should exist but points into not yet allocated area " + dupPointer + " > " + bytePointer); - putIntoMap(map, dupPointer, currentKeyIndex); + object = deserializeObj(null, dupPointer, indexToClass.get(currentKeyIndex)); } else { - int valueLength = putIntoMap(map, tmpPointer, currentKeyIndex); - tmpPointer += 1 + valueLength; + object = deserializeObj(sizeOfObject, tmpPointer, indexToClass.get(currentKeyIndex)); + tmpPointer += sizeOfObject.get(); } + String key = indexToKey.get(currentKeyIndex); + map.put(key, object); } - // value for specified key does not existing for the specified pointer return map; } - private int putIntoMap(Map map, long tmpPointer, int currentKeyIndex) { - int valueLength = vals.getByte(tmpPointer) & 0xFF; - tmpPointer++; - String valueStr; - if (valueLength == 0) { - valueStr = ""; - } else { + private boolean hasDynLength(Class clazz) { + return clazz.equals(String.class) || clazz.equals(byte[].class); + } + + private int getFixLength(Class clazz) { + if (clazz.equals(Integer.class) || clazz.equals(Float.class)) return 4; + else if (clazz.equals(Long.class) || clazz.equals(Double.class)) return 8; + else throw new IllegalArgumentException("unknown class " + clazz); + } + + private byte[] getBytesForValue(Class clazz, Object value) { + byte[] bytes; + if (clazz.equals(String.class)) { + bytes = ((String) value).getBytes(Helper.UTF_CS); + } else if (clazz.equals(Integer.class)) { + return bitUtil.fromInt((int) value); + } else if (clazz.equals(Long.class)) { + return bitUtil.fromLong((long) value); + } else if (clazz.equals(Float.class)) { + return bitUtil.fromFloat((float) value); + } else if (clazz.equals(Double.class)) { + return bitUtil.fromDouble((double) value); + } else if (clazz.equals(byte[].class)) { + bytes = (byte[]) value; + } else + throw new IllegalArgumentException("The Class of a value was " + clazz.getSimpleName() + ", currently supported: byte[], String, int, long, float and double"); + if (bytes.length > MAX_LENGTH) + throw new IllegalArgumentException("bytes.length cannot be > " + MAX_LENGTH + " but was " + bytes.length); + return bytes; + } + + private String classToShortName(Class clazz) { + if (clazz.equals(String.class)) return "S"; + else if (clazz.equals(Integer.class)) return "i"; + else if (clazz.equals(Long.class)) return "l"; + else if (clazz.equals(Float.class)) return "f"; + else if (clazz.equals(Double.class)) return "d"; + else if (clazz.equals(byte[].class)) return "["; + else throw new IllegalArgumentException("Cannot find short name. Unknown class " + clazz); + } + + private Class shortNameToClass(String name) { + if (name.equals("S")) return String.class; + else if (name.equals("i")) return Integer.class; + else if (name.equals("l")) return Long.class; + else if (name.equals("f")) return Float.class; + else if (name.equals("d")) return Double.class; + else if (name.equals("[")) return byte[].class; + else throw new IllegalArgumentException("Cannot find class. Unknown short name " + name); + } + + /** + * This method creates an Object (type Class) which is located at the specified pointer + */ + private Object deserializeObj(AtomicInteger sizeOfObject, long pointer, Class clazz) { + if (hasDynLength(clazz)) { + int valueLength = vals.getByte(pointer) & 0xFF; + pointer++; byte[] valueBytes = new byte[valueLength]; - vals.getBytes(tmpPointer, valueBytes, valueBytes.length); - valueStr = new String(valueBytes, Helper.UTF_CS); + vals.getBytes(pointer, valueBytes, valueBytes.length); + if (sizeOfObject != null) + sizeOfObject.set(1 + valueLength); // For String and byte[] we store the length and the value + if (clazz.equals(String.class)) return new String(valueBytes, Helper.UTF_CS); + else if (clazz.equals(byte[].class)) return valueBytes; + throw new IllegalArgumentException(); + } else { + byte[] valueBytes = new byte[getFixLength(clazz)]; + vals.getBytes(pointer, valueBytes, valueBytes.length); + if (clazz.equals(Integer.class)) { + if (sizeOfObject != null) sizeOfObject.set(4); + return bitUtil.toInt(valueBytes, 0); + } else if (clazz.equals(Long.class)) { + if (sizeOfObject != null) sizeOfObject.set(8); + return bitUtil.toLong(valueBytes, 0); + } else if (clazz.equals(Float.class)) { + if (sizeOfObject != null) sizeOfObject.set(4); + return bitUtil.toFloat(valueBytes, 0); + } else if (clazz.equals(Double.class)) { + if (sizeOfObject != null) sizeOfObject.set(8); + return bitUtil.toDouble(valueBytes, 0); + } else { + throw new IllegalArgumentException("unknown class " + clazz); + } } - - map.put(keyList.get(currentKeyIndex), valueStr); - return valueLength; } - public String get(final long entryPointer, String key) { + public Object get(final long entryPointer, String key) { if (entryPointer < 0) - throw new IllegalStateException("Pointer to access StringIndex cannot be negative:" + entryPointer); + throw new IllegalStateException("Pointer to access EdgeKVStorage cannot be negative:" + entryPointer); - if (entryPointer == EMPTY_POINTER) - return ""; + if (entryPointer == EMPTY_POINTER) return null; - int keyCount = vals.getByte(entryPointer) & 0xFF; - if (keyCount == 0) - return null; + Integer keyIndex = keyToIndex.get(key); + if (keyIndex == null) return null; // key wasn't stored before - Integer keyIndex = keysInMem.get(key); - // specified key is not known to the StringIndex - if (keyIndex == null) - return null; + int keyCount = vals.getByte(entryPointer) & 0xFF; + if (keyCount == 0) return null; // no entries long tmpPointer = entryPointer + 1; for (int i = 0; i < keyCount; i++) { - int currentKeyIndex = vals.getShort(tmpPointer); + int currentKeyIndexRaw = vals.getShort(tmpPointer); + int keyIndexPositive = Math.abs(currentKeyIndexRaw); + assert keyIndexPositive < indexToKey.size() : "invalid key index " + keyIndexPositive + ">=" + indexToKey.size() + ", entryPointer=" + entryPointer + ", max=" + bytePointer; tmpPointer += 2; - if (Math.abs(currentKeyIndex) == keyIndex) { - if (currentKeyIndex < 0) { + if (keyIndexPositive == keyIndex) { + if (currentKeyIndexRaw < 0) { byte[] valueBytes = new byte[4]; vals.getBytes(tmpPointer, valueBytes, valueBytes.length); - tmpPointer = entryPointer - BitUtil.LITTLE.toInt(valueBytes); + tmpPointer = entryPointer - bitUtil.toInt(valueBytes); tmpPointer += 2; if (tmpPointer > bytePointer) throw new IllegalStateException("dup marker " + bytePointer + " should exist but points into not yet allocated area " + tmpPointer); } - int valueLength = vals.getByte(tmpPointer) & 0xFF; - if (valueLength == 0) - return ""; + return deserializeObj(null, tmpPointer, indexToClass.get(keyIndex)); + } - tmpPointer++; - byte[] valueBytes = new byte[valueLength]; - vals.getBytes(tmpPointer, valueBytes, valueBytes.length); - return new String(valueBytes, Helper.UTF_CS); + // skip to next entry of same edge either via skipping the pointer (raw<0) or the real value + if (currentKeyIndexRaw < 0) { + tmpPointer += 4; + } else { + Class clazz = indexToClass.get(keyIndexPositive); + int valueLength = hasDynLength(clazz) ? 1 + vals.getByte(tmpPointer) & 0xFF : getFixLength(clazz); + tmpPointer += valueLength; } - int valueLength = vals.getByte(tmpPointer) & 0xFF; - tmpPointer += 1 + valueLength; } // value for specified key does not exist for the specified pointer return null; } - private byte[] getBytesForString(String info, String name) { - byte[] bytes = name.getBytes(Helper.UTF_CS); - if (bytes.length > MAX_LENGTH) { - String newString = new String(bytes, 0, MAX_LENGTH, Helper.UTF_CS); - if (throwExceptionIfTooLong) - throw new IllegalStateException(info + " is too long: " + name + " truncated to " + newString); - return newString.getBytes(Helper.UTF_CS); - } - - return bytes; - } - public void flush() { - keys.setHeader(0, Constants.VERSION_STRING_IDX); keys.ensureCapacity(2); - keys.setShort(0, (short) keysInMem.size()); + keys.setShort(0, (short) keyToIndex.size()); long keyBytePointer = 2; - for (String key : keysInMem.keySet()) { - byte[] keyBytes = getBytesForString("key", key); + for (int i = 0; i < indexToKey.size(); i++) { + String key = indexToKey.get(i); + byte[] keyBytes = getBytesForValue(String.class, key); keys.ensureCapacity(keyBytePointer + 2 + keyBytes.length); keys.setShort(keyBytePointer, (short) keyBytes.length); keyBytePointer += 2; keys.setBytes(keyBytePointer, keyBytes, keyBytes.length); keyBytePointer += keyBytes.length; + + Class clazz = indexToClass.get(i); + byte[] clazzBytes = getBytesForValue(String.class, classToShortName(clazz)); + if (clazzBytes.length != 1) + throw new IllegalArgumentException("class name byte length must be 1 but was " + clazzBytes.length); + keys.ensureCapacity(keyBytePointer + 1); + keys.setBytes(keyBytePointer, clazzBytes, 1); + keyBytePointer += 1; } + keys.setHeader(0, Constants.VERSION_EDGEKV_STORAGE); keys.flush(); - vals.setHeader(0, Constants.VERSION_STRING_IDX); - vals.setHeader(4, BitUtil.LITTLE.getIntLow(bytePointer)); - vals.setHeader(8, BitUtil.LITTLE.getIntHigh(bytePointer)); + vals.setHeader(0, bitUtil.getIntLow(bytePointer)); + vals.setHeader(4, bitUtil.getIntHigh(bytePointer)); + vals.setHeader(8, Constants.VERSION_EDGEKV_STORAGE); vals.flush(); } @@ -333,5 +484,4 @@ public boolean isClosed() { public long getCapacity() { return vals.getCapacity() + keys.getCapacity(); } - } diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index d224144b60a..2e2e2deeb93 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -43,7 +43,7 @@ * loadExisting, (4) usage, (5) flush, (6) close */ public class BaseGraph implements Graph, Closeable { - private final static String STRING_IDX_NAME_KEY = "name"; + private final static String EDGEKV_NAME_KEY = "name"; final BaseGraphNodesAndEdges store; final NodeAccess nodeAccess; final EdgeKVStorage edgeKVStorage; @@ -62,7 +62,7 @@ public BaseGraph(Directory dir, int intsForFlags, boolean withElevation, boolean this.dir = dir; this.bitUtil = BitUtil.LITTLE; this.wayGeometry = dir.create("geometry", segmentSize); - this.edgeKVStorage = new EdgeKVStorage(dir, 1000, segmentSize); + this.edgeKVStorage = new EdgeKVStorage(dir, 1000); this.store = new BaseGraphNodesAndEdges(dir, intsForFlags, withElevation, withTurnCosts, segmentSize); this.nodeAccess = new GHNodeAccess(store); this.segmentSize = segmentSize; @@ -176,7 +176,7 @@ String toDetailsString() { } /** - * Flush and free resources that are not needed for post-processing (way geometries and StringIndex). + * Flush and free resources that are not needed for post-processing (way geometries and EdgeKVStorage). */ void flushAndCloseGeometryAndNameStorage() { setWayGeometryHeader(); @@ -460,10 +460,10 @@ static int getPointListLength(int pillarNodes, FetchMode mode) { } private void setName(long edgePointer, String name) { - int stringIndexRef = (int) edgeKVStorage.add(Collections.singletonMap(STRING_IDX_NAME_KEY, name)); - if (stringIndexRef < 0) + int nameRef = (int) edgeKVStorage.add(Collections.singletonMap(EDGEKV_NAME_KEY, name)); + if (nameRef < 0) throw new IllegalStateException("Too many names are stored, currently limited to int pointer"); - store.setNameRef(edgePointer, stringIndexRef); + store.setNameRef(edgePointer, nameRef); } private void ensureGeometry(long bytePos, int byteLength) { @@ -955,8 +955,8 @@ public int getReverseEdgeKey() { @Override public String getName() { - int stringIndexRef = store.getNameRef(edgePointer); - String name = baseGraph.edgeKVStorage.get(stringIndexRef, STRING_IDX_NAME_KEY); + int nameRef = store.getNameRef(edgePointer); + String name = (String) baseGraph.edgeKVStorage.get(nameRef, EDGEKV_NAME_KEY); // preserve backward compatibility (returns null if not explicitly set) return name == null ? "" : name; } diff --git a/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java b/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java index 1e8fb134506..fc3c73dbfd2 100644 --- a/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java +++ b/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java @@ -169,7 +169,7 @@ private String getVersionsString() { ",edges:" + Constants.VERSION_EDGE + ",geometry:" + Constants.VERSION_GEOMETRY + ",location_index:" + Constants.VERSION_LOCATION_IDX + - ",string_index:" + Constants.VERSION_STRING_IDX + + ",string_index:" + Constants.VERSION_EDGEKV_STORAGE + ",nodesCH:" + Constants.VERSION_NODE_CH + ",shortcuts:" + Constants.VERSION_SHORTCUT; } @@ -249,7 +249,7 @@ public boolean isAdjacentToNode(int edge, int node) { } /** - * Flush and free base graph resources like way geometries and StringIndex + * Flush and free base graph resources like way geometries and EdgeKVStorage */ public void flushAndCloseGeometryAndNameStorage() { baseGraph.flushAndCloseGeometryAndNameStorage(); diff --git a/core/src/main/java/com/graphhopper/util/Constants.java b/core/src/main/java/com/graphhopper/util/Constants.java index 5f2d5f0a6d2..8d39fa9b52b 100644 --- a/core/src/main/java/com/graphhopper/util/Constants.java +++ b/core/src/main/java/com/graphhopper/util/Constants.java @@ -72,7 +72,7 @@ public class Constants { public static final int VERSION_NODE_CH = 0; public static final int VERSION_GEOMETRY = 6; public static final int VERSION_LOCATION_IDX = 5; - public static final int VERSION_STRING_IDX = 6; + public static final int VERSION_EDGEKV_STORAGE = 1; /** * The version without the snapshot string */ @@ -145,7 +145,7 @@ public class Constants { public static String getVersions() { return VERSION_NODE + "," + VERSION_EDGE + "," + VERSION_GEOMETRY + "," + VERSION_LOCATION_IDX - + "," + VERSION_STRING_IDX + "," + VERSION_SHORTCUT; + + "," + VERSION_EDGEKV_STORAGE + "," + VERSION_SHORTCUT; } public static String getMajorVersion() { diff --git a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java index 2d83fb093ac..5f92e7c1ce0 100644 --- a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java +++ b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java @@ -14,16 +14,18 @@ public class EdgeKVStorageTest { + private final static String location = "./target/edge-kv-storage"; + private EdgeKVStorage create() { - return new EdgeKVStorage(new RAMDirectory(), 1000, -1).create(1000); + return new EdgeKVStorage(new RAMDirectory(), 1000).create(1000); } - Map createMap(String... strings) { - if (strings.length % 2 != 0) - throw new IllegalArgumentException("Cannot create map from strings " + Arrays.toString(strings)); - Map map = new LinkedHashMap<>(); - for (int i = 0; i < strings.length; i += 2) { - map.put(strings[i], strings[i + 1]); + Map createMap(Object... keyValues) { + if (keyValues.length % 2 != 0) + throw new IllegalArgumentException("Cannot create map from " + Arrays.toString(keyValues)); + Map map = new LinkedHashMap<>(); + for (int i = 0; i < keyValues.length; i += 2) { + map.put((String) keyValues[i], keyValues[i + 1]); } return map; } @@ -57,11 +59,14 @@ public void putAB() { public void putEmpty() { EdgeKVStorage index = create(); assertEquals(1, index.add(createMap("", ""))); - assertEquals(5, index.add(createMap("", null))); - assertEquals(9, index.add(createMap(null, null))); - assertEquals("", index.get(0, "")); + // cannot store null (in its first version we accepted null once it was clear which type the value has, but this is inconsequential) + assertThrows(IllegalArgumentException.class, () -> assertEquals(5, index.add(createMap("", null)))); + assertThrows(IllegalArgumentException.class, () -> index.add(createMap("blup", null))); + assertThrows(IllegalArgumentException.class, () -> index.add(createMap(null, null))); + + assertNull(index.get(0, "")); - assertEquals(13, index.add(createMap("else", "else"))); + assertEquals(5, index.add(createMap("else", "else"))); } @Test @@ -123,53 +128,103 @@ public void putDuplicate() { } @Test - public void testNoErrorOnLargeName() { + public void testNoErrorOnLargeStringValue() { EdgeKVStorage index = create(); - // 127 => bytes.length == 254 String str = ""; for (int i = 0; i < 127; i++) { str += "ß"; } + assertEquals(254, str.getBytes(Helper.UTF_CS).length); long result = index.add(createMap("", str)); - assertEquals(127, index.get(result, "").length()); + assertEquals(127, ((String) index.get(result, "")).length()); } @Test - public void testTooLongNameNoError() { + public void testTooLongStringValueError() { EdgeKVStorage index = create(); - index.throwExceptionIfTooLong = true; - try { - index.add(createMap("", "Бухарестская улица (http://ru.wikipedia.org/wiki/%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))")); - fail(); - } catch (IllegalStateException ex) { - } + assertThrows(IllegalArgumentException.class, () -> index.add(createMap("", "Бухарестская улица (http://ru.wikipedia.org/wiki" + + "/%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))"))); String str = "sdfsdfds"; for (int i = 0; i < 256 * 3; i++) { str += "Б"; } - try { - index.add(createMap("", str)); - fail(); - } catch (IllegalStateException ex) { + final String finalStr = str; + assertThrows(IllegalArgumentException.class, () -> index.add(createMap("", finalStr))); + + long pointer = index.add(createMap("", Helper.cutString("Бухарестская улица (http://ru.wikipedia.org/wiki/" + + "%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))", 255))); + assertTrue(((String) index.get(pointer, "")).startsWith("Бухарестская улица (h")); + } + + @Test + public void testNoErrorOnLargestByteArray() { + EdgeKVStorage index = create(); + byte[] bytes = new byte[255]; + byte[] copy = new byte[255]; + for (int i = 0; i < bytes.length; i++) { + bytes[i] = (byte) (i % 255); + copy[i] = bytes[i]; } + long result = index.add(Collections.singletonMap("myval", bytes)); + bytes = (byte[]) index.get(result, "myval"); + assertArrayEquals(copy, bytes); + + final byte[] biggerByteArray = Arrays.copyOf(bytes, 256); + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> index.add(Collections.singletonMap("myval2", biggerByteArray))); + assertTrue(e.getMessage().contains("bytes.length cannot be > 255")); + } + + @Test + public void testIntLongDoubleFloat() { + EdgeKVStorage index = create(); + long intres = index.add(Collections.singletonMap("intres", 4)); + long doubleres = index.add(Collections.singletonMap("doubleres", 4d)); + long floatres = index.add(Collections.singletonMap("floatres", 4f)); + long longres = index.add(Collections.singletonMap("longres", 4L)); + long after4Inserts = index.add(Collections.singletonMap("somenext", 0)); + + // initial point is 1, then twice plus 1 + (2+4) and twice plus 1 + (2+8) + assertEquals(1 + 36, after4Inserts); + + assertEquals(4f, index.get(floatres, "floatres")); + assertEquals(4L, index.get(longres, "longres")); + assertEquals(4d, index.get(doubleres, "doubleres")); + assertEquals(4, index.get(intres, "intres")); + } - index.throwExceptionIfTooLong = false; - long pointer = index.add(createMap("", "Бухарестская улица (http://ru.wikipedia.org/wiki/%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))")); - assertTrue(index.get(pointer, "").startsWith("Бухарестская улица (h")); + @Test + public void testIntLongDoubleFloat2() { + EdgeKVStorage index = create(); + Map map = new HashMap<>(); + map.put("int", 4); + map.put("long", 4L); + map.put("double", 4d); + map.put("float", 4f); + long allInOne = index.add(map); + + long afterMapInsert = index.add(Collections.singletonMap("somenext", 0)); + + // 1 + 1 + (2+4) + (2+8) + (2+8) + (2+4) + assertEquals(1 + 1 + 32, afterMapInsert); + + Map resMap = index.getAll(allInOne); + assertEquals(4, resMap.get("int")); + assertEquals(4L, resMap.get("long")); + assertEquals(4d, resMap.get("double")); + assertEquals(4f, resMap.get("float")); } @Test public void testFlush() { - String location = "./target/stringindex-store"; Helper.removeDir(new File(location)); - EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create(), 1000, -1).create(1000); + EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create(), 1000); long pointer = index.add(createMap("", "test")); index.flush(); index.close(); - index = new EdgeKVStorage(new RAMDirectory(location, true), 1000, -1); + index = new EdgeKVStorage(new RAMDirectory(location, true), 1000); assertTrue(index.loadExisting()); assertEquals("test", index.get(pointer, "")); // make sure bytePointer is correctly set after loadExisting @@ -182,10 +237,9 @@ public void testFlush() { @Test public void testLoadKeys() { - String location = "./target/stringindex-store"; Helper.removeDir(new File(location)); - EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create(), 1000, -1).create(1000); + EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create(), 1000).create(1000); long pointerA = index.add(createMap("c", "test value")); assertEquals(2, index.getKeys().size()); long pointerB = index.add(createMap("a", "value", "b", "another value")); @@ -194,7 +248,7 @@ public void testLoadKeys() { index.flush(); index.close(); - index = new EdgeKVStorage(new RAMDirectory(location, true), 1000, -1); + index = new EdgeKVStorage(new RAMDirectory(location, true), 1000); assertTrue(index.loadExisting()); assertEquals("[, c, a, b]", index.getKeys().toString()); assertEquals("test value", index.get(pointerA, "c")); @@ -222,19 +276,40 @@ public void testEmptyKey() { assertNull(index.get(pointerB, "")); } + @Test + public void testSameByteArray() { + EdgeKVStorage index = create(); + + long pointerA = index.add(createMap("mykey", new byte[]{1, 2, 3, 4})); + long pointerB = index.add(createMap("mykey", new byte[]{1, 2, 3, 4})); + assertEquals(pointerA, pointerB); + + byte[] sameRef = new byte[]{1, 2, 3, 4}; + pointerA = index.add(createMap("mykey", sameRef)); + pointerB = index.add(createMap("mykey", sameRef)); + assertEquals(pointerA, pointerB); + } + + @Test + public void testUnknownValueClass() { + EdgeKVStorage index = create(); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> index.add(createMap("mykey", new Object()))); + assertTrue(ex.getMessage().contains("The Class of a value was Object, currently supported"), ex.getMessage()); + } + @RepeatedTest(20) public void testRandom() { - long seed = new Random().nextLong(); + final long seed = new Random().nextLong(); try { - EdgeKVStorage index = create(); + EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create()).create(1000); Random random = new Random(seed); - List keys = createRandomList(random, "_key", 1000); - List values = createRandomList(random, "_value", 5000); + List keys = createRandomStringList(random, "_key", 100); + List values = createRandomList(random, 500); - int size = 20000; + int size = 10000; LongArrayList pointers = new LongArrayList(size); for (int i = 0; i < size; i++) { - Map map = createRandomMap(random, keys, values); + Map map = createRandomMap(random, keys, values); long pointer = index.add(map); try { assertEquals(map.size(), index.getAll(pointer).size(), "" + i); @@ -245,15 +320,41 @@ public void testRandom() { } for (int i = 0; i < size; i++) { - Map map = index.getAll(pointers.get(i)); + Map map = index.getAll(pointers.get(i)); + assertTrue(map.size() > 0, i + " " + map); + for (Map.Entry entry : map.entrySet()) { + Object value = index.get(pointers.get(i), entry.getKey()); + assertEquals(entry.getValue(), value, i + " " + map); + } + } + index.flush(); + index.close(); + + index = new EdgeKVStorage(new RAMDirectory(location, true).create()); + assertTrue(index.loadExisting()); + for (int i = 0; i < size; i++) { + Map map = index.getAll(pointers.get(i)); assertTrue(map.size() > 0, i + " " + map); + for (Map.Entry entry : map.entrySet()) { + Object value = index.get(pointers.get(i), entry.getKey()); + assertEquals(entry.getValue(), value, i + " " + map); + } } + index.close(); } catch (Throwable t) { - throw new RuntimeException("seed:" + seed + ", error:" + t); + throw new RuntimeException("EdgeKVStorageTest.testRandom seed:" + seed, t); } } - private List createRandomList(Random random, String postfix, int size) { + private List createRandomList(Random random, int size) { + List list = new ArrayList<>(); + for (int i = 0; i < size; i++) { + list.add(random.nextInt(size * 5)); + } + return list; + } + + private List createRandomStringList(Random random, String postfix, int size) { List list = new ArrayList<>(); for (int i = 0; i < size; i++) { list.add(random.nextInt(size * 5) + postfix); @@ -261,11 +362,13 @@ private List createRandomList(Random random, String postfix, int size) { return list; } - private Map createRandomMap(Random random, List keys, List values) { + private Map createRandomMap(Random random, List keys, List values) { int count = random.nextInt(10) + 2; - Map map = new HashMap<>(); + Map map = new HashMap<>(); for (int i = 0; i < count; i++) { - map.put(keys.get(random.nextInt(keys.size())), values.get(random.nextInt(values.size()))); + String key = keys.get(random.nextInt(keys.size())); + Object o = values.get(random.nextInt(values.size())); + map.put(key, key.endsWith("_s") ? o + "_s" : o); } return map; } diff --git a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java index 4b7cb689133..ed1b698a3f0 100644 --- a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java +++ b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java @@ -645,7 +645,7 @@ public void testGetAllEdges() { } @Test - public void testStringIndex() { + public void testEdgeKVStorage() { graph = createGHStorage(); EdgeIteratorState iter1 = graph.edge(0, 1).setDistance(10).set(carAccessEnc, true, true); iter1.setName("named street1"); diff --git a/web-api/src/main/java/com/graphhopper/util/Helper.java b/web-api/src/main/java/com/graphhopper/util/Helper.java index e03ba746f9f..3311d9fdd0e 100644 --- a/web-api/src/main/java/com/graphhopper/util/Helper.java +++ b/web-api/src/main/java/com/graphhopper/util/Helper.java @@ -475,4 +475,12 @@ public static int staticHashCode(String str) { } return val; } + + /** + * This method limits the specified String value to the specified maxBytes. + */ + public static String cutString(String value, int maxBytes) { + byte[] bytes = value.getBytes(UTF_CS); + return bytes.length > maxBytes ? new String(bytes, 0, maxBytes, UTF_CS) : value; + } } From 8dafafb57417719f3bb1e42f6922b4dab69684cd Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 15 Jun 2022 09:49:44 +0200 Subject: [PATCH 040/389] Fix bug in non-CH AlternativeRoute (#2603) * fix plateau-end check * Revert "Disable edge+alt measurements, they take too long" This reverts commit fb39266ce2ab2fa87eb11956d09bddf8cedee25b. * increase count to 10 for Measurement --- .../graphhopper/routing/AlternativeRoute.java | 82 ++++++++----------- .../RoutingAlgorithmFactorySimple.java | 2 +- .../routing/lm/LMRoutingAlgorithmFactory.java | 6 +- .../routing/AlternativeRouteTest.java | 3 +- .../com/graphhopper/tools/Measurement.java | 20 ++--- 5 files changed, 49 insertions(+), 64 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java index d333bd23e1a..b9b83948462 100644 --- a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java +++ b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java @@ -25,10 +25,7 @@ import com.graphhopper.routing.weighting.WeightApproximator; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.Graph; -import com.graphhopper.util.EdgeIterator; -import com.graphhopper.util.EdgeIteratorState; -import com.graphhopper.util.GHUtility; -import com.graphhopper.util.Parameters; +import com.graphhopper.util.*; import java.util.ArrayList; import java.util.Collections; @@ -36,6 +33,7 @@ import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; /** * This class implements the alternative paths search using the "plateau" and partially the @@ -54,7 +52,7 @@ * http://algo2.iti.kit.edu/download/altgraph_tapas_extended.pdf * * - * + *

* Note: This algorithm is quite slow and alternatives are only really practical in combination with CH, see #2566 * * @author Peter Karich @@ -69,7 +67,7 @@ public class AlternativeRoute implements RoutingAlgorithm { private double maxWeightFactor = 1.4; // the higher the maxWeightFactor the higher the explorationFactor needs to be // 1 is default for bidir Dijkstra, 0.8 seems to be a very similar value for bidir A* but roughly 1/2 of the nodes explored - private double maxExplorationFactor = 0.8; + private double maxExplorationFactor = 1.6; private double maxShareFactor = 0.6; private double minPlateauFactor = 0.2; private int maxPaths = 2; @@ -165,7 +163,7 @@ public void setMaxPaths(int maxPaths) { */ public List calcAlternatives(int from, int to) { AlternativeBidirSearch altBidirDijktra = new AlternativeBidirSearch( - graph, weighting, traversalMode, maxExplorationFactor * 2); + graph, weighting, traversalMode, maxExplorationFactor); altBidirDijktra.setMaxVisitedNodes(maxVisitedNodes); if (weightApproximator != null) { altBidirDijktra.setApproximation(weightApproximator); @@ -313,7 +311,7 @@ public List calcAlternatives(final Path bestPath, final int max final AlternativeInfo bestAlt = new AlternativeInfo(sortBy, bestPath, bestFwdEntry, bestBwdEntry, bestShare, getAltNames(graph, bestFwdEntry)); alternatives.add(bestAlt); - final List bestPathEntries = new ArrayList<>(2); + AtomicReference bestEntry = new AtomicReference<>(); bestWeightMapFrom.forEach(new IntObjectPredicate() { @Override @@ -322,27 +320,20 @@ public boolean apply(final int traversalId, final SPTEntry fromSPTEntry) { if (toSPTEntry == null) return true; - if (traversalMode.isEdgeBased()) { - if (toSPTEntry.parent != null) - // move to parent for two reasons: - // 1. make only turn costs missing in 'weight' and not duplicating current edge.weight - // 2. to avoid duplicate edge in Path - toSPTEntry = toSPTEntry.parent; - // TODO else if fromSPTEntry.parent != null fromSPTEntry = fromSPTEntry.parent; - - } else // The alternative path is suboptimal when both entries are parallel - if (fromSPTEntry.edge == toSPTEntry.edge) - return true; + // Using the parent is required to avoid duplicate edge in Path. + // TODO we miss the turn cost weight (but at least we not duplicate the current edge weight) + if (traversalMode.isEdgeBased() && toSPTEntry.parent != null) + toSPTEntry = toSPTEntry.parent; + + // The alternative path is suboptimal if U-turn (after fromSPTEntry) + if (fromSPTEntry.edge == toSPTEntry.edge) + return true; // (1) skip too long paths final double weight = fromSPTEntry.getWeightOfVisitedPath() + toSPTEntry.getWeightOfVisitedPath(); if (weight > maxWeight) return true; - // (2) Use the start traversal ID of a plateau as ID for the alternative path. - // Accept from-EdgeEntries only if such a start of a plateau - // i.e. discard if its parent has the same edgeId as the next to-SPTEntry. - // Ignore already added best path if (isBestPath(fromSPTEntry)) return true; @@ -354,15 +345,13 @@ public boolean apply(final int traversalId, final SPTEntry fromSPTEntry) { assert traversalMode.isEdgeBased(); } else { int nextToTraversalId = traversalMode.createTraversalId(graph.getEdgeIteratorState(tmpFromEntry.edge, tmpFromEntry.parent.adjNode), true); - SPTEntry tmpNextToSPTEntry = bestWeightMapTo.get(nextToTraversalId); - if (tmpNextToSPTEntry == null) - return true; - - if (traversalMode.isEdgeBased()) - tmpNextToSPTEntry = tmpNextToSPTEntry.parent; - // skip if on plateau - if (fromSPTEntry.edge == tmpNextToSPTEntry.edge) - return true; + SPTEntry correspondingToEntry = bestWeightMapTo.get(nextToTraversalId); + if (correspondingToEntry != null) { + if (traversalMode.isEdgeBased()) + correspondingToEntry = correspondingToEntry.parent; + if (correspondingToEntry.edge == fromSPTEntry.edge) + return true; + } } // (3a) calculate plateau, we know we are at the beginning of the 'from'-side of @@ -377,20 +366,17 @@ public boolean apply(final int traversalId, final SPTEntry fromSPTEntry) { // that the from-SPTEntry is the start of the plateau or there is no plateau at all // double plateauWeight = 0; - SPTEntry prevToSPTEntry = toSPTEntry; - // List plateauEdges = new ArrayList(); + SPTEntry prevToSPTEntry = toSPTEntry, prevFrom = fromSPTEntry; while (prevToSPTEntry.parent != null) { int nextFromTraversalId = traversalMode.createTraversalId(graph.getEdgeIteratorState(prevToSPTEntry.edge, prevToSPTEntry.parent.adjNode), false); - SPTEntry nextFromSPTEntry = bestWeightMapFrom.get(nextFromTraversalId); + SPTEntry otherFromEntry = bestWeightMapFrom.get(nextFromTraversalId); // end of a plateau - if (nextFromSPTEntry == null) - break; - - // is the next from-SPTEntry on the plateau? - if (prevToSPTEntry.edge != nextFromSPTEntry.edge) + if (otherFromEntry == null || + otherFromEntry.parent != prevFrom || + otherFromEntry.edge != prevToSPTEntry.edge) break; - // plateauEdges.add(prevToSPTEntry.edge); + prevFrom = otherFromEntry; plateauWeight += (prevToSPTEntry.getWeightOfVisitedPath() - prevToSPTEntry.parent.getWeightOfVisitedPath()); prevToSPTEntry = prevToSPTEntry.parent; } @@ -484,19 +470,21 @@ boolean isBestPath(SPTEntry fromSPTEntry) { if (GHUtility.getEdgeFromEdgeKey(startTID.get()) == fromSPTEntry.edge) { if (fromSPTEntry.parent == null) throw new IllegalStateException("best path must have no parent but was non-null: " + fromSPTEntry); - + if (bestEntry.get() != null && bestEntry.get().edge != fromSPTEntry.edge) + throw new IllegalStateException("there can be only one best entry but was " + fromSPTEntry + " vs old: " + bestEntry.get() + + " " + graph.getEdgeIteratorState(fromSPTEntry.edge, fromSPTEntry.adjNode).fetchWayGeometry(FetchMode.ALL)); + bestEntry.set(fromSPTEntry); return true; } } else if (fromSPTEntry.parent == null) { - bestPathEntries.add(fromSPTEntry); - if (bestPathEntries.size() > 1) - throw new IllegalStateException("There is only one best path but was: " + bestPathEntries); - if (startTID.get() != fromSPTEntry.adjNode) throw new IllegalStateException("Start traversal ID has to be identical to root edge entry " + "which is the plateau start of the best path but was: " + startTID + " vs. adjNode: " + fromSPTEntry.adjNode); - + if (bestEntry.get() != null) + throw new IllegalStateException("there can be only one best entry but was " + fromSPTEntry + " vs old: " + bestEntry.get() + + " " + graph.getEdgeIteratorState(fromSPTEntry.edge, fromSPTEntry.adjNode).fetchWayGeometry(FetchMode.ALL)); + bestEntry.set(fromSPTEntry); return true; } diff --git a/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java b/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java index f6bd5185a62..ce713cbd9f8 100644 --- a/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java +++ b/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java @@ -67,7 +67,7 @@ public RoutingAlgorithm createAlgo(Graph g, Weighting w, AlgorithmOptions opts) altRouteAlgo.setMaxWeightFactor(opts.getHints().getDouble(MAX_WEIGHT, 1.4)); altRouteAlgo.setMaxShareFactor(opts.getHints().getDouble(MAX_SHARE, 0.6)); altRouteAlgo.setMinPlateauFactor(opts.getHints().getDouble("alternative_route.min_plateau_factor", 0.2)); - altRouteAlgo.setMaxExplorationFactor(opts.getHints().getDouble("alternative_route.max_exploration_factor", 1)); + altRouteAlgo.setMaxExplorationFactor(opts.getHints().getDouble("alternative_route.max_exploration_factor", 1.6)); ra = altRouteAlgo; } else { diff --git a/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java b/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java index 11a3bc5948e..85290155236 100644 --- a/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java +++ b/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java @@ -69,9 +69,9 @@ public RoutingAlgorithm createAlgo(Graph g, Weighting w, AlgorithmOptions opts) algo.setMaxShareFactor(opts.getHints().getDouble(MAX_SHARE, 0.6)); algo.setMinPlateauFactor(opts.getHints().getDouble("alternative_route.min_plateau_factor", 0.2)); algo.setApproximation(getApproximator(g, activeLM, epsilon)); - // landmark algorithm follows good compromise between fast response and exploring 'interesting' paths so we - // can decrease this exploration factor further (1->dijkstra, 0.8->bidir. A*) - algo.setMaxExplorationFactor(0.6); + // landmark algorithm follows good compromise between fast response and exploring 'interesting' paths, so we + // can decrease this exploration factor + algo.setMaxExplorationFactor(opts.getHints().getDouble("alternative_route.max_exploration_factor", 1.2)); algo.setMaxVisitedNodes(opts.getMaxVisitedNodes()); return algo; } else { diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java index febf978919f..b849eb16c0d 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java @@ -149,8 +149,7 @@ public void testCalcAlternatives2(Fixture f) { altDijkstra.setMaxShareFactor(0.7); altDijkstra.setMinPlateauFactor(0.15); altDijkstra.setMaxWeightFactor(2); - // edge based traversal requires a bit more exploration than the default of 1 - altDijkstra.setMaxExplorationFactor(1.2); + altDijkstra.setMaxExplorationFactor(1.8); List pathInfos = altDijkstra.calcAlternatives(5, 4); checkAlternatives(pathInfos); diff --git a/tools/src/main/java/com/graphhopper/tools/Measurement.java b/tools/src/main/java/com/graphhopper/tools/Measurement.java index 9d744cdd888..69bda5574aa 100644 --- a/tools/src/main/java/com/graphhopper/tools/Measurement.java +++ b/tools/src/main/java/com/graphhopper/tools/Measurement.java @@ -196,16 +196,15 @@ protected void importOSM() { boolean isLM = false; measureRouting(hopper, new QuerySettings("routing", count / 20, isCH, isLM). withInstructions()); - measureRouting(hopper, new QuerySettings("routing_alt", count / 1000, isCH, isLM). + measureRouting(hopper, new QuerySettings("routing_alt", count / 500, isCH, isLM). alternative()); if (encoder.supportsTurnCosts()) { measureRouting(hopper, new QuerySettings("routing_edge", count / 20, isCH, isLM). withInstructions().edgeBased()); // unfortunately alt routes are so slow that we cannot really afford many iterations - // actually it is just too slow so we skip it for now -// measureRouting(hopper, new QuerySettings("routing_edge_alt", count / 1000, isCH, isLM). -// edgeBased().alternative() -// ); + measureRouting(hopper, new QuerySettings("routing_edge_alt", count / 500, isCH, isLM). + edgeBased().alternative() + ); } if (!blockAreaStr.isEmpty()) measureRouting(hopper, new QuerySettings("routing_block_area", count / 20, isCH, isLM). @@ -220,14 +219,13 @@ protected void importOSM() { .mapToInt(Integer::parseInt).forEach(activeLMCount -> { measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount, count / 20, isCH, isLM). withInstructions().activeLandmarks(activeLMCount)); - measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_alt", count / 1000, isCH, isLM). + measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_alt", count / 500, isCH, isLM). activeLandmarks(activeLMCount).alternative()); if (args.getBool("measurement.lm.edge_based", encoder.supportsTurnCosts())) { measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_edge", count / 20, isCH, isLM). withInstructions().activeLandmarks(activeLMCount).edgeBased()); - // this is too slow -// measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_alt_edge", count / 1000, isCH, isLM). -// activeLandmarks(activeLMCount).edgeBased().alternative()); + measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_alt_edge", count / 500, isCH, isLM). + activeLandmarks(activeLMCount).edgeBased().alternative()); } }); @@ -247,7 +245,7 @@ protected void importOSM() { gcAndWait(); measureRouting(hopper, new QuerySettings("routingCH", count, isCH, isLM). withInstructions().sod()); - measureRouting(hopper, new QuerySettings("routingCH_alt", count / 100, isCH, isLM). + measureRouting(hopper, new QuerySettings("routingCH_alt", count / 10, isCH, isLM). withInstructions().sod().alternative()); measureRouting(hopper, new QuerySettings("routingCH_with_hints", count, isCH, isLM). withInstructions().sod().withPointHints()); @@ -267,7 +265,7 @@ protected void importOSM() { if (edgeBasedCH != null) { measureRouting(hopper, new QuerySettings("routingCH_edge", count, isCH, isLM). edgeBased().withInstructions()); - measureRouting(hopper, new QuerySettings("routingCH_edge_alt", count / 100, isCH, isLM). + measureRouting(hopper, new QuerySettings("routingCH_edge_alt", count / 10, isCH, isLM). edgeBased().withInstructions().alternative()); measureRouting(hopper, new QuerySettings("routingCH_edge_no_instr", count, isCH, isLM). edgeBased()); From 20c60a9866cb4ff6462722c05bada04747b94046 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 15 Jun 2022 14:40:14 +0200 Subject: [PATCH 041/389] AlternativeRoute: follow up refactoring, #2603 --- .../graphhopper/routing/AlternativeRoute.java | 543 ++++++++---------- .../RoutingAlgorithmFactorySimple.java | 2 +- .../routing/lm/LMRoutingAlgorithmFactory.java | 2 +- .../routing/AlternativeRouteTest.java | 6 +- 4 files changed, 239 insertions(+), 314 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java index b9b83948462..1cabd09f5e4 100644 --- a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java +++ b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java @@ -22,7 +22,6 @@ import com.graphhopper.coll.GHIntHashSet; import com.graphhopper.coll.GHIntObjectHashMap; import com.graphhopper.routing.util.TraversalMode; -import com.graphhopper.routing.weighting.WeightApproximator; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.Graph; import com.graphhopper.util.*; @@ -53,39 +52,23 @@ * * *

- * Note: This algorithm is quite slow and alternatives are only really practical in combination with CH, see #2566 + * Note: This algorithm can be slow for longer routes and alternatives are only really practical in combination with CH, see #2566 * * @author Peter Karich */ -public class AlternativeRoute implements RoutingAlgorithm { +public class AlternativeRoute extends AStarBidirection implements RoutingAlgorithm { private static final Comparator ALT_COMPARATOR = Comparator.comparingDouble(o -> o.sortBy); - private final Graph graph; - private final Weighting weighting; - private final TraversalMode traversalMode; - private int visitedNodes; - private int maxVisitedNodes = Integer.MAX_VALUE; private double maxWeightFactor = 1.4; // the higher the maxWeightFactor the higher the explorationFactor needs to be - // 1 is default for bidir Dijkstra, 0.8 seems to be a very similar value for bidir A* but roughly 1/2 of the nodes explored - private double maxExplorationFactor = 1.6; + private double explorationFactor = 1.6; private double maxShareFactor = 0.6; private double minPlateauFactor = 0.2; private int maxPaths = 2; - private WeightApproximator weightApproximator; public AlternativeRoute(Graph graph, Weighting weighting, TraversalMode traversalMode) { + super(graph, weighting, traversalMode); if (weighting.hasTurnCosts() && !traversalMode.isEdgeBased()) throw new IllegalStateException("Weightings supporting turn costs cannot be used with node-based traversal mode"); - this.graph = graph; - this.weighting = weighting; - this.traversalMode = traversalMode; - } - - /** - * This method sets the approximation used for the internal bidirectional A*. - */ - public void setApproximation(WeightApproximator weightApproximator) { - this.weightApproximator = weightApproximator; } static List getAltNames(Graph graph, SPTEntry ee) { @@ -117,7 +100,7 @@ public void setMaxVisitedNodes(int numberOfNodes) { /** * Increasing this factor results in returning more alternatives. E.g. if the factor is 2 than * all alternatives with a weight 2 times longer than the optimal weight are return. (default is - * 1) + * 1.4) */ public void setMaxWeightFactor(double maxWeightFactor) { this.maxWeightFactor = maxWeightFactor; @@ -140,11 +123,11 @@ public void setMinPlateauFactor(double minPlateauFactor) { /** * This method sets the graph exploration percentage for alternative paths. Default for bidirectional A* - * is 0.8 (80%). Specify a higher value to get more alternatives (especially if maxWeightFactor is higher than + * is 1.6 (160%). Specify a higher value to get more alternatives (especially if maxWeightFactor is higher than * 1.5) and a lower value to improve query time but reduces the possibility to find alternatives. */ - public void setMaxExplorationFactor(double explorationFactor) { - this.maxExplorationFactor = explorationFactor; + public void setExplorationFactor(double explorationFactor) { + this.explorationFactor = explorationFactor; } /** @@ -156,36 +139,19 @@ public void setMaxPaths(int maxPaths) { throw new IllegalArgumentException("Use normal algorithm with less overhead instead if no alternatives are required"); } - /** - * This method calculates best paths (alternatives) between 'from' and 'to', where maxPaths-1 - * alternatives are searched and they are only accepted if they are not too similar but close to - * the best path. - */ public List calcAlternatives(int from, int to) { - AlternativeBidirSearch altBidirDijktra = new AlternativeBidirSearch( - graph, weighting, traversalMode, maxExplorationFactor); - altBidirDijktra.setMaxVisitedNodes(maxVisitedNodes); - if (weightApproximator != null) { - altBidirDijktra.setApproximation(weightApproximator); - } - - Path bestPath = altBidirDijktra.searchBest(from, to); - visitedNodes = altBidirDijktra.getVisitedNodes(); - - return altBidirDijktra. - calcAlternatives(bestPath, maxPaths, maxWeightFactor, 7, maxShareFactor, 0.8, minPlateauFactor, -0.2); - } - - @Override - public Path calcPath(int from, int to) { - return calcPaths(from, to).get(0); + Path bestPath = searchBest(from, to); + return calcAlternatives(bestPath, maxPaths, + maxWeightFactor, 7, + maxShareFactor, 0.8, + minPlateauFactor, -0.2); } @Override public List calcPaths(int from, int to) { - List alts = calcAlternatives(from, to); - List paths = new ArrayList<>(alts.size()); - for (AlternativeInfo a : alts) { + List alternatives = calcAlternatives(from, to); + List paths = new ArrayList<>(alternatives.size()); + for (AlternativeInfo a : alternatives) { paths.add(a.getPath()); } return paths; @@ -196,11 +162,6 @@ public String getName() { return Parameters.Algorithms.ALT_ROUTE; } - @Override - public int getVisitedNodes() { - return visitedNodes; - } - public static class AlternativeInfo { private final double sortBy; private final Path path; @@ -246,299 +207,263 @@ public String toString() { } } - /** - * Helper class to find alternatives and alternatives for round trip. - */ - public static class AlternativeBidirSearch extends AStarBidirection { - private final double explorationFactor; - - public AlternativeBidirSearch(Graph graph, Weighting weighting, TraversalMode tMode, - double explorationFactor) { - super(graph, weighting, tMode); - this.explorationFactor = explorationFactor; - } - - @Override - public boolean finished() { - // we need to finish BOTH searches identical to CH - if (finishedFrom && finishedTo) - return true; - - if (isMaxVisitedNodesExceeded()) - return true; - - // The following condition is necessary to avoid traversing the full graph if areas are disconnected - // but it is only valid for non-CH e.g. for CH it can happen that finishedTo is true but the from-SPT could still reach 'to' - if (finishedFrom || finishedTo) - return true; - - // increase overlap of both searches: - return currFrom.weight + currTo.weight > explorationFactor * (bestWeight + stoppingCriterionOffset); - // This is more precise but takes roughly 20% longer: return currFrom.weight > bestWeight && currTo.weight > bestWeight; - // For bidir A* and AStarEdge.getWeightOfVisitedPath see comment in AStarBidirection.finished - } + @Override + public boolean finished() { + // we need to finish BOTH searches identical to CH + if (finishedFrom && finishedTo) + return true; + + if (isMaxVisitedNodesExceeded()) + return true; + + // The following condition is necessary to avoid traversing the full graph if areas are disconnected + // but it is only valid for non-CH e.g. for CH it can happen that finishedTo is true but the from-SPT could still reach 'to' + if (finishedFrom || finishedTo) + return true; + + // increase overlap of both searches: + return currFrom.weight + currTo.weight > explorationFactor * (bestWeight + stoppingCriterionOffset); + // This is more precise but takes roughly 20% longer: return currFrom.weight > bestWeight && currTo.weight > bestWeight; + // For bidir A* and AStarEdge.getWeightOfVisitedPath see comment in AStarBidirection.finished + } - public Path searchBest(int from, int to) { - init(from, 0, to, 0); - // init collections and bestPath.getWeight properly - runAlgo(); - return extractPath(); - } + public Path searchBest(int from, int to) { + init(from, 0, to, 0); + // init collections and bestPath.getWeight properly + runAlgo(); + return extractPath(); + } - /** - * @return the information necessary to handle alternative paths. Note that the paths are - * not yet extracted. - */ - public List calcAlternatives(final Path bestPath, final int maxPaths, - double maxWeightFactor, final double weightInfluence, - final double maxShareFactor, final double shareInfluence, - final double minPlateauFactor, final double plateauInfluence) { - final double maxWeight = maxWeightFactor * bestWeight; - final GHIntObjectHashMap traversalIdMap = new GHIntObjectHashMap<>(); - final AtomicInteger startTID = addToMap(traversalIdMap, bestPath); - - // find all 'good' alternatives from forward-SPT matching the backward-SPT and optimize by - // small total weight (1), small share and big plateau (3a+b) and do these expensive calculations - // only for plateau start candidates (2) - final List alternatives = new ArrayList<>(maxPaths); - - double bestPlateau = bestWeight; - double bestShare = 0; - double sortBy = calcSortBy(weightInfluence, bestWeight, - shareInfluence, bestShare, - plateauInfluence, bestPlateau); - - final AlternativeInfo bestAlt = new AlternativeInfo(sortBy, bestPath, - bestFwdEntry, bestBwdEntry, bestShare, getAltNames(graph, bestFwdEntry)); - alternatives.add(bestAlt); - AtomicReference bestEntry = new AtomicReference<>(); - - bestWeightMapFrom.forEach(new IntObjectPredicate() { - @Override - public boolean apply(final int traversalId, final SPTEntry fromSPTEntry) { - SPTEntry toSPTEntry = bestWeightMapTo.get(traversalId); - if (toSPTEntry == null) - return true; + /** + * @return the information necessary to handle alternative paths. Note that the paths are + * not yet extracted. + */ + public List calcAlternatives(final Path bestPath, final int maxPaths, + double maxWeightFactor, final double weightInfluence, + final double maxShareFactor, final double shareInfluence, + final double minPlateauFactor, final double plateauInfluence) { + final double maxWeight = maxWeightFactor * bestWeight; + final GHIntObjectHashMap traversalIdMap = new GHIntObjectHashMap<>(); + final AtomicInteger startTID = addToMap(traversalIdMap, bestPath); + + // find all 'good' alternatives from forward-SPT matching the backward-SPT and optimize by + // small total weight (1), small share and big plateau (3a+b) and do these expensive calculations + // only for plateau start candidates (2) + final List alternatives = new ArrayList<>(maxPaths); + + double bestPlateau = bestWeight; + double bestShare = 0; + double sortBy = calcSortBy(weightInfluence, bestWeight, + shareInfluence, bestShare, + plateauInfluence, bestPlateau); + + final AlternativeInfo bestAlt = new AlternativeInfo(sortBy, bestPath, + bestFwdEntry, bestBwdEntry, bestShare, getAltNames(graph, bestFwdEntry)); + alternatives.add(bestAlt); + AtomicReference bestEntry = new AtomicReference<>(); + + bestWeightMapFrom.forEach(new IntObjectPredicate() { + @Override + public boolean apply(final int traversalId, final SPTEntry fromSPTEntry) { + SPTEntry toSPTEntry = bestWeightMapTo.get(traversalId); + if (toSPTEntry == null) + return true; - // Using the parent is required to avoid duplicate edge in Path. - // TODO we miss the turn cost weight (but at least we not duplicate the current edge weight) - if (traversalMode.isEdgeBased() && toSPTEntry.parent != null) - toSPTEntry = toSPTEntry.parent; + // Using the parent is required to avoid duplicate edge in Path. + // TODO we miss the turn cost weight (but at least we not duplicate the current edge weight) + if (traversalMode.isEdgeBased() && toSPTEntry.parent != null) + toSPTEntry = toSPTEntry.parent; - // The alternative path is suboptimal if U-turn (after fromSPTEntry) - if (fromSPTEntry.edge == toSPTEntry.edge) - return true; + // The alternative path is suboptimal if U-turn (after fromSPTEntry) + if (fromSPTEntry.edge == toSPTEntry.edge) + return true; - // (1) skip too long paths - final double weight = fromSPTEntry.getWeightOfVisitedPath() + toSPTEntry.getWeightOfVisitedPath(); - if (weight > maxWeight) - return true; + // (1) skip too long paths + final double weight = fromSPTEntry.getWeightOfVisitedPath() + toSPTEntry.getWeightOfVisitedPath(); + if (weight > maxWeight) + return true; - if (isBestPath(fromSPTEntry)) - return true; + if (isBestPath(fromSPTEntry)) + return true; - // For edge based traversal we need the next entry to find out the plateau start - SPTEntry tmpFromEntry = traversalMode.isEdgeBased() ? fromSPTEntry.parent : fromSPTEntry; - if (tmpFromEntry == null || tmpFromEntry.parent == null) { - // we can be here only if edge based and only if entry is not part of the best path - // e.g. when starting point has two edges and one is part of the best path the other edge is path of an alternative - assert traversalMode.isEdgeBased(); - } else { - int nextToTraversalId = traversalMode.createTraversalId(graph.getEdgeIteratorState(tmpFromEntry.edge, tmpFromEntry.parent.adjNode), true); - SPTEntry correspondingToEntry = bestWeightMapTo.get(nextToTraversalId); - if (correspondingToEntry != null) { - if (traversalMode.isEdgeBased()) - correspondingToEntry = correspondingToEntry.parent; - if (correspondingToEntry.edge == fromSPTEntry.edge) - return true; - } + // For edge based traversal we need the next entry to find out the plateau start + SPTEntry tmpFromEntry = traversalMode.isEdgeBased() ? fromSPTEntry.parent : fromSPTEntry; + if (tmpFromEntry == null || tmpFromEntry.parent == null) { + // we can be here only if edge based and only if entry is not part of the best path + // e.g. when starting point has two edges and one is part of the best path the other edge is path of an alternative + assert traversalMode.isEdgeBased(); + } else { + int nextToTraversalId = traversalMode.createTraversalId(graph.getEdgeIteratorState(tmpFromEntry.edge, tmpFromEntry.parent.adjNode), true); + SPTEntry correspondingToEntry = bestWeightMapTo.get(nextToTraversalId); + if (correspondingToEntry != null) { + if (traversalMode.isEdgeBased()) + correspondingToEntry = correspondingToEntry.parent; + if (correspondingToEntry.edge == fromSPTEntry.edge) + return true; } + } - // (3a) calculate plateau, we know we are at the beginning of the 'from'-side of - // the plateau A-B-C and go further to B - // where B is the next-'from' of A and B is also the previous-'to' of A. - // - // *<-A-B-C->* - // / \ - // start end - // - // extend plateau in only one direction necessary (A to B to ...) as we know - // that the from-SPTEntry is the start of the plateau or there is no plateau at all - // - double plateauWeight = 0; - SPTEntry prevToSPTEntry = toSPTEntry, prevFrom = fromSPTEntry; - while (prevToSPTEntry.parent != null) { - int nextFromTraversalId = traversalMode.createTraversalId(graph.getEdgeIteratorState(prevToSPTEntry.edge, prevToSPTEntry.parent.adjNode), false); - SPTEntry otherFromEntry = bestWeightMapFrom.get(nextFromTraversalId); - // end of a plateau - if (otherFromEntry == null || - otherFromEntry.parent != prevFrom || - otherFromEntry.edge != prevToSPTEntry.edge) - break; - - prevFrom = otherFromEntry; - plateauWeight += (prevToSPTEntry.getWeightOfVisitedPath() - prevToSPTEntry.parent.getWeightOfVisitedPath()); - prevToSPTEntry = prevToSPTEntry.parent; - } + // (3a) calculate plateau, we know we are at the beginning of the 'from'-side of + // the plateau A-B-C and go further to B + // where B is the next-'from' of A and B is also the previous-'to' of A. + // + // *<-A-B-C->* + // / \ + // start end + // + // extend plateau in only one direction necessary (A to B to ...) as we know + // that the from-SPTEntry is the start of the plateau or there is no plateau at all + // + double plateauWeight = 0; + SPTEntry prevToSPTEntry = toSPTEntry, prevFrom = fromSPTEntry; + while (prevToSPTEntry.parent != null) { + int nextFromTraversalId = traversalMode.createTraversalId(graph.getEdgeIteratorState(prevToSPTEntry.edge, prevToSPTEntry.parent.adjNode), false); + SPTEntry otherFromEntry = bestWeightMapFrom.get(nextFromTraversalId); + // end of a plateau + if (otherFromEntry == null || + otherFromEntry.parent != prevFrom || + otherFromEntry.edge != prevToSPTEntry.edge) + break; + + prevFrom = otherFromEntry; + plateauWeight += (prevToSPTEntry.getWeightOfVisitedPath() - prevToSPTEntry.parent.getWeightOfVisitedPath()); + prevToSPTEntry = prevToSPTEntry.parent; + } - if (plateauWeight <= 0 || plateauWeight / weight < minPlateauFactor) - return true; + if (plateauWeight <= 0 || plateauWeight / weight < minPlateauFactor) + return true; - if (fromSPTEntry.parent == null) - throw new IllegalStateException("not implemented yet. in case of an edge based traversal the parent of fromSPTEntry could be null"); + if (fromSPTEntry.parent == null) + throw new IllegalStateException("not implemented yet. in case of an edge based traversal the parent of fromSPTEntry could be null"); - // (3b) calculate share - SPTEntry fromEE = getFirstShareEE(fromSPTEntry.parent, true); - SPTEntry toEE = getFirstShareEE(toSPTEntry.parent, false); - double shareWeight = fromEE.getWeightOfVisitedPath() + toEE.getWeightOfVisitedPath(); - boolean smallShare = shareWeight / bestWeight < maxShareFactor; - if (smallShare) { - List altNames = getAltNames(graph, fromSPTEntry); + // (3b) calculate share + SPTEntry fromEE = getFirstShareEE(fromSPTEntry.parent, true); + SPTEntry toEE = getFirstShareEE(toSPTEntry.parent, false); + double shareWeight = fromEE.getWeightOfVisitedPath() + toEE.getWeightOfVisitedPath(); + boolean smallShare = shareWeight / bestWeight < maxShareFactor; + if (smallShare) { + List altNames = getAltNames(graph, fromSPTEntry); - double sortBy = calcSortBy(weightInfluence, weight, shareInfluence, shareWeight, plateauInfluence, plateauWeight); - double worstSortBy = getWorstSortBy(); + double sortBy = calcSortBy(weightInfluence, weight, shareInfluence, shareWeight, plateauInfluence, plateauWeight); + double worstSortBy = getWorstSortBy(); - // plateaus.add(new PlateauInfo(altName, plateauEdges)); - if (sortBy < worstSortBy || alternatives.size() < maxPaths) { - Path path = DefaultBidirPathExtractor.extractPath(graph, weighting, fromSPTEntry, toSPTEntry, weight); + // plateaus.add(new PlateauInfo(altName, plateauEdges)); + if (sortBy < worstSortBy || alternatives.size() < maxPaths) { + Path path = DefaultBidirPathExtractor.extractPath(graph, weighting, fromSPTEntry, toSPTEntry, weight); - // for now do not add alternatives to set, if we do we need to remove then on alternatives.clear too (see below) - // AtomicInteger tid = addToMap(traversalIDMap, path); - // int tid = traversalMode.createTraversalId(path.calcEdges().get(0), false); - alternatives.add(new AlternativeInfo(sortBy, path, fromEE, toEE, shareWeight, altNames)); + // for now do not add alternatives to set, if we do we need to remove then on alternatives.clear too (see below) + // AtomicInteger tid = addToMap(traversalIDMap, path); + // int tid = traversalMode.createTraversalId(path.calcEdges().get(0), false); + alternatives.add(new AlternativeInfo(sortBy, path, fromEE, toEE, shareWeight, altNames)); - Collections.sort(alternatives, ALT_COMPARATOR); - if (alternatives.get(0) != bestAlt) - throw new IllegalStateException("best path should be always first entry"); + Collections.sort(alternatives, ALT_COMPARATOR); + if (alternatives.get(0) != bestAlt) + throw new IllegalStateException("best path should be always first entry"); - if (alternatives.size() > maxPaths) - alternatives.subList(maxPaths, alternatives.size()).clear(); - } + if (alternatives.size() > maxPaths) + alternatives.subList(maxPaths, alternatives.size()).clear(); } - - return true; } - /** - * Extract path until we stumble over an existing traversal id - */ - SPTEntry getFirstShareEE(SPTEntry startEE, boolean reverse) { - while (startEE.parent != null) { - // TODO we could make use of traversal ID directly if stored in SPTEntry - int tid = traversalMode.createTraversalId(graph.getEdgeIteratorState(startEE.edge, startEE.parent.adjNode), reverse); - if (isAlreadyExisting(tid)) - return startEE; - - startEE = startEE.parent; - } + return true; + } - return startEE; + /** + * Extract path until we stumble over an existing traversal id + */ + SPTEntry getFirstShareEE(SPTEntry startEE, boolean reverse) { + while (startEE.parent != null) { + // TODO we could make use of traversal ID directly if stored in SPTEntry + int tid = traversalMode.createTraversalId(graph.getEdgeIteratorState(startEE.edge, startEE.parent.adjNode), reverse); + if (isAlreadyExisting(tid)) + return startEE; + + startEE = startEE.parent; } - /** - * This method returns true if the specified tid is already existent in the - * traversalIDMap - */ - boolean isAlreadyExisting(final int tid) { - final AtomicBoolean exists = new AtomicBoolean(false); - traversalIdMap.forEach(new IntObjectPredicate() { - @Override - public boolean apply(int key, IntSet set) { - if (set.contains(tid)) { - exists.set(true); - return false; - } - return true; - } - }); + return startEE; + } - return exists.get(); - } + /** + * This method returns true if the specified tid is already existent in the + * traversalIDMap + */ + boolean isAlreadyExisting(final int tid) { + final AtomicBoolean exists = new AtomicBoolean(false); + traversalIdMap.forEach(new IntObjectPredicate() { + @Override + public boolean apply(int key, IntSet set) { + if (set.contains(tid)) { + exists.set(true); + return false; + } + return true; + } + }); - /** - * Return the current worst weight for all alternatives - */ - double getWorstSortBy() { - if (alternatives.isEmpty()) - throw new IllegalStateException("Empty alternative list cannot happen"); - return alternatives.get(alternatives.size() - 1).sortBy; - } + return exists.get(); + } - // returns true if fromSPTEntry is identical to the specified best path - boolean isBestPath(SPTEntry fromSPTEntry) { - if (traversalMode.isEdgeBased()) { - if (GHUtility.getEdgeFromEdgeKey(startTID.get()) == fromSPTEntry.edge) { - if (fromSPTEntry.parent == null) - throw new IllegalStateException("best path must have no parent but was non-null: " + fromSPTEntry); - if (bestEntry.get() != null && bestEntry.get().edge != fromSPTEntry.edge) - throw new IllegalStateException("there can be only one best entry but was " + fromSPTEntry + " vs old: " + bestEntry.get() - + " " + graph.getEdgeIteratorState(fromSPTEntry.edge, fromSPTEntry.adjNode).fetchWayGeometry(FetchMode.ALL)); - bestEntry.set(fromSPTEntry); - return true; - } + /** + * Return the current worst weight for all alternatives + */ + double getWorstSortBy() { + if (alternatives.isEmpty()) + throw new IllegalStateException("Empty alternative list cannot happen"); + return alternatives.get(alternatives.size() - 1).sortBy; + } - } else if (fromSPTEntry.parent == null) { - if (startTID.get() != fromSPTEntry.adjNode) - throw new IllegalStateException("Start traversal ID has to be identical to root edge entry " - + "which is the plateau start of the best path but was: " + startTID + " vs. adjNode: " + fromSPTEntry.adjNode); - if (bestEntry.get() != null) + // returns true if fromSPTEntry is identical to the specified best path + boolean isBestPath(SPTEntry fromSPTEntry) { + if (traversalMode.isEdgeBased()) { + if (GHUtility.getEdgeFromEdgeKey(startTID.get()) == fromSPTEntry.edge) { + if (fromSPTEntry.parent == null) + throw new IllegalStateException("best path must have no parent but was non-null: " + fromSPTEntry); + if (bestEntry.get() != null && bestEntry.get().edge != fromSPTEntry.edge) throw new IllegalStateException("there can be only one best entry but was " + fromSPTEntry + " vs old: " + bestEntry.get() + " " + graph.getEdgeIteratorState(fromSPTEntry.edge, fromSPTEntry.adjNode).fetchWayGeometry(FetchMode.ALL)); bestEntry.set(fromSPTEntry); return true; } - return false; + } else if (fromSPTEntry.parent == null) { + if (startTID.get() != fromSPTEntry.adjNode) + throw new IllegalStateException("Start traversal ID has to be identical to root edge entry " + + "which is the plateau start of the best path but was: " + startTID + " vs. adjNode: " + fromSPTEntry.adjNode); + if (bestEntry.get() != null) + throw new IllegalStateException("there can be only one best entry but was " + fromSPTEntry + " vs old: " + bestEntry.get() + + " " + graph.getEdgeIteratorState(fromSPTEntry.edge, fromSPTEntry.adjNode).fetchWayGeometry(FetchMode.ALL)); + bestEntry.set(fromSPTEntry); + return true; } - }); - - return alternatives; - } - - /** - * This method adds the traversal IDs of the specified path as set to the specified map. - */ - AtomicInteger addToMap(GHIntObjectHashMap map, Path path) { - IntSet set = new GHIntHashSet(); - final AtomicInteger startTID = new AtomicInteger(-1); - for (EdgeIteratorState iterState : path.calcEdges()) { - int tid = traversalMode.createTraversalId(iterState, false); - set.add(tid); - if (startTID.get() < 0) { - // for node based traversal we need to explicitly add base node as starting node and to list - if (!traversalMode.isEdgeBased()) { - tid = iterState.getBaseNode(); - set.add(tid); - } - startTID.set(tid); - } + return false; } - map.put(startTID.get(), set); - return startTID; - } - } + }); - public static class PlateauInfo { - String name; - List edges; - - public PlateauInfo(String name, List edges) { - this.name = name; - this.edges = edges; - } - - @Override - public String toString() { - return name; - } + return alternatives; + } - public List getEdges() { - return edges; - } + /** + * This method adds the traversal IDs of the specified path as set to the specified map. + */ + AtomicInteger addToMap(GHIntObjectHashMap map, Path path) { + IntSet set = new GHIntHashSet(); + final AtomicInteger startTID = new AtomicInteger(-1); + for (EdgeIteratorState iterState : path.calcEdges()) { + int tid = traversalMode.createTraversalId(iterState, false); + set.add(tid); + if (startTID.get() < 0) { + // for node based traversal we need to explicitly add base node as starting node and to list + if (!traversalMode.isEdgeBased()) { + tid = iterState.getBaseNode(); + set.add(tid); + } - public String getName() { - return name; + startTID.set(tid); + } } + map.put(startTID.get(), set); + return startTID; } } diff --git a/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java b/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java index ce713cbd9f8..a4cddae1fcf 100644 --- a/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java +++ b/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java @@ -67,7 +67,7 @@ public RoutingAlgorithm createAlgo(Graph g, Weighting w, AlgorithmOptions opts) altRouteAlgo.setMaxWeightFactor(opts.getHints().getDouble(MAX_WEIGHT, 1.4)); altRouteAlgo.setMaxShareFactor(opts.getHints().getDouble(MAX_SHARE, 0.6)); altRouteAlgo.setMinPlateauFactor(opts.getHints().getDouble("alternative_route.min_plateau_factor", 0.2)); - altRouteAlgo.setMaxExplorationFactor(opts.getHints().getDouble("alternative_route.max_exploration_factor", 1.6)); + altRouteAlgo.setExplorationFactor(opts.getHints().getDouble("alternative_route.max_exploration_factor", 1.6)); ra = altRouteAlgo; } else { diff --git a/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java b/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java index 85290155236..f12ef88a35e 100644 --- a/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java +++ b/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java @@ -71,7 +71,7 @@ public RoutingAlgorithm createAlgo(Graph g, Weighting w, AlgorithmOptions opts) algo.setApproximation(getApproximator(g, activeLM, epsilon)); // landmark algorithm follows good compromise between fast response and exploring 'interesting' paths, so we // can decrease this exploration factor - algo.setMaxExplorationFactor(opts.getHints().getDouble("alternative_route.max_exploration_factor", 1.2)); + algo.setExplorationFactor(opts.getHints().getDouble("alternative_route.max_exploration_factor", 1.2)); algo.setMaxVisitedNodes(opts.getMaxVisitedNodes()); return algo; } else { diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java index b849eb16c0d..63e0122c1ef 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java @@ -18,7 +18,6 @@ package com.graphhopper.routing; import com.carrotsearch.hppc.IntArrayList; -import com.graphhopper.routing.AlternativeRoute.AlternativeBidirSearch; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.util.FlagEncoders; @@ -149,7 +148,7 @@ public void testCalcAlternatives2(Fixture f) { altDijkstra.setMaxShareFactor(0.7); altDijkstra.setMinPlateauFactor(0.15); altDijkstra.setMaxWeightFactor(2); - altDijkstra.setMaxExplorationFactor(1.8); + altDijkstra.setExplorationFactor(1.8); List pathInfos = altDijkstra.calcAlternatives(5, 4); checkAlternatives(pathInfos); @@ -184,7 +183,8 @@ public void testDisconnectedAreas(Fixture p) { // one single disconnected node updateDistancesFor(p.graph, 20, 0.00, -0.01); - AlternativeBidirSearch altDijkstra = new AlternativeBidirSearch(p.graph, p.weighting, p.traversalMode, 1); + AlternativeRoute altDijkstra = new AlternativeRoute(p.graph, p.weighting, p.traversalMode); + altDijkstra.setExplorationFactor(1); Path path = altDijkstra.calcPath(1, 20); assertFalse(path.isFound()); From f1083286dfb1111cb60895ca02a1ce3191f8959b Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 15 Jun 2022 15:33:47 +0200 Subject: [PATCH 042/389] MiniGraphUI fixes to make it work again --- .../java/com/graphhopper/ui/DebugAStarBi.java | 2 +- .../com/graphhopper/ui/GraphicsWrapper.java | 6 +- .../java/com/graphhopper/ui/MiniGraphUI.java | 147 ++++++------------ 3 files changed, 54 insertions(+), 101 deletions(-) diff --git a/tools/src/main/java/com/graphhopper/ui/DebugAStarBi.java b/tools/src/main/java/com/graphhopper/ui/DebugAStarBi.java index ef2cda5d000..9c11991b18d 100644 --- a/tools/src/main/java/com/graphhopper/ui/DebugAStarBi.java +++ b/tools/src/main/java/com/graphhopper/ui/DebugAStarBi.java @@ -45,7 +45,7 @@ public void setGraphics2D(Graphics2D g2) { @Override public void updateBestPath(double edgeWeight, SPTEntry entry, int origEdgeId, int traversalId, boolean reverse) { if (g2 != null) { - mg.plotNode(g2, traversalId, Color.YELLOW); + mg.plotNode(g2, entry.adjNode, Color.YELLOW); } super.updateBestPath(edgeWeight, entry, origEdgeId, traversalId, reverse); } diff --git a/tools/src/main/java/com/graphhopper/ui/GraphicsWrapper.java b/tools/src/main/java/com/graphhopper/ui/GraphicsWrapper.java index a0cc5f6cb41..d6916f68777 100644 --- a/tools/src/main/java/com/graphhopper/ui/GraphicsWrapper.java +++ b/tools/src/main/java/com/graphhopper/ui/GraphicsWrapper.java @@ -32,7 +32,7 @@ */ public class GraphicsWrapper { private final Logger logger = LoggerFactory.getLogger(getClass()); - private final NodeAccess na; + private NodeAccess na; private double scaleX; private double scaleY; private double offsetX; @@ -47,6 +47,10 @@ public GraphicsWrapper(Graph g) { offsetX = -b.minLon; } + public void setNodeAccess(Graph graph) { + this.na = graph.getNodeAccess(); + } + public double getOffsetX() { return offsetX; } diff --git a/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java b/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java index 2ff4eb1b5c9..8389de69753 100644 --- a/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java +++ b/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java @@ -35,6 +35,8 @@ import com.graphhopper.routing.util.AllEdgesIterator; import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.util.TraversalMode; +import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.NodeAccess; import com.graphhopper.storage.RoutingCHGraph; @@ -80,7 +82,6 @@ public class MiniGraphUI { // for moving int currentPosX; int currentPosY; - private Path path; private LocationIndexTree index; private String latLon = ""; private GraphicsWrapper mg; @@ -88,18 +89,20 @@ public class MiniGraphUI { private LayeredPanel mainPanel; private MapLayer roadsLayer; private boolean fastPaint = false; + private boolean showQuadTree = false; private Snap fromRes; private Snap toRes; + private QueryGraph qGraph; public static void main(String[] strs) { PMap args = PMap.read(strs); args.putObject("datareader.file", args.getString("datareader.file", "core/files/monaco.osm.gz")); args.putObject("graph.location", args.getString("graph.location", "tools/target/mini-graph-ui-gh")); - args.putObject("graph.flag_encoders", args.getString("graph.flag_encoders", "car")); GraphHopperConfig ghConfig = new GraphHopperConfig(args); ghConfig.setProfiles(Arrays.asList( new Profile("profile") .setVehicle("car") + .setTurnCosts(true) .setWeighting("fastest") )); ghConfig.setCHProfiles(Arrays.asList( @@ -125,8 +128,6 @@ public MiniGraphUI(GraphHopper hopper, boolean debug, boolean useCH) { logger.info("locations:" + graph.getNodes() + ", debug:" + debug); mg = new GraphicsWrapper(graph); - // prepare node quadtree to 'enter' the graph. create a 313*313 grid => <3km -// this.index = new DebugLocation2IDQuadtree(roadGraph, mg); this.index = (LocationIndexTree) hopper.getLocationIndex(); infoPanel = new JPanel() { @Override @@ -154,7 +155,6 @@ protected void paintComponent(Graphics g) { @Override public void paintComponent(final Graphics2D g2) { clearGraphics(g2); - int locs = graph.getNodes(); Rectangle d = getBounds(); BBox b = mg.setBounds(0, d.width, 0, d.height); if (fastPaint) { @@ -162,18 +162,6 @@ public void paintComponent(final Graphics2D g2) { bitset.clear(); } -// g2.setColor(Color.BLUE); -// double fromLat = 42.56819, fromLon = 1.603231; -// mg.plotText(g2, fromLat, fromLon, "from"); -// Snap from = index.findClosest(fromLat, fromLon, EdgeFilter.ALL_EDGES); -// double toLat = 42.571034, toLon = 1.520662; -// mg.plotText(g2, toLat, toLon, "to"); -// Snap to = index.findClosest(toLat, toLon, EdgeFilter.ALL_EDGES); -// -// g2.setColor(Color.RED.brighter().brighter()); -// path = prepare.createAlgo().calcPath(from, to); -// System.out.println("now: " + path.toFlagEncodersAsString()); -// plotPath(path, g2, 1); g2.setColor(Color.black); Color[] speedColors = generateColors(15); @@ -238,27 +226,28 @@ public void paintComponent(final Graphics2D g2) { } } - index.query(graph.getBounds(), new LocationIndexTree.Visitor() { - @Override - public boolean isTileInfo() { - return true; - } + if (showQuadTree) + index.query(graph.getBounds(), new LocationIndexTree.Visitor() { + @Override + public boolean isTileInfo() { + return true; + } - @Override - public void onTile(BBox bbox, int depth) { - int width = Math.max(1, Math.min(4, 4 - depth)); - g2.setColor(Color.GRAY); - mg.plotEdge(g2, bbox.minLat, bbox.minLon, bbox.minLat, bbox.maxLon, width); - mg.plotEdge(g2, bbox.minLat, bbox.maxLon, bbox.maxLat, bbox.maxLon, width); - mg.plotEdge(g2, bbox.maxLat, bbox.maxLon, bbox.maxLat, bbox.minLon, width); - mg.plotEdge(g2, bbox.maxLat, bbox.minLon, bbox.minLat, bbox.minLon, width); - } + @Override + public void onTile(BBox bbox, int depth) { + int width = Math.max(1, Math.min(4, 4 - depth)); + g2.setColor(Color.GRAY); + mg.plotEdge(g2, bbox.minLat, bbox.minLon, bbox.minLat, bbox.maxLon, width); + mg.plotEdge(g2, bbox.minLat, bbox.maxLon, bbox.maxLat, bbox.maxLon, width); + mg.plotEdge(g2, bbox.maxLat, bbox.maxLon, bbox.maxLat, bbox.minLon, width); + mg.plotEdge(g2, bbox.maxLat, bbox.minLon, bbox.minLat, bbox.minLon, width); + } - @Override - public void onEdge(int edgeId) { - // mg.plotNode(g2, node, Color.BLUE); - } - }); + @Override + public void onEdge(int edgeId) { + // mg.plotNode(g2, node, Color.BLUE); + } + }); g2.setColor(Color.WHITE); g2.fillRect(0, 0, 1000, 20); @@ -274,12 +263,11 @@ public void onEdge(int edgeId) { mainPanel.addLayer(pathLayer = new DefaultMapLayer() { @Override public void paintComponent(final Graphics2D g2) { - if (fromRes == null || toRes == null) + if (qGraph == null) return; makeTransparent(g2); - QueryGraph qGraph = QueryGraph.create(graph, fromRes, toRes); - RoutingAlgorithm algo = createAlgo(hopper); + RoutingAlgorithm algo = createAlgo(hopper, qGraph); if (algo instanceof DebugAlgo) { ((DebugAlgo) algo).setGraphics2D(g2); } @@ -287,57 +275,44 @@ public void paintComponent(final Graphics2D g2) { StopWatch sw = new StopWatch().start(); logger.info("start searching with " + algo + " from:" + fromRes + " to:" + toRes); -// GHPoint qp = fromRes.getQueryPoint(); -// TIntHashSet set = index.findNetworkEntries(qp.lat, qp.lon, 1); -// TIntIterator nodeIter = set.iterator(); -// DistanceCalc distCalc = new DistancePlaneProjection(); -// System.out.println("set:" + set.size()); -// while (nodeIter.hasNext()) -// { -// int nodeId = nodeIter.next(); -// double lat = graph.getNodeAccess().getLat(nodeId); -// double lon = graph.getNodeAccess().getLon(nodeId); -// int dist = (int) Math.round(distCalc.calcDist(qp.lat, qp.lon, lat, lon)); -// mg.plotText(g2, lat, lon, nodeId + ": " + dist); -// mg.plotNode(g2, nodeId, Color.red); -// } Color red = Color.red.brighter(); g2.setColor(red); mg.plotNode(g2, qGraph.getNodeAccess(), fromRes.getClosestNode(), red, 10, ""); mg.plotNode(g2, qGraph.getNodeAccess(), toRes.getClosestNode(), red, 10, ""); g2.setColor(Color.blue.brighter().brighter()); - path = algo.calcPath(fromRes.getClosestNode(), toRes.getClosestNode()); + java.util.List paths = algo.calcPaths(fromRes.getClosestNode(), toRes.getClosestNode()); sw.stop(); // if directed edges - if (!path.isFound()) { + if (paths.isEmpty() || !paths.get(0).isFound()) { logger.warn("path not found! direction not valid?"); return; } - + Path best = paths.get(0); logger.info("found path in " + sw.getSeconds() + "s with nodes:" - + path.calcNodes().size() + ", millis: " + path.getTime() + + best.calcNodes().size() + ", millis: " + best.getTime() + ", visited nodes:" + algo.getVisitedNodes()); g2.setColor(red); - plotPath(path, g2, 4); + for (Path p : paths) + plotPath(p, g2, 3); } }); if (debug) { - // disable double buffering for debugging drawing - nice! when do we need DebugGraphics then? + // disable double buffering to see graphic changes while debugging. E.g. to set a break point in the + // algorithm its updateBest method and see the shortest path tree increasing everytime the program continues. RepaintManager repaintManager = RepaintManager.currentManager(mainPanel); repaintManager.setDoubleBufferingEnabled(false); mainPanel.setBuffering(false); } } - private RoutingAlgorithm createAlgo(GraphHopper hopper) { + private RoutingAlgorithm createAlgo(GraphHopper hopper, QueryGraph qGraph) { Profile profile = hopper.getProfiles().iterator().next(); if (useCH) { RoutingCHGraph chGraph = hopper.getCHGraphs().get(profile.getName()); logger.info("CH algo, profile: " + profile.getName()); - QueryGraph qGraph = QueryGraph.create(hopper.getGraphHopperStorage(), fromRes, toRes); QueryRoutingCHGraph queryRoutingCHGraph = new QueryRoutingCHGraph(chGraph, qGraph); return new CHDebugAlgo(queryRoutingCHGraph, mg); } else { @@ -353,13 +328,12 @@ private RoutingAlgorithm createAlgo(GraphHopper hopper) { return new DebugDijkstraBidirection(g, w, opts.getTraversalMode(), mg); } else if (algo instanceof Dijkstra) { return new DebugDijkstraSimple(g, w, opts.getTraversalMode(), mg); - } - return algo; + } else + return algo; }; - AlgorithmOptions algoOpts = new AlgorithmOptions().setAlgorithm(Algorithms.ASTAR_BI); - logger.info("algoOpts:" + algoOpts + ", weighting: " + landmarks.getWeighting() + ", profile: " + profile.getName()); - QueryGraph qGraph = QueryGraph.create(graph, fromRes, toRes); - return algoFactory.createAlgo(qGraph, landmarks.getWeighting(), algoOpts); + AlgorithmOptions algoOpts = new AlgorithmOptions().setAlgorithm(Algorithms.ASTAR_BI). + setTraversalMode(TraversalMode.EDGE_BASED); + return algoFactory.createAlgo(qGraph, new FastestWeighting(encoder), algoOpts); } } @@ -394,19 +368,6 @@ public Color[] generateColors(int n) { return cols; } - // for debugging - private Path calcPath(RoutingAlgorithm algo) { -// int from = index.findID(50.042, 10.19); -// int to = index.findID(50.049, 10.23); -// -//// System.out.println("path " + from + "->" + to); -// return algo.calcPath(from, to); - // System.out.println(GraphUtility.getNodeInfo(graph, 60139, AccessFilter.allEdges(new CarFlagEncoder()).direction(false, true))); - // System.out.println(((GraphStorage) graph).debug(202947, 10)); -// GraphUtility.printInfo(graph, 106511, 10); - return algo.calcPath(162810, 35120); - } - void plotNodeName(Graphics2D g2, int node) { double lat = na.getLat(node); double lon = na.getLon(node); @@ -415,7 +376,7 @@ void plotNodeName(Graphics2D g2, int node) { private Path plotPath(Path tmpPath, Graphics2D g2, int w) { if (!tmpPath.isFound()) { - logger.info("nothing found " + w); + logger.info("cannot plot path as not found: " + tmpPath); return tmpPath; } @@ -505,7 +466,11 @@ public void mouseClicked(MouseEvent e) { // get from and to node id fromRes = index.findClosest(fromLat, fromLon, EdgeFilter.ALL_EDGES); toRes = index.findClosest(toLat, toLon, EdgeFilter.ALL_EDGES); - logger.info("found ids " + fromRes + " -> " + toRes + " in " + sw.stop().getSeconds() + "s"); + if (fromRes.isValid() && toRes.isValid()) { + qGraph = QueryGraph.create(graph, fromRes, toRes); + mg.setNodeAccess(qGraph); + logger.info("found ids " + fromRes + " -> " + toRes + " in " + sw.stop().getSeconds() + "s"); + } repaintPaths(); } @@ -549,22 +514,6 @@ public void mousePressed(MouseEvent e) { mainPanel.addMouseListener(ml); mainPanel.addMouseMotionListener(ml); - // just for fun -// mainPanel.getInputMap().put(KeyStroke.getKeyStroke("DELETE"), "removedNodes"); -// mainPanel.getActionMap().put("removedNodes", new AbstractAction() { -// @Override public void actionPerformed(ActionEvent e) { -// int counter = 0; -// for (CoordTrig coord : quadTreeNodes) { -// int ret = quadTree.remove(coord.lat, coord.lon); -// if (ret < 1) { -//// logger.info("cannot remove " + coord + " " + ret); -//// ret = quadTree.remove(coord.getLat(), coord.getLon()); -// } else -// counter += ret; -// } -// logger.info("Removed " + counter + " of " + quadTreeNodes.size() + " nodes"); -// } -// }); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(frameWidth + 10, frameHeight + 30); frame.setVisible(true); @@ -596,4 +545,4 @@ void repaintRoads() { mainPanel.repaint(); logger.info("roads painting took " + sw.stop().getSeconds() + " sec"); } -} +} \ No newline at end of file From 8e7f080189ae986957c23a6d10bdf73703568f1d Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 15 Jun 2022 15:37:47 +0200 Subject: [PATCH 043/389] move quickstart info into more prominent installation of README (#2605) --- README.md | 3 +-- docs/core/quickstart-from-source.md | 4 ++-- docs/index.md | 2 +- docs/web/quickstart.md | 18 ------------------ 4 files changed, 4 insertions(+), 23 deletions(-) delete mode 100644 docs/web/quickstart.md diff --git a/README.md b/README.md index 383a6011e47..79ac6556ab7 100644 --- a/README.md +++ b/README.md @@ -85,8 +85,7 @@ java -Ddw.graphhopper.datareader.file=berlin-latest.osm.pbf -jar *.jar server co After a while you see a log message with 'Server - Started', then go to http://localhost:8989/ and you'll see a map of Berlin. You should be able to right click on the map to create a route. -For more details about the installation, see [here](./docs/web/quickstart.md) -and the [deployment guide](./docs/core/deploy.md). +See the [documentation](./docs/index.md) that contains e.g. [the elevation guide](./docs/core/elevation.md) and the [deployment guide](./docs/core/deploy.md). ### Docker diff --git a/docs/core/quickstart-from-source.md b/docs/core/quickstart-from-source.md index 896a663456b..3d108ee5372 100644 --- a/docs/core/quickstart-from-source.md +++ b/docs/core/quickstart-from-source.md @@ -2,9 +2,9 @@ ## Try out -To build the GraphHopper jar from the Java sources you need to install `git` and [a recent JDK](https://adoptium.net). +For a simpler start consider the pre-built jar and the general [installation documentation](../../README.md) -(For a simpler start consider the pre-built jar and the documentation [here](../web/quickstart.md)). +To build the GraphHopper jar from the Java sources you need to install `git` and [a recent JDK](https://adoptium.net). Now create the jar from sources via: diff --git a/docs/index.md b/docs/index.md index 8dbded05c2c..2be373c9d5d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,7 +18,7 @@ For bugs see our contribute section below. ## Installation -Install the web demo 'GraphHopper Maps' with [this user installation guide](../README.md#installation) on your +Install the GraphHopper routing engine with the GraphHopper Maps UI with [this installation guide](../README.md#installation) on your machine. This will also install a web API that can be used in many programming languages. * [Routing API](./web/api-doc.md): Documentation of the Web API to communicate with any GraphHopper server via http. diff --git a/docs/web/quickstart.md b/docs/web/quickstart.md deleted file mode 100644 index 2cbefd5a275..00000000000 --- a/docs/web/quickstart.md +++ /dev/null @@ -1,18 +0,0 @@ -## Quickstart - -If you want to build GraphHopper from source look at the [Developers page](../core/quickstart-from-source.md). - -To download GraphHopper follow [the installation instructions](https://github.com/graphhopper/graphhopper#installation) -where you need a recent JRE. - -See [here](./../core/elevation.md) how to enable elevation data. To see how GraphHopper is configured for production usage, see the [deployment guide](./../core/deploy.md). - -## Troubleshooting - - * Make sure JRE8 is installed. If not get Java [here](http://java.com). - * Regarding step 2: - * The folder where you execute the java command should contain the following files: berlin-latest.osm.pbf, config-example.yml and `graphhopper-web-[version].jar` - * The first time you execute this it'll take ~30 seconds (for Berlin), further starts will only load the graph and should be nearly instantaneous. You should see log statements but no exceptions and the last entry should be something like: Started server at HTTP 8989 - * Regarding step 3: - * Depending on the size of the map you might run into `java.lang.OutOfMemoryError`. In this case you need to increase the memory settings of the JVM by starting the above command with `java -Xmx2g -Xms2g ...` (example for 2GB memory) - * Or [contact us](../index.md#contact) From 05e35565f144ea1db136a7ed404465efbc2a231c Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 15 Jun 2022 20:13:53 +0200 Subject: [PATCH 044/389] Measurement: reduce routingCH_alt after it was accidentally raised in #2603 --- tools/src/main/java/com/graphhopper/tools/Measurement.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/src/main/java/com/graphhopper/tools/Measurement.java b/tools/src/main/java/com/graphhopper/tools/Measurement.java index 69bda5574aa..ab9d8143bb5 100644 --- a/tools/src/main/java/com/graphhopper/tools/Measurement.java +++ b/tools/src/main/java/com/graphhopper/tools/Measurement.java @@ -245,7 +245,7 @@ protected void importOSM() { gcAndWait(); measureRouting(hopper, new QuerySettings("routingCH", count, isCH, isLM). withInstructions().sod()); - measureRouting(hopper, new QuerySettings("routingCH_alt", count / 10, isCH, isLM). + measureRouting(hopper, new QuerySettings("routingCH_alt", count / 100, isCH, isLM). withInstructions().sod().alternative()); measureRouting(hopper, new QuerySettings("routingCH_with_hints", count, isCH, isLM). withInstructions().sod().withPointHints()); @@ -265,7 +265,7 @@ protected void importOSM() { if (edgeBasedCH != null) { measureRouting(hopper, new QuerySettings("routingCH_edge", count, isCH, isLM). edgeBased().withInstructions()); - measureRouting(hopper, new QuerySettings("routingCH_edge_alt", count / 10, isCH, isLM). + measureRouting(hopper, new QuerySettings("routingCH_edge_alt", count / 100, isCH, isLM). edgeBased().withInstructions().alternative()); measureRouting(hopper, new QuerySettings("routingCH_edge_no_instr", count, isCH, isLM). edgeBased()); From 79910908b63587bb6bcde2987163dedd8ee276b0 Mon Sep 17 00:00:00 2001 From: Andi Date: Thu, 16 Jun 2022 10:37:14 +0200 Subject: [PATCH 045/389] Remove GraphHopperStorage (#2606) * Rename: GraphHopper#getGraphHopperStorage -> GraphHopper#getBaseGraph * Remove GraphHopperStorage --- .../java/com/graphhopper/GraphHopper.java | 181 ++++++++---- .../java/com/graphhopper/routing/Router.java | 2 - .../routing/ch/CHPreparationHandler.java | 6 +- .../ch/PrepareContractionHierarchies.java | 2 +- .../routing/lm/LMPreparationHandler.java | 9 +- .../routing/querygraph/QueryGraph.java | 18 -- .../routing/util/VehicleTagParser.java | 3 +- .../com/graphhopper/storage/BaseGraph.java | 8 +- .../com/graphhopper/storage/CHStorage.java | 24 +- .../graphhopper/storage/CHStorageBuilder.java | 4 +- .../com/graphhopper/storage/GHNodeAccess.java | 3 - .../com/graphhopper/storage/GraphBuilder.java | 97 ------- .../storage/GraphHopperStorage.java | 258 ------------------ .../java/com/graphhopper/util/GHUtility.java | 21 +- .../java/com/graphhopper/GraphHopperTest.java | 14 +- .../reader/osm/GraphHopperOSMTest.java | 35 ++- .../graphhopper/reader/osm/OSMReaderTest.java | 69 ++--- .../routing/RoutingAlgorithmWithOSMTest.java | 6 +- .../storage/AbstractGraphStorageTester.java | 2 +- ...perStorageTest.java => BaseGraphTest.java} | 2 +- ...t.java => BaseGraphWithTurnCostsTest.java} | 2 +- .../graphhopper/storage/CHStorageTest.java | 9 +- .../graphhopper/example/IsochroneExample.java | 2 +- .../example/LowLevelAPIExample.java | 4 +- .../com/graphhopper/matching/MapMatching.java | 2 +- .../com/graphhopper/gtfs/GraphHopperGtfs.java | 18 +- .../java/com/graphhopper/gtfs/GtfsReader.java | 15 +- .../graphhopper/gtfs/PtLocationSnapper.java | 10 +- .../gtfs/PtRouterFreeWalkImpl.java | 35 ++- .../com/graphhopper/gtfs/PtRouterImpl.java | 33 ++- .../com/graphhopper/gtfs/RealtimeFeed.java | 7 +- .../java/com/graphhopper/AnotherAgencyIT.java | 5 +- .../com/graphhopper/ExtendedRouteTypeIT.java | 2 +- .../test/java/com/graphhopper/FreeWalkIT.java | 6 +- .../com/graphhopper/GraphHopperGtfsIT.java | 2 +- .../graphhopper/GraphHopperMultimodalIT.java | 6 +- .../test/java/com/graphhopper/RealtimeIT.java | 2 +- .../com/graphhopper/tools/CHMeasurement.java | 4 +- .../com/graphhopper/tools/Measurement.java | 6 +- .../java/com/graphhopper/ui/MiniGraphUI.java | 2 +- .../graphhopper/http/GraphHopperBundle.java | 12 +- .../graphhopper/http/GraphHopperManaged.java | 2 +- .../http/RealtimeFeedLoadingCache.java | 13 +- .../http/health/GraphHopperHealthCheck.java | 4 +- .../graphhopper/resources/InfoResource.java | 22 +- .../resources/IsochroneResource.java | 10 +- .../graphhopper/resources/MVTResource.java | 4 +- .../resources/PtIsochroneResource.java | 12 +- .../graphhopper/resources/SPTResource.java | 4 +- .../application/MapMatching2Test.java | 4 +- .../application/MapMatchingTest.java | 2 +- 51 files changed, 358 insertions(+), 667 deletions(-) delete mode 100644 core/src/main/java/com/graphhopper/storage/GraphBuilder.java delete mode 100644 core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java rename core/src/test/java/com/graphhopper/storage/{GraphHopperStorageTest.java => BaseGraphTest.java} (99%) rename core/src/test/java/com/graphhopper/storage/{GraphHopperStorageWithTurnCostsTest.java => BaseGraphWithTurnCostsTest.java} (98%) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 99fae58918b..2668034f1f1 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -85,7 +85,8 @@ public class GraphHopper { // for custom areas: private String customAreasDirectory = ""; // for graph: - private GraphHopperStorage ghStorage; + private BaseGraph baseGraph; + private StorableProperties properties; private EncodingManager encodingManager; private OSMParsers osmParsers; private int defaultSegmentSize = -1; @@ -311,18 +312,22 @@ public GraphHopper setOSMFile(String osmFile) { * * @throws IllegalStateException if graph is not instantiated. */ - public GraphHopperStorage getGraphHopperStorage() { - if (ghStorage == null) + public BaseGraph getBaseGraph() { + if (baseGraph == null) throw new IllegalStateException("GraphHopper storage not initialized"); - return ghStorage; + return baseGraph; } - public void setGraphHopperStorage(GraphHopperStorage ghStorage) { - this.ghStorage = ghStorage; + public void setBaseGraph(BaseGraph baseGraph) { + this.baseGraph = baseGraph; setFullyLoaded(); } + public StorableProperties getProperties() { + return properties; + } + /** * @return a mapping between profile names and according CH preparations. The map will be empty before loading * or import. @@ -662,8 +667,26 @@ private static ElevationProvider createElevationProvider(GraphHopperConfig ghCon private void printInfo() { logger.info("version " + Constants.VERSION + "|" + Constants.BUILD_DATE + " (" + Constants.getVersions() + ")"); - if (ghStorage != null) - logger.info("graph " + ghStorage.toString() + ", details:" + ghStorage.toDetailsString()); + if (baseGraph != null) + logger.info("graph " + getBaseGraphString() + ", details:" + baseGraph.toDetailsString()); + } + + private String getBaseGraphString() { + return encodingManager + + "|" + baseGraph.getDirectory().getDefaultType() + + "|" + baseGraph.getNodeAccess().getDimension() + "D" + + "|" + (baseGraph.getTurnCostStorage() != null ? baseGraph.getTurnCostStorage() : "no_turn_cost") + + "|" + getVersionsString(); + } + + private String getVersionsString() { + return "nodes:" + Constants.VERSION_NODE + + ",edges:" + Constants.VERSION_EDGE + + ",geometry:" + Constants.VERSION_GEOMETRY + + ",location_index:" + Constants.VERSION_LOCATION_IDX + + ",string_index:" + Constants.VERSION_EDGEKV_STORAGE + + ",nodesCH:" + Constants.VERSION_NODE_CH + + ",shortcuts:" + Constants.VERSION_SHORTCUT; } /** @@ -701,9 +724,9 @@ public void importAndClose() { private void process(boolean closeEarly) { GHLock lock = null; try { - if (ghStorage == null) - throw new IllegalStateException("GraphHopperStorage must be initialized before starting the import"); - if (ghStorage.getDirectory().getDefaultType().isStoring()) { + if (baseGraph == null) + throw new IllegalStateException("BaseGraph must be initialized before starting the import"); + if (baseGraph.getDirectory().getDefaultType().isStoring()) { lockFactory.setLockDir(new File(ghLocation)); lock = lockFactory.create(fileLockName, true); if (!lock.tryLock()) @@ -723,10 +746,10 @@ private void process(boolean closeEarly) { protected void postImport() { if (sortGraph) { - GraphHopperStorage newGraph = GHUtility.newStorage(ghStorage); - GHUtility.sortDFS(ghStorage, newGraph); + BaseGraph newGraph = GHUtility.newGraph(baseGraph); + GHUtility.sortDFS(baseGraph, newGraph); logger.info("graph sorted (" + getMemInfo() + ")"); - ghStorage = newGraph; + baseGraph = newGraph; } if (hasElevation()) @@ -746,7 +769,7 @@ protected void importOSM() { customAreas.addAll(readCustomAreas()); } AreaIndex areaIndex = new AreaIndex<>(customAreas); - + if (countryRuleFactory == null || countryRuleFactory.getCountryToRuleMap().isEmpty()) { logger.info("No country rules available"); } else { @@ -754,21 +777,31 @@ protected void importOSM() { } logger.info("start creating graph from " + osmFile); - OSMReader reader = new OSMReader(ghStorage.getBaseGraph(), encodingManager, osmParsers, osmReaderConfig).setFile(_getOSMFile()). + OSMReader reader = new OSMReader(baseGraph.getBaseGraph(), encodingManager, osmParsers, osmReaderConfig).setFile(_getOSMFile()). setAreaIndex(areaIndex). setElevationProvider(eleProvider). setCountryRuleFactory(countryRuleFactory); - logger.info("using " + ghStorage.toString() + ", memory:" + getMemInfo()); - ghStorage.create(100); + logger.info("using " + getBaseGraphString() + ", memory:" + getMemInfo()); + + createBaseGraphAndProperties(); + try { reader.readGraph(); } catch (IOException ex) { throw new RuntimeException("Cannot read file " + getOSMFile(), ex); } DateFormat f = createFormatter(); - ghStorage.getProperties().put("datareader.import.date", f.format(new Date())); + properties.put("datareader.import.date", f.format(new Date())); if (reader.getDataDate() != null) - ghStorage.getProperties().put("datareader.data.date", f.format(reader.getDataDate())); + properties.put("datareader.data.date", f.format(reader.getDataDate())); + } + + protected void createBaseGraphAndProperties() { + baseGraph.getDirectory().create(); + baseGraph.create(100); + properties.create(100); + properties.put("graph.encoded_values", encodingManager.toEncodedValuesAsString()); + properties.put("graph.flag_encoders", encodingManager.toFlagEncodersAsString()); } private List readCustomAreas() { @@ -832,12 +865,13 @@ public boolean load() { GHDirectory directory = new GHDirectory(ghLocation, dataAccessDefaultType); directory.configure(dataAccessConfig); - ghStorage = new GraphBuilder(getEncodingManager()) + baseGraph = new BaseGraph.Builder(getEncodingManager()) .setDir(directory) .set3D(hasElevation()) .withTurnCosts(encodingManager.needsTurnCostsSupport()) .setSegmentSize(defaultSegmentSize) .build(); + properties = new StorableProperties(directory); checkProfilesConsistency(); if (!new File(ghLocation).exists()) @@ -847,23 +881,23 @@ public boolean load() { try { // create locks only if writes are allowed, if they are not allowed a lock cannot be created // (e.g. on a read only filesystem locks would fail) - if (ghStorage.getDirectory().getDefaultType().isStoring() && isAllowWrites()) { + if (baseGraph.getDirectory().getDefaultType().isStoring() && isAllowWrites()) { lockFactory.setLockDir(new File(ghLocation)); lock = lockFactory.create(fileLockName, false); if (!lock.tryLock()) throw new RuntimeException("To avoid reading partial data we need to obtain the read lock but it failed. In " + ghLocation, lock.getObtainFailedReason()); } - if (!ghStorage.loadExisting()) + if (!loadBaseGraphAndProperties()) return false; - String storedProfiles = ghStorage.getProperties().get("profiles"); + String storedProfiles = properties.get("profiles"); String configuredProfiles = getProfilesString(); if (!storedProfiles.equals(configuredProfiles)) throw new IllegalStateException("Profiles do not match:" + "\nGraphhopper config: " + configuredProfiles + "\nGraph: " + storedProfiles - + "\nChange configuration to match the graph or delete " + ghStorage.getDirectory().getLocation()); + + "\nChange configuration to match the graph or delete " + baseGraph.getDirectory().getLocation()); postProcessing(false); directory.loadMMap(); @@ -875,6 +909,34 @@ public boolean load() { } } + private boolean loadBaseGraphAndProperties() { + if (properties.loadExisting()) { + if (properties.containsVersion()) + throw new IllegalStateException("The GraphHopper file format is not compatible with the data you are " + + "trying to load. You either need to use an older version of GraphHopper or run a new import"); + // check encoding for compatibility + String flagEncodersStr = properties.get("graph.flag_encoders"); + + if (!encodingManager.toFlagEncodersAsString().equalsIgnoreCase(flagEncodersStr)) { + throw new IllegalStateException("Flag encoders do not match:" + + "\nGraphhopper config: " + encodingManager.toFlagEncodersAsString() + + "\nLoaded graph: " + flagEncodersStr + + "\nChange configuration to match the graph or delete " + baseGraph.getDirectory().getLocation()); + } + + String encodedValueStr = properties.get("graph.encoded_values"); + if (!encodingManager.toEncodedValuesAsString().equalsIgnoreCase(encodedValueStr)) { + throw new IllegalStateException("Encoded values do not match:" + + "\nGraphhopper config: " + encodingManager.toEncodedValuesAsString() + + "\nLoaded graph: " + encodedValueStr + + "\nChange configuration to match the graph or delete " + baseGraph.getDirectory().getLocation()); + } + baseGraph.loadExisting(); + return true; + } + return false; + } + private String getProfilesString() { return profilesByName.values().stream().map(p -> p.getName() + "|" + p.getVersion()).collect(Collectors.joining(",")); } @@ -996,7 +1058,7 @@ protected void postProcessing(boolean closeEarly) { if (!includesCustomProfiles) // when there are custom profiles we must not close way geometry or EdgeKVStorage, because // they might be needed to evaluate the custom weightings for the following preparations - ghStorage.flushAndCloseGeometryAndNameStorage(); + baseGraph.flushAndCloseGeometryAndNameStorage(); } if (lmPreparationHandler.isEnabled()) @@ -1014,18 +1076,18 @@ protected void importPublicTransit() { } void interpolateBridgesTunnelsAndFerries() { - if (ghStorage.getEncodingManager().hasEncodedValue(RoadEnvironment.KEY)) { - EnumEncodedValue roadEnvEnc = ghStorage.getEncodingManager().getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class); + if (encodingManager.hasEncodedValue(RoadEnvironment.KEY)) { + EnumEncodedValue roadEnvEnc = encodingManager.getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class); StopWatch sw = new StopWatch().start(); - new EdgeElevationInterpolator(ghStorage.getBaseGraph(), roadEnvEnc, RoadEnvironment.TUNNEL).execute(); + new EdgeElevationInterpolator(baseGraph.getBaseGraph(), roadEnvEnc, RoadEnvironment.TUNNEL).execute(); float tunnel = sw.stop().getSeconds(); sw = new StopWatch().start(); - new EdgeElevationInterpolator(ghStorage.getBaseGraph(), roadEnvEnc, RoadEnvironment.BRIDGE).execute(); + new EdgeElevationInterpolator(baseGraph.getBaseGraph(), roadEnvEnc, RoadEnvironment.BRIDGE).execute(); float bridge = sw.stop().getSeconds(); // The SkadiProvider contains bathymetric data. For ferries this can result in bigger elevation changes // See #2098 for mor information sw = new StopWatch().start(); - new EdgeElevationInterpolator(ghStorage.getBaseGraph(), roadEnvEnc, RoadEnvironment.FERRY).execute(); + new EdgeElevationInterpolator(baseGraph.getBaseGraph(), roadEnvEnc, RoadEnvironment.FERRY).execute(); logger.info("Bridge interpolation " + (int) bridge + "s, " + "tunnel interpolation " + (int) tunnel + "s, ferry interpolation " + (int) sw.stop().getSeconds() + "s"); } } @@ -1039,7 +1101,7 @@ public final Weighting createWeighting(Profile profile, PMap hints, boolean disa } protected WeightingFactory createWeightingFactory() { - return new DefaultWeightingFactory(ghStorage.getBaseGraph(), getEncodingManager()); + return new DefaultWeightingFactory(baseGraph.getBaseGraph(), getEncodingManager()); } public GHResponse route(GHRequest request) { @@ -1047,27 +1109,27 @@ public GHResponse route(GHRequest request) { } private Router createRouter() { - if (ghStorage == null || !fullyLoaded) + if (baseGraph == null || !fullyLoaded) throw new IllegalStateException("Do a successful call to load or importOrLoad before routing"); - if (ghStorage.isClosed()) + if (baseGraph.isClosed()) throw new IllegalStateException("You need to create a new GraphHopper instance as it is already closed"); if (locationIndex == null) throw new IllegalStateException("Location index not initialized"); - return doCreateRouter(ghStorage, locationIndex, profilesByName, pathBuilderFactory, + return doCreateRouter(baseGraph, encodingManager, locationIndex, profilesByName, pathBuilderFactory, trMap, routerConfig, createWeightingFactory(), chGraphs, landmarks); } - protected Router doCreateRouter(GraphHopperStorage ghStorage, LocationIndex locationIndex, Map profilesByName, + protected Router doCreateRouter(BaseGraph baseGraph, EncodingManager encodingManager, LocationIndex locationIndex, Map profilesByName, PathDetailsBuilderFactory pathBuilderFactory, TranslationMap trMap, RouterConfig routerConfig, WeightingFactory weightingFactory, Map chGraphs, Map landmarks) { - return new Router(ghStorage.getBaseGraph(), ghStorage.getEncodingManager(), locationIndex, profilesByName, pathBuilderFactory, + return new Router(baseGraph, encodingManager, locationIndex, profilesByName, pathBuilderFactory, trMap, routerConfig, weightingFactory, chGraphs, landmarks ); } protected LocationIndex createLocationIndex(Directory dir) { - LocationIndexTree tmpIndex = new LocationIndexTree(ghStorage, dir); + LocationIndexTree tmpIndex = new LocationIndexTree(baseGraph, dir); tmpIndex.setResolution(preciseIndexResolution); tmpIndex.setMaxRegionSearch(maxRegionSearch); if (!tmpIndex.loadExisting()) { @@ -1085,23 +1147,23 @@ protected void initLocationIndex() { if (locationIndex != null) throw new IllegalStateException("Cannot initialize locationIndex twice!"); - locationIndex = createLocationIndex(ghStorage.getDirectory()); + locationIndex = createLocationIndex(baseGraph.getDirectory()); } private String getCHProfileVersion(String profile) { - return ghStorage.getProperties().get("graph.profiles.ch." + profile + ".version"); + return properties.get("graph.profiles.ch." + profile + ".version"); } private void setCHProfileVersion(String profile, int version) { - ghStorage.getProperties().put("graph.profiles.ch." + profile + ".version", version); + properties.put("graph.profiles.ch." + profile + ".version", version); } private String getLMProfileVersion(String profile) { - return ghStorage.getProperties().get("graph.profiles.lm." + profile + ".version"); + return properties.get("graph.profiles.lm." + profile + ".version"); } private void setLMProfileVersion(String profile, int version) { - ghStorage.getProperties().put("graph.profiles.lm." + profile + ".version", version); + properties.put("graph.profiles.lm." + profile + ".version", version); } protected void loadOrPrepareCH(boolean closeEarly) { @@ -1112,7 +1174,7 @@ protected void loadOrPrepareCH(boolean closeEarly) { // we load ch graphs that already exist and prepare the other ones List chConfigs = createCHConfigs(chPreparationHandler.getCHProfiles()); - Map loaded = chPreparationHandler.load(ghStorage.getBaseGraph(), chConfigs); + Map loaded = chPreparationHandler.load(baseGraph.getBaseGraph(), chConfigs); List configsToPrepare = chConfigs.stream().filter(c -> !loaded.containsKey(c.getName())).collect(Collectors.toList()); Map prepared = prepareCH(closeEarly, configsToPrepare); @@ -1124,7 +1186,7 @@ protected void loadOrPrepareCH(boolean closeEarly) { else if (prepared.containsKey(profile.getProfile())) { setCHProfileVersion(profile.getProfile(), profilesByName.get(profile.getProfile()).getVersion()); PrepareContractionHierarchies.Result res = prepared.get(profile.getProfile()); - chGraphs.put(profile.getProfile(), RoutingCHGraphImpl.fromGraph(ghStorage.getBaseGraph(), res.getCHStorage(), res.getCHConfig())); + chGraphs.put(profile.getProfile(), RoutingCHGraphImpl.fromGraph(baseGraph.getBaseGraph(), res.getCHStorage(), res.getCHConfig())); } else if (loaded.containsKey(profile.getProfile())) { chGraphs.put(profile.getProfile(), loaded.get(profile.getProfile())); } else @@ -1135,8 +1197,9 @@ else if (prepared.containsKey(profile.getProfile())) { protected Map prepareCH(boolean closeEarly, List configsToPrepare) { if (!configsToPrepare.isEmpty()) ensureWriteAccess(); - ghStorage.freeze(); - return chPreparationHandler.prepare(ghStorage, configsToPrepare, closeEarly); + if (!baseGraph.isFrozen()) + baseGraph.freeze(); + return chPreparationHandler.prepare(baseGraph, properties, configsToPrepare, closeEarly); } /** @@ -1150,7 +1213,7 @@ protected void loadOrPrepareLM(boolean closeEarly) { // we load landmark storages that already exist and prepare the other ones List lmConfigs = createLMConfigs(lmPreparationHandler.getLMProfiles()); - List loaded = lmPreparationHandler.load(lmConfigs, ghStorage.getBaseGraph(), ghStorage.getEncodingManager()); + List loaded = lmPreparationHandler.load(lmConfigs, baseGraph, encodingManager); List loadedConfigs = loaded.stream().map(LandmarkStorage::getLMConfig).collect(Collectors.toList()); List configsToPrepare = lmConfigs.stream().filter(c -> !loadedConfigs.contains(c)).collect(Collectors.toList()); List prepared = prepareLM(closeEarly, configsToPrepare); @@ -1175,19 +1238,20 @@ else if (preparedLMS.isPresent()) { protected List prepareLM(boolean closeEarly, List configsToPrepare) { if (!configsToPrepare.isEmpty()) ensureWriteAccess(); - ghStorage.freeze(); - return lmPreparationHandler.prepare(configsToPrepare, ghStorage, locationIndex, closeEarly); + if (!baseGraph.isFrozen()) + baseGraph.freeze(); + return lmPreparationHandler.prepare(configsToPrepare, baseGraph, encodingManager, properties, locationIndex, closeEarly); } /** * Internal method to clean up the graph. */ protected void cleanUp() { - PrepareRoutingSubnetworks preparation = new PrepareRoutingSubnetworks(ghStorage.getBaseGraph(), buildSubnetworkRemovalJobs()); + PrepareRoutingSubnetworks preparation = new PrepareRoutingSubnetworks(baseGraph.getBaseGraph(), buildSubnetworkRemovalJobs()); preparation.setMinNetworkSize(minNetworkSize); preparation.doWork(); - ghStorage.getProperties().put("profiles", getProfilesString()); - logger.info("nodes: " + Helper.nf(ghStorage.getNodes()) + ", edges: " + Helper.nf(ghStorage.getEdges())); + properties.put("profiles", getProfilesString()); + logger.info("nodes: " + Helper.nf(baseGraph.getNodes()) + ", edges: " + Helper.nf(baseGraph.getEdges())); } private List buildSubnetworkRemovalJobs() { @@ -1201,9 +1265,10 @@ private List buildSubnetworkRemovalJobs() { } protected void flush() { - logger.info("flushing graph " + ghStorage.toString() + ", details:" + ghStorage.toDetailsString() + ", " + logger.info("flushing graph " + getBaseGraphString() + ", details:" + baseGraph.toDetailsString() + ", " + getMemInfo() + ")"); - ghStorage.flush(); + baseGraph.flush(); + properties.flush(); logger.info("flushed graph " + getMemInfo() + ")"); setFullyLoaded(); } @@ -1213,8 +1278,10 @@ protected void flush() { * remove the files created in graphhopperLocation you have to call clean(). */ public void close() { - if (ghStorage != null) - ghStorage.close(); + if (baseGraph != null) + baseGraph.close(); + if (properties != null) + properties.close(); chGraphs.values().forEach(RoutingCHGraph::close); landmarks.values().forEach(LandmarkStorage::close); diff --git a/core/src/main/java/com/graphhopper/routing/Router.java b/core/src/main/java/com/graphhopper/routing/Router.java index c82571760fc..feb1a394345 100644 --- a/core/src/main/java/com/graphhopper/routing/Router.java +++ b/core/src/main/java/com/graphhopper/routing/Router.java @@ -65,8 +65,6 @@ public class Router { private final TranslationMap translationMap; private final RouterConfig routerConfig; private final WeightingFactory weightingFactory; - // todo: these should not be necessary anymore as soon as GraphHopperStorage (or something that replaces) it acts - // like a 'graph database' private final Map chGraphs; private final Map landmarks; private final boolean chEnabled; diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationHandler.java b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationHandler.java index 8d45bb2e629..3a39fbf1bbe 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationHandler.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationHandler.java @@ -115,14 +115,14 @@ public Map load(BaseGraph graph, List chConfig return loaded; } - public Map prepare(GraphHopperStorage ghStorage, List chConfigs, final boolean closeEarly) { + public Map prepare(BaseGraph baseGraph, StorableProperties properties, List chConfigs, final boolean closeEarly) { if (chConfigs.isEmpty()) { LOGGER.info("There are no CHs to prepare"); return Collections.emptyMap(); } LOGGER.info("Creating CH preparations, {}", getMemInfo()); List preparations = chConfigs.stream() - .map(c -> createCHPreparation(ghStorage.getBaseGraph(), c)) + .map(c -> createCHPreparation(baseGraph, c)) .collect(Collectors.toList()); Map results = Collections.synchronizedMap(new LinkedHashMap<>()); List> callables = new ArrayList<>(preparations.size()); @@ -139,7 +139,7 @@ public Map prepare(GraphHopperStor prepare.flush(); if (closeEarly) prepare.close(); - ghStorage.getProperties().put(CH.PREPARE + "date." + name, createFormatter().format(new Date())); + properties.put(CH.PREPARE + "date." + name, createFormatter().format(new Date())); return name; }); } diff --git a/core/src/main/java/com/graphhopper/routing/ch/PrepareContractionHierarchies.java b/core/src/main/java/com/graphhopper/routing/ch/PrepareContractionHierarchies.java index b95d86c687b..55d92e99d4f 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/PrepareContractionHierarchies.java +++ b/core/src/main/java/com/graphhopper/routing/ch/PrepareContractionHierarchies.java @@ -123,7 +123,7 @@ public Result doWork() { throw new IllegalStateException("Call doWork only once!"); prepared = true; if (!graph.isFrozen()) { - throw new IllegalStateException("Given GraphHopperStorage has not been frozen yet"); + throw new IllegalStateException("Given BaseGraph has not been frozen yet"); } if (chStore.getShortcuts() > 0) { throw new IllegalStateException("Given CHStore already contains shortcuts"); diff --git a/core/src/main/java/com/graphhopper/routing/lm/LMPreparationHandler.java b/core/src/main/java/com/graphhopper/routing/lm/LMPreparationHandler.java index 1ff78c3e4cc..7e5ecbb626f 100644 --- a/core/src/main/java/com/graphhopper/routing/lm/LMPreparationHandler.java +++ b/core/src/main/java/com/graphhopper/routing/lm/LMPreparationHandler.java @@ -23,8 +23,9 @@ import com.graphhopper.config.LMProfile; import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.util.AreaIndex; +import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.BaseGraph; -import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.storage.StorableProperties; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.util.GHUtility; import com.graphhopper.util.JsonFeatureCollection; @@ -172,8 +173,8 @@ public List load(List lmConfigs, BaseGraph baseGraph, /** * Prepares the landmark data for all given configs */ - public List prepare(List lmConfigs, GraphHopperStorage ghStorage, LocationIndex locationIndex, final boolean closeEarly) { - List preparations = createPreparations(lmConfigs, ghStorage.getBaseGraph(), ghStorage.getEncodingManager(), locationIndex); + public List prepare(List lmConfigs, BaseGraph baseGraph, EncodingManager encodingManager, StorableProperties properties, LocationIndex locationIndex, final boolean closeEarly) { + List preparations = createPreparations(lmConfigs, baseGraph, encodingManager, locationIndex); List> prepareCallables = new ArrayList<>(); for (int i = 0; i < preparations.size(); i++) { PrepareLandmarks prepare = preparations.get(i); @@ -186,7 +187,7 @@ public List prepare(List lmConfigs, GraphHopperStora if (closeEarly) prepare.close(); LOGGER.info("LM {} finished {}", name, getMemInfo()); - ghStorage.getProperties().put(Landmark.PREPARE + "date." + name, createFormatter().format(new Date())); + properties.put(Landmark.PREPARE + "date." + name, createFormatter().format(new Date())); return name; }); } diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/QueryGraph.java b/core/src/main/java/com/graphhopper/routing/querygraph/QueryGraph.java index cf7dd1825f0..f8b84fab864 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/QueryGraph.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/QueryGraph.java @@ -67,28 +67,10 @@ public static QueryGraph create(BaseGraph graph, Snap snap) { return QueryGraph.create(graph, Collections.singletonList(snap)); } - /** - * @deprecated currently we use this only for easier GraphHopperStorage -> BaseGraph migration - * instead of just calling graph.getBaseGraph() better try to convert graph to a BaseGraph - */ - @Deprecated - public static QueryGraph create(Graph graph, Snap snap) { - return create(graph.getBaseGraph(), snap); - } - public static QueryGraph create(BaseGraph graph, Snap fromSnap, Snap toSnap) { return QueryGraph.create(graph.getBaseGraph(), Arrays.asList(fromSnap, toSnap)); } - /** - * @deprecated currently we use this only for easier GraphHopperStorage -> BaseGraph migration - * instead of just calling graph.getBaseGraph() better try to convert graph to a BaseGraph - */ - @Deprecated - public static QueryGraph create(Graph graph, Snap fromSnap, Snap toSnap) { - return create(graph.getBaseGraph(), fromSnap, toSnap); - } - public static QueryGraph create(BaseGraph graph, List snaps) { return new QueryGraph(graph, snaps); } diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java index 68e87bb1553..1bb796941f3 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java @@ -36,8 +36,7 @@ /** * Abstract class which handles flag decoding and encoding. Every encoder should be registered to a - * EncodingManager to be usable. If you want the full long to be stored you need to enable this in - * the GraphHopperStorage. + * EncodingManager to be usable. * * @author Peter Karich * @author Nop diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index 2e2e2deeb93..bbf7869d29b 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -169,7 +169,11 @@ public BaseGraph create(long initSize) { return this; } - String toDetailsString() { + public int getIntsForFlags() { + return store.getIntsForFlags(); + } + + public String toDetailsString() { return store.toDetailsString() + ", " + "name:(" + edgeKVStorage.getCapacity() / Helper.MB + "MB), " + "geo:" + nf(maxGeoRef) + "(" + wayGeometry.getCapacity() / Helper.MB + "MB)"; @@ -178,7 +182,7 @@ String toDetailsString() { /** * Flush and free resources that are not needed for post-processing (way geometries and EdgeKVStorage). */ - void flushAndCloseGeometryAndNameStorage() { + public void flushAndCloseGeometryAndNameStorage() { setWayGeometryHeader(); wayGeometry.flush(); diff --git a/core/src/main/java/com/graphhopper/storage/CHStorage.java b/core/src/main/java/com/graphhopper/storage/CHStorage.java index 0a1c356ce8e..a54a178048e 100644 --- a/core/src/main/java/com/graphhopper/storage/CHStorage.java +++ b/core/src/main/java/com/graphhopper/storage/CHStorage.java @@ -83,12 +83,11 @@ public static CHStorage fromGraph(BaseGraph baseGraph, CHConfig chConfig) { " nodeA (" + nodeAccess.getLat(s.nodeA) + "," + nodeAccess.getLon(s.nodeA) + " nodeB " + nodeAccess.getLat(s.nodeB) + "," + nodeAccess.getLon(s.nodeB)); }); - store.create(); // we use a rather small value here. this might result in more allocations later, but they should // not matter that much. if we expect a too large value the shortcuts DataAccess will end up // larger than needed, because we do not do something like trimToSize in the end. double expectedShortcuts = 0.3 * baseGraph.getEdges(); - store.init(baseGraph.getNodes(), (int) expectedShortcuts); + store.create(baseGraph.getNodes(), (int) expectedShortcuts); return store; } @@ -123,30 +122,21 @@ public void setLowShortcutWeightConsumer(Consumer lowWeightSh /** * Creates a new storage. Alternatively we could load an existing one using {@link #loadExisting()}}. - */ - public void create() { - // We have to create the DataAccess here before we flush it. Otherwise we get an error when calling - // loadExisting() later, see #2384 - nodesCH.create(0); - shortcuts.create(0); - } - - /** - * Initializes the storage. The number of nodes must be given here while the expected number of shortcuts can + * The number of nodes must be given here while the expected number of shortcuts can * be given to prevent some memory allocations, but is not a requirement. When in doubt rather use a small value * so the resulting files/byte arrays won't be unnecessarily large. * todo: we could also trim down the shortcuts DataAccess when we are done adding shortcuts */ - public void init(int nodes, int expectedShortcuts) { + public void create(int nodes, int expectedShortcuts) { if (nodeCount >= 0) - throw new IllegalStateException("CHStorage can only be initialized once"); + throw new IllegalStateException("CHStorage can only be created once"); if (nodes < 0) - throw new IllegalStateException("CHStorage must be initialized with a positive number of nodes"); - nodesCH.ensureCapacity((long) nodes * nodeCHEntryBytes); + throw new IllegalStateException("CHStorage must be created with a positive number of nodes"); + nodesCH.create((long) nodes * nodeCHEntryBytes); nodeCount = nodes; - shortcuts.ensureCapacity((long) expectedShortcuts * shortcutEntryBytes); for (int node = 0; node < nodes; node++) setLastShortcut(toNodePointer(node), -1); + shortcuts.create((long) expectedShortcuts * shortcutEntryBytes); } public void flush() { diff --git a/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java b/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java index 8aa941241e2..c382ef517c0 100644 --- a/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java +++ b/core/src/main/java/com/graphhopper/storage/CHStorageBuilder.java @@ -31,9 +31,7 @@ public class CHStorageBuilder { private final CHStorage storage; public CHStorageBuilder(CHStorage chStorage) { - // todo: currently we create a GraphHopperStorage which creates a CHStorage for us, but really we should rather - // be able to create a GraphHopperStorage and build a CHStorage on top. So if anything CHStorageBuilder should - // create CHStorage, not receive it here. + // todo: maybe CHStorageBuilder should create CHStorage, not receive it here this.storage = chStorage; } diff --git a/core/src/main/java/com/graphhopper/storage/GHNodeAccess.java b/core/src/main/java/com/graphhopper/storage/GHNodeAccess.java index 9d0d396e4a0..ace800d23d7 100644 --- a/core/src/main/java/com/graphhopper/storage/GHNodeAccess.java +++ b/core/src/main/java/com/graphhopper/storage/GHNodeAccess.java @@ -18,9 +18,6 @@ package com.graphhopper.storage; /** - * A helper class for GraphHopperStorage for its node access. - *

- * * @author Peter Karich */ class GHNodeAccess implements NodeAccess { diff --git a/core/src/main/java/com/graphhopper/storage/GraphBuilder.java b/core/src/main/java/com/graphhopper/storage/GraphBuilder.java deleted file mode 100644 index 57e39f2308c..00000000000 --- a/core/src/main/java/com/graphhopper/storage/GraphBuilder.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.storage; - -import com.graphhopper.routing.util.EncodingManager; - -/** - * Used to build {@link GraphHopperStorage} - * - * @author Peter Karich - * @author easbar - */ -public class GraphBuilder { - private final EncodingManager encodingManager; - private Directory dir = new RAMDirectory(); - private boolean elevation; - private boolean turnCosts; - private long bytes = 100; - private int segmentSize = -1; - - public static GraphBuilder start(EncodingManager encodingManager) { - return new GraphBuilder(encodingManager); - } - - public GraphBuilder(EncodingManager encodingManager) { - this.encodingManager = encodingManager; - this.turnCosts = encodingManager.needsTurnCostsSupport(); - } - - public GraphBuilder setDir(Directory dir) { - this.dir = dir; - return this; - } - - public GraphBuilder setMMap(String location) { - return setDir(new MMapDirectory(location)); - } - - public GraphBuilder setRAM() { - return setDir(new RAMDirectory()); - } - - public GraphBuilder setRAM(String location) { - return setDir(new RAMDirectory(location)); - } - - public GraphBuilder setRAM(String location, boolean store) { - return setDir(new RAMDirectory(location, store)); - } - - public GraphBuilder set3D(boolean withElevation) { - this.elevation = withElevation; - return this; - } - - public GraphBuilder withTurnCosts(boolean turnCosts) { - this.turnCosts = turnCosts; - return this; - } - - public GraphBuilder setSegmentSize(int segmentSize) { - this.segmentSize = segmentSize; - return this; - } - - /** - * Default graph is a {@link GraphHopperStorage} with an in memory directory and disabled storing on flush. - * Afterwards you'll need to call {@link GraphHopperStorage#create} to have a usable object. Better use - * {@link #create} directly. - */ - public GraphHopperStorage build() { - return new GraphHopperStorage(dir, encodingManager, elevation, turnCosts, segmentSize); - } - - /** - * Default graph is a {@link GraphHopperStorage} with an in memory directory and disabled storing on flush. - */ - public GraphHopperStorage create() { - return build().create(bytes); - } - -} diff --git a/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java b/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java deleted file mode 100644 index fc3c73dbfd2..00000000000 --- a/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.storage; - -import com.graphhopper.routing.util.AllEdgesIterator; -import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.util.Constants; -import com.graphhopper.util.EdgeExplorer; -import com.graphhopper.util.EdgeIteratorState; -import com.graphhopper.util.shapes.BBox; - -import java.io.Closeable; - -/** - * This class manages all storage related methods and delegates the calls to the associated graphs. - * The associated graphs manage their own necessary data structures and are used to provide e.g. - * different traversal methods. By default this class implements the graph interface and results in - * identical behavior as the Graph instance from getBaseGraph() - *

- * - * @author Peter Karich - */ -public final class GraphHopperStorage implements Graph, Closeable { - private final Directory dir; - private final EncodingManager encodingManager; - private final StorableProperties properties; - private final BaseGraph baseGraph; - - /** - * Use {@link GraphBuilder} to create a graph - */ - public GraphHopperStorage(Directory dir, EncodingManager encodingManager, boolean withElevation, boolean withTurnCosts, int segmentSize) { - if (encodingManager == null) - throw new IllegalArgumentException("EncodingManager needs to be non-null since 0.7. Create one using EncodingManager.create or EncodingManager.create(flagEncoderFactory, ghLocation)"); - - this.encodingManager = encodingManager; - this.dir = dir; - this.properties = new StorableProperties(dir); - baseGraph = new BaseGraph(dir, encodingManager.getIntsForFlags(), withElevation, withTurnCosts, segmentSize); - } - - /** - * @return the directory where this graph is stored. - */ - public Directory getDirectory() { - return dir; - } - - /** - * After configuring this storage you need to create it explicitly. - */ - public GraphHopperStorage create(long byteCount) { - baseGraph.checkNotInitialized(); - if (encodingManager == null) - throw new IllegalStateException("EncodingManager can only be null if you call loadExisting"); - - dir.create(); - - properties.create(100); - properties.put("graph.encoded_values", encodingManager.toEncodedValuesAsString()); - properties.put("graph.flag_encoders", encodingManager.toFlagEncodersAsString()); - - baseGraph.create(Math.max(byteCount, 100)); - return this; - } - - public EncodingManager getEncodingManager() { - return encodingManager; - } - - public StorableProperties getProperties() { - return properties; - } - - public boolean loadExisting() { - baseGraph.checkNotInitialized(); - if (properties.loadExisting()) { - if (properties.containsVersion()) - throw new IllegalStateException("The GraphHopper file format is not compatible with the data you are " + - "trying to load. You either need to use an older version of GraphHopper or run a new import"); - // check encoding for compatibility - String flagEncodersStr = properties.get("graph.flag_encoders"); - - if (!encodingManager.toFlagEncodersAsString().equalsIgnoreCase(flagEncodersStr)) { - throw new IllegalStateException("Flag encoders do not match:" - + "\nGraphhopper config: " + encodingManager.toFlagEncodersAsString() - + "\nLoaded graph: " + flagEncodersStr - + "\nChange configuration to match the graph or delete " + dir.getLocation()); - } - - String encodedValueStr = properties.get("graph.encoded_values"); - if (!encodingManager.toEncodedValuesAsString().equalsIgnoreCase(encodedValueStr)) { - throw new IllegalStateException("Encoded values do not match:" - + "\nGraphhopper config: " + encodingManager.toEncodedValuesAsString() - + "\nLoaded graph: " + encodedValueStr - + "\nChange configuration to match the graph or delete " + dir.getLocation()); - } - baseGraph.loadExisting(); - return true; - } - return false; - } - - public void flush() { - baseGraph.flush(); - properties.flush(); - } - - @Override - public void close() { - properties.close(); - baseGraph.close(); - } - - public boolean isClosed() { - return baseGraph.isClosed(); - } - - public long getCapacity() { - return baseGraph.getCapacity() + properties.getCapacity(); - } - - /** - * Avoid that edges and nodes of the base graph are further modified. Necessary as hook for e.g. - * ch graphs on top to initialize themselves - */ - public synchronized void freeze() { - if (isFrozen()) - return; - baseGraph.freeze(); - } - - public boolean isFrozen() { - return baseGraph.isFrozen(); - } - - public String toDetailsString() { - return baseGraph.toDetailsString(); - } - - @Override - public String toString() { - return encodingManager - + "|" + getDirectory().getDefaultType() - + "|" + baseGraph.nodeAccess.getDimension() + "D" - + "|" + (baseGraph.supportsTurnCosts() ? baseGraph.turnCostStorage : "no_turn_cost") - + "|" + getVersionsString(); - } - - private String getVersionsString() { - return "nodes:" + Constants.VERSION_NODE + - ",edges:" + Constants.VERSION_EDGE + - ",geometry:" + Constants.VERSION_GEOMETRY + - ",location_index:" + Constants.VERSION_LOCATION_IDX + - ",string_index:" + Constants.VERSION_EDGEKV_STORAGE + - ",nodesCH:" + Constants.VERSION_NODE_CH + - ",shortcuts:" + Constants.VERSION_SHORTCUT; - } - - // now delegate all Graph methods to BaseGraph to avoid ugly programming flow ala - // GraphHopperStorage storage = ..; - // Graph g = storage.getBaseGraph(); - // instead directly the storage can be used to traverse the base graph - @Override - public BaseGraph getBaseGraph() { - return baseGraph; - } - - @Override - public int getNodes() { - return baseGraph.getNodes(); - } - - @Override - public int getEdges() { - return baseGraph.getEdges(); - } - - @Override - public NodeAccess getNodeAccess() { - return baseGraph.getNodeAccess(); - } - - @Override - public BBox getBounds() { - return baseGraph.getBounds(); - } - - @Override - public EdgeIteratorState edge(int a, int b) { - return baseGraph.edge(a, b); - } - - @Override - public EdgeIteratorState getEdgeIteratorState(int edgeId, int adjNode) { - return baseGraph.getEdgeIteratorState(edgeId, adjNode); - } - - @Override - public EdgeIteratorState getEdgeIteratorStateForKey(int edgeKey) { - return baseGraph.getEdgeIteratorStateForKey(edgeKey); - } - - @Override - public AllEdgesIterator getAllEdges() { - return baseGraph.getAllEdges(); - } - - @Override - public EdgeExplorer createEdgeExplorer(EdgeFilter filter) { - return baseGraph.createEdgeExplorer(filter); - } - - @Override - public TurnCostStorage getTurnCostStorage() { - return baseGraph.getTurnCostStorage(); - } - - @Override - public Weighting wrapWeighting(Weighting weighting) { - return weighting; - } - - @Override - public int getOtherNode(int edge, int node) { - return baseGraph.getOtherNode(edge, node); - } - - @Override - public boolean isAdjacentToNode(int edge, int node) { - return baseGraph.isAdjacentToNode(edge, node); - } - - /** - * Flush and free base graph resources like way geometries and EdgeKVStorage - */ - public void flushAndCloseGeometryAndNameStorage() { - baseGraph.flushAndCloseGeometryAndNameStorage(); - } - -} diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index c5ce254dc64..b06687f6e85 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -423,28 +423,25 @@ static Graph createSortedGraph(Graph fromGraph, Graph toSortedGraph, final IntIn return toSortedGraph; } - static Directory guessDirectory(GraphHopperStorage store) { - if (store.getDirectory() instanceof MMapDirectory) { + static Directory guessDirectory(BaseGraph graph) { + if (graph.getDirectory() instanceof MMapDirectory) { throw new IllegalStateException("not supported yet: mmap will overwrite existing storage at the same location"); } - String location = store.getDirectory().getLocation(); - boolean isStoring = ((GHDirectory) store.getDirectory()).isStoring(); + String location = graph.getDirectory().getLocation(); + boolean isStoring = ((GHDirectory) graph.getDirectory()).isStoring(); return new RAMDirectory(location, isStoring); } /** * Create a new storage from the specified one without copying the data. CHGraphs won't be copied. */ - public static GraphHopperStorage newStorage(GraphHopperStorage store) { - Directory outdir = guessDirectory(store); - boolean is3D = store.getNodeAccess().is3D(); - GraphHopperStorage copy = new GraphBuilder(store.getEncodingManager()) - .withTurnCosts(store.getTurnCostStorage() != null) - .set3D(is3D) + public static BaseGraph newGraph(BaseGraph baseGraph) { + Directory outdir = guessDirectory(baseGraph); + return new BaseGraph.Builder(baseGraph.getIntsForFlags()) + .withTurnCosts(baseGraph.getTurnCostStorage() != null) + .set3D(baseGraph.getNodeAccess().is3D()) .setDir(outdir) .create(); - copy.getProperties().putAll(store.getProperties().getAll()); - return copy; } public static int getAdjNode(Graph g, int edge, int adjNode) { diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 83b2af87a46..95d53002d45 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -1763,7 +1763,7 @@ public void testCompareAlgos(boolean turnCosts) { long seed = System.nanoTime(); Random rnd = new Random(seed); for (int i = 0; i < 100; i++) { - BBox bounds = hopper.getGraphHopperStorage().getBounds(); + BBox bounds = hopper.getBaseGraph().getBounds(); double lat1 = bounds.minLat + rnd.nextDouble() * (bounds.maxLat - bounds.minLat); double lat2 = bounds.minLat + rnd.nextDouble() * (bounds.maxLat - bounds.minLat); double lon1 = bounds.minLon + rnd.nextDouble() * (bounds.maxLon - bounds.minLon); @@ -2031,10 +2031,10 @@ public void testEdgeCount() { setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")); hopper.importOrLoad(); int count = 0; - AllEdgesIterator iter = hopper.getGraphHopperStorage().getAllEdges(); + AllEdgesIterator iter = hopper.getBaseGraph().getAllEdges(); while (iter.next()) count++; - assertEquals(hopper.getGraphHopperStorage().getEdges(), count); + assertEquals(hopper.getBaseGraph().getEdges(), count); } @Test @@ -2542,7 +2542,7 @@ public void testLoadGraph_implicitEncodedValues_issue1862() { .setGraphHopperLocation(GH_LOCATION) .setOSMFile(BAYREUTH); hopper.importOrLoad(); - int nodes = hopper.getGraphHopperStorage().getNodes(); + int nodes = hopper.getBaseGraph().getNodes(); hopper.close(); // load without configured FlagEncoders @@ -2553,8 +2553,8 @@ public void testLoadGraph_implicitEncodedValues_issue1862() { ); hopper.setGraphHopperLocation(GH_LOCATION); assertTrue(hopper.load()); - hopper.getGraphHopperStorage(); - assertEquals(nodes, hopper.getGraphHopperStorage().getNodes()); + hopper.getBaseGraph(); + assertEquals(nodes, hopper.getBaseGraph().getNodes()); hopper.close(); // load via explicitly configured FlagEncoders @@ -2566,7 +2566,7 @@ public void testLoadGraph_implicitEncodedValues_issue1862() { ); hopper.setGraphHopperLocation(GH_LOCATION); assertTrue(hopper.load()); - assertEquals(nodes, hopper.getGraphHopperStorage().getNodes()); + assertEquals(nodes, hopper.getBaseGraph().getNodes()); hopper.close(); } diff --git a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java index 734444ea1c2..12fdbbce2d0 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java @@ -164,13 +164,13 @@ public void testQueryLocationIndexWithBBox() { setOSMFile("../core/files/monaco.osm.gz"); gh.importOrLoad(); - final NodeAccess na = gh.getGraphHopperStorage().getNodeAccess(); + final NodeAccess na = gh.getBaseGraph().getNodeAccess(); final Collection indexNodeList = new TreeSet<>(); LocationIndexTree index = (LocationIndexTree) gh.getLocationIndex(); - final EdgeExplorer edgeExplorer = gh.getGraphHopperStorage().createEdgeExplorer(); + final EdgeExplorer edgeExplorer = gh.getBaseGraph().createEdgeExplorer(); final BBox bbox = new BBox(7.422, 7.429, 43.729, 43.734); index.query(bbox, edgeId -> { - EdgeIteratorState edge = gh.getGraphHopperStorage().getEdgeIteratorStateForKey(edgeId * 2); + EdgeIteratorState edge = gh.getBaseGraph().getEdgeIteratorStateForKey(edgeId * 2); for (int i = 0; i < 2; i++) { int nodeId = i == 0 ? edge.getBaseNode() : edge.getAdjNode(); double lat = na.getLat(nodeId); @@ -190,7 +190,7 @@ public void testQueryLocationIndexWithBBox() { new BreadthFirstSearch() { @Override protected GHBitSet createBitSet() { - return new GHBitSetImpl(gh.getGraphHopperStorage().getNodes()); + return new GHBitSetImpl(gh.getBaseGraph().getNodes()); } @Override @@ -417,8 +417,8 @@ public void testFootAndCar() { // Now it doesn't work like that anymore, so I set this parameter so the test doesn't fail. ((LocationIndexTree) instance.getLocationIndex()).setMaxRegionSearch(300); - assertEquals(5, instance.getGraphHopperStorage().getNodes()); - assertEquals(8, instance.getGraphHopperStorage().getEdges()); + assertEquals(5, instance.getBaseGraph().getNodes()); + assertEquals(8, instance.getBaseGraph().getEdges()); // A to D GHResponse grsp = instance.route(new GHRequest(11.1, 50, 11.3, 51).setProfile(profile1)); @@ -466,7 +466,7 @@ public void testFailsForWrongConfig() { ))). setGraphHopperLocation(ghLoc); instance.importOrLoad(); - assertEquals(5, instance.getGraphHopperStorage().getNodes()); + assertEquals(5, instance.getBaseGraph().getNodes()); instance.close(); // different config (flagEncoder list) @@ -540,9 +540,9 @@ public void testFailsForWrongEVConfig() { setGraphHopperLocation(ghLoc); instance.importOrLoad(); // older versions <= 0.12 did not store this property, ensure that we fail to load it - instance.getGraphHopperStorage().getProperties().remove("graph.encoded_values"); - instance.getGraphHopperStorage().flush(); - assertEquals(5, instance.getGraphHopperStorage().getNodes()); + instance.getProperties().remove("graph.encoded_values"); + instance.getBaseGraph().flush(); + assertEquals(5, instance.getBaseGraph().getNodes()); instance.close(); // different encoded values should fail to load @@ -647,8 +647,8 @@ public void testFootOnly() { ((LocationIndexTree) instance.getLocationIndex()).setMaxRegionSearch(300); - assertEquals(2, instance.getGraphHopperStorage().getNodes()); - assertEquals(2, instance.getGraphHopperStorage().getAllEdges().length()); + assertEquals(2, instance.getBaseGraph().getNodes()); + assertEquals(2, instance.getBaseGraph().getAllEdges().length()); // A to E only for foot GHResponse grsp = instance.route(new GHRequest(11.1, 50, 11.19, 52).setProfile(profile)); @@ -732,11 +732,11 @@ public void testMultipleCHPreparationsInParallel() { assertEquals((long) shortcutCount, chGraph.getValue().getShortcuts()); String keyError = Parameters.CH.PREPARE + "error." + name; - String valueError = hopper.getGraphHopperStorage().getProperties().get(keyError); + String valueError = hopper.getProperties().get(keyError); assertTrue(valueError.isEmpty(), "Properties for " + name + " should NOT contain error " + valueError + " [" + threadCount + "]"); String key = Parameters.CH.PREPARE + "date." + name; - String value = hopper.getGraphHopperStorage().getProperties().get(key); + String value = hopper.getProperties().get(key); assertFalse(value.isEmpty(), "Properties for " + name + " did NOT contain finish date [" + threadCount + "]"); } hopper.close(); @@ -781,11 +781,11 @@ public void testMultipleLMPreparationsInParallel() { assertEquals((int) landmarksCount, landmarks.getValue().getSubnetworksWithLandmarks()); String keyError = Parameters.Landmark.PREPARE + "error." + name; - String valueError = hopper.getGraphHopperStorage().getProperties().get(keyError); + String valueError = hopper.getProperties().get(keyError); assertTrue(valueError.isEmpty(), "Properties for " + name + " should NOT contain error " + valueError + " [" + threadCount + "]"); String key = Parameters.Landmark.PREPARE + "date." + name; - String value = hopper.getGraphHopperStorage().getProperties().get(key); + String value = hopper.getProperties().get(key); assertFalse(value.isEmpty(), "Properties for " + name + " did NOT contain finish date [" + threadCount + "]"); } hopper.close(); @@ -846,8 +846,7 @@ public void testProfilesMustNotBeChanged() { new Profile("car2").setVehicle("car").setWeighting("fastest") )); IllegalStateException e = assertThrows(IllegalStateException.class, hopper::importOrLoad); - // so far we get another error message in this case, because GraphHopperStorage checks the encoded values - // in loadExisting already + // so far we get another error message in this case, because we check the encoded values and encoders first assertTrue(e.getMessage().contains("Flag encoders do not match"), e.getMessage()); hopper.close(); } diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 8f70263eaf8..25ea3b1402b 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -82,12 +82,13 @@ public void tearDown() { @Test public void testMain() { GraphHopper hopper = new GraphHopperFacade(file1).importOrLoad(); - GraphHopperStorage graph = hopper.getGraphHopperStorage(); + BaseGraph graph = hopper.getBaseGraph(); + StorableProperties properties = hopper.getProperties(); - assertNotNull(graph.getProperties().get("datareader.import.date")); - assertNotEquals("", graph.getProperties().get("datareader.import.date")); + assertNotNull(properties.get("datareader.import.date")); + assertNotEquals("", properties.get("datareader.import.date")); - assertEquals("2013-01-02T01:10:14Z", graph.getProperties().get("datareader.data.date")); + assertEquals("2013-01-02T01:10:14Z", properties.get("datareader.data.date")); assertEquals(4, graph.getNodes()); int n20 = AbstractGraphStorageTester.getIdOf(graph, 52); @@ -143,7 +144,7 @@ protected int findID(LocationIndex index, double lat, double lon) { @Test public void testSort() { GraphHopper hopper = new GraphHopperFacade(file1).setSortGraph(true).importOrLoad(); - NodeAccess na = hopper.getGraphHopperStorage().getNodeAccess(); + NodeAccess na = hopper.getBaseGraph().getNodeAccess(); assertEquals(10, na.getLon(findID(hopper.getLocationIndex(), 49, 10)), 1e-3); assertEquals(51.249, na.getLat(findID(hopper.getLocationIndex(), 51.2492152, 9.4317166)), 1e-3); } @@ -153,9 +154,10 @@ public void testOneWay() { GraphHopper hopper = new GraphHopperFacade(file2) .setMinNetworkSize(0) .importOrLoad(); - GraphHopperStorage graph = hopper.getGraphHopperStorage(); + BaseGraph graph = hopper.getBaseGraph(); + StorableProperties properties = hopper.getProperties(); - assertEquals("2014-01-02T01:10:14Z", graph.getProperties().get("datareader.data.date")); + assertEquals("2014-01-02T01:10:14Z", properties.get("datareader.data.date")); int n20 = AbstractGraphStorageTester.getIdOf(graph, 52.0); int n22 = AbstractGraphStorageTester.getIdOf(graph, 52.133); @@ -205,7 +207,7 @@ public void testFerry() { public void cleanUp() { } }.importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); int n40 = AbstractGraphStorageTester.getIdOf(graph, 54.0); int n50 = AbstractGraphStorageTester.getIdOf(graph, 55.0); @@ -231,7 +233,7 @@ public void testMaxSpeed() { public void cleanUp() { } }.importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); int n60 = AbstractGraphStorageTester.getIdOf(graph, 56.0); EdgeIterator iter = carOutExplorer.setBaseNode(n60); @@ -242,7 +244,7 @@ public void cleanUp() { @Test public void testWayReferencesNotExistingAdjNode_issue19() { GraphHopper hopper = new GraphHopperFacade(file4).importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); assertEquals(2, graph.getNodes()); // the missing node is ignored, but the separated nodes are still connected @@ -256,7 +258,7 @@ public void testWayReferencesNotExistingAdjNode_issue19() { @Test public void testDoNotRejectEdgeIfFirstNodeIsMissing_issue2221() { GraphHopper hopper = new GraphHopperFacade("test-osm9.xml").importOrLoad(); - GraphHopperStorage graph = hopper.getGraphHopperStorage(); + BaseGraph graph = hopper.getBaseGraph(); assertEquals(2, graph.getNodes()); assertEquals(1, graph.getEdges()); AllEdgesIterator iter = graph.getAllEdges(); @@ -276,7 +278,7 @@ public void testDoNotRejectEdgeIfFirstNodeIsMissing_issue2221() { @Test public void test_edgeDistanceWhenFirstNodeIsMissing_issue2221() { GraphHopper hopper = new GraphHopperFacade("test-osm10.xml").importOrLoad(); - GraphHopperStorage graph = hopper.getGraphHopperStorage(); + BaseGraph graph = hopper.getBaseGraph(); assertEquals(3, graph.getNodes()); assertEquals(3, graph.getEdges()); AllEdgesIterator iter = graph.getAllEdges(); @@ -293,7 +295,7 @@ public void testFoot() { GraphHopper hopper = new GraphHopperFacade(file3) .setMinNetworkSize(0) .importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); int n10 = AbstractGraphStorageTester.getIdOf(graph, 11.1); int n20 = AbstractGraphStorageTester.getIdOf(graph, 12); @@ -316,7 +318,7 @@ public void testFoot() { public void testNegativeIds() { String fileNegIds = "test-osm-negative-ids.xml"; GraphHopper hopper = new GraphHopperFacade(fileNegIds).importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); assertEquals(4, graph.getNodes()); int n20 = AbstractGraphStorageTester.getIdOf(graph, 52); int n10 = AbstractGraphStorageTester.getIdOf(graph, 51.2492152); @@ -343,7 +345,7 @@ public void testBarriers() { setMinNetworkSize(0). importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); // we ignore the barrier at node 50, but not the one at node 20 assertEquals(7, graph.getNodes()); assertEquals(7, graph.getEdges()); @@ -382,7 +384,7 @@ public void testBarrierBetweenWays() { setMinNetworkSize(0). importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); // there are seven ways, but there should also be six barrier edges // we first split the loop way into two parts, and then we split the barrier node => 3 edges total assertEquals(7 + 6, graph.getEdges()); @@ -408,7 +410,7 @@ public void testFords() { ). setMinNetworkSize(0). importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); // our way is split into five edges, because there are two ford nodes assertEquals(5, graph.getEdges()); FlagEncoder encoder = hopper.getEncodingManager().fetchEdgeEncoders().get(0); @@ -437,7 +439,7 @@ public void avoidsLoopEdges_1525() { } void checkLoop(GraphHopper hopper) { - GraphHopperStorage graph = hopper.getGraphHopperStorage(); + BaseGraph graph = hopper.getBaseGraph(); // A, B, E and one of C or D should be tower nodes, in any case C and D should not be collapsed entirely // into a loop edge from B to B. @@ -471,7 +473,7 @@ public void testBarriersOnTowerNodes() { GraphHopper hopper = new GraphHopperFacade(fileBarriers). setMinNetworkSize(0). importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); // we ignore the barrier at node 50 // 10-20-30 produces three edges: 10-20, 20-2x, 2x-30, the second one is a barrier edge assertEquals(7, graph.getNodes()); @@ -526,7 +528,7 @@ public void testTurnRestrictions() { GraphHopper hopper = new GraphHopperFacade(fileTurnRestrictions, true, ""). importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); assertEquals(15, graph.getNodes()); TurnCostStorage tcStorage = graph.getTurnCostStorage(); assertNotNull(tcStorage); @@ -601,7 +603,7 @@ public void testRoadAttributes() { DecimalEncodedValue heightEnc = hopper.getEncodingManager().getDecimalEncodedValue(MaxHeight.KEY); DecimalEncodedValue weightEnc = hopper.getEncodingManager().getDecimalEncodedValue(MaxWeight.KEY); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); assertEquals(5, graph.getNodes()); int na = AbstractGraphStorageTester.getIdOf(graph, 11.1, 50); @@ -644,7 +646,7 @@ public void testReadEleFromDataProvider() { hopper.setElevationProvider(provider); hopper.importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); int n10 = AbstractGraphStorageTester.getIdOf(graph, 49.501); int n30 = AbstractGraphStorageTester.getIdOf(graph, 49.5011); int n50 = AbstractGraphStorageTester.getIdOf(graph, 49.5001); @@ -698,7 +700,7 @@ public void testTurnFlagCombination() { DecimalEncodedValue truckTCEnc = manager.getDecimalEncodedValue(TurnCost.key("truck")); DecimalEncodedValue bikeTCEnc = manager.getDecimalEncodedValue(TurnCost.key("bike")); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); TurnCostStorage tcStorage = graph.getTurnCostStorage(); int edge1 = GHUtility.getEdge(graph, 1, 0).getEdge(); @@ -729,7 +731,7 @@ public void testConditionalTurnRestriction() { setMinNetworkSize(0). importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); assertEquals(8, graph.getNodes()); TurnCostStorage tcStorage = graph.getTurnCostStorage(); assertNotNull(tcStorage); @@ -797,7 +799,7 @@ public void testMultipleTurnRestrictions() { GraphHopper hopper = new GraphHopperFacade(fileMultipleConditionalTurnRestrictions, true, ""). importOrLoad(); - Graph graph = hopper.getGraphHopperStorage(); + Graph graph = hopper.getBaseGraph(); assertEquals(5, graph.getNodes()); TurnCostStorage tcStorage = graph.getTurnCostStorage(); assertNotNull(tcStorage); @@ -838,7 +840,7 @@ public void testMultipleTurnRestrictions() { public void testPreferredLanguage() { GraphHopper hopper = new GraphHopperFacade(file1, false, "de"). importOrLoad(); - GraphHopperStorage graph = hopper.getGraphHopperStorage(); + BaseGraph graph = hopper.getBaseGraph(); int n20 = AbstractGraphStorageTester.getIdOf(graph, 52); EdgeIterator iter = carOutExplorer.setBaseNode(n20); assertTrue(iter.next()); @@ -846,7 +848,7 @@ public void testPreferredLanguage() { hopper = new GraphHopperFacade(file1, false, "el"). importOrLoad(); - graph = hopper.getGraphHopperStorage(); + graph = hopper.getBaseGraph(); n20 = AbstractGraphStorageTester.getIdOf(graph, 52); iter = carOutExplorer.setBaseNode(n20); assertTrue(iter.next()); @@ -859,9 +861,8 @@ public void testDataDateWithinPBF() { GraphHopper hopper = new GraphHopperFacade("test-osm6.pbf") .setMinNetworkSize(0) .importOrLoad(); - GraphHopperStorage graph = hopper.getGraphHopperStorage(); - - assertEquals("2014-01-02T00:10:14Z", graph.getProperties().get("datareader.data.date")); + StorableProperties properties = hopper.getProperties(); + assertEquals("2014-01-02T00:10:14Z", properties.get("datareader.data.date")); } @Test @@ -1004,14 +1005,14 @@ public GraphHopperFacade(String osmFile, boolean turnCosts, String prefLang) { @Override protected void importOSM() { - GraphHopperStorage tmpGraph = new GraphBuilder(getEncodingManager()).set3D(hasElevation()).withTurnCosts(getEncodingManager().needsTurnCostsSupport()).build(); - setGraphHopperStorage(tmpGraph); + BaseGraph baseGraph = new BaseGraph.Builder(getEncodingManager()).set3D(hasElevation()).withTurnCosts(getEncodingManager().needsTurnCostsSupport()).build(); + setBaseGraph(baseGraph); super.importOSM(); carEncoder = getEncodingManager().getEncoder("car"); footEncoder = getEncodingManager().getEncoder("foot"); carAccessEnc = carEncoder.getAccessEnc(); - carOutExplorer = getGraphHopperStorage().createEdgeExplorer(AccessFilter.outEdges(carAccessEnc)); - carAllExplorer = getGraphHopperStorage().createEdgeExplorer(AccessFilter.allEdges(carAccessEnc)); + carOutExplorer = getBaseGraph().createEdgeExplorer(AccessFilter.outEdges(carAccessEnc)); + carAllExplorer = getBaseGraph().createEdgeExplorer(AccessFilter.allEdges(carAccessEnc)); } @Override diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index ee6452af162..8dce1d5b190 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -74,7 +74,7 @@ public void testMonaco() { GraphHopper hopper = createHopper(MONACO, new Profile("car").setVehicle("car").setWeighting("shortest")); hopper.importOrLoad(); checkQueries(hopper, createMonacoCarQueries()); - Graph g = hopper.getGraphHopperStorage(); + Graph g = hopper.getBaseGraph(); // When OSM file stays unchanged make static edge and node IDs a requirement assertEquals(GHUtility.asSet(9, 111, 182), GHUtility.getNeighbors(g.createEdgeExplorer().setBaseNode(10))); @@ -268,7 +268,7 @@ public void testMonacoFoot() { new Profile("foot").setVehicle("foot").setWeighting("shortest")); hopper.importOrLoad(); checkQueries(hopper, createMonacoFoot()); - Graph g = hopper.getGraphHopperStorage(); + Graph g = hopper.getBaseGraph(); // see testMonaco for a similar ID test assertEquals(GHUtility.asSet(2, 909, 571), GHUtility.getNeighbors(g.createEdgeExplorer().setBaseNode(10))); @@ -440,7 +440,7 @@ public void testKremsBikeRelation() { new Profile("bike").setVehicle("bike").setWeighting("fastest")); hopper.importOrLoad(); checkQueries(hopper, queries); - hopper.getGraphHopperStorage(); + hopper.getBaseGraph(); Helper.removeDir(new File(GH_LOCATION)); diff --git a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java index ed1b698a3f0..924c8ca4b9c 100644 --- a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java +++ b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java @@ -35,7 +35,7 @@ /** * Abstract test class to be extended for implementations of the Graph interface. Graphs - * implementing GraphStorage should extend {@link GraphHopperStorageTest} instead. + * implementing GraphStorage should extend {@link BaseGraphTest} instead. *

* * @author Peter Karich diff --git a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java similarity index 99% rename from core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java rename to core/src/test/java/com/graphhopper/storage/BaseGraphTest.java index cdf3ad8a277..8cf003735eb 100644 --- a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java @@ -28,7 +28,7 @@ /** * @author Peter Karich */ -public class GraphHopperStorageTest extends AbstractGraphStorageTester { +public class BaseGraphTest extends AbstractGraphStorageTester { @Override public BaseGraph createGHStorage(String location, boolean enabled3D) { // reduce segment size in order to test the case where multiple segments come into the game diff --git a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java similarity index 98% rename from core/src/test/java/com/graphhopper/storage/GraphHopperStorageWithTurnCostsTest.java rename to core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java index 2f632b68bd0..e73beea37bd 100644 --- a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java @@ -34,7 +34,7 @@ /** * @author Karl Hübner */ -public class GraphHopperStorageWithTurnCostsTest extends GraphHopperStorageTest { +public class BaseGraphWithTurnCostsTest extends BaseGraphTest { @Override FlagEncoder createCarFlagEncoder() { return FlagEncoders.createCar(new PMap().putObject("max_turn_costs", 1400)); diff --git a/core/src/test/java/com/graphhopper/storage/CHStorageTest.java b/core/src/test/java/com/graphhopper/storage/CHStorageTest.java index bbea4ebde17..4524f8b7f3c 100644 --- a/core/src/test/java/com/graphhopper/storage/CHStorageTest.java +++ b/core/src/test/java/com/graphhopper/storage/CHStorageTest.java @@ -15,8 +15,7 @@ class CHStorageTest { void setAndGetLevels() { RAMDirectory dir = new RAMDirectory(); CHStorage store = new CHStorage(dir, "ch1", -1, false); - store.create(); - store.init(30, 5); + store.create(30, 5); assertEquals(0, store.getLevel(store.toNodePointer(10))); store.setLevel(store.toNodePointer(10), 100); assertEquals(100, store.getLevel(store.toNodePointer(10))); @@ -30,11 +29,7 @@ void createAndLoad(@TempDir Path path) { GHDirectory dir = new GHDirectory(path.toAbsolutePath().toString(), DAType.RAM_INT_STORE); CHStorage chStorage = new CHStorage(dir, "car", -1, false); // we have to call create, because we want to create a new storage not load an existing one - chStorage.create(); - // init is needed as well, because we have to set the nodes capacity and we cannot do this in create() yet. - // we can also not use init instead of create, because currently GraphHopperStorage needs to 'create' all - // its data objects. if we want to change this lifecycle we need to change this in GraphHopperStorage first - chStorage.init(5, 3); + chStorage.create(5, 3); assertEquals(0, chStorage.shortcutNodeBased(0, 1, PrepareEncoder.getScFwdDir(), 10, 3, 5)); assertEquals(1, chStorage.shortcutNodeBased(1, 2, PrepareEncoder.getScFwdDir(), 11, 4, 6)); assertEquals(2, chStorage.shortcutNodeBased(2, 3, PrepareEncoder.getScFwdDir(), 12, 5, 7)); diff --git a/example/src/main/java/com/graphhopper/example/IsochroneExample.java b/example/src/main/java/com/graphhopper/example/IsochroneExample.java index 1e20817c731..ff80ed904bd 100644 --- a/example/src/main/java/com/graphhopper/example/IsochroneExample.java +++ b/example/src/main/java/com/graphhopper/example/IsochroneExample.java @@ -25,7 +25,7 @@ public static void main(String[] args) { // snap some GPS coordinates to the routing graph and build a query graph FastestWeighting weighting = new FastestWeighting(encoder); Snap snap = hopper.getLocationIndex().findClosest(42.508679, 1.532078, new DefaultSnapFilter(weighting, encodingManager.getBooleanEncodedValue(Subnetwork.key("car")))); - QueryGraph queryGraph = QueryGraph.create(hopper.getGraphHopperStorage(), snap); + QueryGraph queryGraph = QueryGraph.create(hopper.getBaseGraph(), snap); // run the isochrone calculation ShortestPathTree tree = new ShortestPathTree(queryGraph, weighting, false, TraversalMode.NODE_BASED); diff --git a/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java b/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java index 435d76f923c..4761cb58979 100644 --- a/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java +++ b/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java @@ -33,7 +33,7 @@ public static void createAndSaveGraph() { { FlagEncoder encoder = FlagEncoders.createCar(); EncodingManager em = EncodingManager.create(encoder); - GraphHopperStorage graph = new GraphBuilder(em).setRAM(graphLocation, true).create(); + BaseGraph graph = new BaseGraph.Builder(em).setDir(new RAMDirectory(graphLocation, true)).create(); // Make a weighted edge between two nodes and set average speed to 50km/h EdgeIteratorState edge = graph.edge(0, 1).setDistance(1234).set(encoder.getAverageSpeedEnc(), 50); @@ -57,7 +57,7 @@ public static void createAndSaveGraph() { // note that the EncodingManager must be the same FlagEncoder encoder = FlagEncoders.createCar(); EncodingManager em = EncodingManager.create(encoder); - GraphHopperStorage graph = new GraphBuilder(em).setRAM(graphLocation, true).build(); + BaseGraph graph = new BaseGraph.Builder(em).setDir(new RAMDirectory(graphLocation, true)).build(); graph.loadExisting(); // Load the location index diff --git a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java index 44d784ddd34..aba6870c005 100644 --- a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java +++ b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java @@ -129,7 +129,7 @@ public MapMatching(GraphHopper graphHopper, PMap hints) { } else { landmarks = null; } - graph = graphHopper.getGraphHopperStorage().getBaseGraph(); + graph = graphHopper.getBaseGraph(); unwrappedWeighting = graphHopper.createWeighting(profile, hints); inSubnetworkEnc = graphHopper.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(profileStr)); this.maxVisitedNodes = hints.getInt(Parameters.Routing.MAX_VISITED_NODES, Integer.MAX_VALUE); diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java index 23f08c1a11e..1fb4b40283b 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java @@ -23,7 +23,6 @@ import com.graphhopper.GraphHopperConfig; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.storage.GraphHopperStorage; import com.graphhopper.storage.index.InMemConstructionIndex; import com.graphhopper.storage.index.IndexStructureInfo; import com.graphhopper.storage.index.LineIntIndex; @@ -56,15 +55,15 @@ protected void importOSM() { if (ghConfig.has("datareader.file")) { super.importOSM(); } else { - getGraphHopperStorage().create(1000); + createBaseGraphAndProperties(); } } @Override protected void importPublicTransit() { - ptGraph = new PtGraph(getGraphHopperStorage().getDirectory(), 100); - gtfsStorage = new GtfsStorage(getGraphHopperStorage().getDirectory()); - LineIntIndex stopIndex = new LineIntIndex(new BBox(-180.0, 180.0, -90.0, 90.0), getGraphHopperStorage().getDirectory(), "stop_index"); + ptGraph = new PtGraph(getBaseGraph().getDirectory(), 100); + gtfsStorage = new GtfsStorage(getBaseGraph().getDirectory()); + LineIntIndex stopIndex = new LineIntIndex(new BBox(-180.0, 180.0, -90.0, 90.0), getBaseGraph().getDirectory(), "stop_index"); if (getGtfsStorage().loadExisting()) { ptGraph.loadExisting(); stopIndex.loadExisting(); @@ -86,7 +85,7 @@ protected void importPublicTransit() { getGtfsStorage().getGtfsFeeds().forEach((id, gtfsFeed) -> { Transfers transfers = new Transfers(gtfsFeed); allTransfers.put(id, transfers); - GtfsReader gtfsReader = new GtfsReader(id, getGraphHopperStorage(), ptGraph, ptGraph, getGtfsStorage(), getLocationIndex(), transfers, indexBuilder); + GtfsReader gtfsReader = new GtfsReader(id, getBaseGraph(), getEncodingManager(), ptGraph, ptGraph, getGtfsStorage(), getLocationIndex(), transfers, indexBuilder); gtfsReader.connectStopsToStreetNetwork(); LOGGER.info("Building transit graph for feed {}", gtfsFeed.feedId); gtfsReader.buildPtNetwork(); @@ -107,8 +106,7 @@ protected void importPublicTransit() { private void interpolateTransfers(HashMap readers, Map allTransfers) { LOGGER.info("Looking for transfers"); final int maxTransferWalkTimeSeconds = ghConfig.getInt("gtfs.max_transfer_interpolation_walk_time_seconds", 120); - GraphHopperStorage graphHopperStorage = getGraphHopperStorage(); - QueryGraph queryGraph = QueryGraph.create(graphHopperStorage.getBaseGraph(), Collections.emptyList()); + QueryGraph queryGraph = QueryGraph.create(getBaseGraph(), Collections.emptyList()); Weighting transferWeighting = createWeighting(getProfile("foot"), new PMap()); final GraphExplorer graphExplorer = new GraphExplorer(queryGraph, ptGraph, transferWeighting, getGtfsStorage(), RealtimeFeed.empty(), true, true, false, 5.0, false, 0); getGtfsStorage().getStationNodes().values().stream().distinct().map(n -> { @@ -150,7 +148,7 @@ private void insertInterpolatedTransfer(Label label, GtfsStorage.PlatformDescrip List transitions = Label.getTransitions(label.parent, true); int[] skippedEdgesForTransfer = transitions.stream().filter(t -> t.edge != null).mapToInt(t -> { Label.NodeId adjNode = t.label.node; - EdgeIteratorState edgeIteratorState = getGraphHopperStorage().getEdgeIteratorState(t.edge.getId(), adjNode.streetNode); + EdgeIteratorState edgeIteratorState = getBaseGraph().getEdgeIteratorState(t.edge.getId(), adjNode.streetNode); return edgeIteratorState.getEdgeKey(); }).toArray(); if (skippedEdgesForTransfer.length > 0) { // TODO: Elsewhere, we distinguish empty path ("at" a node) from no path @@ -162,7 +160,7 @@ private void insertInterpolatedTransfer(Label label, GtfsStorage.PlatformDescrip } private boolean isValidPath(int[] edgeKeys) { - List edges = Arrays.stream(edgeKeys).mapToObj(i -> getGraphHopperStorage().getEdgeIteratorStateForKey(i)).collect(Collectors.toList()); + List edges = Arrays.stream(edgeKeys).mapToObj(i -> getBaseGraph().getEdgeIteratorStateForKey(i)).collect(Collectors.toList()); for (int i = 1; i < edges.size(); i++) { if (edges.get(i).getBaseNode() != edges.get(i-1).getAdjNode()) return false; diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java index caf38ef7150..8847de0a08a 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java @@ -28,7 +28,7 @@ import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.FastestWeighting; -import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.InMemConstructionIndex; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.Snap; @@ -77,7 +77,8 @@ static class TripWithStopTimes { private static final Logger LOGGER = LoggerFactory.getLogger(GtfsReader.class); - private final GraphHopperStorage graph; + private final BaseGraph baseGraph; + private final EncodingManager encodingManager; private final LocationIndex walkNetworkIndex; private final GtfsStorage gtfsStorage; @@ -87,9 +88,10 @@ static class TripWithStopTimes { private final Map>> departureTimelinesByStop = new HashMap<>(); private final Map>> arrivalTimelinesByStop = new HashMap<>(); - GtfsReader(String id, GraphHopperStorage graph, PtGraph ptGraph, PtGraphOut out, GtfsStorage gtfsStorage, LocationIndex walkNetworkIndex, Transfers transfers, InMemConstructionIndex indexBuilder) { + GtfsReader(String id, BaseGraph baseGraph, EncodingManager encodingManager, PtGraph ptGraph, PtGraphOut out, GtfsStorage gtfsStorage, LocationIndex walkNetworkIndex, Transfers transfers, InMemConstructionIndex indexBuilder) { this.id = id; - this.graph = graph; + this.baseGraph = baseGraph; + this.encodingManager = encodingManager; this.gtfsStorage = gtfsStorage; this.walkNetworkIndex = walkNetworkIndex; this.feed = this.gtfsStorage.getGtfsFeeds().get(id); @@ -102,9 +104,8 @@ static class TripWithStopTimes { } void connectStopsToStreetNetwork() { - EncodingManager em = graph.getEncodingManager(); - FlagEncoder footEncoder = em.getEncoder("foot"); - final EdgeFilter filter = new DefaultSnapFilter(new FastestWeighting(footEncoder), em.getBooleanEncodedValue(Subnetwork.key("foot"))); + FlagEncoder footEncoder = encodingManager.getEncoder("foot"); + final EdgeFilter filter = new DefaultSnapFilter(new FastestWeighting(footEncoder), encodingManager.getBooleanEncodedValue(Subnetwork.key("foot"))); for (Stop stop : feed.stops.values()) { if (stop.location_type == 0) { // Only stops. Not interested in parent stations for now. Snap locationSnap = walkNetworkIndex.findClosest(stop.stop_lat, stop.stop_lon, filter); diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtLocationSnapper.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtLocationSnapper.java index da45de5b754..c5eaa3d184d 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtLocationSnapper.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtLocationSnapper.java @@ -6,7 +6,7 @@ import com.conveyal.gtfs.model.Stop; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.Snap; import com.graphhopper.util.PointList; @@ -33,12 +33,12 @@ public Result(QueryGraph queryGraph, List nodes, PointList points) } } - GraphHopperStorage graphHopperStorage; + BaseGraph baseGraph; LocationIndex locationIndex; GtfsStorage gtfsStorage; - public PtLocationSnapper(GraphHopperStorage graphHopperStorage, LocationIndex locationIndex, GtfsStorage gtfsStorage) { - this.graphHopperStorage = graphHopperStorage; + public PtLocationSnapper(BaseGraph baseGraph, LocationIndex locationIndex, GtfsStorage gtfsStorage) { + this.baseGraph = baseGraph; this.locationIndex = locationIndex; this.gtfsStorage = gtfsStorage; } @@ -80,7 +80,7 @@ public Result snapAll(List locations, List snapFilters) points.add(stopSnap.getQueryPoint().lat, stopSnap.getQueryPoint().lon); } } - QueryGraph queryGraph = QueryGraph.create(graphHopperStorage.getBaseGraph(), pointSnaps); // modifies pointSnaps! + QueryGraph queryGraph = QueryGraph.create(baseGraph.getBaseGraph(), pointSnaps); // modifies pointSnaps! List nodes = new ArrayList<>(); for (Supplier supplier : allSnaps) { diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java index c94dfaf8449..7cd6e9f414c 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java @@ -30,9 +30,10 @@ import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.util.*; import com.graphhopper.util.details.PathDetailsBuilderFactory; @@ -50,7 +51,8 @@ public final class PtRouterFreeWalkImpl implements PtRouter { private final GraphHopperConfig config; private final TranslationMap translationMap; private final Weighting accessEgressWeighting; - private final GraphHopperStorage graphHopperStorage; + private final BaseGraph baseGraph; + private final EncodingManager encodingManager; private final LocationIndex locationIndex; private final GtfsStorage gtfsStorage; private final RealtimeFeed realtimeFeed; @@ -59,12 +61,13 @@ public final class PtRouterFreeWalkImpl implements PtRouter { private final PtGraph ptGraph; @Inject - public PtRouterFreeWalkImpl(GraphHopperConfig config, TranslationMap translationMap, GraphHopperStorage graphHopperStorage, LocationIndex locationIndex, GtfsStorage gtfsStorage, RealtimeFeed realtimeFeed, PathDetailsBuilderFactory pathDetailsBuilderFactory) { + public PtRouterFreeWalkImpl(GraphHopperConfig config, TranslationMap translationMap, BaseGraph baseGraph, EncodingManager encodingManager, LocationIndex locationIndex, GtfsStorage gtfsStorage, RealtimeFeed realtimeFeed, PathDetailsBuilderFactory pathDetailsBuilderFactory) { this.config = config; - this.weightingFactory = new DefaultWeightingFactory(graphHopperStorage.getBaseGraph(), graphHopperStorage.getEncodingManager()); - this.accessEgressWeighting = new FastestWeighting(graphHopperStorage.getEncodingManager().getEncoder("foot")); + this.weightingFactory = new DefaultWeightingFactory(baseGraph.getBaseGraph(), encodingManager); + this.accessEgressWeighting = new FastestWeighting(encodingManager.getEncoder("foot")); this.translationMap = translationMap; - this.graphHopperStorage = graphHopperStorage; + this.baseGraph = baseGraph; + this.encodingManager = encodingManager; this.locationIndex = locationIndex; this.gtfsStorage = gtfsStorage; this.realtimeFeed = realtimeFeed; @@ -80,15 +83,17 @@ public GHResponse route(Request request) { public static class Factory { private final GraphHopperConfig config; private final TranslationMap translationMap; - private final GraphHopperStorage graphHopperStorage; + private final BaseGraph baseGraph; + private final EncodingManager encodingManager; private final LocationIndex locationIndex; private final GtfsStorage gtfsStorage; private final Map transfers; - public Factory(GraphHopperConfig config, TranslationMap translationMap, GraphHopperStorage graphHopperStorage, LocationIndex locationIndex, GtfsStorage gtfsStorage) { + public Factory(GraphHopperConfig config, TranslationMap translationMap, BaseGraph baseGraph, EncodingManager encodingManager, LocationIndex locationIndex, GtfsStorage gtfsStorage) { this.config = config; this.translationMap = translationMap; - this.graphHopperStorage = graphHopperStorage; + this.baseGraph = baseGraph; + this.encodingManager = encodingManager; this.locationIndex = locationIndex; this.gtfsStorage = gtfsStorage; this.transfers = new HashMap<>(); @@ -100,11 +105,11 @@ public Factory(GraphHopperConfig config, TranslationMap translationMap, GraphHop public PtRouter createWith(GtfsRealtime.FeedMessage realtimeFeed) { Map realtimeFeeds = new HashMap<>(); realtimeFeeds.put("gtfs_0", realtimeFeed); - return new PtRouterFreeWalkImpl(config, translationMap, graphHopperStorage, locationIndex, gtfsStorage, RealtimeFeed.fromProtobuf(graphHopperStorage, gtfsStorage, this.transfers, realtimeFeeds), new PathDetailsBuilderFactory()); + return new PtRouterFreeWalkImpl(config, translationMap, baseGraph, encodingManager, locationIndex, gtfsStorage, RealtimeFeed.fromProtobuf(baseGraph, encodingManager, gtfsStorage, this.transfers, realtimeFeeds), new PathDetailsBuilderFactory()); } public PtRouter createWithoutRealtimeFeed() { - return new PtRouterFreeWalkImpl(config, translationMap, graphHopperStorage, locationIndex, gtfsStorage, RealtimeFeed.empty(), new PathDetailsBuilderFactory()); + return new PtRouterFreeWalkImpl(config, translationMap, baseGraph, encodingManager, locationIndex, gtfsStorage, RealtimeFeed.empty(), new PathDetailsBuilderFactory()); } } @@ -161,15 +166,15 @@ private class RequestHandler { requestedPathDetails = request.getPathDetails(); accessProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getAccessProfile())).findFirst().get(); accessWeighting = weightingFactory.createWeighting(accessProfile, new PMap(), false); - accessSnapFilter = new DefaultSnapFilter(new FastestWeighting(graphHopperStorage.getEncodingManager().getEncoder(accessProfile.getVehicle())), graphHopperStorage.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); + accessSnapFilter = new DefaultSnapFilter(new FastestWeighting(encodingManager.getEncoder(accessProfile.getVehicle())), encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); egressProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getEgressProfile())).findFirst().get(); egressWeighting = weightingFactory.createWeighting(egressProfile, new PMap(), false); - egressSnapFilter = new DefaultSnapFilter(new FastestWeighting(graphHopperStorage.getEncodingManager().getEncoder(egressProfile.getVehicle())), graphHopperStorage.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); + egressSnapFilter = new DefaultSnapFilter(new FastestWeighting(encodingManager.getEncoder(egressProfile.getVehicle())), encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); } GHResponse route() { StopWatch stopWatch = new StopWatch().start(); - PtLocationSnapper.Result result = new PtLocationSnapper(graphHopperStorage, locationIndex, gtfsStorage).snapAll(Arrays.asList(enter, exit), Arrays.asList(accessSnapFilter, egressSnapFilter)); + PtLocationSnapper.Result result = new PtLocationSnapper(baseGraph, locationIndex, gtfsStorage).snapAll(Arrays.asList(enter, exit), Arrays.asList(accessSnapFilter, egressSnapFilter)); queryGraph = result.queryGraph; response.addDebugInfo("idLookup:" + stopWatch.stop().getSeconds() + "s"); @@ -188,7 +193,7 @@ GHResponse route() { } private void parseSolutionsAndAddToResponse(List> solutions, PointList waypoints) { - TripFromLabel tripFromLabel = new TripFromLabel(queryGraph, graphHopperStorage.getEncodingManager(), gtfsStorage, realtimeFeed, pathDetailsBuilderFactory, walkSpeedKmH); + TripFromLabel tripFromLabel = new TripFromLabel(queryGraph, encodingManager, gtfsStorage, realtimeFeed, pathDetailsBuilderFactory, walkSpeedKmH); for (List solution : solutions) { final ResponsePath responsePath = tripFromLabel.createResponsePath(translation, waypoints, queryGraph, accessWeighting, egressWeighting, solution, requestedPathDetails); responsePath.setImpossible(solution.stream().anyMatch(t -> t.label.impossible)); diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java index 99e78e73d65..573679469d5 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java @@ -30,9 +30,10 @@ import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.util.*; import com.graphhopper.util.details.PathDetailsBuilderFactory; @@ -51,7 +52,8 @@ public final class PtRouterImpl implements PtRouter { private final GraphHopperConfig config; private final TranslationMap translationMap; - private final GraphHopperStorage graphHopperStorage; + private final BaseGraph baseGraph; + private final EncodingManager encodingManager; private final LocationIndex locationIndex; private final GtfsStorage gtfsStorage; private final PtGraph ptGraph; @@ -60,11 +62,12 @@ public final class PtRouterImpl implements PtRouter { private final WeightingFactory weightingFactory; @Inject - public PtRouterImpl(GraphHopperConfig config, TranslationMap translationMap, GraphHopperStorage graphHopperStorage, LocationIndex locationIndex, GtfsStorage gtfsStorage, RealtimeFeed realtimeFeed, PathDetailsBuilderFactory pathDetailsBuilderFactory) { + public PtRouterImpl(GraphHopperConfig config, TranslationMap translationMap, BaseGraph baseGraph, EncodingManager encodingManager, LocationIndex locationIndex, GtfsStorage gtfsStorage, RealtimeFeed realtimeFeed, PathDetailsBuilderFactory pathDetailsBuilderFactory) { this.config = config; - this.weightingFactory = new DefaultWeightingFactory(graphHopperStorage.getBaseGraph(), graphHopperStorage.getEncodingManager()); + this.weightingFactory = new DefaultWeightingFactory(baseGraph, encodingManager); this.translationMap = translationMap; - this.graphHopperStorage = graphHopperStorage; + this.baseGraph = baseGraph; + this.encodingManager = encodingManager; this.locationIndex = locationIndex; this.gtfsStorage = gtfsStorage; this.ptGraph = gtfsStorage.getPtGraph(); @@ -80,15 +83,17 @@ public GHResponse route(Request request) { public static class Factory { private final GraphHopperConfig config; private final TranslationMap translationMap; - private final GraphHopperStorage graphHopperStorage; + private final BaseGraph baseGraph; + private final EncodingManager encodingManager; private final LocationIndex locationIndex; private final GtfsStorage gtfsStorage; private final Map transfers; - public Factory(GraphHopperConfig config, TranslationMap translationMap, GraphHopperStorage graphHopperStorage, LocationIndex locationIndex, GtfsStorage gtfsStorage) { + public Factory(GraphHopperConfig config, TranslationMap translationMap, BaseGraph baseGraph, EncodingManager encodingManager, LocationIndex locationIndex, GtfsStorage gtfsStorage) { this.config = config; this.translationMap = translationMap; - this.graphHopperStorage = graphHopperStorage; + this.baseGraph = baseGraph; + this.encodingManager = encodingManager; this.locationIndex = locationIndex; this.gtfsStorage = gtfsStorage; this.transfers = new HashMap<>(); @@ -100,11 +105,11 @@ public Factory(GraphHopperConfig config, TranslationMap translationMap, GraphHop public PtRouter createWith(GtfsRealtime.FeedMessage realtimeFeed) { Map realtimeFeeds = new HashMap<>(); realtimeFeeds.put("gtfs_0", realtimeFeed); - return new PtRouterImpl(config, translationMap, graphHopperStorage, locationIndex, gtfsStorage, RealtimeFeed.fromProtobuf(graphHopperStorage, gtfsStorage, this.transfers, realtimeFeeds), new PathDetailsBuilderFactory()); + return new PtRouterImpl(config, translationMap, baseGraph, encodingManager, locationIndex, gtfsStorage, RealtimeFeed.fromProtobuf(baseGraph, encodingManager, gtfsStorage, this.transfers, realtimeFeeds), new PathDetailsBuilderFactory()); } public PtRouter createWithoutRealtimeFeed() { - return new PtRouterImpl(config, translationMap, graphHopperStorage, locationIndex, gtfsStorage, RealtimeFeed.empty(), new PathDetailsBuilderFactory()); + return new PtRouterImpl(config, translationMap, baseGraph, encodingManager, locationIndex, gtfsStorage, RealtimeFeed.empty(), new PathDetailsBuilderFactory()); } } @@ -161,15 +166,15 @@ private class RequestHandler { requestedPathDetails = request.getPathDetails(); accessProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getAccessProfile())).findFirst().get(); accessWeighting = weightingFactory.createWeighting(accessProfile, new PMap(), false); - accessSnapFilter = new DefaultSnapFilter(new FastestWeighting(graphHopperStorage.getEncodingManager().getEncoder(accessProfile.getVehicle())), graphHopperStorage.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); + accessSnapFilter = new DefaultSnapFilter(new FastestWeighting(encodingManager.getEncoder(accessProfile.getVehicle())), encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); egressProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getEgressProfile())).findFirst().get(); egressWeighting = weightingFactory.createWeighting(egressProfile, new PMap(), false); - egressSnapFilter = new DefaultSnapFilter(new FastestWeighting(graphHopperStorage.getEncodingManager().getEncoder(egressProfile.getVehicle())), graphHopperStorage.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); + egressSnapFilter = new DefaultSnapFilter(new FastestWeighting(encodingManager.getEncoder(egressProfile.getVehicle())), encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); } GHResponse route() { StopWatch stopWatch = new StopWatch().start(); - PtLocationSnapper.Result result = new PtLocationSnapper(graphHopperStorage, locationIndex, gtfsStorage).snapAll(Arrays.asList(enter, exit), Arrays.asList(accessSnapFilter, egressSnapFilter)); + PtLocationSnapper.Result result = new PtLocationSnapper(baseGraph, locationIndex, gtfsStorage).snapAll(Arrays.asList(enter, exit), Arrays.asList(accessSnapFilter, egressSnapFilter)); queryGraph = result.queryGraph; response.addDebugInfo("idLookup:" + stopWatch.stop().getSeconds() + "s"); @@ -188,7 +193,7 @@ GHResponse route() { } private void parseSolutionsAndAddToResponse(List> solutions, PointList waypoints) { - TripFromLabel tripFromLabel = new TripFromLabel(queryGraph, graphHopperStorage.getEncodingManager(), gtfsStorage, realtimeFeed, pathDetailsBuilderFactory, walkSpeedKmH); + TripFromLabel tripFromLabel = new TripFromLabel(queryGraph, encodingManager, gtfsStorage, realtimeFeed, pathDetailsBuilderFactory, walkSpeedKmH); for (List solution : solutions) { final ResponsePath responsePath = tripFromLabel.createResponsePath(translation, waypoints, queryGraph, accessWeighting, egressWeighting, solution, requestedPathDetails); responsePath.setImpossible(solution.stream().anyMatch(t -> t.label.impossible)); diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/RealtimeFeed.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/RealtimeFeed.java index ba5ff98c3b7..1a19c12a541 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/RealtimeFeed.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/RealtimeFeed.java @@ -26,7 +26,8 @@ import com.conveyal.gtfs.model.StopTime; import com.conveyal.gtfs.model.Trip; import com.google.transit.realtime.GtfsRealtime; -import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.storage.BaseGraph; import org.mapdb.Fun; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,7 +68,7 @@ public static RealtimeFeed empty() { return new RealtimeFeed(Collections.emptyMap(), new IntHashSet(), new IntLongHashMap(), new IntLongHashMap(), Collections.emptyList()); } - public static RealtimeFeed fromProtobuf(GraphHopperStorage graphHopperStorage, GtfsStorage staticGtfs, Map transfers, Map feedMessages) { + public static RealtimeFeed fromProtobuf(BaseGraph baseGraph, EncodingManager encodingManager, GtfsStorage staticGtfs, Map transfers, Map feedMessages) { final IntHashSet blockedEdges = new IntHashSet(); final IntLongHashMap delaysForBoardEdges = new IntLongHashMap(); final IntLongHashMap delaysForAlightEdges = new IntLongHashMap(); @@ -94,7 +95,7 @@ public int createNode() { GTFSFeed feed = staticGtfs.getGtfsFeeds().get(feedKey); ZoneId timezone = ZoneId.of(feed.agency.values().stream().findFirst().get().agency_timezone); PtGraph ptGraphNodesAndEdges = staticGtfs.getPtGraph(); - final GtfsReader gtfsReader = new GtfsReader(feedKey, graphHopperStorage, ptGraphNodesAndEdges, overlayGraph, staticGtfs, null, transfers.get(feedKey), null); + final GtfsReader gtfsReader = new GtfsReader(feedKey, baseGraph, encodingManager, ptGraphNodesAndEdges, overlayGraph, staticGtfs, null, transfers.get(feedKey), null); Instant timestamp = Instant.ofEpochSecond(feedMessage.getHeader().getTimestamp()); LocalDate dateToChange = timestamp.atZone(timezone).toLocalDate(); //FIXME BitSet validOnDay = new BitSet(); diff --git a/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java b/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java index 4dce057aef0..13b3ac4f19d 100644 --- a/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java +++ b/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java @@ -40,7 +40,8 @@ import static com.graphhopper.gtfs.GtfsHelper.time; import static com.graphhopper.util.Parameters.Details.EDGE_KEY; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; public class AnotherAgencyIT { @@ -62,7 +63,7 @@ public static void init() { graphHopperGtfs = new GraphHopperGtfs(ghConfig); graphHopperGtfs.init(ghConfig); graphHopperGtfs.importOrLoad(); - ptRouter = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getGraphHopperStorage(), graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage()) + ptRouter = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getBaseGraph(), graphHopperGtfs.getEncodingManager(), graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage()) .createWithoutRealtimeFeed(); } diff --git a/reader-gtfs/src/test/java/com/graphhopper/ExtendedRouteTypeIT.java b/reader-gtfs/src/test/java/com/graphhopper/ExtendedRouteTypeIT.java index e660fb00dac..8b0a3386729 100644 --- a/reader-gtfs/src/test/java/com/graphhopper/ExtendedRouteTypeIT.java +++ b/reader-gtfs/src/test/java/com/graphhopper/ExtendedRouteTypeIT.java @@ -57,7 +57,7 @@ public static void init() { graphHopperGtfs = new GraphHopperGtfs(ghConfig); graphHopperGtfs.init(ghConfig); graphHopperGtfs.importOrLoad(); - ptRouter = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getGraphHopperStorage(), graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage()).createWithoutRealtimeFeed(); + ptRouter = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getBaseGraph(), graphHopperGtfs.getEncodingManager(), graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage()).createWithoutRealtimeFeed(); } @AfterAll diff --git a/reader-gtfs/src/test/java/com/graphhopper/FreeWalkIT.java b/reader-gtfs/src/test/java/com/graphhopper/FreeWalkIT.java index 9cfbcdb7207..b1f2f03ffcf 100644 --- a/reader-gtfs/src/test/java/com/graphhopper/FreeWalkIT.java +++ b/reader-gtfs/src/test/java/com/graphhopper/FreeWalkIT.java @@ -30,7 +30,9 @@ import org.locationtech.jts.io.WKTReader; import java.io.File; -import java.time.*; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; import java.util.Arrays; import java.util.stream.Collectors; @@ -64,7 +66,7 @@ public static void init() { graphHopperGtfs = new GraphHopperGtfs(ghConfig); graphHopperGtfs.init(ghConfig); graphHopperGtfs.importOrLoad(); - ptRouter = new PtRouterFreeWalkImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getGraphHopperStorage(), graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage()) + ptRouter = new PtRouterFreeWalkImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getBaseGraph(), graphHopperGtfs.getEncodingManager(), graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage()) .createWithoutRealtimeFeed(); } diff --git a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperGtfsIT.java b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperGtfsIT.java index 5b224f006c2..1a875f113d7 100644 --- a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperGtfsIT.java +++ b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperGtfsIT.java @@ -64,7 +64,7 @@ public static void init() { graphHopperGtfs = new GraphHopperGtfs(ghConfig); graphHopperGtfs.init(ghConfig); graphHopperGtfs.importOrLoad(); - ptRouter = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getGraphHopperStorage(), graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage()) + ptRouter = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getBaseGraph(), graphHopperGtfs.getEncodingManager(), graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage()) .createWithoutRealtimeFeed(); } diff --git a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java index 7ed35fa89ad..f4b4c2a4d80 100644 --- a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java +++ b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java @@ -67,7 +67,7 @@ public static void init() { graphHopperGtfs.init(ghConfig); graphHopperGtfs.importOrLoad(); locationIndex = graphHopperGtfs.getLocationIndex(); - graphHopper = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getGraphHopperStorage(), locationIndex, graphHopperGtfs.getGtfsStorage()) + graphHopper = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getBaseGraph(), graphHopperGtfs.getEncodingManager(), locationIndex, graphHopperGtfs.getGtfsStorage()) .createWithoutRealtimeFeed(); } @@ -281,11 +281,11 @@ public void testSubnetworkRemoval() { // Go through all edges on removed foot subnetworks, and check that we can get to our destination station from there List responses = new ArrayList<>(); - AllEdgesIterator edges = graphHopperGtfs.getGraphHopperStorage().getAllEdges(); + AllEdgesIterator edges = graphHopperGtfs.getBaseGraph().getAllEdges(); while (edges.next()) { if (edges.get(footSub)) { Request ghRequest = new Request(Arrays.asList( - new GHPointLocation(new GHPoint(graphHopperGtfs.getGraphHopperStorage().getNodeAccess().getLat(edges.getBaseNode()), graphHopperGtfs.getGraphHopperStorage().getNodeAccess().getLon(edges.getBaseNode()))), + new GHPointLocation(new GHPoint(graphHopperGtfs.getBaseGraph().getNodeAccess().getLat(edges.getBaseNode()), graphHopperGtfs.getBaseGraph().getNodeAccess().getLon(edges.getBaseNode()))), new GHStationLocation("EMSI")), LocalDateTime.of(2007, 1, 1, 6, 40, 0).atZone(zoneId).toInstant()); ghRequest.setWalkSpeedKmH(50); // Yes, I can walk very fast, 50 km/h. Problem? diff --git a/reader-gtfs/src/test/java/com/graphhopper/RealtimeIT.java b/reader-gtfs/src/test/java/com/graphhopper/RealtimeIT.java index 72a67280f4f..2ac7c4aa179 100644 --- a/reader-gtfs/src/test/java/com/graphhopper/RealtimeIT.java +++ b/reader-gtfs/src/test/java/com/graphhopper/RealtimeIT.java @@ -67,7 +67,7 @@ public static void init() { graphHopperGtfs.init(ghConfig); graphHopperGtfs.importOrLoad(); - graphHopperFactory = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getGraphHopperStorage(), graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage()); + graphHopperFactory = new PtRouterImpl.Factory(ghConfig, new TranslationMap().doImport(), graphHopperGtfs.getBaseGraph(), graphHopperGtfs.getEncodingManager(), graphHopperGtfs.getLocationIndex(), graphHopperGtfs.getGtfsStorage()); } @AfterAll diff --git a/tools/src/main/java/com/graphhopper/tools/CHMeasurement.java b/tools/src/main/java/com/graphhopper/tools/CHMeasurement.java index 2eaeecfd561..96afb6b963e 100644 --- a/tools/src/main/java/com/graphhopper/tools/CHMeasurement.java +++ b/tools/src/main/java/com/graphhopper/tools/CHMeasurement.java @@ -208,7 +208,7 @@ private static String getStatLine(TreeSet keys, Map resu private static void runCompareTest(final String algo, final GraphHopper graphHopper, final boolean withTurnCosts, final int uTurnCosts, long seed, final int iterations, final double threshold, final PMap results) { LOGGER.info("Running compare test for {}, using seed {}", algo, seed); - Graph g = graphHopper.getGraphHopperStorage(); + Graph g = graphHopper.getBaseGraph(); final int numNodes = g.getNodes(); final NodeAccess nodeAccess = g.getNodeAccess(); final Random random = new Random(seed); @@ -291,7 +291,7 @@ public int doCalc(boolean warmup, int run) { private static void runPerformanceTest(final String algo, final GraphHopper graphHopper, final boolean withTurnCosts, long seed, final int iterations, final PMap results) { - Graph g = graphHopper.getGraphHopperStorage(); + Graph g = graphHopper.getBaseGraph(); final int numNodes = g.getNodes(); final NodeAccess nodeAccess = g.getNodeAccess(); final Random random = new Random(seed); diff --git a/tools/src/main/java/com/graphhopper/tools/Measurement.java b/tools/src/main/java/com/graphhopper/tools/Measurement.java index ab9d8143bb5..ada120fc1eb 100644 --- a/tools/src/main/java/com/graphhopper/tools/Measurement.java +++ b/tools/src/main/java/com/graphhopper/tools/Measurement.java @@ -175,7 +175,7 @@ protected void importOSM() { hopper.importOrLoad(); - BaseGraph g = hopper.getGraphHopperStorage().getBaseGraph(); + BaseGraph g = hopper.getBaseGraph(); EncodingManager encodingManager = hopper.getEncodingManager(); if (encodingManager.fetchEdgeEncoders().size() != 1) { throw new IllegalArgumentException("There has to be exactly one encoder for each measurement"); @@ -538,7 +538,7 @@ private void measureCountryAreaIndex(int count) { } private void measureRouting(final GraphHopper hopper, final QuerySettings querySettings) { - final Graph g = hopper.getGraphHopperStorage(); + final Graph g = hopper.getBaseGraph(); final AtomicLong maxDistance = new AtomicLong(0); final AtomicLong minDistance = new AtomicLong(Long.MAX_VALUE); final AtomicLong distSum = new AtomicLong(0); @@ -586,7 +586,7 @@ private void measureRouting(final GraphHopper hopper, final QuerySettings queryS try { req.getHints().putObject(BLOCK_AREA, querySettings.blockArea); // run this method to check if creating the blocked area is possible - GraphEdgeIdFinder.createBlockArea(hopper.getGraphHopperStorage(), hopper.getLocationIndex(), req.getPoints(), req.getHints(), edgeFilter); + GraphEdgeIdFinder.createBlockArea(hopper.getBaseGraph(), hopper.getLocationIndex(), req.getPoints(), req.getHints(), edgeFilter); break; } catch (IllegalArgumentException ex) { if (i >= 4) diff --git a/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java b/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java index 8389de69753..2decd67a603 100644 --- a/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java +++ b/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java @@ -118,7 +118,7 @@ public static void main(String[] strs) { } public MiniGraphUI(GraphHopper hopper, boolean debug, boolean useCH) { - this.graph = hopper.getGraphHopperStorage().getBaseGraph(); + this.graph = hopper.getBaseGraph(); this.na = graph.getNodeAccess(); encoder = hopper.getEncodingManager().fetchEdgeEncoders().get(0); avSpeedEnc = encoder.getAverageSpeedEnc(); diff --git a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java index 764da6de617..f1821b35b93 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java +++ b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java @@ -31,7 +31,7 @@ import com.graphhopper.resources.*; import com.graphhopper.routing.ProfileResolver; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.util.TranslationMap; import com.graphhopper.util.details.PathDetailsBuilderFactory; @@ -61,18 +61,18 @@ public void dispose(TranslationMap instance) { } } - static class GraphHopperStorageFactory implements Factory { + static class BaseGraphFactory implements Factory { @Inject GraphHopper graphHopper; @Override - public GraphHopperStorage provide() { - return graphHopper.getGraphHopperStorage(); + public BaseGraph provide() { + return graphHopper.getBaseGraph(); } @Override - public void dispose(GraphHopperStorage instance) { + public void dispose(BaseGraph instance) { } } @@ -242,7 +242,7 @@ protected void configure() { bindFactory(LocationIndexFactory.class).to(LocationIndex.class); bindFactory(TranslationMapFactory.class).to(TranslationMap.class); bindFactory(EncodingManagerFactory.class).to(EncodingManager.class); - bindFactory(GraphHopperStorageFactory.class).to(GraphHopperStorage.class); + bindFactory(BaseGraphFactory.class).to(BaseGraph.class); bindFactory(GtfsStorageFactory.class).to(GtfsStorage.class); } }); diff --git a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java index acb7fa806b8..7a84312f877 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java +++ b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java @@ -105,7 +105,7 @@ public void start() { graphHopper.getGraphHopperLocation(), graphHopper.getOSMFile(), graphHopper.getEncodingManager().toEncodedValuesAsString(), graphHopper.getEncodingManager().getIntsForFlags(), - graphHopper.getGraphHopperStorage().toDetailsString()); + graphHopper.getBaseGraph().toDetailsString()); } public GraphHopper getGraphHopper() { diff --git a/web-bundle/src/main/java/com/graphhopper/http/RealtimeFeedLoadingCache.java b/web-bundle/src/main/java/com/graphhopper/http/RealtimeFeedLoadingCache.java index b555192b2b6..d6f2f3e3620 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/RealtimeFeedLoadingCache.java +++ b/web-bundle/src/main/java/com/graphhopper/http/RealtimeFeedLoadingCache.java @@ -28,7 +28,8 @@ import com.graphhopper.gtfs.GtfsStorage; import com.graphhopper.gtfs.RealtimeFeed; import com.graphhopper.gtfs.Transfers; -import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.storage.BaseGraph; import io.dropwizard.lifecycle.Managed; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; @@ -47,7 +48,8 @@ public class RealtimeFeedLoadingCache implements Factory, Managed { private final HttpClient httpClient; - private final GraphHopperStorage graphHopperStorage; + private final BaseGraph baseGraph; + private final EncodingManager encodingManager; private final GtfsStorage gtfsStorage; private final RealtimeBundleConfiguration bundleConfiguration; private ExecutorService executor; @@ -55,8 +57,9 @@ public class RealtimeFeedLoadingCache implements Factory, Managed private Map transfers; @Inject - RealtimeFeedLoadingCache(GraphHopperStorage graphHopperStorage, GtfsStorage gtfsStorage, HttpClient httpClient, RealtimeBundleConfiguration bundleConfiguration) { - this.graphHopperStorage = graphHopperStorage; + RealtimeFeedLoadingCache(BaseGraph baseGraph, EncodingManager encodingManager, GtfsStorage gtfsStorage, HttpClient httpClient, RealtimeBundleConfiguration bundleConfiguration) { + this.baseGraph = baseGraph; + this.encodingManager = encodingManager; this.gtfsStorage = gtfsStorage; this.bundleConfiguration = bundleConfiguration; this.httpClient = httpClient; @@ -115,7 +118,7 @@ private RealtimeFeed fetchFeedsAndCreateGraph() { throw new RuntimeException(e); } } - return RealtimeFeed.fromProtobuf(graphHopperStorage, gtfsStorage, this.transfers, feedMessageMap); + return RealtimeFeed.fromProtobuf(baseGraph, encodingManager, gtfsStorage, this.transfers, feedMessageMap); } } diff --git a/web-bundle/src/main/java/com/graphhopper/http/health/GraphHopperHealthCheck.java b/web-bundle/src/main/java/com/graphhopper/http/health/GraphHopperHealthCheck.java index 63c3db0bda7..5abfa8a07d1 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/health/GraphHopperHealthCheck.java +++ b/web-bundle/src/main/java/com/graphhopper/http/health/GraphHopperHealthCheck.java @@ -31,8 +31,8 @@ public GraphHopperHealthCheck(GraphHopper graphHopper) { @Override protected Result check() { - if (!graphHopper.getGraphHopperStorage().getBounds().isValid()) { - return Result.unhealthy("GraphHopperStorage has invalid bounds."); + if (!graphHopper.getBaseGraph().getBounds().isValid()) { + return Result.unhealthy("BaseGraph has invalid bounds."); } if (!graphHopper.getFullyLoaded()) { return Result.unhealthy("GraphHopper is not fully loaded."); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/InfoResource.java b/web-bundle/src/main/java/com/graphhopper/resources/InfoResource.java index 053b6809b32..58564c0151a 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/InfoResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/InfoResource.java @@ -21,7 +21,9 @@ import com.graphhopper.GraphHopperConfig; import com.graphhopper.config.Profile; import com.graphhopper.routing.ev.*; -import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.storage.BaseGraph; +import com.graphhopper.storage.StorableProperties; import com.graphhopper.util.Constants; import org.locationtech.jts.geom.Envelope; @@ -41,13 +43,17 @@ public class InfoResource { private final GraphHopperConfig config; - private final GraphHopperStorage storage; + private final BaseGraph baseGraph; + private final EncodingManager encodingManager; + private final StorableProperties properties; private final boolean hasElevation; @Inject public InfoResource(GraphHopperConfig config, GraphHopper graphHopper, @Named("hasElevation") Boolean hasElevation) { this.config = config; - this.storage = graphHopper.getGraphHopperStorage(); + this.baseGraph = graphHopper.getBaseGraph(); + this.encodingManager = graphHopper.getEncodingManager(); + this.properties = graphHopper.getProperties(); this.hasElevation = hasElevation; } @@ -78,7 +84,7 @@ public ProfileData(String name, String vehicle) { @GET public Info getInfo() { final Info info = new Info(); - info.bbox = new Envelope(storage.getBounds().minLon, storage.getBounds().maxLon, storage.getBounds().minLat, storage.getBounds().maxLat); + info.bbox = new Envelope(baseGraph.getBounds().minLon, baseGraph.getBounds().maxLon, baseGraph.getBounds().minLat, baseGraph.getBounds().maxLat); for (Profile p : config.getProfiles()) { Info.ProfileData profileData = new Info.ProfileData(p.getName(), p.getVehicle()); info.profiles.add(profileData); @@ -87,15 +93,15 @@ public Info getInfo() { info.profiles.add(new Info.ProfileData("pt", "pt")); info.elevation = hasElevation; - List encoderNames = Arrays.asList(storage.getEncodingManager().toString().split(",")); + List encoderNames = Arrays.asList(encodingManager.toString().split(",")); info.supported_vehicles = new ArrayList<>(encoderNames); if (config.has("gtfs.file")) { info.supported_vehicles.add("pt"); } - info.import_date = storage.getProperties().get("datareader.import.date"); - info.data_date = storage.getProperties().get("datareader.data.date"); + info.import_date = properties.get("datareader.import.date"); + info.data_date = properties.get("datareader.data.date"); - List evList = storage.getEncodingManager().getEncodedValues(); + List evList = encodingManager.getEncodedValues(); info.encoded_values = new LinkedHashMap<>(); for (EncodedValue encodedValue : evList) { List possibleValueList = new ArrayList<>(); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java b/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java index fa6bf52f0b7..0ec76366081 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java @@ -18,7 +18,7 @@ import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.BlockAreaWeighting; import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.storage.Graph; +import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.GraphEdgeIdFinder; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.Snap; @@ -35,11 +35,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.OptionalInt; -import java.util.OptionalLong; +import java.util.*; import java.util.function.ToDoubleFunction; import static com.graphhopper.resources.IsochroneResource.ResponseType.geojson; @@ -95,7 +91,7 @@ public Response doGet( if (profile == null) throw new IllegalArgumentException("The requested profile '" + profileName + "' does not exist"); LocationIndex locationIndex = graphHopper.getLocationIndex(); - Graph graph = graphHopper.getGraphHopperStorage(); + BaseGraph graph = graphHopper.getBaseGraph(); Weighting weighting = graphHopper.createWeighting(profile, hintsMap); BooleanEncodedValue inSubnetworkEnc = graphHopper.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(profileName)); if (hintsMap.has(Parameters.Routing.BLOCK_AREA)) { diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java index d74d2a3e9bb..98f330b6deb 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java @@ -70,7 +70,7 @@ public Response doGetXyz( Coordinate nw = num2deg(xInfo, yInfo, zInfo); Coordinate se = num2deg(xInfo + 1, yInfo + 1, zInfo); LocationIndexTree locationIndex = (LocationIndexTree) graphHopper.getLocationIndex(); - final NodeAccess na = graphHopper.getGraphHopperStorage().getNodeAccess(); + final NodeAccess na = graphHopper.getBaseGraph().getNodeAccess(); BBox bbox = new BBox(nw.x, se.x, se.y, nw.y); if (!bbox.isValid()) throw new IllegalStateException("Invalid bbox " + bbox); @@ -92,7 +92,7 @@ public Response doGetXyz( final VectorTile.Tile.Layer.Builder layerBuilder = MvtLayerBuild.newLayerBuilder("roads", layerParams); locationIndex.query(bbox, edgeId -> { - EdgeIteratorState edge = graphHopper.getGraphHopperStorage().getEdgeIteratorStateForKey(edgeId * 2); + EdgeIteratorState edge = graphHopper.getBaseGraph().getEdgeIteratorStateForKey(edgeId * 2); LineString lineString; RoadClass rc = edge.get(roadClassEnc); if (zInfo >= 14) { diff --git a/web-bundle/src/main/java/com/graphhopper/resources/PtIsochroneResource.java b/web-bundle/src/main/java/com/graphhopper/resources/PtIsochroneResource.java index bab5927f0ca..f364f1dff41 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/PtIsochroneResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/PtIsochroneResource.java @@ -31,7 +31,7 @@ import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.storage.GraphHopperStorage; +import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.NodeAccess; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.util.EdgeIteratorState; @@ -59,14 +59,14 @@ public class PtIsochroneResource { private final GtfsStorage gtfsStorage; private final EncodingManager encodingManager; - private final GraphHopperStorage graphHopperStorage; + private final BaseGraph baseGraph; private final LocationIndex locationIndex; @Inject - public PtIsochroneResource(GtfsStorage gtfsStorage, EncodingManager encodingManager, GraphHopperStorage graphHopperStorage, LocationIndex locationIndex) { + public PtIsochroneResource(GtfsStorage gtfsStorage, EncodingManager encodingManager, BaseGraph baseGraph, LocationIndex locationIndex) { this.gtfsStorage = gtfsStorage; this.encodingManager = encodingManager; - this.graphHopperStorage = graphHopperStorage; + this.baseGraph = baseGraph; this.locationIndex = locationIndex; } @@ -96,9 +96,9 @@ public Response doGet( GeometryFactory geometryFactory = new GeometryFactory(); final FlagEncoder footEncoder = encodingManager.getEncoder("foot"); final Weighting weighting = new FastestWeighting(footEncoder); - DefaultSnapFilter snapFilter = new DefaultSnapFilter(weighting, graphHopperStorage.getEncodingManager().getBooleanEncodedValue(Subnetwork.key("foot"))); + DefaultSnapFilter snapFilter = new DefaultSnapFilter(weighting, encodingManager.getBooleanEncodedValue(Subnetwork.key("foot"))); - PtLocationSnapper.Result snapResult = new PtLocationSnapper(graphHopperStorage, locationIndex, gtfsStorage).snapAll(Arrays.asList(location), Arrays.asList(snapFilter)); + PtLocationSnapper.Result snapResult = new PtLocationSnapper(baseGraph, locationIndex, gtfsStorage).snapAll(Arrays.asList(location), Arrays.asList(snapFilter)); GraphExplorer graphExplorer = new GraphExplorer(snapResult.queryGraph, gtfsStorage.getPtGraph(), weighting, gtfsStorage, RealtimeFeed.empty(), reverseFlow, false, false, 5.0, reverseFlow, blockedRouteTypes); MultiCriteriaLabelSetting router = new MultiCriteriaLabelSetting(graphExplorer, reverseFlow, false, false, 0, Collections.emptyList()); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java index b2916fc81cf..b4914b0155b 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java @@ -13,7 +13,7 @@ import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.BlockAreaWeighting; import com.graphhopper.routing.weighting.Weighting; -import com.graphhopper.storage.Graph; +import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.GraphEdgeIdFinder; import com.graphhopper.storage.NodeAccess; import com.graphhopper.storage.index.LocationIndex; @@ -95,7 +95,7 @@ public Response doGet( if (profile == null) throw new IllegalArgumentException("The requested profile '" + profileName + "' does not exist"); LocationIndex locationIndex = graphHopper.getLocationIndex(); - Graph graph = graphHopper.getGraphHopperStorage(); + BaseGraph graph = graphHopper.getBaseGraph(); Weighting weighting = graphHopper.createWeighting(profile, hintsMap); BooleanEncodedValue inSubnetworkEnc = graphHopper.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(profileName)); if (hintsMap.has(Parameters.Routing.BLOCK_AREA)) { diff --git a/web/src/test/java/com/graphhopper/application/MapMatching2Test.java b/web/src/test/java/com/graphhopper/application/MapMatching2Test.java index 7fee9845b74..f2c30de04b3 100644 --- a/web/src/test/java/com/graphhopper/application/MapMatching2Test.java +++ b/web/src/test/java/com/graphhopper/application/MapMatching2Test.java @@ -69,7 +69,7 @@ public void testIssue13() throws IOException { MatchResult mr = mapMatching.match(GpxConversions.getEntries(gpx.trk.get(0))); // make sure no virtual edges are returned - int edgeCount = hopper.getGraphHopperStorage().getAllEdges().length(); + int edgeCount = hopper.getBaseGraph().getAllEdges().length(); for (EdgeMatch em : mr.getEdgeMatches()) { assertTrue(em.getEdgeState().getEdge() < edgeCount, "result contains virtual edges:" + em.getEdgeState().toString()); validateEdgeMatch(em); @@ -115,7 +115,7 @@ public void testIssue127() throws IOException { MatchResult mr = mapMatching.match(GpxConversions.getEntries(gpx.trk.get(0))); // make sure no virtual edges are returned - int edgeCount = hopper.getGraphHopperStorage().getAllEdges().length(); + int edgeCount = hopper.getBaseGraph().getAllEdges().length(); for (EdgeMatch em : mr.getEdgeMatches()) { assertTrue(em.getEdgeState().getEdge() < edgeCount, "result contains virtual edges:" + em.getEdgeState().toString()); validateEdgeMatch(em); diff --git a/web/src/test/java/com/graphhopper/application/MapMatchingTest.java b/web/src/test/java/com/graphhopper/application/MapMatchingTest.java index 4bd10de14cb..2733bbfcbeb 100644 --- a/web/src/test/java/com/graphhopper/application/MapMatchingTest.java +++ b/web/src/test/java/com/graphhopper/application/MapMatchingTest.java @@ -108,7 +108,7 @@ public void testDoWork(PMap hints) { MatchResult mr = mapMatching.match(inputGPXEntries); // make sure no virtual edges are returned - int edgeCount = graphHopper.getGraphHopperStorage().getAllEdges().length(); + int edgeCount = graphHopper.getBaseGraph().getAllEdges().length(); for (EdgeMatch em : mr.getEdgeMatches()) { assertTrue(em.getEdgeState().getEdge() < edgeCount, "result contains virtual edges:" + em.getEdgeState().toString()); } From d476629b930e857eda2b117ec773fc82fe430fc1 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 16 Jun 2022 15:48:26 +0200 Subject: [PATCH 046/389] reduce benchmark load e.g. exclude too slow LM16 case --- benchmark/benchmark.sh | 4 ++-- tools/src/main/java/com/graphhopper/tools/Measurement.java | 2 +- .../com/graphhopper/maps/js/graphhopper/GHRequest.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/benchmark/benchmark.sh b/benchmark/benchmark.sh index 485c91c02bf..05904f5952d 100755 --- a/benchmark/benchmark.sh +++ b/benchmark/benchmark.sh @@ -78,7 +78,7 @@ measurement.weighting=fastest \ measurement.ch.node=true \ measurement.ch.edge=false \ measurement.lm=true \ -"measurement.lm.active_counts=[4,8,12,16]" \ +"measurement.lm.active_counts=[4,8,12]" \ measurement.lm.edge_based=true \ "graph.flag_encoders=car|turn_costs=true" \ graph.location=${TMP_DIR}measurement-big-gh \ @@ -165,7 +165,7 @@ measurement.weighting=fastest \ measurement.ch.node=true \ measurement.ch.edge=false \ measurement.lm=true \ -"measurement.lm.active_counts=[4,8,12,16]" \ +"measurement.lm.active_counts=[4,8,12]" \ measurement.lm.edge_based=false \ "graph.flag_encoders=foot" \ graph.location=${TMP_DIR}measurement-big-outdoor-gh \ diff --git a/tools/src/main/java/com/graphhopper/tools/Measurement.java b/tools/src/main/java/com/graphhopper/tools/Measurement.java index ada120fc1eb..5e74ee264f2 100644 --- a/tools/src/main/java/com/graphhopper/tools/Measurement.java +++ b/tools/src/main/java/com/graphhopper/tools/Measurement.java @@ -215,7 +215,7 @@ protected void importOSM() { gcAndWait(); boolean isCH = false; boolean isLM = true; - Helper.parseList(args.getString("measurement.lm.active_counts", "[4,8,12,16]")).stream() + Helper.parseList(args.getString("measurement.lm.active_counts", "[4,8,12]")).stream() .mapToInt(Integer::parseInt).forEach(activeLMCount -> { measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount, count / 20, isCH, isLM). withInstructions().activeLandmarks(activeLMCount)); diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRequest.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRequest.js index 1c7fc1e8cca..7e29731a32c 100644 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRequest.js +++ b/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRequest.js @@ -261,7 +261,7 @@ GHRequest.prototype.flatParameter = function (key, val) { GHRequest.prototype.doRequest = function (url, callback) { var that = this; $.ajax({ - timeout: 30000, + timeout: 60000, url: url, beforeSend: function(request) { request.setRequestHeader("GH-Client", "web-ui 3.0") From ba1969513efca3688c7a2887e762e690c44971a7 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 16 Jun 2022 15:50:07 +0200 Subject: [PATCH 047/389] AlternativeRoute: closer to CH version; default is now a better compromise of speed vs. alternatives found (alternative rate is 1.8 for DE and 1.9 for bavaria) --- .../graphhopper/routing/AlternativeRoute.java | 88 ++++++++----------- .../RoutingAlgorithmFactorySimple.java | 8 +- .../routing/lm/LMRoutingAlgorithmFactory.java | 10 +-- .../routing/AlternativeRouteTest.java | 26 +++--- 4 files changed, 54 insertions(+), 78 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java index 1cabd09f5e4..6170b53ef90 100644 --- a/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java +++ b/core/src/main/java/com/graphhopper/routing/AlternativeRoute.java @@ -34,6 +34,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; +import static com.graphhopper.util.Parameters.Algorithms.AltRoute.*; + /** * This class implements the alternative paths search using the "plateau" and partially the * "penalty" method described in the following papers. @@ -58,17 +60,45 @@ */ public class AlternativeRoute extends AStarBidirection implements RoutingAlgorithm { private static final Comparator ALT_COMPARATOR = Comparator.comparingDouble(o -> o.sortBy); - private double maxWeightFactor = 1.4; - // the higher the maxWeightFactor the higher the explorationFactor needs to be - private double explorationFactor = 1.6; - private double maxShareFactor = 0.6; - private double minPlateauFactor = 0.2; - private int maxPaths = 2; - - public AlternativeRoute(Graph graph, Weighting weighting, TraversalMode traversalMode) { + + private final int maxPaths; + /** + * This variable influences the graph exploration for alternative paths. Specify a higher value than the default to + * potentially get more alternatives and a lower value to improve query time but reduces chance to find alternatives. + */ + private final double explorationFactor; + /** + * Decreasing this factor filters found alternatives and increases quality. E.g. if the factor is 2 than + * all alternatives with a weight 2 times longer than the optimal weight are return. + */ + private final double maxWeightFactor; + /** + * Decreasing this factor filters found alternatives and might increase quality. This parameter is used to avoid + * alternatives too similar to the best path. Specify 0.2 to ensure maximum 20% of the best path are on the same roads. + * The unit is also the 'weight'. + */ + private final double maxShareFactor; + /** + * Increasing this factor filters found alternatives and might increase quality. This specifies the minimum plateau + * portion of every alternative path that is required. Keep in mind that a plateau is often not complete especially + * when the explorationFactor is low (and for performance reasons the explorationFactor should be as low as possible). + * This is the reason we cannot require a too big plateau portion here as default. + */ + private final double minPlateauFactor; + + public AlternativeRoute(Graph graph, Weighting weighting, TraversalMode traversalMode, PMap hints) { super(graph, weighting, traversalMode); if (weighting.hasTurnCosts() && !traversalMode.isEdgeBased()) throw new IllegalStateException("Weightings supporting turn costs cannot be used with node-based traversal mode"); + + this.maxPaths = hints.getInt(MAX_PATHS, 2); + if (this.maxPaths < 2) + throw new IllegalArgumentException("Use normal algorithm with less overhead instead if no alternatives are required"); + + this.explorationFactor = hints.getDouble("alternative_route.max_exploration_factor", 1.12); + this.maxWeightFactor = hints.getDouble(MAX_WEIGHT, 1.25); + this.maxShareFactor = hints.getDouble(MAX_SHARE, 0.6); + this.minPlateauFactor = hints.getDouble("alternative_route.min_plateau_factor", 0.1); } static List getAltNames(Graph graph, SPTEntry ee) { @@ -97,48 +127,6 @@ public void setMaxVisitedNodes(int numberOfNodes) { this.maxVisitedNodes = numberOfNodes; } - /** - * Increasing this factor results in returning more alternatives. E.g. if the factor is 2 than - * all alternatives with a weight 2 times longer than the optimal weight are return. (default is - * 1.4) - */ - public void setMaxWeightFactor(double maxWeightFactor) { - this.maxWeightFactor = maxWeightFactor; - } - - /** - * This parameter is used to avoid alternatives too similar to the best path. Specify 0.5 to - * force a same paths of maximum 50%. The unit is the 'weight' returned in the Weighting. - */ - public void setMaxShareFactor(double maxShareFactor) { - this.maxShareFactor = maxShareFactor; - } - - /** - * This method sets the minimum plateau portion of every alternative path that is required. - */ - public void setMinPlateauFactor(double minPlateauFactor) { - this.minPlateauFactor = minPlateauFactor; - } - - /** - * This method sets the graph exploration percentage for alternative paths. Default for bidirectional A* - * is 1.6 (160%). Specify a higher value to get more alternatives (especially if maxWeightFactor is higher than - * 1.5) and a lower value to improve query time but reduces the possibility to find alternatives. - */ - public void setExplorationFactor(double explorationFactor) { - this.explorationFactor = explorationFactor; - } - - /** - * Specifies how many paths (including the optimal) are returned. (default is 2) - */ - public void setMaxPaths(int maxPaths) { - this.maxPaths = maxPaths; - if (this.maxPaths < 2) - throw new IllegalArgumentException("Use normal algorithm with less overhead instead if no alternatives are required"); - } - public List calcAlternatives(int from, int to) { Path bestPath = searchBest(from, to); return calcAlternatives(bestPath, maxPaths, diff --git a/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java b/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java index a4cddae1fcf..d7840439b17 100644 --- a/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java +++ b/core/src/main/java/com/graphhopper/routing/RoutingAlgorithmFactorySimple.java @@ -28,7 +28,6 @@ import com.graphhopper.util.PMap; import static com.graphhopper.util.Parameters.Algorithms.*; -import static com.graphhopper.util.Parameters.Algorithms.AltRoute.*; /** * A simple factory creating normal algorithms (RoutingAlgorithm) without preparation. @@ -62,12 +61,7 @@ public RoutingAlgorithm createAlgo(Graph g, Weighting w, AlgorithmOptions opts) ra = aStar; } else if (ALT_ROUTE.equalsIgnoreCase(algoStr)) { - AlternativeRoute altRouteAlgo = new AlternativeRoute(g, weighting, opts.getTraversalMode()); - altRouteAlgo.setMaxPaths(opts.getHints().getInt(MAX_PATHS, 2)); - altRouteAlgo.setMaxWeightFactor(opts.getHints().getDouble(MAX_WEIGHT, 1.4)); - altRouteAlgo.setMaxShareFactor(opts.getHints().getDouble(MAX_SHARE, 0.6)); - altRouteAlgo.setMinPlateauFactor(opts.getHints().getDouble("alternative_route.min_plateau_factor", 0.2)); - altRouteAlgo.setExplorationFactor(opts.getHints().getDouble("alternative_route.max_exploration_factor", 1.6)); + AlternativeRoute altRouteAlgo = new AlternativeRoute(g, weighting, opts.getTraversalMode(), opts.getHints()); ra = altRouteAlgo; } else { diff --git a/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java b/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java index f12ef88a35e..69f4ca93692 100644 --- a/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java +++ b/core/src/main/java/com/graphhopper/routing/lm/LMRoutingAlgorithmFactory.java @@ -26,7 +26,6 @@ import com.graphhopper.util.Parameters; import static com.graphhopper.util.Parameters.Algorithms.*; -import static com.graphhopper.util.Parameters.Algorithms.AltRoute.*; public class LMRoutingAlgorithmFactory implements RoutingAlgorithmFactory { private final LandmarkStorage lms; @@ -63,15 +62,8 @@ public RoutingAlgorithm createAlgo(Graph g, Weighting w, AlgorithmOptions opts) return algo; } else if (ALT_ROUTE.equalsIgnoreCase(algoStr)) { double epsilon = opts.getHints().getDouble(Parameters.Algorithms.AStarBi.EPSILON, 1); - AlternativeRoute algo = new AlternativeRoute(g, weighting, opts.getTraversalMode()); - algo.setMaxPaths(opts.getHints().getInt(MAX_PATHS, 2)); - algo.setMaxWeightFactor(opts.getHints().getDouble(MAX_WEIGHT, 1.4)); - algo.setMaxShareFactor(opts.getHints().getDouble(MAX_SHARE, 0.6)); - algo.setMinPlateauFactor(opts.getHints().getDouble("alternative_route.min_plateau_factor", 0.2)); + AlternativeRoute algo = new AlternativeRoute(g, weighting, opts.getTraversalMode(), opts.getHints()); algo.setApproximation(getApproximator(g, activeLM, epsilon)); - // landmark algorithm follows good compromise between fast response and exploring 'interesting' paths, so we - // can decrease this exploration factor - algo.setExplorationFactor(opts.getHints().getDouble("alternative_route.max_exploration_factor", 1.2)); algo.setMaxVisitedNodes(opts.getMaxVisitedNodes()); return algo; } else { diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java index 63e0122c1ef..8d404978af3 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java @@ -29,6 +29,7 @@ import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.util.GHUtility; +import com.graphhopper.util.PMap; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -114,9 +115,11 @@ public static void initTestGraph(Graph graph, FlagEncoder encoder) { @ArgumentsSource(FixtureProvider.class) public void testCalcAlternatives(Fixture f) { initTestGraph(f.graph, f.carFE); - AlternativeRoute altDijkstra = new AlternativeRoute(f.graph, f.weighting, f.traversalMode); - altDijkstra.setMaxShareFactor(0.5); - altDijkstra.setMaxWeightFactor(2); + PMap hints = new PMap(). + putObject("alternative_route.max_share_factor", 0.5). + putObject("alternative_route.max_weight_factor", 2). + putObject("alternative_route.max_exploration_factor", 1.3); + AlternativeRoute altDijkstra = new AlternativeRoute(f.graph, f.weighting, f.traversalMode, hints); List pathInfos = altDijkstra.calcAlternatives(5, 4); checkAlternatives(pathInfos); assertEquals(2, pathInfos.size()); @@ -143,13 +146,12 @@ public void testCalcAlternatives(Fixture f) { @ArgumentsSource(FixtureProvider.class) public void testCalcAlternatives2(Fixture f) { initTestGraph(f.graph, f.carFE); - AlternativeRoute altDijkstra = new AlternativeRoute(f.graph, f.weighting, f.traversalMode); - altDijkstra.setMaxPaths(3); - altDijkstra.setMaxShareFactor(0.7); - altDijkstra.setMinPlateauFactor(0.15); - altDijkstra.setMaxWeightFactor(2); - altDijkstra.setExplorationFactor(1.8); - + PMap hints = new PMap().putObject("alternative_route.max_paths", 3). + putObject("alternative_route.max_share_factor", 0.7). + putObject("alternative_route.min_plateau_factor", 0.15). + putObject("alternative_route.max_weight_factor", 2). + putObject("alternative_route.max_exploration_factor", 1.8); + AlternativeRoute altDijkstra = new AlternativeRoute(f.graph, f.weighting, f.traversalMode, hints); List pathInfos = altDijkstra.calcAlternatives(5, 4); checkAlternatives(pathInfos); assertEquals(3, pathInfos.size()); @@ -183,8 +185,8 @@ public void testDisconnectedAreas(Fixture p) { // one single disconnected node updateDistancesFor(p.graph, 20, 0.00, -0.01); - AlternativeRoute altDijkstra = new AlternativeRoute(p.graph, p.weighting, p.traversalMode); - altDijkstra.setExplorationFactor(1); + PMap hints = new PMap().putObject("alternative_route.max_exploration_factor", 1); + AlternativeRoute altDijkstra = new AlternativeRoute(p.graph, p.weighting, p.traversalMode, hints); Path path = altDijkstra.calcPath(1, 20); assertFalse(path.isFound()); From 7682380c64abf763163a4b9f1c57833bd6babeed Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 16 Jun 2022 15:58:28 +0200 Subject: [PATCH 048/389] Move/Rename: EncodingManager.Access -> WayAccess --- .../routing/util/BikeCommonTagParser.java | 34 ++++++++-------- .../routing/util/CarTagParser.java | 28 ++++++------- .../routing/util/EncodingManager.java | 20 ---------- .../routing/util/FootTagParser.java | 34 ++++++++-------- .../routing/util/MotorcycleTagParser.java | 28 ++++++------- .../graphhopper/routing/util/OSMParsers.java | 2 +- .../routing/util/RoadsTagParser.java | 6 +-- .../routing/util/VehicleTagParser.java | 2 +- .../graphhopper/routing/util/WayAccess.java | 39 +++++++++++++++++++ .../routing/util/WheelchairTagParser.java | 18 ++++----- .../util/Bike2WeightTagParserTest.java | 2 +- .../routing/util/CarTagParserTest.java | 4 +- .../routing/util/RacingBikeTagParserTest.java | 4 +- 13 files changed, 120 insertions(+), 101 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/util/WayAccess.java diff --git a/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java b/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java index 8438c89ff47..68347599f12 100644 --- a/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java @@ -184,68 +184,68 @@ protected BikeCommonTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue } @Override - public EncodingManager.Access getAccess(ReaderWay way) { + public WayAccess getAccess(ReaderWay way) { String highwayValue = way.getTag("highway"); if (highwayValue == null) { - EncodingManager.Access access = EncodingManager.Access.CAN_SKIP; + WayAccess access = WayAccess.CAN_SKIP; if (way.hasTag("route", ferries)) { // if bike is NOT explicitly tagged allow bike but only if foot is not specified either String bikeTag = way.getTag("bicycle"); if (bikeTag == null && !way.hasTag("foot") || intendedValues.contains(bikeTag)) - access = EncodingManager.Access.FERRY; + access = WayAccess.FERRY; } // special case not for all acceptedRailways, only platform if (way.hasTag("railway", "platform")) - access = EncodingManager.Access.WAY; + access = WayAccess.WAY; if (way.hasTag("man_made", "pier")) - access = EncodingManager.Access.WAY; + access = WayAccess.WAY; if (!access.canSkip()) { if (way.hasTag(restrictions, restrictedValues) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; return access; } - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } if (!highwaySpeeds.containsKey(highwayValue)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; String sacScale = way.getTag("sac_scale"); if (sacScale != null) { if (!isSacScaleAllowed(sacScale)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } // use the way if it is tagged for bikes if (way.hasTag("bicycle", intendedValues) || way.hasTag("bicycle", "dismount") || way.hasTag("highway", "cycleway")) - return EncodingManager.Access.WAY; + return WayAccess.WAY; // accept only if explicitly tagged for bike usage if ("motorway".equals(highwayValue) || "motorway_link".equals(highwayValue) || "bridleway".equals(highwayValue)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (way.hasTag("motorroad", "yes")) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; // do not use fords with normal bikes, flagged fords are in included above if (isBlockFords() && (way.hasTag("highway", "ford") || way.hasTag("ford"))) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; // check access restrictions if (way.hasTag(restrictions, restrictedValues) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (getConditionalTagInspector().isPermittedWayConditionallyRestricted(way)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; else - return EncodingManager.Access.WAY; + return WayAccess.WAY; } boolean isSacScaleAllowed(String sacScale) { @@ -271,7 +271,7 @@ protected double applyMaxSpeed(ReaderWay way, double speed) { @Override public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { - EncodingManager.Access access = getAccess(way); + WayAccess access = getAccess(way); if (access.canSkip()) return edgeFlags; diff --git a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java index c3b5dfcd114..4f3ea5654cf 100644 --- a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java @@ -164,56 +164,56 @@ protected double getSpeed(ReaderWay way) { } @Override - public EncodingManager.Access getAccess(ReaderWay way) { + public WayAccess getAccess(ReaderWay way) { // TODO: Ferries have conditionals, like opening hours or are closed during some time in the year String highwayValue = way.getTag("highway"); String firstValue = way.getFirstPriorityTag(restrictions); if (highwayValue == null) { if (way.hasTag("route", ferries)) { if (restrictedValues.contains(firstValue)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (intendedValues.contains(firstValue) || // implied default is allowed only if foot and bicycle is not specified: firstValue.isEmpty() && !way.hasTag("foot") && !way.hasTag("bicycle")) - return EncodingManager.Access.FERRY; + return WayAccess.FERRY; } - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } if ("service".equals(highwayValue) && "emergency_access".equals(way.getTag("service"))) { - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } if ("track".equals(highwayValue) && trackTypeSpeedMap.get(way.getTag("tracktype")) == null) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (!defaultSpeedMap.containsKey(highwayValue)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (way.hasTag("impassable", "yes") || way.hasTag("status", "impassable")) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; // multiple restrictions needs special handling compared to foot and bike, see also motorcycle if (!firstValue.isEmpty()) { if (restrictedValues.contains(firstValue) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (intendedValues.contains(firstValue)) - return EncodingManager.Access.WAY; + return WayAccess.WAY; } // do not drive street cars into fords if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford"))) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (getConditionalTagInspector().isPermittedWayConditionallyRestricted(way)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; else - return EncodingManager.Access.WAY; + return WayAccess.WAY; } @Override public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { - EncodingManager.Access access = getAccess(way); + WayAccess access = getAccess(way); if (access.canSkip()) return edgeFlags; diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java index eece47905a3..04a46b4bb53 100644 --- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java +++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java @@ -255,26 +255,6 @@ private FlagEncoder getEncoder(String name, boolean throwExc) { return null; } - public enum Access { - WAY, FERRY, OTHER, CAN_SKIP; - - public boolean isFerry() { - return this.ordinal() == FERRY.ordinal(); - } - - public boolean isWay() { - return this.ordinal() == WAY.ordinal(); - } - - public boolean isOther() { - return this.ordinal() == OTHER.ordinal(); - } - - public boolean canSkip() { - return this.ordinal() == CAN_SKIP.ordinal(); - } - } - public String toFlagEncodersAsString() { StringBuilder str = new StringBuilder(); for (FlagEncoder encoder : edgeEncoders) { diff --git a/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java b/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java index 489a52e86a2..5aee1625660 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java @@ -135,67 +135,67 @@ protected FootTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speed * Some ways are okay but not separate for pedestrians. */ @Override - public EncodingManager.Access getAccess(ReaderWay way) { + public WayAccess getAccess(ReaderWay way) { String highwayValue = way.getTag("highway"); if (highwayValue == null) { - EncodingManager.Access acceptPotentially = EncodingManager.Access.CAN_SKIP; + WayAccess acceptPotentially = WayAccess.CAN_SKIP; if (way.hasTag("route", ferries)) { String footTag = way.getTag("foot"); if (footTag == null || intendedValues.contains(footTag)) - acceptPotentially = EncodingManager.Access.FERRY; + acceptPotentially = WayAccess.FERRY; } // special case not for all acceptedRailways, only platform if (way.hasTag("railway", "platform")) - acceptPotentially = EncodingManager.Access.WAY; + acceptPotentially = WayAccess.WAY; if (way.hasTag("man_made", "pier")) - acceptPotentially = EncodingManager.Access.WAY; + acceptPotentially = WayAccess.WAY; if (!acceptPotentially.canSkip()) { if (way.hasTag(restrictions, restrictedValues) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; return acceptPotentially; } - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } // other scales are too dangerous, see http://wiki.openstreetmap.org/wiki/Key:sac_scale if (way.getTag("sac_scale") != null && !way.hasTag("sac_scale", allowedSacScale)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; // no need to evaluate ferries or fords - already included here if (way.hasTag("foot", intendedValues)) - return EncodingManager.Access.WAY; + return WayAccess.WAY; // check access restrictions if (way.hasTag(restrictions, restrictedValues) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (way.hasTag("sidewalk", sidewalkValues)) - return EncodingManager.Access.WAY; + return WayAccess.WAY; if (!allowedHighwayTags.contains(highwayValue)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (way.hasTag("motorroad", "yes")) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; // do not get our feet wet, "yes" is already included above if (isBlockFords() && (way.hasTag("highway", "ford") || way.hasTag("ford"))) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (getConditionalTagInspector().isPermittedWayConditionallyRestricted(way)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; - return EncodingManager.Access.WAY; + return WayAccess.WAY; } @Override public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { - EncodingManager.Access access = getAccess(way); + WayAccess access = getAccess(way); if (access.canSkip()) return edgeFlags; diff --git a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java index 6326d4d80ce..a154da15b30 100644 --- a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java @@ -113,57 +113,57 @@ public MotorcycleTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue sp } @Override - public EncodingManager.Access getAccess(ReaderWay way) { + public WayAccess getAccess(ReaderWay way) { String highwayValue = way.getTag("highway"); String firstValue = way.getFirstPriorityTag(restrictions); if (highwayValue == null) { if (way.hasTag("route", ferries)) { if (restrictedValues.contains(firstValue)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (intendedValues.contains(firstValue) || // implied default is allowed only if foot and bicycle is not specified: firstValue.isEmpty() && !way.hasTag("foot") && !way.hasTag("bicycle")) - return EncodingManager.Access.FERRY; + return WayAccess.FERRY; } - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } if ("service".equals(highwayValue) && "emergency_access".equals(way.getTag("service"))) { - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } if ("track".equals(highwayValue)) { String tt = way.getTag("tracktype"); if (tt != null && !tt.equals("grade1")) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } if (!defaultSpeedMap.containsKey(highwayValue)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (way.hasTag("impassable", "yes") || way.hasTag("status", "impassable")) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (!firstValue.isEmpty()) { if (restrictedValues.contains(firstValue) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (intendedValues.contains(firstValue)) - return EncodingManager.Access.WAY; + return WayAccess.WAY; } // do not drive street cars into fords if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford"))) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (getConditionalTagInspector().isPermittedWayConditionallyRestricted(way)) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; else - return EncodingManager.Access.WAY; + return WayAccess.WAY; } @Override public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { - EncodingManager.Access access = getAccess(way); + WayAccess access = getAccess(way); if (access.canSkip()) return edgeFlags; diff --git a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java index 1b68876fed2..680aa3ab8ea 100644 --- a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java +++ b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java @@ -75,7 +75,7 @@ public OSMParsers addTurnCostTagParser(TurnCostParser turnCostParser) { } public boolean acceptWay(ReaderWay way) { - return vehicleTagParsers.stream().anyMatch(v -> !v.getAccess(way).equals(EncodingManager.Access.CAN_SKIP)); + return vehicleTagParsers.stream().anyMatch(v -> !v.getAccess(way).equals(WayAccess.CAN_SKIP)); } public IntsRef handleRelationTags(ReaderRelation relation, IntsRef relFlags) { diff --git a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java index 0102c904be9..f556c0264ba 100644 --- a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java @@ -37,10 +37,10 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { } @Override - public EncodingManager.Access getAccess(ReaderWay way) { + public WayAccess getAccess(ReaderWay way) { if (way.getTag("highway", "").isEmpty()) - return EncodingManager.Access.CAN_SKIP; - return EncodingManager.Access.WAY; + return WayAccess.CAN_SKIP; + return WayAccess.WAY; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java index 1bb796941f3..61b66fdb5d1 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java @@ -154,7 +154,7 @@ public IntsRef handleNodeTags(IntsRef edgeFlags, Map nodeTags) { * * @return the encoded value to indicate if this encoder allows travel or not. */ - public abstract EncodingManager.Access getAccess(ReaderWay way); + public abstract WayAccess getAccess(ReaderWay way); /** * @return true if the given OSM node blocks access for this vehicle, false otherwise diff --git a/core/src/main/java/com/graphhopper/routing/util/WayAccess.java b/core/src/main/java/com/graphhopper/routing/util/WayAccess.java new file mode 100644 index 00000000000..de629db61ff --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/WayAccess.java @@ -0,0 +1,39 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util; + +public enum WayAccess { + WAY, FERRY, OTHER, CAN_SKIP; + + public boolean isFerry() { + return this.ordinal() == FERRY.ordinal(); + } + + public boolean isWay() { + return this.ordinal() == WAY.ordinal(); + } + + public boolean isOther() { + return this.ordinal() == OTHER.ordinal(); + } + + public boolean canSkip() { + return this.ordinal() == CAN_SKIP.ordinal(); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java b/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java index 9ccf0701fe2..1cc04a9b63d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java @@ -100,25 +100,25 @@ protected WheelchairTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue * Avoid some more ways than for pedestrian like hiking trails. */ @Override - public EncodingManager.Access getAccess(ReaderWay way) { + public WayAccess getAccess(ReaderWay way) { if (way.hasTag("surface", excludeSurfaces)) { if (!way.hasTag("sidewalk", sidewalkValues)) { - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } else { String sidewalk = way.getTag("sidewalk"); if (way.hasTag("sidewalk:" + sidewalk + ":surface", excludeSurfaces)) { - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } } } if (way.hasTag("smoothness", excludeSmoothness)) { if (!way.hasTag("sidewalk", sidewalkValues)) { - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } else { String sidewalk = way.getTag("sidewalk"); if (way.hasTag("sidewalk:" + sidewalk + ":smoothness", excludeSmoothness)) { - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } } } @@ -133,7 +133,7 @@ public EncodingManager.Access getAccess(ReaderWay way) { } if (-maxInclinePercent > incline || incline > maxInclinePercent) { - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } } catch (NumberFormatException ex) { } @@ -141,7 +141,7 @@ public EncodingManager.Access getAccess(ReaderWay way) { } if (way.hasTag("kerb", "raised")) - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; if (way.hasTag("kerb")) { String tagValue = way.getTag("kerb"); @@ -154,7 +154,7 @@ public EncodingManager.Access getAccess(ReaderWay way) { int maxKerbHeightCm = 3; if (kerbHeight > maxKerbHeightCm) { - return EncodingManager.Access.CAN_SKIP; + return WayAccess.CAN_SKIP; } } catch (NumberFormatException ex) { } @@ -166,7 +166,7 @@ public EncodingManager.Access getAccess(ReaderWay way) { @Override public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { - EncodingManager.Access access = getAccess(way); + WayAccess access = getAccess(way); if (access.canSkip()) return edgeFlags; diff --git a/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java index 31fd7825cbc..cb35eef80b7 100644 --- a/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java @@ -119,7 +119,7 @@ public void testRoutingFailsWithInvalidGraph_issue665() { way.setTag("route", "ferry"); way.setTag("edge_distance", 500.0); - assertNotEquals(EncodingManager.Access.CAN_SKIP, parser.getAccess(way)); + assertNotEquals(WayAccess.CAN_SKIP, parser.getAccess(way)); IntsRef edgeFlags = encodingManager.createEdgeFlags(); edgeFlags = osmParsers.handleWayTags(edgeFlags, way, encodingManager.createRelationFlags()); graph.edge(0, 1).setDistance(247).setFlags(edgeFlags); diff --git a/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java index 2be9b603b40..31f3ddb5bee 100644 --- a/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java @@ -574,8 +574,8 @@ public void testCombination() { BikeTagParser bikeParser = new BikeTagParser(em, new PMap()); bikeParser.init(new DateRangeParser()); - assertEquals(EncodingManager.Access.CAN_SKIP, parser.getAccess(way)); - assertNotEquals(EncodingManager.Access.CAN_SKIP, bikeParser.getAccess(way)); + assertEquals(WayAccess.CAN_SKIP, parser.getAccess(way)); + assertNotEquals(WayAccess.CAN_SKIP, bikeParser.getAccess(way)); IntsRef edgeFlags = em.createEdgeFlags(); parser.handleWayTags(edgeFlags, way); bikeParser.handleWayTags(edgeFlags, way); diff --git a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java index 13fd75b9c4b..851954a62de 100644 --- a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java @@ -28,8 +28,8 @@ import org.junit.jupiter.api.Test; import static com.graphhopper.routing.util.BikeCommonTagParser.PUSHING_SECTION_SPEED; -import static com.graphhopper.routing.util.EncodingManager.Access.WAY; import static com.graphhopper.routing.util.PriorityCode.*; +import static com.graphhopper.routing.util.WayAccess.WAY; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -223,7 +223,7 @@ public void testPriority_avoidanceOfHighMaxSpeed() { EncodingManager encodingManager = EncodingManager.create("racingbike"); BikeCommonTagParser parser = new RacingBikeTagParser(encodingManager, new PMap("block_fords=true")) { @Override - public EncodingManager.Access getAccess(ReaderWay way) { + public WayAccess getAccess(ReaderWay way) { return WAY; } }; From b1ad9f6ce0e5b3f7147c4c7569c713e7d02cd538 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 16 Jun 2022 15:58:24 +0200 Subject: [PATCH 049/389] AlternativeRoute: fix test --- core/src/test/java/com/graphhopper/GraphHopperTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 95d53002d45..281f086f18f 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -463,6 +463,7 @@ public void testAlternativeRoutesCar() { GHRequest req = new GHRequest(50.023513, 11.548862, 49.969441, 11.537876). setAlgorithm(ALT_ROUTE).setProfile(profile); req.putHint("alternative_route.max_paths", 3); + req.putHint("alternative_route.max_exploration_factor", 1.2); GHResponse rsp = hopper.route(req); assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); From 0c7705408c510a792bd0cc24ed9d1902e46b87a1 Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 16 Jun 2022 18:45:30 +0200 Subject: [PATCH 050/389] Clean up EncodingManager Builder --- .../routing/util/EncodingManager.java | 216 ++++++------------ .../graphhopper/routing/util/FlagEncoder.java | 2 + .../routing/util/VehicleEncodedValues.java | 1 + .../reader/osm/GraphHopperOSMTest.java | 9 +- 4 files changed, 76 insertions(+), 152 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java index 04a46b4bb53..b67c93e34e0 100644 --- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java +++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java @@ -36,7 +36,7 @@ * @author Nop */ public class EncodingManager implements EncodedValueLookup { - private final List edgeEncoders; + private final Map flagEncoders; private final Map encodedValueMap; private final EncodedValue.InitializerConfig turnCostConfig; private final EncodedValue.InitializerConfig edgeConfig; @@ -83,100 +83,97 @@ public static Builder start() { return new Builder(); } - public EncodingManager( - List edgeEncoders, - Map encodedValueMap, - EncodedValue.InitializerConfig turnCostConfig, - EncodedValue.InitializerConfig edgeConfig) { - this.edgeEncoders = edgeEncoders; - this.encodedValueMap = encodedValueMap; - this.turnCostConfig = turnCostConfig; - this.edgeConfig = edgeConfig; - } - private EncodingManager() { - this( - new ArrayList<>(), new LinkedHashMap<>(), - new EncodedValue.InitializerConfig(), - new EncodedValue.InitializerConfig() - ); + flagEncoders = new LinkedHashMap<>(); + encodedValueMap = new LinkedHashMap<>(); + edgeConfig = new EncodedValue.InitializerConfig(); + turnCostConfig = new EncodedValue.InitializerConfig(); } public static class Builder { - private EncodingManager em; - private final Map flagEncoderMap = new LinkedHashMap<>(); - private final Map encodedValueMap = new LinkedHashMap<>(); - - public Builder() { - em = new EncodingManager(); - } + private EncodingManager em = new EncodingManager(); public Builder add(FlagEncoder encoder) { - check(); - if (flagEncoderMap.containsKey(encoder.toString())) - throw new IllegalArgumentException("FlagEncoder already exists: " + encoder); - flagEncoderMap.put(encoder.toString(), (VehicleEncodedValues) encoder); + checkNotBuiltAlready(); + if (em.hasEncoder(encoder.getName())) + throw new IllegalArgumentException("FlagEncoder already exists: " + encoder.getName()); + VehicleEncodedValues v = (VehicleEncodedValues) encoder; + v.setEncodedValueLookup(em); + + List list = new ArrayList<>(); + v.createEncodedValues(list); + list.forEach(this::add); + + list = new ArrayList<>(); + v.createTurnCostEncodedValues(list); + list.forEach(this::addTurnCostEncodedValue); + + em.flagEncoders.put(v.getName(), v); return this; } public Builder add(EncodedValue encodedValue) { - check(); - if (encodedValueMap.containsKey(encodedValue.getName())) + checkNotBuiltAlready(); + if (em.hasEncodedValue(encodedValue.getName())) throw new IllegalArgumentException("EncodedValue already exists: " + encodedValue.getName()); - encodedValueMap.put(encodedValue.getName(), encodedValue); + encodedValue.init(em.edgeConfig); + em.encodedValueMap.put(encodedValue.getName(), encodedValue); + return this; + } + + public Builder addTurnCostEncodedValue(EncodedValue turnCostEnc) { + checkNotBuiltAlready(); + if (em.hasEncodedValue(turnCostEnc.getName())) + throw new IllegalArgumentException("Already defined: " + turnCostEnc.getName() + ". Please note that " + + "EncodedValues for edges and turn costs are in the same namespace."); + turnCostEnc.init(em.turnCostConfig); + em.encodedValueMap.put(turnCostEnc.getName(), turnCostEnc); return this; } - private void check() { + private void checkNotBuiltAlready() { if (em == null) throw new IllegalStateException("Cannot call method after Builder.build() was called"); } public EncodingManager build() { - check(); - - for (EncodedValue ev : encodedValueMap.values()) { - em.addEncodedValue(ev); - } + checkNotBuiltAlready(); + addDefaultEncodedValues(); + if (em.encodedValueMap.isEmpty()) + throw new IllegalStateException("No EncodedValues were added to the EncodingManager"); + EncodingManager result = em; + em = null; + return result; + } + private void addDefaultEncodedValues() { + // todo: I think ultimately these should all be removed and must be added explicitly if (!em.hasEncodedValue(Roundabout.KEY)) - em.addEncodedValue(Roundabout.create()); + add(Roundabout.create()); if (!em.hasEncodedValue(RoadClass.KEY)) - em.addEncodedValue(new EnumEncodedValue<>(RoadClass.KEY, RoadClass.class)); + add(new EnumEncodedValue<>(RoadClass.KEY, RoadClass.class)); if (!em.hasEncodedValue(RoadClassLink.KEY)) - em.addEncodedValue(new SimpleBooleanEncodedValue(RoadClassLink.KEY)); + add(new SimpleBooleanEncodedValue(RoadClassLink.KEY)); if (!em.hasEncodedValue(RoadEnvironment.KEY)) - em.addEncodedValue(new EnumEncodedValue<>(RoadEnvironment.KEY, RoadEnvironment.class)); + add(new EnumEncodedValue<>(RoadEnvironment.KEY, RoadEnvironment.class)); if (!em.hasEncodedValue(MaxSpeed.KEY)) - em.addEncodedValue(MaxSpeed.create()); - if (!em.hasEncodedValue(RoadAccess.KEY)) { - em.addEncodedValue(new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class)); - } + add(MaxSpeed.create()); + if (!em.hasEncodedValue(RoadAccess.KEY)) + add(new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class)); - for (VehicleEncodedValues encoder : flagEncoderMap.values()) { + for (VehicleEncodedValues encoder : em.flagEncoders.values()) { if (encoder.getName().contains("bike") || encoder.getName().contains("mtb")) { if (!em.hasEncodedValue(RouteNetwork.key("bike"))) - em.addEncodedValue(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)); + add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)); if (!em.hasEncodedValue(GetOffBike.KEY)) - em.addEncodedValue(GetOffBike.create()); + add(GetOffBike.create()); if (!em.hasEncodedValue(Smoothness.KEY)) - em.addEncodedValue(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)); + add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)); } else if (encoder.getName().contains("foot") || encoder.getName().contains("hike") || encoder.getName().contains("wheelchair")) { if (!em.hasEncodedValue(RouteNetwork.key("foot"))) - em.addEncodedValue(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)); + add(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)); } } - - for (VehicleEncodedValues encoder : flagEncoderMap.values()) { - em.addEncoder(encoder); - } - - if (em.encodedValueMap.isEmpty()) - throw new IllegalStateException("No EncodedValues found"); - - EncodingManager tmp = em; - em = null; - return tmp; } } @@ -201,44 +198,12 @@ public int getIntsForFlags() { return edgeConfig.getRequiredInts(); } - private void addEncoder(VehicleEncodedValues encoder) { - encoder.setEncodedValueLookup(this); - List list = new ArrayList<>(); - encoder.createEncodedValues(list); - for (EncodedValue ev : list) { - addEncodedValue(ev); - } - list = new ArrayList<>(); - encoder.createTurnCostEncodedValues(list); - for (EncodedValue ev : list) - addTurnCostEncodedValue(ev); - edgeEncoders.add(encoder); - } - - private void addEncodedValue(EncodedValue ev) { - if (hasEncodedValue(ev.getName())) - throw new IllegalStateException("EncodedValue " + ev.getName() + " collides with " + ev.getName()); - ev.init(edgeConfig); - encodedValueMap.put(ev.getName(), ev); - } - - private void addTurnCostEncodedValue(EncodedValue turnCostEnc) { - if (encodedValueMap.containsKey(turnCostEnc.getName())) - throw new IllegalArgumentException("Already defined: " + turnCostEnc.getName() + ". Please note that " + - "EncodedValues for edges and turn cost are in the same namespace."); - turnCostEnc.init(turnCostConfig); - encodedValueMap.put(turnCostEnc.getName(), turnCostEnc); - } - public boolean hasEncodedValue(String key) { return encodedValueMap.get(key) != null; } - /** - * @return true if the specified encoder is found - */ public boolean hasEncoder(String encoder) { - return getEncoder(encoder, false) != null; + return flagEncoders.containsKey(encoder); } public FlagEncoder getEncoder(String name) { @@ -246,53 +211,23 @@ public FlagEncoder getEncoder(String name) { } private FlagEncoder getEncoder(String name, boolean throwExc) { - for (FlagEncoder encoder : edgeEncoders) { - if (name.equalsIgnoreCase(encoder.toString())) - return encoder; - } - if (throwExc) - throw new IllegalArgumentException("FlagEncoder for " + name + " not found. Existing: " + edgeEncoders.stream().map(FlagEncoder::toString).collect(Collectors.joining(","))); - return null; + VehicleEncodedValues flagEncoder = flagEncoders.get(name); + if (flagEncoder == null && throwExc) + throw new IllegalArgumentException("FlagEncoder " + name + " not found. Existing: " + flagEncoders.keySet()); + return flagEncoder; } public String toFlagEncodersAsString() { - StringBuilder str = new StringBuilder(); - for (FlagEncoder encoder : edgeEncoders) { - if (str.length() > 0) - str.append(","); - - str - .append(((VehicleEncodedValues) encoder).getName()) - .append("|") - .append(((VehicleEncodedValues) encoder).getSharedEncodedValueString()); - } - - return str.toString(); + return flagEncoders.values().stream().map(fe -> fe.getName() + "|" + fe.getSharedEncodedValueString()).collect(Collectors.joining(",")); } public String toEncodedValuesAsString() { - StringBuilder str = new StringBuilder(); - for (EncodedValue ev : encodedValueMap.values()) { - if (str.length() > 0) - str.append(","); - - str.append(ev.toString()); - } - - return str.toString(); + return encodedValueMap.values().stream().map(Object::toString).collect(Collectors.joining(",")); } @Override public String toString() { - StringBuilder str = new StringBuilder(); - for (FlagEncoder encoder : edgeEncoders) { - if (str.length() > 0) - str.append(","); - - str.append(encoder.toString()); - } - - return str.toString(); + return flagEncoders.values().stream().map(Object::toString).collect(Collectors.joining(",")); } // TODO hide IntsRef even more in a later version: https://gist.github.com/karussell/f4c2b2b1191be978d7ee9ec8dd2cd48f @@ -305,29 +240,14 @@ public IntsRef createRelationFlags() { return new IntsRef(2); } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - EncodingManager that = (EncodingManager) o; - return edgeEncoders.equals(that.edgeEncoders) && - encodedValueMap.equals(that.encodedValueMap); - } - - @Override - public int hashCode() { - return Objects.hash(edgeEncoders, encodedValueMap); - } - public List fetchEdgeEncoders() { - return new ArrayList<>(edgeEncoders); + return new ArrayList<>(flagEncoders.values()); } public boolean needsTurnCostsSupport() { - for (FlagEncoder encoder : edgeEncoders) { + for (FlagEncoder encoder : flagEncoders.values()) if (encoder.supportsTurnCosts()) return true; - } return false; } diff --git a/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java index 0f2b87c940a..4d1de1f65b2 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java @@ -29,6 +29,8 @@ */ public interface FlagEncoder extends EncodedValueLookup { + String getName(); + boolean isMotorVehicle(); boolean isHGV(); diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index 868d781f210..2b5846eb7f9 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -280,6 +280,7 @@ public boolean hasEncodedValue(String key) { return encodedValueLookup.hasEncodedValue(key); } + @Override public String getName() { return name; } diff --git a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java index 12fdbbce2d0..d5a92ed4f89 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java @@ -841,13 +841,14 @@ public void testProfilesMustNotBeChanged() { { // problem: we add another profile, which is not allowed, because there would be no subnetwork ev for it GraphHopper hopper = createHopperWithProfiles(Arrays.asList( - new Profile("car").setVehicle("car").setWeighting("shortest"), + new Profile("car").setVehicle("car").setWeighting("fastest"), new CustomProfile("custom").setCustomModel(new CustomModel().setDistanceInfluence(3)).setVehicle("car"), new Profile("car2").setVehicle("car").setWeighting("fastest") )); IllegalStateException e = assertThrows(IllegalStateException.class, hopper::importOrLoad); - // so far we get another error message in this case, because we check the encoded values and encoders first - assertTrue(e.getMessage().contains("Flag encoders do not match"), e.getMessage()); + // so far we get another error message in this case, because we check the encoded values (and encoders) first, + // for example here the encoded values are different, because of the extra car2_subnetwork EV + assertTrue(e.getMessage().contains("Encoded values do not match"), e.getMessage()); hopper.close(); } { @@ -857,7 +858,7 @@ public void testProfilesMustNotBeChanged() { new Profile("car").setVehicle("car").setWeighting("shortest") )); IllegalStateException e = assertThrows(IllegalStateException.class, hopper::importOrLoad); - assertTrue(e.getMessage().contains("Flag encoders do not match"), e.getMessage()); + assertTrue(e.getMessage().contains("Encoded values do not match"), e.getMessage()); hopper.close(); } } From 2af3a047861f1671d02cfe6d130f4e063846b9db Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 16 Jun 2022 19:52:46 +0200 Subject: [PATCH 051/389] minor: Use Bike/FootNetwork.KEY --- .../java/com/graphhopper/routing/util/EncodingManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java index b67c93e34e0..8756739c54b 100644 --- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java +++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java @@ -163,14 +163,14 @@ private void addDefaultEncodedValues() { for (VehicleEncodedValues encoder : em.flagEncoders.values()) { if (encoder.getName().contains("bike") || encoder.getName().contains("mtb")) { - if (!em.hasEncodedValue(RouteNetwork.key("bike"))) + if (!em.hasEncodedValue(BikeNetwork.KEY)) add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)); if (!em.hasEncodedValue(GetOffBike.KEY)) add(GetOffBike.create()); if (!em.hasEncodedValue(Smoothness.KEY)) add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)); } else if (encoder.getName().contains("foot") || encoder.getName().contains("hike") || encoder.getName().contains("wheelchair")) { - if (!em.hasEncodedValue(RouteNetwork.key("foot"))) + if (!em.hasEncodedValue(FootNetwork.KEY)) add(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)); } } From 47d3d3482346be50326999c6604d7c2c717f885f Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 17 Jun 2022 09:41:25 +0200 Subject: [PATCH 052/389] Rename freshFlags -> refreshFlags --- .../java/com/graphhopper/storage/BaseGraph.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index bbf7869d29b..b62c57b0146 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -587,7 +587,7 @@ void goToNext() { boolean baseNodeIsNodeA = baseNode == nodeA; adjNode = baseNodeIsNodeA ? store.getNodeB(edgePointer) : nodeA; reverse = !baseNodeIsNodeA; - freshFlags = false; + refreshFlags = true; // position to next edge nextEdgeId = baseNodeIsNodeA ? store.getLinkA(edgePointer) : store.getLinkB(edgePointer); @@ -624,7 +624,7 @@ public boolean next() { edgePointer = store.toEdgePointer(edgeId); baseNode = store.getNodeA(edgePointer); adjNode = store.getNodeB(edgePointer); - freshFlags = false; + refreshFlags = true; reverse = false; return true; } @@ -658,7 +658,7 @@ static class EdgeIteratorStateImpl implements EdgeIteratorState { int adjNode; // we need reverse if detach is called boolean reverse = false; - boolean freshFlags; + boolean refreshFlags; int edgeId = -1; private final IntsRef edgeFlags; @@ -678,7 +678,7 @@ final boolean init(int edgeId, int expectedAdjNode) { edgePointer = store.toEdgePointer(edgeId); baseNode = store.getNodeA(edgePointer); adjNode = store.getNodeB(edgePointer); - freshFlags = false; + refreshFlags = true; if (expectedAdjNode == adjNode || expectedAdjNode == Integer.MIN_VALUE) { reverse = false; @@ -703,7 +703,7 @@ final void init(int edgeKey) { edgePointer = store.toEdgePointer(edgeId); baseNode = store.getNodeA(edgePointer); adjNode = store.getNodeB(edgePointer); - freshFlags = false; + refreshFlags = true; if (edgeKey % 2 == 0 || baseNode == adjNode) { reverse = false; @@ -738,9 +738,9 @@ public EdgeIteratorState setDistance(double dist) { @Override public IntsRef getFlags() { - if (!freshFlags) { + if (refreshFlags) { store.readFlags(edgePointer, edgeFlags); - freshFlags = true; + refreshFlags = false; } return edgeFlags; } @@ -752,7 +752,7 @@ public final EdgeIteratorState setFlags(IntsRef edgeFlags) { for (int i = 0; i < edgeFlags.ints.length; i++) { this.edgeFlags.ints[i] = edgeFlags.ints[i]; } - freshFlags = true; + refreshFlags = false; return this; } From b8d9b55a0d63e42d1663257c121359e6b0550f49 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 20 Jun 2022 10:20:55 +0200 Subject: [PATCH 053/389] BaseGraph: remove copying flags on write, see #2593 --- core/src/main/java/com/graphhopper/storage/BaseGraph.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index b62c57b0146..a30139a8b06 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -749,10 +749,6 @@ public IntsRef getFlags() { public final EdgeIteratorState setFlags(IntsRef edgeFlags) { assert edgeId < store.getEdges() : "must be edge but was shortcut: " + edgeId + " >= " + store.getEdges() + ". Use setFlagsAndWeight"; store.writeFlags(edgePointer, edgeFlags); - for (int i = 0; i < edgeFlags.ints.length; i++) { - this.edgeFlags.ints[i] = edgeFlags.ints[i]; - } - refreshFlags = false; return this; } From 0b2c0a7cb14a3896ab4e7305ab908724f09c82ee Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 20 Jun 2022 12:00:06 +0200 Subject: [PATCH 054/389] added elevation data to reduce internet-dependence while running test --- .gitignore | 1 - core/files/N42E001.hgt.zip | Bin 0 -> 2037759 bytes 2 files changed, 1 deletion(-) create mode 100755 core/files/N42E001.hgt.zip diff --git a/.gitignore b/.gitignore index dc3d0209e7c..9e896cadab7 100644 --- a/.gitignore +++ b/.gitignore @@ -40,7 +40,6 @@ android/.gradle local/ local.properties **/node_modules -*.zip .DS_Store /graph-cache package-lock.json \ No newline at end of file diff --git a/core/files/N42E001.hgt.zip b/core/files/N42E001.hgt.zip new file mode 100755 index 0000000000000000000000000000000000000000..30eba1d23a1557bb686154db4f3e74ec50f7d81e GIT binary patch literal 2037759 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%0AgCzkuL5C@19{xt_Du*Y?^PTjhIM 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͗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�U!c>d81#q0TGk=f}Exj*== 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ð#?)uQk;c0#*jJM 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

Yf-^Zx1{8F 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 z

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 z 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

dbb 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

klj!P?FR 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

?C_~qV25b5ILd}NRoCiHJ&rn_Lc%Jp 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%0AIx>L#;i6G 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

Th0XQ{Xnnj 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%0A5WbwYJ|C%sfv!7L5t02!S$bjr| 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≺cXQ^{-j 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 z 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�=knGU! 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

n(4il86RE2qFBR^}V9Q)#qgSjuJR# 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 literal 0 HcmV?d00001 From c79bb964b42fb9416fb719ec22c1c6ae575b7a39 Mon Sep 17 00:00:00 2001 From: easbar Date: Mon, 20 Jun 2022 14:42:43 +0200 Subject: [PATCH 055/389] Add comment about GraphHopper#init --- core/src/main/java/com/graphhopper/GraphHopper.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 2668034f1f1..db7a5a79dd9 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -442,6 +442,13 @@ public CountryRuleFactory getCountryRuleFactory() { /** * Reads the configuration from a {@link GraphHopperConfig} object which can be manually filled, or more typically * is read from `config.yml`. + *

+ * Important note: Calling this method overwrites the configuration done in some of the setter methods of this class, + * so generally it is advised to either use this method to configure GraphHopper or the different setter methods, + * but not both. Unfortunately, this still does not cover all cases and sometimes you have to use both, but then you + * should make sure there are no conflicts. If you need both it might also help to call the init before calling the + * setters, because this way the init method won't apply defaults to configuration options you already chose using + * the setters. */ public GraphHopper init(GraphHopperConfig ghConfig) { ensureNotLoaded(); From eca4de06a31e976359480bf3ed9cfeb0c4f8b18b Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 21 Jun 2022 10:04:09 +0200 Subject: [PATCH 056/389] Merged #2593, i.e. revert b8d9b55a0d63e42d1 Co-authored-by: Andi Co-authored-by: Thomas Butz --- .../com/graphhopper/storage/BaseGraph.java | 1 + .../graphhopper/storage/BaseGraphTest.java | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index a30139a8b06..077e600c2ca 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -749,6 +749,7 @@ public IntsRef getFlags() { public final EdgeIteratorState setFlags(IntsRef edgeFlags) { assert edgeId < store.getEdges() : "must be edge but was shortcut: " + edgeId + " >= " + store.getEdges() + ". Use setFlagsAndWeight"; store.writeFlags(edgePointer, edgeFlags); + System.arraycopy(edgeFlags.ints, 0, this.edgeFlags.ints, 0, edgeFlags.ints.length); return this; } diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java index 8cf003735eb..b6292a64473 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java @@ -17,6 +17,8 @@ */ package com.graphhopper.storage; +import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.RoadClass; import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; import org.junit.jupiter.api.Test; @@ -257,4 +259,26 @@ public void outOfBounds() { assertThrows(IllegalArgumentException.class, () -> graph.getEdgeIteratorState(0, Integer.MIN_VALUE)); } + @Test + public void setGetFlagsRaw() { + BaseGraph graph = new BaseGraph.Builder(1).create(); + EdgeIteratorState edge = graph.edge(0, 1); + IntsRef flags = new IntsRef(graph.getIntsForFlags()); + flags.ints[0] = 10; + edge.setFlags(flags); + assertEquals(10, edge.getFlags().ints[0]); + flags.ints[0] = 9; + edge.setFlags(flags); + assertEquals(9, edge.getFlags().ints[0]); + } + + @Test + public void setGetFlags() { + BaseGraph graph = createGHStorage(); + EnumEncodedValue rcEnc = encodingManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); + EdgeIteratorState edge = graph.edge(0, 1).set(rcEnc, RoadClass.BRIDLEWAY); + assertEquals(RoadClass.BRIDLEWAY, edge.get(rcEnc)); + edge.set(rcEnc, RoadClass.CORRIDOR); + assertEquals(RoadClass.CORRIDOR, edge.get(rcEnc)); + } } From ddc1bb69a98c66d58c09fec33f363ff201810f08 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 21 Jun 2022 19:04:57 +0200 Subject: [PATCH 057/389] Add another elevation file used in tests --- core/files/N41E001.hgt.zip | Bin 0 -> 1385072 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 core/files/N41E001.hgt.zip diff --git a/core/files/N41E001.hgt.zip b/core/files/N41E001.hgt.zip new file mode 100644 index 0000000000000000000000000000000000000000..79c19112ac8b8bd5efdfd8641c4ee8fd6a1ee880 GIT binary patch literal 1385072 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 z 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 z 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�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

oal3TeKLWAkA?{Rr_{p|Xa3pG|TGFavK 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

`|R(`dh`- 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%0D!OvO-ovhy6m0#f&+>oQWIOpS>Y;A_U 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 bJJ`KU}v_U|L&>$lkT_v0sY*Ps6fZBI)f literal 0 HcmV?d00001 From 0758bf1e5f2b234b3e45dba876163bc4faab0d80 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 21 Jun 2022 20:29:57 +0200 Subject: [PATCH 058/389] Use access and speed EVs rather than flag encoder for GHUtility#setSpeed --- .../java/com/graphhopper/util/GHUtility.java | 7 +- .../algorithm/ShortestPathTreeTest.java | 35 +- .../dem/EdgeElevationInterpolatorTest.java | 6 + .../dem/TunnelElevationInterpolatorTest.java | 36 +- .../routing/AStarBidirectionTest.java | 26 +- .../routing/AlternativeRouteEdgeCHTest.java | 37 +- .../routing/CHQueryWithTurnCostsTest.java | 172 ++--- .../DefaultBidirPathExtractorTest.java | 9 +- .../routing/DijkstraBidirectionCHTest.java | 10 +- .../DirectedBidirectionalDijkstraTest.java | 172 ++--- .../DirectionResolverOnQueryGraphTest.java | 2 +- .../routing/DirectionResolverTest.java | 2 +- .../EdgeBasedRoutingAlgorithmTest.java | 79 ++- .../routing/HeadingResolverTest.java | 26 +- .../routing/HeadingRoutingTest.java | 56 +- .../com/graphhopper/routing/PathTest.java | 112 ++-- .../routing/QueryRoutingCHGraphTest.java | 12 +- .../routing/RandomCHRoutingTest.java | 9 +- .../routing/RoundTripRoutingTest.java | 2 +- .../routing/RoutingAlgorithmTest.java | 333 ++++----- .../routing/RoutingCHGraphImplTest.java | 46 +- .../routing/ch/CHTurnCostTest.java | 488 +++++++------- .../ch/EdgeBasedNodeContractorTest.java | 630 +++++++++--------- .../ch/NodeBasedNodeContractorTest.java | 97 +-- .../ch/PrepareContractionHierarchiesTest.java | 273 ++++---- .../graphhopper/routing/lm/LMIssueTest.java | 31 +- .../routing/lm/LandmarkStorageTest.java | 49 +- .../routing/lm/PrepareLandmarksTest.java | 9 +- .../routing/querygraph/QueryGraphTest.java | 54 +- .../PrepareRoutingSubnetworksTest.java | 44 +- .../routing/util/AccessFilterTest.java | 10 +- .../parsers/OSMTurnRelationParserTest.java | 23 +- .../weighting/BlockAreaWeightingTest.java | 2 +- .../weighting/FastestWeightingTest.java | 10 +- .../weighting/custom/CustomWeightingTest.java | 11 +- .../storage/AbstractGraphStorageTester.java | 23 +- .../graphhopper/storage/BaseGraphTest.java | 10 +- .../storage/GraphEdgeIdFinderTest.java | 52 +- .../storage/index/LocationIndexTreeTest.java | 97 +-- .../com/graphhopper/util/GHUtilityTest.java | 20 +- .../graphhopper/util/InstructionListTest.java | 93 +-- .../util/PathSimplificationTest.java | 28 +- .../graphhopper/gpx/GpxConversionsTest.java | 16 +- 43 files changed, 1720 insertions(+), 1539 deletions(-) diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index b06687f6e85..56fe03df02a 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -633,11 +633,12 @@ public static void setSpeed(double fwdSpeed, double bwdSpeed, FlagEncoder encode } public static EdgeIteratorState setSpeed(double averageSpeed, boolean fwd, boolean bwd, FlagEncoder encoder, EdgeIteratorState edge) { + return setSpeed(averageSpeed, fwd, bwd, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge); + } + + public static EdgeIteratorState setSpeed(double averageSpeed, boolean fwd, boolean bwd, BooleanEncodedValue accessEnc, DecimalEncodedValue avSpeedEnc, EdgeIteratorState edge) { if (averageSpeed < 0.0001 && (fwd || bwd)) throw new IllegalStateException("Zero speed is only allowed if edge will get inaccessible. Otherwise Weighting can produce inconsistent results"); - - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue avSpeedEnc = encoder.getAverageSpeedEnc(); edge.set(accessEnc, fwd, bwd); if (fwd) edge.set(avSpeedEnc, averageSpeed); diff --git a/core/src/test/java/com/graphhopper/isochrone/algorithm/ShortestPathTreeTest.java b/core/src/test/java/com/graphhopper/isochrone/algorithm/ShortestPathTreeTest.java index e39bae66fea..29fc51753c3 100644 --- a/core/src/test/java/com/graphhopper/isochrone/algorithm/ShortestPathTreeTest.java +++ b/core/src/test/java/com/graphhopper/isochrone/algorithm/ShortestPathTreeTest.java @@ -1,6 +1,7 @@ package com.graphhopper.isochrone.algorithm; import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.AllEdgesIterator; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; @@ -61,13 +62,14 @@ public long calcTurnMillis(int inEdge, int viaNode, int outEdge) { private final EncodingManager encodingManager = EncodingManager.create("car"); private final FlagEncoder carEncoder = encodingManager.getEncoder("car"); + private final BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + private final DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); private BaseGraph graph; @BeforeEach public void setUp() { graph = new BaseGraph.Builder(encodingManager).create(); - // 8 // / // 0-1-2-3 @@ -75,31 +77,30 @@ public void setUp() { // 4-5-- | // |/ \--7 // 6----/ - GHUtility.setSpeed(10, true, false, carEncoder, ((Graph) graph).edge(0, 1).setDistance(70)); - GHUtility.setSpeed(20, true, false, carEncoder, ((Graph) graph).edge(0, 4).setDistance(50)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, ((Graph) graph).edge(0, 1).setDistance(70)); + GHUtility.setSpeed(20, true, false, accessEnc, speedEnc, ((Graph) graph).edge(0, 4).setDistance(50)); - GHUtility.setSpeed(10, true, true, carEncoder, ((Graph) graph).edge(1, 4).setDistance(70)); - GHUtility.setSpeed(10, true, true, carEncoder, ((Graph) graph).edge(1, 5).setDistance(70)); - GHUtility.setSpeed(10, true, true, carEncoder, ((Graph) graph).edge(1, 2).setDistance(200)); + GHUtility.setSpeed(10, true, true, accessEnc, speedEnc, ((Graph) graph).edge(1, 4).setDistance(70)); + GHUtility.setSpeed(10, true, true, accessEnc, speedEnc, ((Graph) graph).edge(1, 5).setDistance(70)); + GHUtility.setSpeed(10, true, true, accessEnc, speedEnc, ((Graph) graph).edge(1, 2).setDistance(200)); - GHUtility.setSpeed(10, true, false, carEncoder, ((Graph) graph).edge(5, 2).setDistance(50)); - GHUtility.setSpeed(10, true, false, carEncoder, ((Graph) graph).edge(2, 3).setDistance(50)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, ((Graph) graph).edge(5, 2).setDistance(50)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, ((Graph) graph).edge(2, 3).setDistance(50)); - GHUtility.setSpeed(20, true, false, carEncoder, ((Graph) graph).edge(5, 3).setDistance(110)); - GHUtility.setSpeed(10, true, false, carEncoder, ((Graph) graph).edge(3, 7).setDistance(70)); + GHUtility.setSpeed(20, true, false, accessEnc, speedEnc, ((Graph) graph).edge(5, 3).setDistance(110)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, ((Graph) graph).edge(3, 7).setDistance(70)); - GHUtility.setSpeed(20, true, false, carEncoder, ((Graph) graph).edge(4, 6).setDistance(50)); - GHUtility.setSpeed(10, true, false, carEncoder, ((Graph) graph).edge(5, 4).setDistance(70)); + GHUtility.setSpeed(20, true, false, accessEnc, speedEnc, ((Graph) graph).edge(4, 6).setDistance(50)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, ((Graph) graph).edge(5, 4).setDistance(70)); - GHUtility.setSpeed(10, true, false, carEncoder, ((Graph) graph).edge(5, 6).setDistance(70)); - GHUtility.setSpeed(20, true, false, carEncoder, ((Graph) graph).edge(7, 5).setDistance(50)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, ((Graph) graph).edge(5, 6).setDistance(70)); + GHUtility.setSpeed(20, true, false, accessEnc, speedEnc, ((Graph) graph).edge(7, 5).setDistance(50)); - GHUtility.setSpeed(20, true, true, carEncoder, ((Graph) graph).edge(6, 7).setDistance(50)); - GHUtility.setSpeed(20, true, true, carEncoder, ((Graph) graph).edge(3, 8).setDistance(25)); + GHUtility.setSpeed(20, true, true, accessEnc, speedEnc, ((Graph) graph).edge(6, 7).setDistance(50)); + GHUtility.setSpeed(20, true, true, accessEnc, speedEnc, ((Graph) graph).edge(3, 8).setDistance(25)); } private int countDirectedEdges(BaseGraph graph) { - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); int result = 0; AllEdgesIterator iter = graph.getAllEdges(); while (iter.next()) { diff --git a/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationInterpolatorTest.java b/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationInterpolatorTest.java index 487ae1a1c41..044b34f3838 100644 --- a/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationInterpolatorTest.java +++ b/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationInterpolatorTest.java @@ -19,6 +19,8 @@ import com.graphhopper.coll.GHBitSetImpl; import com.graphhopper.coll.GHIntHashSet; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.RoadEnvironment; import com.graphhopper.routing.util.EncodingManager; @@ -42,6 +44,8 @@ public abstract class EdgeElevationInterpolatorTest { protected BaseGraph graph; protected EnumEncodedValue roadEnvEnc; protected FlagEncoder encoder; + protected BooleanEncodedValue accessEnc; + protected DecimalEncodedValue speedEnc; protected EncodingManager encodingManager; protected EdgeElevationInterpolator edgeElevationInterpolator; @@ -50,6 +54,8 @@ public abstract class EdgeElevationInterpolatorTest { public void setUp() { encoder = FlagEncoders.createCar(); encodingManager = EncodingManager.create(encoder); + accessEnc = encoder.getAccessEnc(); + speedEnc = encoder.getAverageSpeedEnc(); graph = new BaseGraph.Builder(encodingManager).set3D(true).create(); roadEnvEnc = encodingManager.getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class); edgeElevationInterpolator = createEdgeElevationInterpolator(); diff --git a/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java b/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java index 6f78ba86f81..1ca67ee4fed 100644 --- a/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java +++ b/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java @@ -61,9 +61,9 @@ public void doesNotInterpolateElevationOfTunnelWithZeroOuterNodes() { na.setNode(3, 30, 0, 20); na.setNode(4, 40, 0, 0); - EdgeIteratorState edge01 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)); - EdgeIteratorState edge12 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10)); - EdgeIteratorState edge34 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(10)); + EdgeIteratorState edge01 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); + EdgeIteratorState edge12 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); + EdgeIteratorState edge34 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); edge01.setFlags(interpolatableFlags); edge12.setFlags(interpolatableFlags); @@ -100,10 +100,10 @@ public void interpolatesElevationOfTunnelWithSingleOuterNode() { na.setNode(3, 30, 0, 20); na.setNode(4, 40, 0, 00); - EdgeIteratorState edge01 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)); - EdgeIteratorState edge12 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10)); - EdgeIteratorState edge23 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(10)); - EdgeIteratorState edge34 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(10)); + EdgeIteratorState edge01 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); + EdgeIteratorState edge12 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); + EdgeIteratorState edge23 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10)); + EdgeIteratorState edge34 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); edge01.setFlags(interpolatableFlags); edge12.setFlags(interpolatableFlags); @@ -141,10 +141,10 @@ public void interpolatesElevationOfTunnelWithTwoOuterNodes() { na.setNode(3, 30, 0, 30); na.setNode(4, 40, 0, 40); - EdgeIteratorState edge01 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)); - EdgeIteratorState edge12 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10)); - EdgeIteratorState edge23 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(10)); - EdgeIteratorState edge34 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(10)); + EdgeIteratorState edge01 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); + EdgeIteratorState edge12 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); + EdgeIteratorState edge23 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10)); + EdgeIteratorState edge34 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); edge01.setFlags(normalFlags); edge12.setFlags(interpolatableFlags); @@ -191,13 +191,13 @@ public void interpolatesElevationOfTunnelWithThreeOuterNodes() { na.setNode(6, 30, 10, 30); na.setNode(7, 40, 10, 40); - EdgeIteratorState edge01 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)); - EdgeIteratorState edge12 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10)); - EdgeIteratorState edge23 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(10)); - EdgeIteratorState edge34 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(10)); - EdgeIteratorState edge25 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 5).setDistance(10)); - EdgeIteratorState edge56 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6).setDistance(10)); - EdgeIteratorState edge67 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(10)); + EdgeIteratorState edge01 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); + EdgeIteratorState edge12 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); + EdgeIteratorState edge23 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10)); + EdgeIteratorState edge34 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); + EdgeIteratorState edge25 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 5).setDistance(10)); + EdgeIteratorState edge56 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(10)); + EdgeIteratorState edge67 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(10)); edge01.setFlags(normalFlags); edge12.setFlags(interpolatableFlags); diff --git a/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java b/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java index 35952874b6d..dce8e6281f5 100644 --- a/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java +++ b/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java @@ -19,6 +19,8 @@ package com.graphhopper.routing; import com.carrotsearch.hppc.IntArrayList; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.util.FlagEncoders; @@ -49,22 +51,24 @@ void infeasibleApproximator_noException() { // \ / // 10 BaseGraph graph = new BaseGraph.Builder(em).create(); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(100)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); // the distance 1-2 is longer than 1-10-2 // we deliberately use 2-1 as storage direction, even though the edge points from 1 to 2, because this way // we can reproduce the 'Calculating time should not require to read speed from edge in wrong direction' error // from #2600 - graph.edge(2, 1).setDistance(300).set(encoder.getAccessEnc(), false, true).set(encoder.getAverageSpeedEnc(), 60); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(100)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(100)); + graph.edge(2, 1).setDistance(300).set(accessEnc, false, true).set(speedEnc, 60); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(100)); // distance 4-5 is very long - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(10_000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(100)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 7).setDistance(100)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 8).setDistance(100)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(8, 9).setDistance(100)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 10).setDistance(100)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(10, 2).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(10_000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 7).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 8).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(8, 9).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 10).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(10, 2).setDistance(100)); Weighting weighting = new ShortestWeighting(encoder); AStarBidirection algo = new AStarBidirection(graph, weighting, TraversalMode.NODE_BASED); diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java index 71cd35eb383..355bd3c353c 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java @@ -19,6 +19,7 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ch.PrepareContractionHierarchies; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.util.EncodingManager; @@ -61,23 +62,25 @@ public BaseGraph createTestGraph(EncodingManager tmpEM) { // So we get all three alternatives. FlagEncoder encoder = carFE; - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6).setDistance(10000)); - EdgeIteratorState e6_3 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 3).setDistance(10000)); - EdgeIteratorState e3_4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(10000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 10).setDistance(10000)); - - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(10000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(7, 8).setDistance(10000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 4).setDistance(10000)); - - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 1).setDistance(10000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 9).setDistance(10000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(9, 2).setDistance(10000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(10000)); - - EdgeIteratorState e4_11 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 11).setDistance(9000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(11, 12).setDistance(9000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(12, 10).setDistance(10000)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(10000)); + EdgeIteratorState e6_3 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 3).setDistance(10000)); + EdgeIteratorState e3_4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 10).setDistance(10000)); + + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(10000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(7, 8).setDistance(10000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 4).setDistance(10000)); + + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 1).setDistance(10000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 9).setDistance(10000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(9, 2).setDistance(10000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10000)); + + EdgeIteratorState e4_11 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 11).setDistance(9000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(11, 12).setDistance(9000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(12, 10).setDistance(10000)); TurnCostStorage turnCostStorage = graph.getTurnCostStorage(); DecimalEncodedValue carTurnCost = em.getDecimalEncodedValue(TurnCost.key(carFE.toString())); diff --git a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java index 36f81f03947..b892cd22b04 100644 --- a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java @@ -20,6 +20,8 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ch.PrepareEncoder; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.util.EncodingManager; @@ -55,6 +57,8 @@ public class CHQueryWithTurnCostsTest { private static class Fixture { private final int maxCost = 10; private final FlagEncoder encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxCost).putObject("speed_two_directions", true)); + private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + private final DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); private final EncodingManager encodingManager = EncodingManager.create(encoder); private final BaseGraph graph; private final CHConfig chConfig; @@ -152,8 +156,8 @@ public Stream provideArguments(ExtensionContext context) { public void testFindPathWithTurnCosts_bidirected_no_shortcuts_smallGraph(Fixture f) { // some special cases where from=to, or start and target edges are the same // 1 -- 0 -- 2 - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(1, 0).setDistance(3)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(0, 2).setDistance(5)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(1, 0).setDistance(3)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(0, 2).setDistance(5)); f.setTurnCost(1, 0, 2, 3); f.freeze(); @@ -175,12 +179,12 @@ public void testFindPathWithTurnCosts_bidirected_no_shortcuts_smallGraph(Fixture @ArgumentsSource(FixtureProvider.class) public void testFindPathWithTurnCosts_bidirected_no_shortcuts(Fixture f) { // 0 -- 2 -- 4 -- 6 -- 5 -- 3 -- 1 - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(0, 2).setDistance(3)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(2, 4).setDistance(2)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(4, 6).setDistance(7)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(6, 5).setDistance(9)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(5, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(3, 1).setDistance(4)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(0, 2).setDistance(3)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(2, 4).setDistance(2)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(4, 6).setDistance(7)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(6, 5).setDistance(9)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(5, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(3, 1).setDistance(4)); f.setTurnCost(0, 2, 4, 3); f.setTurnCost(4, 6, 5, 6); f.setTurnCost(5, 6, 4, 2); @@ -214,15 +218,15 @@ public void testFindPathWithTurnCosts_loopShortcutBwdSearch(Fixture f) { // 1 2 // \ / // 0 - 7 - 8 - 4 - 6 - 5 - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(7, 8).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(8, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(4, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(1, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(4, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(6, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(7, 8).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(8, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(1, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(4, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(6, 5).setDistance(1)); f.setRestriction(8, 4, 6); f.setRestriction(8, 4, 2); f.setRestriction(1, 4, 6); @@ -286,10 +290,10 @@ public void testFindPathWithTurnCosts_directed_single_shortcut(Fixture f) { // /5\ /1\ // / \2/ \ // 1 0 4 - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(1, 2).setDistance(4)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 0).setDistance(2)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 3).setDistance(3)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 4).setDistance(2)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(1, 2).setDistance(4)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 0).setDistance(2)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 3).setDistance(3)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 4).setDistance(2)); f.setTurnCost(1, 2, 0, 5); f.setTurnCost(2, 0, 3, 2); f.setTurnCost(0, 3, 4, 1); @@ -315,10 +319,10 @@ public void testFindPathWithTurnCosts_directed_single_shortcut_fwdSearchStopsQui // 0 // / \ // 1-2-s-3-4 - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(1, 2).setDistance(2)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 0).setDistance(3)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 4).setDistance(3)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(1, 2).setDistance(2)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 0).setDistance(3)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 4).setDistance(3)); f.freeze(); f.setTurnCost(1, 2, 0, 2); @@ -338,10 +342,10 @@ public void testFindPathWithTurnCosts_directed_two_shortcuts(Fixture f) { // /5\ /1\ // / \2/ \ // 2 1 4 - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 3).setDistance(4)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 1).setDistance(2)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(1, 0).setDistance(3)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 4).setDistance(2)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 3).setDistance(4)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 1).setDistance(2)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(1, 0).setDistance(3)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 4).setDistance(2)); f.setTurnCost(2, 3, 1, 5); f.setTurnCost(3, 1, 0, 2); f.setTurnCost(1, 0, 4, 1); @@ -368,10 +372,10 @@ public void testFindPath_directConnectionIsNotTheBestPath(Fixture f) { // | | // v v // 2 -> 3 -> 1 - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 2).setDistance(3)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 3).setDistance(2)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 1).setDistance(9)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 1).setDistance(50)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 2).setDistance(3)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 3).setDistance(2)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 1).setDistance(9)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 1).setDistance(50)); f.setTurnCost(2, 3, 1, 4); f.freeze(); @@ -411,10 +415,10 @@ public void testFindPath_downwardSearchRunsIntoTarget(Fixture f) { // \ ^ // \ | // <-2<-3 - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(1, 0).setDistance(9)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 0).setDistance(14)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 1).setDistance(2)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 2).setDistance(9)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(1, 0).setDistance(9)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 0).setDistance(14)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 1).setDistance(2)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 2).setDistance(9)); f.freeze(); //no shortcuts @@ -430,9 +434,9 @@ public void testFindPath_incomingShortcut(Fixture f) { // | __/ // v/ // 3 -> 2 - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(0, 1).setDistance(9)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 3).setDistance(14)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 2).setDistance(9)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(0, 1).setDistance(9)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 3).setDistance(14)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 2).setDistance(9)); f.freeze(); f.setIdentityLevels(); f.addShortcut(1, 3, 1, 2, 0, 1, 23, false); @@ -445,9 +449,9 @@ public void testFindPathWithTurnCosts_fwdBwdSearchesMeetWithUTurn(Fixture f) { // 3 // | // 0 --- 2 --- 1 - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(2, 3).setDistance(2)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 1).setDistance(3)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(2, 3).setDistance(2)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 1).setDistance(3)); f.setRestriction(0, 2, 1); f.setTurnCost(0, 2, 3, 5); f.setTurnCost(2, 3, 2, 4); @@ -489,11 +493,11 @@ private void checkUTurnNotBeingUsed(Fixture f, boolean toLowerLevelNode) { nodeA = nodeB; nodeB = tmp; } - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(1, nodeA).setDistance(4)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 3).setDistance(4)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(nodeB, 2).setDistance(1)); - final EdgeIteratorState e3toB = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, nodeB).setDistance(2)); - final EdgeIteratorState e3toA = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(3, nodeA).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(1, nodeA).setDistance(4)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 3).setDistance(4)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(nodeB, 2).setDistance(1)); + final EdgeIteratorState e3toB = GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, nodeB).setDistance(2)); + final EdgeIteratorState e3toA = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(3, nodeA).setDistance(1)); f.freeze(); f.setRestriction(0, 3, nodeB); @@ -515,10 +519,10 @@ public void testFindPathWithTurnCosts_loop(Fixture f) { // 3\ // |/ // 0 --- 2 --- 1 - final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 2).setDistance(4)); - final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(2, 3).setDistance(1)); - final EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 2).setDistance(7)); - final EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 1).setDistance(3)); + final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 2).setDistance(4)); + final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(2, 3).setDistance(1)); + final EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 2).setDistance(7)); + final EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 1).setDistance(3)); // need to specify edges explicitly because there are two edges between nodes 2 and 3 f.setRestriction(edge1, edge4, 2); f.setTurnCost(edge1, edge2, 2, 3); @@ -568,10 +572,10 @@ public void testFindPath_loopIsRecognizedAsIncomingEdge(Fixture f) { // --- // \ / // 0 -- 3 -- 2 -- 1 - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(0, 3).setDistance(1)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 3).setDistance(1)); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(3, 2).setDistance(1)); - EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 1).setDistance(1)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(0, 3).setDistance(1)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 3).setDistance(1)); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(3, 2).setDistance(1)); + EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 1).setDistance(1)); f.setRestriction(edge0, edge2, 3); f.freeze(); @@ -591,11 +595,11 @@ public void testFindPath_shortcutLoopIsRecognizedAsIncomingEdge(Fixture f) { // -0- // \ / // 3 -- 4 -- 2 -- 1 - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(3, 4).setDistance(1)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(4, 2).setDistance(1)); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 0).setDistance(1)); - EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 2).setDistance(1)); - EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(2, 1).setDistance(1)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(3, 4).setDistance(1)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(4, 2).setDistance(1)); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 0).setDistance(1)); + EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 2).setDistance(1)); + EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(2, 1).setDistance(1)); f.setRestriction(edge1, edge4, 2); f.freeze(); @@ -622,11 +626,11 @@ public void testFindPathWithTurnRestriction_single_loop(Fixture f) { // | // v no right turn at 4 when coming from 3! // 2 - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 4).setDistance(2)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(4, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 1).setDistance(3)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(4, 1).setDistance(5)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(4, 2).setDistance(4)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 4).setDistance(2)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(4, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 1).setDistance(3)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(4, 1).setDistance(5)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(4, 2).setDistance(4)); f.setRestriction(3, 4, 2); f.freeze(); @@ -699,15 +703,15 @@ public void testFindPathWithTurnRestriction_double_loop(Fixture f) { // | // | no right turn at 7 when coming from 4 and no left turn at 7 when coming from 5! // 5 - final EdgeIteratorState e0to1 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(0, 1).setDistance(2)); - final EdgeIteratorState e1to6 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(1, 6).setDistance(1)); - final EdgeIteratorState e0to6 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(0, 6).setDistance(4)); - final EdgeIteratorState e2to6 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(2, 6).setDistance(5)); - final EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(2, 3).setDistance(3)); - final EdgeIteratorState e3to6 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(3, 6).setDistance(2)); - final EdgeIteratorState e6to7 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(7, 6).setDistance(1)); - final EdgeIteratorState e4to7 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(7, 4).setDistance(3)); - final EdgeIteratorState e5to7 = GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(7, 5).setDistance(2)); + final EdgeIteratorState e0to1 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(0, 1).setDistance(2)); + final EdgeIteratorState e1to6 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(1, 6).setDistance(1)); + final EdgeIteratorState e0to6 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(0, 6).setDistance(4)); + final EdgeIteratorState e2to6 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(2, 6).setDistance(5)); + final EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(2, 3).setDistance(3)); + final EdgeIteratorState e3to6 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(3, 6).setDistance(2)); + final EdgeIteratorState e6to7 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(7, 6).setDistance(1)); + final EdgeIteratorState e4to7 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(7, 4).setDistance(3)); + final EdgeIteratorState e5to7 = GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(7, 5).setDistance(2)); f.setRestriction(e6to7, e1to6, 6); f.setRestriction(e6to7, e2to6, 6); @@ -750,15 +754,15 @@ public void testFindPathWithTurnRestriction_two_different_loops(Fixture f) { // | // v no right turn at 6 when coming from 3! // 2 - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(0, 1).setDistance(2)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(1, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(5, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(5, 4).setDistance(5)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(5, 6).setDistance(3)); - GHUtility.setSpeed(60, true, true, f.encoder, f.graph.edge(6, 4).setDistance(4)); - - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(3, 6).setDistance(3)); - GHUtility.setSpeed(60, true, false, f.encoder, f.graph.edge(6, 2).setDistance(4)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(0, 1).setDistance(2)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(1, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(5, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(5, 4).setDistance(5)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(5, 6).setDistance(3)); + GHUtility.setSpeed(60, true, true, f.accessEnc, f.speedEnc, f.graph.edge(6, 4).setDistance(4)); + + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(3, 6).setDistance(3)); + GHUtility.setSpeed(60, true, false, f.accessEnc, f.speedEnc, f.graph.edge(6, 2).setDistance(4)); f.setRestriction(3, 6, 2); f.freeze(); diff --git a/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java b/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java index 0a29d0b6b78..aeda19ea475 100644 --- a/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java @@ -18,6 +18,7 @@ package com.graphhopper.routing; import com.carrotsearch.hppc.IntArrayList; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.util.EncodingManager; @@ -40,6 +41,8 @@ */ public class DefaultBidirPathExtractorTest { private final FlagEncoder carEncoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", 10)); + private final BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + private final DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); private final EncodingManager encodingManager = EncodingManager.create(carEncoder); BaseGraph createGraph() { @@ -49,7 +52,7 @@ BaseGraph createGraph() { @Test public void testExtract() { Graph graph = createGraph(); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); SPTEntry fwdEntry = new SPTEntry(0, 2, 0, new SPTEntry(1, 10)); SPTEntry bwdEntry = new SPTEntry(2, 0); Path p = DefaultBidirPathExtractor.extractPath(graph, new FastestWeighting(carEncoder), fwdEntry, bwdEntry, 0); @@ -61,8 +64,8 @@ public void testExtract() { public void testExtract2() { // 1->2->3 Graph graph = createGraph(); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(1, 2).setDistance(10)); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(2, 3).setDistance(20)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(20)); // add some turn costs at node 2 where fwd&bwd searches meet. these costs have to be included in the // weight and the time of the path TurnCostStorage turnCostStorage = graph.getTurnCostStorage(); diff --git a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java index 2836edf61ac..6247aacf430 100644 --- a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java @@ -126,10 +126,10 @@ public void testStallingNodesReducesNumberOfVisitedNodes() { graph.edge(1, 8).setDistance(1), graph.edge(2, 3).setDistance(3)); for (int i = 3; i < 7; ++i) { - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(i, i + 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(i, i + 1).setDistance(1)); } - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(9, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(3, 9).setDistance(200)); + GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(9, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(3, 9).setDistance(200)); graph.freeze(); ShortestWeighting weighting = new ShortestWeighting(carEncoder); @@ -178,11 +178,11 @@ public void testDirectionDependentSpeedBwdSearch() { private void runTestWithDirectionDependentEdgeSpeed(double speed, double revSpeed, int from, int to, IntArrayList expectedPath, FlagEncoder encoder) { BaseGraph graph = createGHStorage(); - EdgeIteratorState edge = GHUtility.setSpeed(encoder.getMaxSpeed() / 2, true, true, encoder, graph.edge(0, 1).setDistance(2)); + EdgeIteratorState edge = GHUtility.setSpeed(encoder.getMaxSpeed() / 2, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(2)); DecimalEncodedValue avSpeedEnc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(encoder, "average_speed")); edge.set(avSpeedEnc, speed, revSpeed); - GHUtility.setSpeed(encoder.getMaxSpeed() / 2, true, true, encoder, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(encoder.getMaxSpeed() / 2, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(1)); graph.freeze(); FastestWeighting weighting = new FastestWeighting(encoder); CHConfig chConfig = CHConfig.nodeBased(weighting.getName(), weighting); diff --git a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java index b026a033d68..1046d7eac35 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java @@ -2,10 +2,14 @@ import com.carrotsearch.hppc.IntArrayList; import com.carrotsearch.hppc.IntHashSet; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.querygraph.QueryGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.AvoidEdgesWeighting; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; @@ -42,6 +46,8 @@ public class DirectedBidirectionalDijkstraTest { private int maxTurnCosts; private BaseGraph graph; private FlagEncoder encoder; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; private EncodingManager encodingManager; private Weighting weighting; private DecimalEncodedValue turnCostEnc; @@ -51,6 +57,8 @@ public void setup() { maxTurnCosts = 10; encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxTurnCosts)); encodingManager = EncodingManager.create(encoder); + accessEnc = encoder.getAccessEnc(); + speedEnc = encoder.getAverageSpeedEnc(); graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); turnCostStorage = graph.getTurnCostStorage(); weighting = createWeighting(Weighting.INFINITE_U_TURN_COSTS); @@ -65,8 +73,8 @@ private Weighting createWeighting(int uTurnCosts) { public void connectionNotFound() { // nodes 0 and 2 are not connected // 0 -> 1 2 -> 3 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); Path path = calcPath(0, 3, 0, 1); assertNotFound(path); @@ -74,7 +82,7 @@ public void connectionNotFound() { @Test public void singleEdge() { - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); // source edge does not exist -> no path assertNotFound(calcPath(0, 1, 5, 0)); @@ -93,8 +101,8 @@ public void singleEdge() { @Test public void simpleGraph() { // 0 -> 1 -> 2 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); // source edge does not exist -> no path assertNotFound(calcPath(0, 2, 5, 0)); @@ -118,9 +126,9 @@ public void sourceEqualsTarget() { // 0 - 1 // \ | // - 2 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); assertPath(calcPath(0, 0, 0, 1), 0.18, 3, 180, nodes(0, 1, 2, 0)); assertPath(calcPath(0, 0, 1, 0), 0.18, 3, 180, nodes(0, 2, 1, 0)); // without restrictions the weight should be zero @@ -136,15 +144,15 @@ public void restrictedEdges() { // 0 = 1 - 2 - 3 = 4 // \ | / // - 5 - 6 - 7 - - int costlySource = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(5)).getEdge(); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(1)); - int costlyTarget = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(5)).getEdge(); - int cheapSource = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 5).setDistance(1)).getEdge(); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(1)); - int cheapTarget = GHUtility.setSpeed(60, true, true, encoder, graph.edge(7, 4).setDistance(1)).getEdge(); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 6).setDistance(1)); + int costlySource = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(5)).getEdge(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + int costlyTarget = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(5)).getEdge(); + int cheapSource = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 5).setDistance(1)).getEdge(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(1)); + int cheapTarget = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(7, 4).setDistance(1)).getEdge(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 6).setDistance(1)); assertPath(calcPath(0, 4, cheapSource, cheapTarget), 0.24, 4, 240, nodes(0, 5, 6, 7, 4)); assertPath(calcPath(0, 4, cheapSource, costlyTarget), 0.54, 9, 540, nodes(0, 5, 6, 2, 3, 4)); @@ -160,10 +168,10 @@ public void notConnectedDueToRestrictions() { // \ / // - 3 - // we cannot go from 0 to 2 if we enforce north-south or south-north - int sourceNorth = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)).getEdge(); - int sourceSouth = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 3).setDistance(2)).getEdge(); - int targetNorth = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(3)).getEdge(); - int targetSouth = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 2).setDistance(4)).getEdge(); + int sourceNorth = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)).getEdge(); + int sourceSouth = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 3).setDistance(2)).getEdge(); + int targetNorth = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(3)).getEdge(); + int targetSouth = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 2).setDistance(4)).getEdge(); assertPath(calcPath(0, 2, sourceNorth, targetNorth), 0.24, 4, 240, nodes(0, 1, 2)); assertNotFound(calcPath(0, 2, sourceNorth, targetSouth)); @@ -176,11 +184,11 @@ public void restrictions_one_ways() { // 0 <- 1 <- 2 // \ | / // >--3--> - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); assertPath(calcPath(0, 2, 0, 2), 0.12, 2, 120, nodes(0, 3, 2)); assertNotFound(calcPath(0, 2, 1, 2)); @@ -197,15 +205,15 @@ public void forcingDirectionDoesNotMeanWeCannotUseEdgeAtAll() { // 2 - 3 // | | // 5 - 4 - int north = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 0).setDistance(1)).getEdge(); - int south = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)).getEdge(); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 6).setDistance(1)); - int targetEdge = GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 7).setDistance(1)).getEdge(); + int north = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 0).setDistance(1)).getEdge(); + int south = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)).getEdge(); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 6).setDistance(1)); + int targetEdge = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 7).setDistance(1)).getEdge(); assertPath(calcPath(1, 7, north, targetEdge), 0.18, 3, 180, nodes(1, 0, 6, 7)); assertPath(calcPath(1, 7, south, targetEdge), 0.54, 9, 540, nodes(1, 2, 5, 4, 3, 2, 1, 0, 6, 7)); } @@ -215,13 +223,13 @@ public void directedCircle() { // 0---6--1 -> 2 // | / // 5 <- 4 <- 3 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 0).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 0).setDistance(1)); assertPath(calcPath(6, 0, 1, 6), 0.36, 6, 360, nodes(6, 1, 2, 3, 4, 5, 0)); } @@ -274,10 +282,10 @@ public void directedRouting() { public void enforceLoopEdge() { // o o // 0 - 1 - 2 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 0).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 0).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 2).setDistance(1)); assertPath(calcPath(0, 2, ANY_EDGE, ANY_EDGE), 0.12, 2, 120, nodes(0, 1, 2)); assertPath(calcPath(0, 2, 1, 2), 0.12, 2, 120, nodes(0, 1, 2)); @@ -290,9 +298,9 @@ public void enforceLoopEdge() { @Test public void sourceAndTargetAreNeighbors() { // 0-1-2-3 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(100)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(100)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(100)); assertPath(calcPath(1, 2, ANY_EDGE, ANY_EDGE), 6, 100, 6000, nodes(1, 2)); assertPath(calcPath(1, 2, 1, ANY_EDGE), 6, 100, 6000, nodes(1, 2)); assertPath(calcPath(1, 2, ANY_EDGE, 1), 6, 100, 6000, nodes(1, 2)); @@ -315,13 +323,13 @@ public void worksWithTurnCosts() { // 0 - 1 - 2 // | | | // 3 - 4 - 5 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 2).setDistance(1)); setRestriction(0, 3, 4); setTurnCost(4, 5, 2, 6); @@ -344,17 +352,17 @@ public void finiteUTurnCosts() { // 0 -- 1 -- 6 // | | // 7 -- 8 -- 9 - int right0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)).getEdge(); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 2).setDistance(1000)); - int left6 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 6).setDistance(10)).getEdge(); - int left0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 7).setDistance(10)).getEdge(); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(7, 8).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 9).setDistance(10)); - int right6 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(9, 6).setDistance(10)).getEdge(); + int right0 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)).getEdge(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 2).setDistance(1000)); + int left6 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 6).setDistance(10)).getEdge(); + int left0 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 7).setDistance(10)).getEdge(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(7, 8).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 9).setDistance(10)); + int right6 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(9, 6).setDistance(10)).getEdge(); // enforce p-turn (using the loop in clockwise direction) setRestriction(0, 1, 6); @@ -391,7 +399,7 @@ private void compare_with_dijkstra(Weighting w) { Random rnd = new Random(seed); int numNodes = 100; GHUtility.buildRandomGraph(graph, rnd, numNodes, 2.2, true, true, - encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), null, 0.7, 0.8, 0.8); + accessEnc, speedEnc, null, 0.7, 0.8, 0.8); GHUtility.addRandomTurnCosts(graph, seed, encodingManager, encoder, maxTurnCosts, turnCostStorage); long numStrictViolations = 0; @@ -421,13 +429,13 @@ public void blockArea() { // 0 - 1 - 2 - 3 // | | // 4 --- 5 --- 6 - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10)); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 4).setDistance(100)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(100)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6).setDistance(100)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 3).setDistance(100)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 4).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 3).setDistance(100)); // usually we would take the direct route assertPath(calcPath(0, 3, ANY_EDGE, ANY_EDGE), 1.8, 30, 1800, nodes(0, 1, 2, 3)); @@ -466,12 +474,12 @@ public void directedRouting_noUTurnAtVirtualEdge() { // 0 -- 1 -> 2 // | | // 5 <- 4 <- 3 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 0).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 0).setDistance(1)); NodeAccess na = graph.getNodeAccess(); na.setNode(0, 1, 0); na.setNode(1, 1, 1); diff --git a/core/src/test/java/com/graphhopper/routing/DirectionResolverOnQueryGraphTest.java b/core/src/test/java/com/graphhopper/routing/DirectionResolverOnQueryGraphTest.java index 372ce470e91..6e1f9fbbe57 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectionResolverOnQueryGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectionResolverOnQueryGraphTest.java @@ -294,7 +294,7 @@ private void addNode(int nodeId, double lat, double lon) { } private EdgeIteratorState addEdge(int from, int to, boolean bothDirections) { - return GHUtility.setSpeed(60, true, bothDirections, encoder, graph.edge(from, to).setDistance(1)); + return GHUtility.setSpeed(60, true, bothDirections, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(from, to).setDistance(1)); } private void init() { diff --git a/core/src/test/java/com/graphhopper/routing/DirectionResolverTest.java b/core/src/test/java/com/graphhopper/routing/DirectionResolverTest.java index 1510d7f2cc1..84152715c70 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectionResolverTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectionResolverTest.java @@ -382,7 +382,7 @@ private void addNode(int nodeId, double lat, double lon) { } private EdgeIteratorState addEdge(int from, int to, boolean bothDirections) { - return GHUtility.setSpeed(60, true, bothDirections, encoder, graph.edge(from, to).setDistance(1)); + return GHUtility.setSpeed(60, true, bothDirections, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(from, to).setDistance(1)); } private boolean isAccessible(EdgeIteratorState edge, boolean reverse) { diff --git a/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java b/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java index c3b4f59cbd6..08d668e736c 100644 --- a/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java +++ b/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java @@ -19,6 +19,7 @@ import com.carrotsearch.hppc.IntArrayList; import com.carrotsearch.hppc.cursors.IntCursor; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.util.EncodingManager; @@ -58,6 +59,8 @@ public class EdgeBasedRoutingAlgorithmTest { private static final Logger LOGGER = LoggerFactory.getLogger(EdgeBasedRoutingAlgorithmTest.class); private FlagEncoder carEncoder; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; private DecimalEncodedValue turnCostEnc; private TurnCostStorage tcs; @@ -82,21 +85,23 @@ public Stream provideArguments(ExtensionContext context) { // | | | // 5--6--7 private void initGraph(Graph graph) { - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(0, 1).setDistance(3)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(0, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(1, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(2, 5).setDistance(0.5)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(3, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(4, 7).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(6, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 5).setDistance(0.5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(1)); } private EncodingManager createEncodingManager(boolean restrictedOnly) { carEncoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", restrictedOnly ? 1 : 3)); EncodingManager em = EncodingManager.create(carEncoder); + accessEnc = carEncoder.getAccessEnc(); + speedEnc = carEncoder.getAverageSpeedEnc(); turnCostEnc = getTurnCostEnc(carEncoder); return em; } @@ -164,7 +169,7 @@ public void testRandomGraph(String algoStr) { EncodingManager em = createEncodingManager(false); BaseGraph g = createStorage(em); GHUtility.buildRandomGraph(g, rnd, 50, 2.2, true, true, - carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), null, 0.8, 0.8, 0.8); + accessEnc, speedEnc, null, 0.8, 0.8, 0.8); GHUtility.addRandomTurnCosts(g, seed, em, carEncoder, 3, tcs); g.freeze(); int numPathsNotFound = 0; @@ -235,12 +240,12 @@ public void testLoop_issue1592(String algoStr) { // 4-3 // | // 1o - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(0, 6).setDistance(10)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(6, 3).setDistance(10)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(0, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(4, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(4, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(1, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 6).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 3).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 1).setDistance(10)); setTurnRestriction(graph, 0, 4, 3); Path p = calcPath(graph, 0, 3, algoStr); @@ -255,10 +260,10 @@ public void testTurnCosts_timeCalculation(String algoStr) { BaseGraph graph = createStorage(createEncodingManager(false)); final int distance = 100; final int turnCosts = 2; - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(0, 1).setDistance(distance)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(1, 2).setDistance(distance)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(2, 3).setDistance(distance)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(3, 4).setDistance(distance)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(distance)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(distance)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(distance)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(distance)); setTurnCost(graph, turnCosts, 1, 2, 3); { @@ -359,11 +364,11 @@ public void uTurnCostAtMeetingNode(String algoStr) { // | // 0 -> 1 -> 2 -> 4 -> 5 BaseGraph g = createStorage(createEncodingManager(false)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(0, 1).setDistance(10)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(1, 2).setDistance(10)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 3).setDistance(10)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(2, 4).setDistance(10)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(4, 5).setDistance(10)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(2, 4).setDistance(10)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(4, 5).setDistance(10)); // cannot go straight at node 2 setTurnRestriction(g, 1, 2, 4); @@ -437,11 +442,11 @@ public void testLoopEdge(String algoStr) { // \| // 0 final BaseGraph graph = createStorage(createEncodingManager(false)); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(3, 2).setDistance(188)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(3, 0).setDistance(182)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(4, 2).setDistance(690)); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(2, 2).setDistance(121)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(2, 0).setDistance(132)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(188)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 0).setDistance(182)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 2).setDistance(690)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 2).setDistance(121)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 0).setDistance(132)); setTurnRestriction(graph, 2, 2, 0); setTurnRestriction(graph, 3, 2, 4); @@ -460,12 +465,12 @@ public void testDoubleLoopPTurn(String algoStr) { // | // 5 final BaseGraph graph = createStorage(createEncodingManager(false)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(3, 4).setDistance(2)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(4, 4).setDistance(4)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(3, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(1, 4).setDistance(5)); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(5, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 4).setDistance(4)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 4).setDistance(1)); setTurnRestriction(graph, 1, 4, 5); Path p = calcPath(graph, 0, 5, algoStr); diff --git a/core/src/test/java/com/graphhopper/routing/HeadingResolverTest.java b/core/src/test/java/com/graphhopper/routing/HeadingResolverTest.java index 1814a084aa1..72debe7f8df 100644 --- a/core/src/test/java/com/graphhopper/routing/HeadingResolverTest.java +++ b/core/src/test/java/com/graphhopper/routing/HeadingResolverTest.java @@ -19,6 +19,8 @@ package com.graphhopper.routing; import com.carrotsearch.hppc.IntArrayList; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; @@ -57,14 +59,16 @@ public void straightEdges() { na.setNode(7, 48.8611, 1.2194); na.setNode(8, 48.8538, 2.3950); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 0).setDistance(10)); // edge 0 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 1).setDistance(10)); // edge 1 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 2).setDistance(10)); // edge 2 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 3).setDistance(10)); // edge 3 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 4).setDistance(10)); // edge 4 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 5).setDistance(10)); // edge 5 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 6).setDistance(10)); // edge 6 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 7).setDistance(10)); // edge 7 + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 0).setDistance(10)); // edge 0 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 1).setDistance(10)); // edge 1 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 2).setDistance(10)); // edge 2 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 3).setDistance(10)); // edge 3 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 4).setDistance(10)); // edge 4 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 5).setDistance(10)); // edge 5 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 6).setDistance(10)); // edge 6 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 7).setDistance(10)); // edge 7 HeadingResolver resolver = new HeadingResolver(graph); // using default tolerance @@ -92,9 +96,9 @@ public void curvyEdge() { na.setNode(1, 0.01, 0.00); na.setNode(0, 0.00, 0.00); na.setNode(2, -0.01, 0.00); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)). + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(10)). setWayGeometry(Helper.createPointList(0.00, 0.01, 0.01, 0.01)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 2).setDistance(10)). + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 2).setDistance(10)). setWayGeometry(Helper.createPointList(0.00, -0.01, -0.01, -0.01)); HeadingResolver resolver = new HeadingResolver(graph); resolver.setTolerance(120); @@ -115,7 +119,7 @@ public void withQueryGraph() { na.setNode(0, 48.8611, 1.2194); na.setNode(1, 48.8538, 2.3950); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(10)); Snap snap = createSnap(edge, 48.859, 2.00, 0); QueryGraph queryGraph = QueryGraph.create(graph, snap); HeadingResolver resolver = new HeadingResolver(queryGraph); diff --git a/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java b/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java index b04a398ae61..17c5f899a8a 100644 --- a/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java @@ -22,6 +22,8 @@ import com.graphhopper.GHResponse; import com.graphhopper.ResponsePath; import com.graphhopper.config.Profile; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; @@ -324,19 +326,21 @@ private BaseGraph createSquareGraph(EncodingManager encodingManager) { na.setNode(7, 0.000, 0.001); na.setNode(8, 0.001, 0.001); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 1).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 2).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 3).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 4).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(4, 5).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(5, 6).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(6, 7).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(7, 0).setDistance(100)); - - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 8).setDistance(110)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 8).setDistance(110)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(5, 8).setDistance(110)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(7, 8).setDistance(110)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 6).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 0).setDistance(100)); + + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 8).setDistance(110)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 8).setDistance(110)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(110)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(110)); return g; } @@ -361,18 +365,20 @@ private BaseGraph createSquareGraphWithTunnel(EncodingManager encodingManager) { na.setNode(7, 0.000, 0.001); na.setNode(8, 0.001, 0.001); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 1).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 2).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 3).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 4).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(4, 5).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(5, 6).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(6, 7).setDistance(100)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(7, 0).setDistance(100)); - - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(1, 5).setDistance(110)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 8).setDistance(110)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(7, 8).setDistance(110)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 6).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 0).setDistance(100)); + + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(1, 5).setDistance(110)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 8).setDistance(110)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(110)); return g; } diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index 86951d568b3..4303cf91dac 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -47,7 +47,7 @@ public class PathTest { private final FlagEncoder encoder = FlagEncoders.createCar(); private final EncodingManager carManager = EncodingManager.create(encoder); private final BooleanEncodedValue carAccessEnc = encoder.getAccessEnc(); - private final DecimalEncodedValue carAvSpeedEnv = encoder.getAverageSpeedEnc(); + private final DecimalEncodedValue carAvSpeedEnc = encoder.getAverageSpeedEnc(); private final EncodingManager mixedEncoders = EncodingManager.create(FlagEncoders.createCar(), FlagEncoders.createFoot()); private final TranslationMap trMap = TranslationMapTest.SINGLETON; private final Translation tr = trMap.getWithFallBack(Locale.US); @@ -71,10 +71,10 @@ public void testWayList() { na.setNode(1, 1.0, 0.1); na.setNode(2, 2.0, 0.1); - EdgeIteratorState edge1 = g.edge(0, 1).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnv, 10.0); + EdgeIteratorState edge1 = g.edge(0, 1).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 10.0); edge1.setWayGeometry(Helper.createPointList(8, 1, 9, 1)); - EdgeIteratorState edge2 = g.edge(2, 1).setDistance(2000).set(carAccessEnc, true, true).set(carAvSpeedEnv, 50.0); + EdgeIteratorState edge2 = g.edge(2, 1).setDistance(2000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge2.setWayGeometry(Helper.createPointList(11, 1, 10, 1)); SPTEntry e1 = new SPTEntry(edge2.getEdge(), 2, 1, new SPTEntry(edge1.getEdge(), 1, 1, new SPTEntry(0, 1))); @@ -104,7 +104,7 @@ public void testWayList() { // force minor change for instructions edge2.setName("2"); na.setNode(3, 1.0, 1.0); - g.edge(1, 3).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnv, 10.0); + g.edge(1, 3).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 10.0); e1 = new SPTEntry(edge2.getEdge(), 2, 1, new SPTEntry(edge1.getEdge(), 1, 1, @@ -167,22 +167,22 @@ public void testFindInstruction() { na.setNode(4, 7.5, 0.25); na.setNode(5, 5.0, 1.0); - EdgeIteratorState edge1 = g.edge(0, 1).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnv, 50.0); + EdgeIteratorState edge1 = g.edge(0, 1).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge1.setWayGeometry(Helper.createPointList()); edge1.setName("Street 1"); - EdgeIteratorState edge2 = g.edge(1, 2).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnv, 50.0); + EdgeIteratorState edge2 = g.edge(1, 2).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge2.setWayGeometry(Helper.createPointList()); edge2.setName("Street 2"); - EdgeIteratorState edge3 = g.edge(2, 3).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnv, 50.0); + EdgeIteratorState edge3 = g.edge(2, 3).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge3.setWayGeometry(Helper.createPointList()); edge3.setName("Street 3"); - EdgeIteratorState edge4 = g.edge(3, 4).setDistance(500).set(carAccessEnc, true, true).set(carAvSpeedEnv, 50.0); + EdgeIteratorState edge4 = g.edge(3, 4).setDistance(500).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge4.setWayGeometry(Helper.createPointList()); edge4.setName("Street 4"); - g.edge(1, 5).setDistance(10000).set(carAccessEnc, true, true).set(carAvSpeedEnv, 50.0); - g.edge(2, 5).setDistance(10000).set(carAccessEnc, true, true).set(carAvSpeedEnv, 50.0); - g.edge(3, 5).setDistance(100000).set(carAccessEnc, true, true).set(carAvSpeedEnv, 50.0); + g.edge(1, 5).setDistance(10000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); + g.edge(2, 5).setDistance(10000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); + g.edge(3, 5).setDistance(100000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); SPTEntry e1 = new SPTEntry(edge4.getEdge(), 4, 1, @@ -494,32 +494,32 @@ public void testCalcInstructionsRoundaboutIssue353() { na.setNode(10, 52.5135, 13.348); na.setNode(11, 52.514, 13.347); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 1).setDistance(5)).setName("MainStreet 2 1"); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 11).setDistance(5)).setName("MainStreet 1 11"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 1).setDistance(5)).setName("MainStreet 2 1"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 11).setDistance(5)).setName("MainStreet 1 11"); // roundabout EdgeIteratorState tmpEdge; - tmpEdge = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 9).setDistance(2)).setName("3-9"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 9).setDistance(2)).setName("3-9"); BooleanEncodedValue carManagerRoundabout = carManager.getBooleanEncodedValue(Roundabout.KEY); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, encoder, graph.edge(9, 10).setDistance(2)).setName("9-10"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(9, 10).setDistance(2)).setName("9-10"); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 10).setDistance(2)).setName("6-10"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(6, 10).setDistance(2)).setName("6-10"); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, encoder, graph.edge(10, 1).setDistance(2)).setName("10-1"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(10, 1).setDistance(2)).setName("10-1"); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(5)).setName("2-3"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 2).setDistance(5)).setName("2-3"); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 3).setDistance(5)).setName("3-4"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 3).setDistance(5)).setName("3-4"); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 4).setDistance(5)).setName("4-5"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(5, 4).setDistance(5)).setName("4-5"); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 5).setDistance(5)).setName("5-2"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 5).setDistance(5)).setName("5-2"); tmpEdge.set(carManagerRoundabout, true); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 7).setDistance(5)).setName("MainStreet 4 7"); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 8).setDistance(5)).setName("5-8"); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 6).setDistance(5)).setName("3-6"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 7).setDistance(5)).setName("MainStreet 4 7"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 8).setDistance(5)).setName("5-8"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 6).setDistance(5)).setName("3-6"); ShortestWeighting weighting = new ShortestWeighting(encoder); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) @@ -595,9 +595,9 @@ public void testCalcInstructionForForkWithSameName() { na.setNode(3, 48.982611, 13.121012); na.setNode(4, 48.982336, 13.121002); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(5)).setName("Regener Weg"); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4).setDistance(5)).setName("Regener Weg"); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(5)); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setName("Regener Weg"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setName("Regener Weg"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)); ShortestWeighting weighting = new ShortestWeighting(encoder); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) @@ -628,9 +628,9 @@ public void testCalcInstructionForMotorwayFork() { EnumEncodedValue roadClassEnc = carManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BooleanEncodedValue roadClassLinkEnc = carManager.getBooleanEncodedValue(RoadClassLink.KEY); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(5)).setName("A 8").set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4).setDistance(5)).setName("A 8").set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(5)).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, true); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setName("A 8").set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setName("A 8").set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, true); ShortestWeighting weighting = new ShortestWeighting(encoder); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) @@ -656,9 +656,9 @@ public void testCalcInstructionsEnterMotorway() { na.setNode(3, 48.630558, 9.459851); na.setNode(4, 48.63054, 9.459406); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(5)).setName("A 8"); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(5)).setName("A 8"); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 2).setDistance(5)).setName("A 8"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setName("A 8"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setName("A 8"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 2).setDistance(5)).setName("A 8"); ShortestWeighting weighting = new ShortestWeighting(encoder); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) @@ -685,9 +685,9 @@ public void testCalcInstructionsMotorwayJunction() { na.setNode(3, 48.706805, 9.162995); na.setNode(4, 48.706705, 9.16329); - GHUtility.setSpeed(60, true, false, encoder, g.edge(1, 2).setDistance(5)).setName("A 8"); - GHUtility.setSpeed(60, true, false, encoder, g.edge(2, 3).setDistance(5)).setName("A 8"); - GHUtility.setSpeed(60, true, false, encoder, g.edge(2, 4).setDistance(5)).setName("A 8"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setName("A 8"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("A 8"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setName("A 8"); ShortestWeighting weighting = new ShortestWeighting(encoder); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -715,9 +715,9 @@ public void testCalcInstructionsOntoOneway() { na.setNode(3, -33.824415, 151.188177); na.setNode(4, -33.824437, 151.187925); - GHUtility.setSpeed(60, true, false, encoder, g.edge(1, 2).setDistance(5)).setName("Pacific Highway"); - GHUtility.setSpeed(60, true, false, encoder, g.edge(2, 3).setDistance(5)).setName("Pacific Highway"); - GHUtility.setSpeed(60, true, true, encoder, g.edge(4, 2).setDistance(5)).setName("Greenwich Road"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setName("Pacific Highway"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("Pacific Highway"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(4, 2).setDistance(5)).setName("Greenwich Road"); ShortestWeighting weighting = new ShortestWeighting(encoder); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -750,9 +750,9 @@ public void testCalcInstructionIssue1047() { EnumEncodedValue roadClassEnc = carManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BooleanEncodedValue roadClassLinkEnc = carManager.getBooleanEncodedValue(RoadClassLink.KEY); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 2).setDistance(5)).setName("B 156").set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 4).setDistance(5)).setName("S 108").set(roadClassEnc, RoadClass.SECONDARY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 3).setDistance(5)).setName("B 156").set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setName("B 156").set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setName("S 108").set(roadClassEnc, RoadClass.SECONDARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("B 156").set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); ShortestWeighting weighting = new ShortestWeighting(encoder); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -784,9 +784,9 @@ public void testCalcInstructionContinueLeavingStreet() { na.setNode(3, 48.982611, 13.121012); na.setNode(4, 48.982565, 13.121002); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 2).setDistance(5)).setName("Regener Weg"); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 3).setDistance(5)).setName("Regener Weg"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setName("Regener Weg"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("Regener Weg"); ShortestWeighting weighting = new ShortestWeighting(encoder); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -814,9 +814,9 @@ public void testCalcInstructionSlightTurn() { na.setNode(3, 48.412034, 15.599411); na.setNode(4, 48.411927, 15.599197); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 2).setDistance(5)).setName("Stöhrgasse"); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 3).setDistance(5)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 4).setDistance(5)).setName("Stöhrgasse"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setName("Stöhrgasse"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setName("Stöhrgasse"); ShortestWeighting weighting = new ShortestWeighting(encoder); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -949,9 +949,9 @@ public void testCalcInstructionsForSlightTurnOntoDifferentStreet() { na.setNode(3, 48.764149, 8.678926); na.setNode(4, 48.764085, 8.679183); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 3).setDistance(5)).setName("Talstraße, K 4313"); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 3).setDistance(5)).setName("Calmbacher Straße, K 4312"); - GHUtility.setSpeed(60, true, true, encoder, g.edge(3, 4).setDistance(5)).setName("Calmbacher Straße, K 4312"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 3).setDistance(5)).setName("Talstraße, K 4313"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("Calmbacher Straße, K 4312"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(3, 4).setDistance(5)).setName("Calmbacher Straße, K 4312"); ShortestWeighting weighting = new ShortestWeighting(encoder); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -995,11 +995,11 @@ private Graph generatePathDetailsGraph() { na.setNode(5, 52.516, 13.3452); na.setNode(6, 52.516, 13.344); - GHUtility.setSpeed(45, true, true, encoder, graph.edge(1, 2).setDistance(5)).setName("1-2"); - GHUtility.setSpeed(45, true, true, encoder, graph.edge(4, 5).setDistance(5)).setName("4-5"); - GHUtility.setSpeed(90, true, true, encoder, graph.edge(2, 3).setDistance(5)).setName("2-3"); - GHUtility.setSpeed(9, true, true, encoder, graph.edge(3, 4).setDistance(10)).setName("3-4"); - GHUtility.setSpeed(9, true, true, encoder, graph.edge(5, 6).setDistance(0.01)).setName("3-4"); + GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setName("1-2"); + GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 5).setDistance(5)).setName("4-5"); + GHUtility.setSpeed(90, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setName("2-3"); + GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 4).setDistance(10)).setName("3-4"); + GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 6).setDistance(0.01)).setName("3-4"); return graph; } diff --git a/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java b/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java index 8dfce062197..c94deb7e817 100644 --- a/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java @@ -62,8 +62,8 @@ public void setup() { @Test public void basic() { // 0-1-2 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(10)); graph.freeze(); assertEquals(2, graph.getEdges()); @@ -100,8 +100,8 @@ public void basic() { public void withShortcuts() { // 0-1-2 // \-/ - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(10)); graph.freeze(); assertEquals(2, graph.getEdges()); @@ -266,7 +266,7 @@ public void withVirtualEdgesAndShortcuts() { @Test public void getBaseGraph() { - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(10)); graph.freeze(); CHConfig chConfig = CHConfig.edgeBased("x", weighting); @@ -695,7 +695,7 @@ private void assertEnd(RoutingCHEdgeIterator outIter) { private EdgeIteratorState addEdge(Graph graph, int from, int to) { NodeAccess na = graph.getNodeAccess(); double dist = DistancePlaneProjection.DIST_PLANE.calcDist(na.getLat(from), na.getLon(from), na.getLat(to), na.getLon(to)); - return GHUtility.setSpeed(60, true, true, encoder, graph.edge(from, to).setDistance(dist)); + return GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(from, to).setDistance(dist)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java b/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java index dc7cc4962a1..67d9fc91451 100644 --- a/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java @@ -5,7 +5,10 @@ import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.querygraph.QueryRoutingCHGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -33,8 +36,6 @@ import static com.graphhopper.util.GHUtility.createRandomSnaps; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -import static org.junit.jupiter.api.Assumptions.assumeFalse; -import static org.junit.jupiter.api.Assumptions.assumeTrue; public class RandomCHRoutingTest { private static final Logger LOGGER = LoggerFactory.getLogger(RandomCHRoutingTest.class); @@ -251,7 +252,7 @@ private void buildRandomGraphLegacy(Graph graph, FlagEncoder encoder, Random ran maxDist = Math.max(maxDist, distance); // using bidirectional edges will increase mean degree of graph above given value boolean bothDirections = random.nextDouble() < pBothDir; - EdgeIteratorState edge = GHUtility.setSpeed(60, true, bothDirections, encoder, graph.edge(from, to).setDistance(distance)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, bothDirections, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(from, to).setDistance(distance)); double fwdSpeed = 10 + random.nextDouble() * 120; double bwdSpeed = 10 + random.nextDouble() * 120; DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); diff --git a/core/src/test/java/com/graphhopper/routing/RoundTripRoutingTest.java b/core/src/test/java/com/graphhopper/routing/RoundTripRoutingTest.java index 589f968ad74..3089c6e1c34 100644 --- a/core/src/test/java/com/graphhopper/routing/RoundTripRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoundTripRoutingTest.java @@ -135,7 +135,7 @@ private BaseGraph createSquareGraph() { // |-1 0 1 BaseGraph graph = new BaseGraph.Builder(em).create(); for (int i = 0; i < 8; ++i) { - GHUtility.setSpeed(60, true, true, carFE, graph.edge(i, (i + 1) % 8).setDistance(1)); + GHUtility.setSpeed(60, true, true, carFE.getAccessEnc(), carFE.getAverageSpeedEnc(), graph.edge(i, (i + 1) % 8).setDistance(1)); } updateDistancesFor(graph, 0, 1, -1); updateDistancesFor(graph, 1, 1, 0); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java index ea4fb78d6c8..56ea6b63a78 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java @@ -90,6 +90,8 @@ private static class Fixture { private final FlagEncoder carEncoder; private final FlagEncoder footEncoder; private final FlagEncoder bike2Encoder; + private final BooleanEncodedValue carAccessEnc; + private final DecimalEncodedValue carSpeedEnc; private final PathCalculator pathCalculator; private final TraversalMode traversalMode; private final Weighting defaultWeighting; @@ -107,6 +109,8 @@ public Fixture(PathCalculator pathCalculator, TraversalMode traversalMode) { defaultWeighting = new ShortestWeighting(carEncoder); // most tests do not limit the number of visited nodes, but this can be chosen for each test separately defaultMaxVisitedNodes = Integer.MAX_VALUE; + carAccessEnc = carEncoder.getAccessEnc(); + carSpeedEnc = carEncoder.getAverageSpeedEnc(); } @Override @@ -237,8 +241,8 @@ public void testCalcShortestPath(Fixture f) { public void testCalcShortestPath_sourceEqualsTarget(Fixture f) { // 0-1-2 BaseGraph graph = f.createGHStorage(); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(1, 2).setDistance(2)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(1, 2).setDistance(2)); Path p = f.calcPath(graph, 0, 0); assertPathFromEqualsTo(p, 0); @@ -251,11 +255,11 @@ public void testSimpleAlternative(Fixture f) { // | | // 3--4 BaseGraph graph = f.createGHStorage(); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(0, 2).setDistance(9)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(2, 1).setDistance(2)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(2, 3).setDistance(11)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(3, 4).setDistance(6)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(4, 1).setDistance(9)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 2).setDistance(9)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(2, 1).setDistance(2)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(2, 3).setDistance(11)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(3, 4).setDistance(6)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(4, 1).setDistance(9)); Path p = f.calcPath(graph, 0, 4); assertEquals(20, p.getDistance(), 1e-4, p.toString()); assertEquals(nodes(0, 2, 1, 4), p.calcNodes()); @@ -266,10 +270,10 @@ public void testSimpleAlternative(Fixture f) { public void testBidirectionalLinear(Fixture f) { //3--2--1--4--5 BaseGraph graph = f.createGHStorage(); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(2, 1).setDistance(2)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(2, 3).setDistance(11)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(5, 4).setDistance(6)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(4, 1).setDistance(9)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(2, 1).setDistance(2)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(2, 3).setDistance(11)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(5, 4).setDistance(6)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(4, 1).setDistance(9)); Path p = f.calcPath(graph, 3, 5); assertEquals(28, p.getDistance(), 1e-4, p.toString()); assertEquals(nodes(3, 2, 1, 4, 5), p.calcNodes()); @@ -300,26 +304,28 @@ public void testCalcFastestPath(Fixture f) { // |/ \--7 // 6----/ static void initDirectedAndDiffSpeed(Graph graph, FlagEncoder enc) { - GHUtility.setSpeed(10, true, false, enc, graph.edge(0, 1)); - GHUtility.setSpeed(100, true, false, enc, graph.edge(0, 4)); + BooleanEncodedValue accessEnc = enc.getAccessEnc(); + DecimalEncodedValue speedEnc = enc.getAverageSpeedEnc(); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, graph.edge(0, 1)); + GHUtility.setSpeed(100, true, false, accessEnc, speedEnc, graph.edge(0, 4)); - GHUtility.setSpeed(10, true, true, enc, graph.edge(1, 4)); - GHUtility.setSpeed(10, true, true, enc, graph.edge(1, 5)); - EdgeIteratorState edge12 = GHUtility.setSpeed(10, true, true, enc, graph.edge(1, 2)); + GHUtility.setSpeed(10, true, true, accessEnc, speedEnc, graph.edge(1, 4)); + GHUtility.setSpeed(10, true, true, accessEnc, speedEnc, graph.edge(1, 5)); + EdgeIteratorState edge12 = GHUtility.setSpeed(10, true, true, accessEnc, speedEnc, graph.edge(1, 2)); - GHUtility.setSpeed(10, true, false, enc, graph.edge(5, 2)); - GHUtility.setSpeed(10, true, false, enc, graph.edge(2, 3)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, graph.edge(5, 2)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, graph.edge(2, 3)); - EdgeIteratorState edge53 = GHUtility.setSpeed(20, true, false, enc, graph.edge(5, 3)); - GHUtility.setSpeed(10, true, false, enc, graph.edge(3, 7)); + EdgeIteratorState edge53 = GHUtility.setSpeed(20, true, false, accessEnc, speedEnc, graph.edge(5, 3)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, graph.edge(3, 7)); - GHUtility.setSpeed(100, true, false, enc, graph.edge(4, 6)); - GHUtility.setSpeed(10, true, false, enc, graph.edge(5, 4)); + GHUtility.setSpeed(100, true, false, accessEnc, speedEnc, graph.edge(4, 6)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, graph.edge(5, 4)); - GHUtility.setSpeed(10, true, false, enc, graph.edge(5, 6)); - GHUtility.setSpeed(100, true, false, enc, graph.edge(7, 5)); + GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, graph.edge(5, 6)); + GHUtility.setSpeed(100, true, false, accessEnc, speedEnc, graph.edge(7, 5)); - GHUtility.setSpeed(100, true, true, enc, graph.edge(6, 7)); + GHUtility.setSpeed(100, true, true, accessEnc, speedEnc, graph.edge(6, 7)); updateDistancesFor(graph, 0, 0.002, 0); updateDistancesFor(graph, 1, 0.002, 0.001); @@ -347,64 +353,71 @@ public void testCalcFootPath(Fixture f) { } static void initFootVsCar(FlagEncoder carEncoder, FlagEncoder footEncoder, Graph graph) { + BooleanEncodedValue footAccessEnc = footEncoder.getAccessEnc(); + DecimalEncodedValue footSpeedEnc = footEncoder.getAverageSpeedEnc(); + BooleanEncodedValue carAccessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue carSpeedEnc = carEncoder.getAverageSpeedEnc(); + EdgeIteratorState edge = graph.edge(0, 1).setDistance(7000); - GHUtility.setSpeed(5, true, true, footEncoder, edge); - GHUtility.setSpeed(10, true, false, carEncoder, edge); + GHUtility.setSpeed(5, true, true, footAccessEnc, footSpeedEnc, edge); + GHUtility.setSpeed(10, true, false, carAccessEnc, carSpeedEnc, edge); edge = graph.edge(0, 4).setDistance(5000); - GHUtility.setSpeed(5, true, true, footEncoder, edge); - GHUtility.setSpeed(20, true, false, carEncoder, edge); + GHUtility.setSpeed(5, true, true, footAccessEnc, footSpeedEnc, edge); + GHUtility.setSpeed(20, true, false, carAccessEnc, carSpeedEnc, edge); - GHUtility.setSpeed(10, true, true, carEncoder, graph.edge(1, 4).setDistance(7000)); - GHUtility.setSpeed(10, true, true, carEncoder, graph.edge(1, 5).setDistance(7000)); + GHUtility.setSpeed(10, true, true, carAccessEnc, carSpeedEnc, graph.edge(1, 4).setDistance(7000)); + GHUtility.setSpeed(10, true, true, carAccessEnc, carSpeedEnc, graph.edge(1, 5).setDistance(7000)); edge = graph.edge(1, 2).setDistance(20000); - GHUtility.setSpeed(5, true, true, footEncoder, edge); - GHUtility.setSpeed(10, true, true, carEncoder, edge); + GHUtility.setSpeed(5, true, true, footAccessEnc, footSpeedEnc, edge); + GHUtility.setSpeed(10, true, true, carAccessEnc, carSpeedEnc, edge); - GHUtility.setSpeed(10, true, false, carEncoder, graph.edge(5, 2).setDistance(5000)); + GHUtility.setSpeed(10, true, false, carAccessEnc, carSpeedEnc, graph.edge(5, 2).setDistance(5000)); edge = graph.edge(2, 3).setDistance(5000); - GHUtility.setSpeed(5, true, true, footEncoder, edge); - GHUtility.setSpeed(10, true, false, carEncoder, edge); + GHUtility.setSpeed(5, true, true, footAccessEnc, footSpeedEnc, edge); + GHUtility.setSpeed(10, true, false, carAccessEnc, carSpeedEnc, edge); - GHUtility.setSpeed(20, true, false, carEncoder, graph.edge(5, 3).setDistance(11000)); + GHUtility.setSpeed(20, true, false, carAccessEnc, carSpeedEnc, graph.edge(5, 3).setDistance(11000)); edge = graph.edge(3, 7).setDistance(7000); - GHUtility.setSpeed(5, true, true, footEncoder, edge); - GHUtility.setSpeed(10, true, false, carEncoder, edge); + GHUtility.setSpeed(5, true, true, footAccessEnc, footSpeedEnc, edge); + GHUtility.setSpeed(10, true, false, carAccessEnc, carSpeedEnc, edge); - GHUtility.setSpeed(20, true, false, carEncoder, graph.edge(4, 6).setDistance(5000)); + GHUtility.setSpeed(20, true, false, carAccessEnc, carSpeedEnc, graph.edge(4, 6).setDistance(5000)); edge = graph.edge(5, 4).setDistance(7000); - GHUtility.setSpeed(5, true, true, footEncoder, edge); - GHUtility.setSpeed(10, true, false, carEncoder, edge); + GHUtility.setSpeed(5, true, true, footAccessEnc, footSpeedEnc, edge); + GHUtility.setSpeed(10, true, false, carAccessEnc, carSpeedEnc, edge); - GHUtility.setSpeed(10, true, false, carEncoder, graph.edge(5, 6).setDistance(7000)); + GHUtility.setSpeed(10, true, false, carAccessEnc, carSpeedEnc, graph.edge(5, 6).setDistance(7000)); edge = graph.edge(7, 5).setDistance(5000); - GHUtility.setSpeed(5, true, true, footEncoder, edge); - GHUtility.setSpeed(20, true, false, carEncoder, edge); + GHUtility.setSpeed(5, true, true, footAccessEnc, footSpeedEnc, edge); + GHUtility.setSpeed(20, true, false, carAccessEnc, carSpeedEnc, edge); - GHUtility.setSpeed(20, true, true, carEncoder, graph.edge(6, 7).setDistance(5000)); + GHUtility.setSpeed(20, true, true, carAccessEnc, carSpeedEnc, graph.edge(6, 7).setDistance(5000)); } // see test-graph.svg ! static void initTestStorage(Graph graph, FlagEncoder encoder) { - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(7)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 4).setDistance(6)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(7)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 4).setDistance(6)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 5).setDistance(8)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 5).setDistance(8)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 5).setDistance(5)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 5).setDistance(5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 5).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 7).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 5).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 7).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 6).setDistance(4)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(7)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 6).setDistance(4)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(7)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 7).setDistance(1)); - EdgeIteratorState edge6_7 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(5)); + EdgeIteratorState edge6_7 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(5)); updateDistancesFor(graph, 0, 0.0010, 0.00001); updateDistancesFor(graph, 1, 0.0008, 0.0000); @@ -434,18 +447,18 @@ public void testNoPathFound(Fixture f) { // 7-5-6 // \| // 8 - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(0, 1).setDistance(7)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(5, 6).setDistance(2)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(5, 7).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(5, 8).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(7, 8).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 1).setDistance(7)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(5, 6).setDistance(2)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(5, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(5, 8).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(7, 8).setDistance(1)); assertFalse(f.calcPath(graph, 0, 5).isFound()); // disconnected as directed graph // 2-0->1 graph = f.createGHStorage(); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(0, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 2).setDistance(1)); f.resetCH(); assertFalse(f.calcPath(graph, 1, 2).isFound()); assertTrue(f.calcPath(graph, 2, 1).isFound()); @@ -473,15 +486,17 @@ public void testCalcIf1EdgeAway(Fixture f) { // see wikipedia-graph.svg ! private void initWikipediaTestGraph(Graph graph, FlagEncoder encoder) { - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(7)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 2).setDistance(9)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 5).setDistance(14)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3).setDistance(15)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 5).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(11)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(6)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(9)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(7)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2).setDistance(9)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 5).setDistance(14)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(15)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 5).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(11)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(6)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(9)); } @ParameterizedTest @@ -507,16 +522,18 @@ public void testBidirectional(Fixture f) { // 7-6----5 public static void initBiGraph(Graph graph, FlagEncoder encoder) { // distance will be overwritten in second step as we need to calculate it from lat,lon - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(7, 0).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 8).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 6).setDistance(1)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(7, 0).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 8).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 6).setDistance(1)); // we need lat,lon for edge precise queries because the distances of snapped point // to adjacent nodes is calculated from lat,lon of the necessary points @@ -542,16 +559,16 @@ public void testCreateAlgoTwice(Fixture f) { // \ / / // 7-6-5-/ BaseGraph graph = f.createGHStorage(); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(6, 7).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(7, 0).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(3, 8).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(8, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(6, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(7, 0).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(3, 8).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(8, 6).setDistance(1)); // run the same query twice, this can be interesting because in the second call algorithms that pre-process // the graph might depend on the state of the graph after the first call @@ -591,16 +608,18 @@ private void initBidirGraphManualDistances(BaseGraph graph, FlagEncoder encoder) // | 8 | // \ / / // 7-6-5-/ - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(100)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(20)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(5)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(7, 0).setDistance(5)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 8).setDistance(20)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 6).setDistance(20)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(20)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(7, 0).setDistance(5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 8).setDistance(20)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 6).setDistance(20)); } @ParameterizedTest @@ -645,7 +664,7 @@ private static void initMatrixALikeGraph(BaseGraph tmpGraph, FlagEncoder encoder if (print) System.out.print(" " + (int) dist + "\t "); - GHUtility.setSpeed(60, true, true, encoder, tmpGraph.edge(matrix[w][h], matrix[w][h - 1]).setDistance(dist)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), tmpGraph.edge(matrix[w][h], matrix[w][h - 1]).setDistance(dist)); } } if (print) { @@ -663,7 +682,7 @@ private static void initMatrixALikeGraph(BaseGraph tmpGraph, FlagEncoder encoder float dist = 5 + Math.abs(rand.nextInt(5)); if (print) System.out.print("-- " + (int) dist + "\t-- "); - GHUtility.setSpeed(60, true, true, encoder, tmpGraph.edge(matrix[w][h], matrix[w - 1][h]).setDistance(dist)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), tmpGraph.edge(matrix[w][h], matrix[w - 1][h]).setDistance(dist)); } if (print) System.out.print("(" + matrix[w][h] + ")\t"); @@ -691,8 +710,8 @@ private void testCorrectWeight(Fixture f, BaseGraph g) { public void testCannotCalculateSP(Fixture f) { // 0->1->2 BaseGraph graph = f.createGHStorage(); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(1, 2).setDistance(1)); Path p = f.calcPath(graph, 0, 2); assertEquals(3, p.calcNodes().size(), p.toString()); } @@ -701,12 +720,12 @@ public void testCannotCalculateSP(Fixture f) { @ArgumentsSource(FixtureProvider.class) public void testDirectedGraphBug1(Fixture f) { BaseGraph graph = f.createGHStorage(); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(0, 1).setDistance(3)); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(1, 2).setDistance(2.99)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 1).setDistance(3)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(1, 2).setDistance(2.99)); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(0, 3).setDistance(2)); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(3, 4).setDistance(3)); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(4, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 3).setDistance(2)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(3, 4).setDistance(3)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(4, 2).setDistance(1)); Path p = f.calcPath(graph, 0, 2); assertEquals(nodes(0, 1, 2), p.calcNodes(), p.toString()); @@ -720,10 +739,10 @@ public void testDirectedGraphBug2(Fixture f) { // | / // 3< BaseGraph graph = f.createGHStorage(); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(3, 1).setDistance(4)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(3, 1).setDistance(4)); Path p = f.calcPath(graph, 0, 3); assertEquals(nodes(0, 1, 2, 3), p.calcNodes()); @@ -738,21 +757,21 @@ public void testDirectedGraphBug2(Fixture f) { public void testWithCoordinates(Fixture f) { Weighting weighting = new ShortestWeighting(f.carEncoder); BaseGraph graph = f.createGHStorage(false); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(0, 1).setDistance(2)). + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 1).setDistance(2)). setWayGeometry(Helper.createPointList(1.5, 1)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(2, 3).setDistance(2)). + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(2, 3).setDistance(2)). setWayGeometry(Helper.createPointList(0, 1.5)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(3, 4).setDistance(2)). + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(3, 4).setDistance(2)). setWayGeometry(Helper.createPointList(0, 2)); // duplicate but the second edge is longer - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(0, 2).setDistance(1.2)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(0, 2).setDistance(1.5)). + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 2).setDistance(1.2)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 2).setDistance(1.5)). setWayGeometry(Helper.createPointList(0.5, 0)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(1, 3).setDistance(1.3)). + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(1, 3).setDistance(1.3)). setWayGeometry(Helper.createPointList(0.5, 1.5)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(1, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(1, 4).setDistance(1)); updateDistancesFor(graph, 0, 1, 0.6); updateDistancesFor(graph, 1, 1, 1.5); @@ -833,11 +852,11 @@ public void testViaEdges_SpecialCases(Fixture f) { // 0->1\ // | 2 // 4<-3/ - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(0, 1).setDistance(7)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(1, 2).setDistance(7)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(2, 3).setDistance(7)); - GHUtility.setSpeed(60, true, false, f.carEncoder, graph.edge(3, 4).setDistance(7)); - GHUtility.setSpeed(60, true, true, f.carEncoder, graph.edge(4, 0).setDistance(7)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 1).setDistance(7)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(1, 2).setDistance(7)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(2, 3).setDistance(7)); + GHUtility.setSpeed(60, true, false, f.carAccessEnc, f.carSpeedEnc, graph.edge(3, 4).setDistance(7)); + GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(4, 0).setDistance(7)); updateDistancesFor(graph, 4, 0, 0); updateDistancesFor(graph, 0, 0.00010, 0); @@ -879,7 +898,7 @@ public void testTwoWeightsPerEdge(Fixture f) { BaseGraph graph = f.createGHStorage(true); initEleGraph(graph, f.bike2Encoder, 18); // force the other path - GHUtility.setSpeed(10, false, true, f.bike2Encoder, GHUtility.getEdge(graph, 0, 3)); + GHUtility.setSpeed(10, false, true, f.bike2Encoder.getAccessEnc(), f.bike2Encoder.getAverageSpeedEnc(), GHUtility.getEdge(graph, 0, 3)); // for two weights per edge it happened that Path (and also the Weighting) read the wrong side // of the speed and read 0 => infinity weight => overflow of millis => negative millis! @@ -895,12 +914,10 @@ public void test0SpeedButUnblocked_Issue242(Fixture f) { BaseGraph graph = f.createGHStorage(); EdgeIteratorState edge01 = graph.edge(0, 1).setDistance(10); EdgeIteratorState edge12 = graph.edge(1, 2).setDistance(10); - BooleanEncodedValue carAccessEnc = f.carEncoder.getAccessEnc(); - DecimalEncodedValue carAvSpeedEnc = f.carEncoder.getAverageSpeedEnc(); - edge01.set(carAvSpeedEnc, 0.0).set(carAccessEnc, true, true); + edge01.set(f.carSpeedEnc, 0.0).set(f.carAccessEnc, true, true); edge01.setFlags(edge01.getFlags()); - edge12.set(carAvSpeedEnc, 0.0).set(carAccessEnc, true, true); + edge12.set(f.carSpeedEnc, 0.0).set(f.carAccessEnc, true, true); edge12.setFlags(edge12.getFlags()); try { @@ -1004,7 +1021,7 @@ public void testRandomGraph(Fixture f) { Random rnd = new Random(seed); // we're not including loops otherwise duplicate nodes in path might fail the test GHUtility.buildRandomGraph(graph, rnd, 10, 2.0, false, true, - f.carEncoder.getAccessEnc(), f.carEncoder.getAverageSpeedEnc(), null, 0.7, 0.7, 0.7); + f.carAccessEnc, f.carSpeedEnc, null, 0.7, 0.7, 0.7); final PathCalculator refCalculator = new DijkstraCalculator(); int numRuns = 100; for (int i = 0; i < numRuns; i++) { @@ -1039,7 +1056,7 @@ public void testMultipleVehicles_issue548(Fixture f) { // we can create new CHs :( graph = f.createGHStorage(false); initFootVsCar(f.carEncoder, f.footEncoder, graph); - GHUtility.setSpeed(20, false, false, f.carEncoder, GHUtility.getEdge(graph, 4, 6)); + GHUtility.setSpeed(20, false, false, f.carAccessEnc, f.carSpeedEnc, GHUtility.getEdge(graph, 4, 6)); f.resetCH(); // ... car needs to take another way @@ -1060,25 +1077,27 @@ public void testMultipleVehicles_issue548(Fixture f) { // | |\| // 8-9-10 private void initEleGraph(Graph graph, FlagEncoder encoder, double s) { - GHUtility.setSpeed(s, true, true, encoder, graph.edge(0, 1).setDistance(10)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(0, 4).setDistance(12)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(0, 3).setDistance(5)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(1, 2).setDistance(10)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(1, 4).setDistance(5)); - GHUtility.setSpeed(s, true, false, encoder, graph.edge(3, 5).setDistance(5)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(5, 6).setDistance(10)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(5, 8).setDistance(10)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(6, 4).setDistance(5)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(6, 7).setDistance(10)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(6, 10).setDistance(12)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(6, 9).setDistance(12)); - GHUtility.setSpeed(s, true, false, encoder, graph.edge(2, 11).setDistance(5)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(4, 11).setDistance(10)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(7, 11).setDistance(5)); - GHUtility.setSpeed(s, true, true, encoder, graph.edge(7, 10).setDistance(5)); - GHUtility.setSpeed(s, true, false, encoder, graph.edge(8, 9).setDistance(10)); - GHUtility.setSpeed(s, true, false, encoder, graph.edge(9, 8).setDistance(9)); - GHUtility.setSpeed(s, true, false, encoder, graph.edge(10, 9).setDistance(10)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(0, 4).setDistance(12)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(0, 3).setDistance(5)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(5)); + GHUtility.setSpeed(s, true, false, accessEnc, speedEnc, graph.edge(3, 5).setDistance(5)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(10)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(5, 8).setDistance(10)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(6, 4).setDistance(5)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(10)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(6, 10).setDistance(12)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(6, 9).setDistance(12)); + GHUtility.setSpeed(s, true, false, accessEnc, speedEnc, graph.edge(2, 11).setDistance(5)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(4, 11).setDistance(10)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(7, 11).setDistance(5)); + GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(7, 10).setDistance(5)); + GHUtility.setSpeed(s, true, false, accessEnc, speedEnc, graph.edge(8, 9).setDistance(10)); + GHUtility.setSpeed(s, true, false, accessEnc, speedEnc, graph.edge(9, 8).setDistance(9)); + GHUtility.setSpeed(s, true, false, accessEnc, speedEnc, graph.edge(10, 9).setDistance(10)); updateDistancesFor(graph, 0, 3, 0); updateDistancesFor(graph, 3, 2.5, 0); updateDistancesFor(graph, 5, 1, 0); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java b/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java index 40d87e9f46e..7713ce75ff1 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java @@ -19,6 +19,8 @@ package com.graphhopper.routing; import com.graphhopper.routing.ch.PrepareEncoder; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.AccessFilter; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; @@ -78,7 +80,7 @@ void testShortcutConnection() { EncodingManager em = EncodingManager.create(encoder); BaseGraph graph = new BaseGraph.Builder(em).create(); EdgeExplorer baseCarOutExplorer = graph.createEdgeExplorer(AccessFilter.outEdges(encoder.getAccessEnc())); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 1).setDistance(30)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(4, 1).setDistance(30)); graph.freeze(); CHConfig chConfig = CHConfig.nodeBased("ch", new FastestWeighting(encoder)); @@ -168,8 +170,10 @@ public void testWeightExact() { FlagEncoder encoder = FlagEncoders.createCar(); EncodingManager em = EncodingManager.create(encoder); BaseGraph graph = new BaseGraph.Builder(em).create(); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); graph.freeze(); CHConfig chConfig = CHConfig.nodeBased("ch", new FastestWeighting(encoder)); @@ -193,8 +197,10 @@ public void testSimpleShortcutCreationAndTraversal() { EncodingManager em = EncodingManager.create(encoder); BaseGraph graph = new BaseGraph.Builder(em).create(); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(10)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); graph.freeze(); FastestWeighting weighting = new FastestWeighting(encoder); @@ -216,8 +222,10 @@ public void testAddShortcutSkippedEdgesWriteRead() { FlagEncoder carEncoder = FlagEncoders.createCar(); EncodingManager em = EncodingManager.create(carEncoder); BaseGraph graph = new BaseGraph.Builder(em).create(); - final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(1, 3).setDistance(10)); - final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(3, 4).setDistance(10)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(10)); + final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); graph.freeze(); FastestWeighting weighting = new FastestWeighting(carEncoder); @@ -237,8 +245,10 @@ public void testSkippedEdges() { FlagEncoder carEncoder = FlagEncoders.createCar(); EncodingManager em = EncodingManager.create(carEncoder); BaseGraph graph = new BaseGraph.Builder(em).create(); - final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(1, 3).setDistance(10)); - final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(3, 4).setDistance(10)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(10)); + final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); graph.freeze(); FastestWeighting weighting = new FastestWeighting(carEncoder); @@ -257,8 +267,10 @@ public void testAddShortcut_edgeBased_throwsIfNotConfiguredForEdgeBased() { EncodingManager em = EncodingManager.create(carEncoder); BaseGraph graph = new BaseGraph.Builder(em).create(); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(1, 2).setDistance(1)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); graph.freeze(); FastestWeighting weighting = new FastestWeighting(carEncoder); @@ -274,8 +286,10 @@ public void testAddShortcut_edgeBased() { FlagEncoder carEncoder = FlagEncoders.createCar(); EncodingManager em = EncodingManager.create(carEncoder); BaseGraph graph = new BaseGraph.Builder(em).set3D(true).create(); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(1, 2).setDistance(3)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(3)); graph.freeze(); FastestWeighting weighting = new FastestWeighting(carEncoder); @@ -307,8 +321,10 @@ public void testGetEdgeIterator() { FlagEncoder carEncoder = FlagEncoders.createCar(); EncodingManager em = EncodingManager.create(carEncoder); BaseGraph graph = new BaseGraph.Builder(em).set3D(true).create(); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, graph.edge(1, 2).setDistance(1)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); graph.freeze(); FastestWeighting weighting = new FastestWeighting(carEncoder); diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java index f98cc3dd108..32d764dcb1d 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java @@ -69,6 +69,8 @@ public class CHTurnCostTest { private static final Logger LOGGER = LoggerFactory.getLogger(CHTurnCostTest.class); private int maxCost; private FlagEncoder encoder; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; private EncodingManager encodingManager; private BaseGraph graph; private TurnCostStorage turnCostStorage; @@ -81,6 +83,8 @@ public class CHTurnCostTest { public void init() { maxCost = 10; encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxCost)); + accessEnc = encoder.getAccessEnc(); + speedEnc = encoder.getAverageSpeedEnc(); encodingManager = EncodingManager.create(encoder); graph = new BaseGraph.Builder(encodingManager).build(); turnCostStorage = graph.getTurnCostStorage(); @@ -116,10 +120,10 @@ private List createCHConfigs() { @RepeatedTest(10) public void testFindPath_randomContractionOrder_linear() { // 2-1-0-3-4 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 1).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 0).setDistance(3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 1).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 0).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(3)); graph.freeze(); setTurnCost(2, 1, 0, 2); setTurnCost(0, 3, 4, 4); @@ -131,11 +135,11 @@ public void testFindPath_randomContractionOrder_duplicate_edges() { // /\ /<-3 // 0 1--2 // \/ \->4 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(5)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(6)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(6)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(3)); setRestriction(3, 2, 4); graph.freeze(); compareCHWithDijkstra(10, new int[]{0, 1, 2, 3, 4}); @@ -146,11 +150,11 @@ public void testFindPath_randomContractionOrder_double_duplicate_edges() { // /\ /\ // 0 1 2--3 // \/ \/ - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(25.789000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(26.016000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(21.902000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(21.862000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(52.987000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(25.789000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(26.016000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(21.902000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(21.862000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(52.987000)); graph.freeze(); compareCHWithDijkstra(1000, new int[]{0, 1, 2, 3}); } @@ -168,17 +172,17 @@ public void testFindPath_multipleInOutEdges_turnReplacementDifference() { // To cover all or at least as many as possible different cases we randomly apply some restrictions and compare // the resulting query with a standard Dijkstra search. // If this test fails use the logger output to generate code for further debugging. - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 7).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 8).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 9).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 10).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 7).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 8).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 9).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 10).setDistance(1)); long seed = System.nanoTime(); Random rnd = new Random(seed); @@ -212,15 +216,15 @@ public void testFindPath_multipleInOutEdges_turnReplacementDifference_bug1() { // 1 - 5 - 6 - 7 - 9 // / \ // 2 10 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 7).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 9).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 10).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 7).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 9).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 10).setDistance(1)); setTurnCost(2, 5, 6, 4); setRestriction(1, 5, 6); @@ -234,11 +238,11 @@ public void testFindPath_multipleInOutEdges_turnReplacementDifference_bug1() { public void testFindPath_duplicateEdge() { // 0 -> 1 -> 2 -> 3 -> 4 // \->/ - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); compareCHWithDijkstra(100, new int[]{2, 3, 0, 4, 1}); } @@ -247,14 +251,14 @@ public void testFindPath_chain() { // 0 2 4 6 8 // \ / \ / \ / \ / // 1 3 5 7 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 8).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 8).setDistance(1)); graph.freeze(); setTurnCost(1, 2, 3, 4); setTurnCost(3, 4, 5, 2); @@ -271,12 +275,12 @@ public void testFindPath_bidir_chain() { // 5 3 2 1 4 turn costs -> // 0-1-2-3-4-5-6 // 0 1 4 2 3 turn costs <- - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(1)); - EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(1)); - EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(1)); - EdgeIteratorState edge5 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6).setDistance(1)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + EdgeIteratorState edge5 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); graph.freeze(); // turn costs -> @@ -311,11 +315,11 @@ public void testFindPath_randomContractionOrder_simpleLoop() { // 0-4-3 // | // 1 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 4).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 3).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 4).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 3).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); graph.freeze(); // enforce loop (going counter-clockwise) @@ -333,14 +337,14 @@ public void testFindPath_randomContractionOrder_singleDirectedLoop() { // 7-5-0 // | // 6-4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 5).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 0).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 1).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 4).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 5).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 0).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 1).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 4).setDistance(2)); graph.freeze(); setRestriction(7, 5, 6); @@ -360,13 +364,13 @@ public void testFindPath_randomContractionOrder_singleLoop() { // 1-2-3 // | // 5-6 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(2)); graph.freeze(); // enforce loop (going counter-clockwise) @@ -391,29 +395,29 @@ public void testFindPath_randomContractionOrder_singleLoopWithNoise() { // } | } } // 11~12-13-14 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(7, 8).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 2).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 7).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(7, 12).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(12, 13).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(13, 14).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(7, 8).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 2).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(7, 12).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(12, 13).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(13, 14).setDistance(2)); // some more edges to make it more complicated -> potentially find more bugs - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(8)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 11).setDistance(3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(11, 12).setDistance(50)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 13).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 15).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(15, 16).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(16, 17).setDistance(3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(17, 4).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 9).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(9, 14).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(8)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 11).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(11, 12).setDistance(50)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 13).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 15).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(15, 16).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(16, 17).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(17, 4).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 9).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(9, 14).setDistance(2)); graph.freeze(); // enforce loop (going counter-clockwise) @@ -454,49 +458,49 @@ public void testFindPath_randomContractionOrder_complicatedGraphAndPath() { // 21-22-23-24 25-26 // first we add all edges that contribute to the shortest path, verticals: cost=1, horizontals: cost=2 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 7).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 8).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 2).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 7).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(7, 12).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(12, 11).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(11, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 7).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(7, 13).setDistance(3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(13, 14).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(14, 9).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(9, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 10).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(10, 9).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(14, 19).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(19, 18).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(18, 17).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(17, 16).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(16, 21).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(21, 22).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(22, 23).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(23, 24).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(24, 19).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(19, 20).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(20, 25).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(25, 26).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 7).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 8).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 2).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(7, 12).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(12, 11).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(11, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 7).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(7, 13).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(13, 14).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(14, 9).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(9, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 10).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(10, 9).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(14, 19).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(19, 18).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(18, 17).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(17, 16).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(16, 21).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(21, 22).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(22, 23).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(23, 24).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(24, 19).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(19, 20).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(20, 25).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(25, 26).setDistance(2)); //some more edges to make it more complicated -> potentially find more bugs - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 9).setDistance(75)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(17, 22).setDistance(9)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(18, 23).setDistance(15)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(12, 17).setDistance(50)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(13, 18).setDistance(80)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(14, 15).setDistance(3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(15, 27).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(27, 28).setDistance(100)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(28, 26).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(20, 28).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 9).setDistance(75)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(17, 22).setDistance(9)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(18, 23).setDistance(15)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(12, 17).setDistance(50)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(13, 18).setDistance(80)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(14, 15).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(15, 27).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(27, 28).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(28, 26).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(20, 28).setDistance(1)); graph.freeze(); // enforce figure of eight curve at node 7 @@ -537,13 +541,13 @@ public void testFindPath_pTurn_uTurnAtContractedNode() { // 4- 0 // | // 5 -> 6 -> 1 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(1)); graph.freeze(); setRestriction(5, 6, 1); @@ -561,14 +565,14 @@ public void testFindPath_pTurn_uTurnAtContractedNode_twoShortcutsInAndOut() { // 1 // | // 5 -> 6 -> 7 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 7).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(1)); graph.freeze(); setRestriction(5, 6, 7); @@ -602,7 +606,7 @@ public void testFindPath_highlyConnectedGraph_compareWithDijkstra() { final int from = i * size + j; final int to = from + 1; final double dist = nextDist(maxDist, rnd); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(from, to).setDistance(dist)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(from, to).setDistance(dist)); LOGGER.trace("final EdgeIteratorState edge{} = graph.edge({},{},{},true);", edgeCounter++, from, to, dist); } } @@ -612,7 +616,7 @@ public void testFindPath_highlyConnectedGraph_compareWithDijkstra() { final int from = i * size + j; final int to = from + size; double dist = nextDist(maxDist, rnd); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(from, to).setDistance(dist)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(from, to).setDistance(dist)); LOGGER.trace("final EdgeIteratorState edge{} = graph.edge({},{},{},true);", edgeCounter++, from, to, dist); } } @@ -623,20 +627,20 @@ public void testFindPath_highlyConnectedGraph_compareWithDijkstra() { if (j < size - 1) { final double dist = nextDist(maxDist, rnd); final int to = from + size + 1; - GHUtility.setSpeed(60, true, true, encoder, graph.edge(from, to).setDistance(dist)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(from, to).setDistance(dist)); LOGGER.trace("final EdgeIteratorState edge{} = graph.edge({},{},{},true);", edgeCounter++, from, to, dist); } if (j > 0) { final double dist = nextDist(maxDist, rnd); final int to = from + size - 1; - GHUtility.setSpeed(60, true, true, encoder, graph.edge(from, to).setDistance(dist)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(from, to).setDistance(dist)); LOGGER.trace("final EdgeIteratorState edge{} = graph.edge({},{},{},true);", edgeCounter++, from, to, dist); } } } graph.freeze(); - EdgeExplorer inExplorer = graph.createEdgeExplorer(AccessFilter.inEdges(encoder.getAccessEnc())); - EdgeExplorer outExplorer = graph.createEdgeExplorer(AccessFilter.outEdges(encoder.getAccessEnc())); + EdgeExplorer inExplorer = graph.createEdgeExplorer(AccessFilter.inEdges(accessEnc)); + EdgeExplorer outExplorer = graph.createEdgeExplorer(AccessFilter.outEdges(accessEnc)); // add turn costs or restrictions for (int node = 0; node < size * size; ++node) { @@ -661,11 +665,11 @@ public void testFindPath_highlyConnectedGraph_compareWithDijkstra() { @Test public void testFindPath_bug() { - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(18.364000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(29.814000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 2).setDistance(14.554000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(29.819000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3).setDistance(29.271000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(18.364000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(29.814000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2).setDistance(14.554000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(29.819000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(29.271000)); setRestriction(3, 1, 2); graph.freeze(); @@ -675,11 +679,11 @@ public void testFindPath_bug() { @Test public void testFindPath_bug2() { // 1 = 0 - 3 - 2 - 4 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 3).setDistance(24.001000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(6.087000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(6.067000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(46.631000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4).setDistance(46.184000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 3).setDistance(24.001000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(6.087000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(6.067000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(46.631000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 4).setDistance(46.184000)); graph.freeze(); compareCHWithDijkstra(1000, new int[]{1, 0, 3, 2, 4}); @@ -692,15 +696,15 @@ public void testFindPath_loop() { // 1 2 // \ / // 0 - 7 - 8 - 4 - 6 - 5 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 8).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(8, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 8).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(8, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 5).setDistance(1)); setRestriction(8, 4, 6); graph.freeze(); @@ -717,11 +721,11 @@ public void testFindPath_finiteUTurnCost() { // 0-3-4 // |/ // 2 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(100)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(100)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 2).setDistance(500)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(200)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 1).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 2).setDistance(500)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(200)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 1).setDistance(100)); setRestriction(0, 3, 1); graph.freeze(); chConfig = chConfigs.get(2); @@ -739,11 +743,11 @@ public void testFindPath_calcTurnCostTime() { // 2-1--3 // | | // 0->4 - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 4).setDistance(1)); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 3).setDistance(1)); - EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3).setDistance(1)); - EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 0).setDistance(1)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 4).setDistance(1)); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 3).setDistance(1)); + EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); + EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 0).setDistance(1)); setTurnCost(edge0, edge4, 1, 8); setRestriction(edge0, edge3, 1); graph.freeze(); @@ -755,10 +759,10 @@ public void testFindPath_loopsMustAlwaysBeAccepted() { // --- // \ / // 0 -- 1 -- 2 -- 3 - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 1).setDistance(1)); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 1).setDistance(1)); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); setTurnCost(edge0, edge1, 1, 1); setRestriction(edge0, edge2, 1); graph.freeze(); @@ -768,14 +772,14 @@ public void testFindPath_loopsMustAlwaysBeAccepted() { @Test public void testFindPath_compareWithDijkstra_zeroWeightLoops_random() { - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 3).setDistance(21.329000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(29.126000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(38.865000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 4).setDistance(80.005000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 1).setDistance(91.023000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 3).setDistance(21.329000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(29.126000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(38.865000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 4).setDistance(80.005000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 1).setDistance(91.023000)); // add loops with zero weight ... - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 1).setDistance(0.000000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 1).setDistance(0.000000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 1).setDistance(0.000000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 1).setDistance(0.000000)); graph.freeze(); automaticCompareCHWithDijkstra(100); } @@ -786,12 +790,12 @@ public void testFindPath_compareWithDijkstra_zeroWeightLoops() { // 0 -> 1 -> 2 -> 3 -- // | \| // 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); graph.freeze(); IntArrayList expectedPath = IntArrayList.from(0, 1, 2, 3, 4); checkPath(expectedPath, 4, 0, 0, 4, new int[]{2, 0, 4, 1, 3}); @@ -823,12 +827,12 @@ public void testFindPath_compareWithDijkstra_zeroWeightLoops_withTurnRestriction // 0 -> 1 -> 2 -> 3 -- // | \| // 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - EdgeIteratorState edge5 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + EdgeIteratorState edge5 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); setTurnCost(edge2, edge3, 3, 5); setTurnCost(edge2, edge4, 3, 4); setTurnCost(edge3, edge4, 3, 2); @@ -842,11 +846,11 @@ public void testFindPath_compareWithDijkstra_zeroWeightLoops_withTurnRestriction public void testFindPath_oneWayLoop() { // o // 0-1-2-3-4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); setRestriction(1, 2, 3); graph.freeze(); automaticPrepareCH(); @@ -863,11 +867,11 @@ public void testFindPath_loopEdge() { // 1-0 // | | // 4-2o - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(802.964000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(615.195000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 2).setDistance(181.788000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 2).setDistance(191.996000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(527.821000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(802.964000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(615.195000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 2).setDistance(181.788000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2).setDistance(191.996000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(527.821000)); setRestriction(0, 2, 4); setTurnCost(0, 2, 2, 3); setTurnCost(2, 2, 4, 4); @@ -891,11 +895,11 @@ public void test_issue1593_full(String algo) { na.setNode(2, 49.404004, 9.709110); na.setNode(3, 49.400160, 9.708787); na.setNode(4, 49.400883, 9.706347); - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 3).setDistance(194.063000)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(525.106000)); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(525.106000)); - EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 1).setDistance(703.778000)); - EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4).setDistance(400.509000)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 3).setDistance(194.063000)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(525.106000)); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(525.106000)); + EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 1).setDistance(703.778000)); + EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 4).setDistance(400.509000)); // cannot go 4-2-1 and 1-2-4 (at least when using edge1, there is still edge2!) setRestriction(edge4, edge1, 2); setRestriction(edge1, edge4, 2); @@ -947,11 +951,11 @@ public void test_issue_1593_simple(String algo) { na.setNode(0, 0.1, 0.1); na.setNode(5, 0.1, 0.2); na.setNode(4, 0.1, 0.3); - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 1).setDistance(10)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 0).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 5).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 4).setDistance(10)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 1).setDistance(10)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 0).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 5).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 4).setDistance(10)); // cannot go, 2-3-1 setRestriction(edge1, edge0, 3); graph.freeze(); @@ -980,8 +984,8 @@ public void test_issue_1593_simple(String algo) { public void testRouteViaVirtualNode(String algo) { // 3 // 0-x-1-2 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(0)); updateDistancesFor(graph, 0, 0.00, 0.00); updateDistancesFor(graph, 1, 0.02, 0.02); updateDistancesFor(graph, 2, 0.03, 0.03); @@ -1007,9 +1011,9 @@ public void testRouteViaVirtualNode_withAlternative(String algo) { // 0-x-1 // \ | // \-2 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 0).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 0).setDistance(1)); updateDistancesFor(graph, 0, 0.01, 0.00); updateDistancesFor(graph, 1, 0.01, 0.02); updateDistancesFor(graph, 2, 0.00, 0.02); @@ -1035,12 +1039,12 @@ public void testFiniteUTurnCost_virtualViaNode(String algo) { // 4->3->2->1-x-0 // | // 5->6 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 1).setDistance(0)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 0).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 5).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 1).setDistance(0)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 0).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 5).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(0)); updateDistancesFor(graph, 4, 0.1, 0.0); updateDistancesFor(graph, 3, 0.1, 0.1); updateDistancesFor(graph, 2, 0.1, 0.2); @@ -1087,8 +1091,6 @@ public void test_astar_issue2061(String algo) { // cancelled the entire fwd search instead of simply stalling node 6. // |-------1-| // 7-6---0---2-3-4-5 - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); graph.edge(0, 1).set(accessEnc, true).set(speedEnc, 60); graph.edge(1, 5).set(accessEnc, true).set(speedEnc, 60); graph.edge(0, 2).set(accessEnc, true).set(speedEnc, 60); @@ -1204,7 +1206,7 @@ private void compareWithDijkstraOnRandomGraph(long seed) { final Random rnd = new Random(seed); // for larger graphs preparation takes much longer the higher the degree is! GHUtility.buildRandomGraph(graph, rnd, 20, 3.0, true, true, - encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), null, 0.7, 0.9, 0.8); + accessEnc, speedEnc, null, 0.7, 0.9, 0.8); GHUtility.addRandomTurnCosts(graph, seed, encodingManager, encoder, maxCost, turnCostStorage); graph.freeze(); checkStrict = false; @@ -1232,7 +1234,7 @@ public void testFindPath_heuristic_compareWithDijkstra_finiteUTurnCost() { private void compareWithDijkstraOnRandomGraph_heuristic(long seed) { GHUtility.buildRandomGraph(graph, new Random(seed), 20, 3.0, true, true, - encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), null, 0.7, 0.9, 0.8); + accessEnc, speedEnc, null, 0.7, 0.9, 0.8); GHUtility.addRandomTurnCosts(graph, seed, encodingManager, encoder, maxCost, turnCostStorage); graph.freeze(); checkStrict = false; diff --git a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java index 56cadb7803b..c3f35ad8bad 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java @@ -18,6 +18,8 @@ package com.graphhopper.routing.ch; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; @@ -48,6 +50,8 @@ public class EdgeBasedNodeContractorTest { private final int maxCost = 10; private FlagEncoder encoder; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; private BaseGraph graph; private Weighting weighting; private CHStorage chStore; @@ -63,6 +67,8 @@ public void setup() { private void initialize() { encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxCost)); EncodingManager encodingManager = EncodingManager.create(encoder); + accessEnc = encoder.getAccessEnc(); + speedEnc = encoder.getAverageSpeedEnc(); graph = new BaseGraph.Builder(encodingManager).create(); chConfigs = Arrays.asList( CHConfig.edgeBased("p1", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage()))), @@ -85,12 +91,12 @@ public void testContractNodes_simpleLoop() { // 6- 7-8 // | // 9 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 7).setDistance(2)); - final EdgeIteratorState edge7to8 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 8).setDistance(2)); - final EdgeIteratorState edge8to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(8, 3).setDistance(1)); - final EdgeIteratorState edge3to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(2)); - final EdgeIteratorState edge2to7 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 9).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 7).setDistance(2)); + final EdgeIteratorState edge7to8 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 8).setDistance(2)); + final EdgeIteratorState edge8to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(8, 3).setDistance(1)); + final EdgeIteratorState edge3to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(2)); + final EdgeIteratorState edge2to7 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 9).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); @@ -113,13 +119,13 @@ public void testContractNodes_necessaryAlternative() { // 2 -> 6 -> 3 -> 5 -> 4 // | ^ // -> 0-| - final EdgeIteratorState e6to0 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 0).setDistance(4)); - final EdgeIteratorState e0to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 6).setDistance(1)); - final EdgeIteratorState e6to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 3).setDistance(1)); - final EdgeIteratorState e3to5 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 5).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 4).setDistance(2)); + final EdgeIteratorState e6to0 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 0).setDistance(4)); + final EdgeIteratorState e0to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 6).setDistance(1)); + final EdgeIteratorState e6to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 3).setDistance(1)); + final EdgeIteratorState e3to5 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 5).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 4).setDistance(2)); freeze(); setMaxLevelOnAllNodes(); setRestriction(1, 6, 3); @@ -140,11 +146,11 @@ public void testContractNodes_alternativeNecessary_noUTurn() { // /->0--> // v \ // 4 <-----> 2 -> 3 -> 1 - EdgeIteratorState e0to4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 0).setDistance(3)); - EdgeIteratorState e0to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 2).setDistance(5)); - EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(2)); - EdgeIteratorState e1to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 1).setDistance(2)); - EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 2).setDistance(2)); + EdgeIteratorState e0to4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 0).setDistance(3)); + EdgeIteratorState e0to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 2).setDistance(5)); + EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(2)); + EdgeIteratorState e1to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 1).setDistance(2)); + EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 2).setDistance(2)); freeze(); setMaxLevelOnAllNodes(); @@ -167,13 +173,13 @@ public void testContractNodes_bidirectionalLoop() { // 0-4-6 // | // 5-2 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 4).setDistance(2)); - final EdgeIteratorState e4to6 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 6).setDistance(2)); - final EdgeIteratorState e6to3 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 3).setDistance(1)); - final EdgeIteratorState e3to4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(1)); - final EdgeIteratorState e4to5 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 2).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 4).setDistance(2)); + final EdgeIteratorState e4to6 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 6).setDistance(2)); + final EdgeIteratorState e6to3 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 3).setDistance(1)); + final EdgeIteratorState e3to4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + final EdgeIteratorState e4to5 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 2).setDistance(2)); freeze(); // enforce loop (going counter-clockwise) @@ -197,9 +203,9 @@ public void testContractNodes_bidirectionalLoop() { @Test public void testContractNode_twoNormalEdges_noSourceEdgeToConnect() { // 1 --> 0 --> 2 --> 3 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 2).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 2).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(0, 3, 1, 2); @@ -212,9 +218,9 @@ public void testContractNode_twoNormalEdges_noSourceEdgeToConnect() { @Test public void testContractNode_twoNormalEdges_noTargetEdgeToConnect() { // 3 --> 1 --> 0 --> 2 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 2).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 2).setDistance(5)); freeze(); setMaxLevelOnAllNodes(); contractNodes(0, 3, 1, 2); @@ -227,10 +233,10 @@ public void testContractNode_twoNormalEdges_noTargetEdgeToConnect() { @Test public void testContractNode_twoNormalEdges_noEdgesToConnectBecauseOfTurnRestrictions() { // 0 --> 3 --> 2 --> 4 --> 1 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); setRestriction(0, 3, 2); setRestriction(2, 4, 1); freeze(); @@ -243,10 +249,10 @@ public void testContractNode_twoNormalEdges_noEdgesToConnectBecauseOfTurnRestric @Test public void testContractNode_twoNormalEdges_noTurncosts() { // 0 --> 3 --> 2 --> 4 --> 1 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(1)); - final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(3)); - final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(3)); + final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); EdgeBasedNodeContractor nodeContractor = createNodeContractor(); @@ -266,10 +272,10 @@ public void testContractNode_twoNormalEdges_noTurncosts() { @Test public void testContractNode_twoNormalEdges_noShortcuts() { // 0 --> 1 --> 2 --> 3 --> 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractAllNodesInOrder(); @@ -280,10 +286,10 @@ public void testContractNode_twoNormalEdges_noShortcuts() { @Test public void testContractNode_twoNormalEdges_noOutgoingEdges() { // 0 --> 1 --> 2 <-- 3 <-- 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 3).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 4, 1, 3); @@ -293,10 +299,10 @@ public void testContractNode_twoNormalEdges_noOutgoingEdges() { @Test public void testContractNode_twoNormalEdges_noIncomingEdges() { // 0 <-- 1 <-- 2 --> 3 --> 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 1).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 1).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 4, 1, 3); @@ -310,11 +316,11 @@ public void testContractNode_duplicateOutgoingEdges_differentWeight() { // 0 -> 1 -> 2 -> 3 -> 4 // \->/ - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 4, 1, 3); @@ -328,11 +334,11 @@ public void testContractNode_duplicateOutgoingEdges_differentWeight() { public void testContractNode_duplicateIncomingEdges_differentWeight() { // 0 -> 1 -> 2 -> 3 -> 4 // \->/ - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 4, 1, 3); @@ -350,11 +356,11 @@ public void testContractNode_duplicateOutgoingEdges_sameWeight() { // 0 -> 1 -> 2 -> 3 -> 4 // \->/ - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 4, 1, 3); @@ -365,11 +371,11 @@ public void testContractNode_duplicateOutgoingEdges_sameWeight() { public void testContractNode_duplicateIncomingEdges_sameWeight() { // 0 -> 1 -> 2 -> 3 -> 4 // \->/ - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 4, 1, 3); @@ -379,10 +385,10 @@ public void testContractNode_duplicateIncomingEdges_sameWeight() { @Test public void testContractNode_twoNormalEdges_withTurnCost() { // 0 --> 3 --> 2 --> 4 --> 1 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(1)); - final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(3)); - final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(3)); + final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); setTurnCost(3, 2, 4, 4); freeze(); setMaxLevelOnAllNodes(); @@ -393,10 +399,10 @@ public void testContractNode_twoNormalEdges_withTurnCost() { @Test public void testContractNode_twoNormalEdges_withTurnRestriction() { // 0 --> 3 --> 2 --> 4 --> 1 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); setRestriction(3, 2, 4); freeze(); setMaxLevelOnAllNodes(); @@ -407,10 +413,10 @@ public void testContractNode_twoNormalEdges_withTurnRestriction() { @Test public void testContractNode_twoNormalEdges_bidirectional() { // 0 -- 3 -- 2 -- 4 -- 1 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 3).setDistance(1)); - final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 2).setDistance(3)); - final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 2).setDistance(3)); + final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 4).setDistance(5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); setTurnCost(e3to2, e2to4, 2, 4); setTurnCost(e2to4, e3to2, 2, 4); freeze(); @@ -428,10 +434,10 @@ public void testContractNode_twoNormalEdges_bidirectional() { @Test public void testContractNode_twoNormalEdges_bidirectional_differentCosts() { // 0 -- 3 -- 2 -- 4 -- 1 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 3).setDistance(1)); - final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 2).setDistance(3)); - final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 2).setDistance(3)); + final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 4).setDistance(5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); setTurnCost(e3to2, e2to4, 2, 4); setTurnCost(e2to4, e3to2, 2, 7); freeze(); @@ -446,9 +452,9 @@ public void testContractNode_twoNormalEdges_bidirectional_differentCosts() { @Test public void testContractNode_multiple_bidirectional_linear() { // 3 -- 2 -- 1 -- 4 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 2).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 1).setDistance(3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(6)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 2).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 1).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(6)); freeze(); setMaxLevelOnAllNodes(); @@ -471,11 +477,11 @@ private void runTestWithTurnCostAndLoop(boolean loopHelps) { // />\ // \ / // 0 --> 3 --> 2 --> 4 --> 1 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(1)); - final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(3)); - final EdgeIteratorState e2to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 2).setDistance(2)); - final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(3)); + final EdgeIteratorState e2to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 2).setDistance(2)); + final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); setTurnCost(e3to2, e2to2, 2, 2); setTurnCost(e2to2, e2to4, 2, 1); @@ -502,12 +508,12 @@ public void testContractNode_shortcutDoesNotSpanUTurn() { // 2 -> 7 -> 3 -> 5 -> 6 // | // 1 <-> 4 - final EdgeIteratorState e7to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 3).setDistance(1)); - final EdgeIteratorState e3to5 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 5).setDistance(1)); - final EdgeIteratorState e3to4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(1)); + final EdgeIteratorState e7to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 3).setDistance(1)); + final EdgeIteratorState e3to5 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 5).setDistance(1)); + final EdgeIteratorState e3to4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); setRestriction(7, 3, 5); @@ -577,19 +583,19 @@ public void testContractNode_multiple_loops_rightLeftLoopIsBest() { // 9--7 5 8--10 private class GraphWithTwoLoops { final int centerNode = 6; - final EdgeIteratorState e0to1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(3)); - final EdgeIteratorState e1to6 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 6).setDistance(2)); - final EdgeIteratorState e6to0 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 0).setDistance(4)); - final EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(2)); - final EdgeIteratorState e3to6 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 6).setDistance(7)); - final EdgeIteratorState e6to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 2).setDistance(1)); - final EdgeIteratorState e7to6 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 6).setDistance(1)); - final EdgeIteratorState e6to8 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 8).setDistance(6)); - final EdgeIteratorState e9to7 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(9, 7).setDistance(2)); - final EdgeIteratorState e8to10 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(8, 10).setDistance(3)); + final EdgeIteratorState e0to1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(3)); + final EdgeIteratorState e1to6 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 6).setDistance(2)); + final EdgeIteratorState e6to0 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 0).setDistance(4)); + final EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(2)); + final EdgeIteratorState e3to6 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 6).setDistance(7)); + final EdgeIteratorState e6to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 2).setDistance(1)); + final EdgeIteratorState e7to6 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 6).setDistance(1)); + final EdgeIteratorState e6to8 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 8).setDistance(6)); + final EdgeIteratorState e9to7 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(9, 7).setDistance(2)); + final EdgeIteratorState e8to10 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(8, 10).setDistance(3)); // these two edges help to avoid loop avoidance for the left and right loops - final EdgeIteratorState e4to6 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 6).setDistance(1)); - final EdgeIteratorState e5to6 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(1)); + final EdgeIteratorState e4to6 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 6).setDistance(1)); + final EdgeIteratorState e5to6 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); final int numEdges = 12; GraphWithTwoLoops(int turnCost70, int turnCost72, int turnCost12, int turnCost18, int turnCost38, int turnCost78) { @@ -649,11 +655,11 @@ public void testContractNode_detour_detourIsWorse() { // / \ // 4--1---2--3 private class GraphWithDetour { - private final EdgeIteratorState e4to1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 1).setDistance(2)); - private final EdgeIteratorState e1to0 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(4)); - private final EdgeIteratorState e1to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(3)); - private final EdgeIteratorState e0to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 2).setDistance(3)); - private final EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(2)); + private final EdgeIteratorState e4to1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 1).setDistance(2)); + private final EdgeIteratorState e1to0 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(4)); + private final EdgeIteratorState e1to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(3)); + private final EdgeIteratorState e0to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 2).setDistance(3)); + private final EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(2)); GraphWithDetour(int turnCost42, int turnCost13, int turnCost40, int turnCost03) { setTurnCost(e4to1, e1to2, 1, turnCost42); @@ -691,14 +697,14 @@ public void testContractNode_detour_multipleInOut_restrictedIn() { // \ / \ / // 2-1-0-4-6 private class GraphWithDetourMultipleInOutEdges { - final EdgeIteratorState e5to1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 1).setDistance(3)); - final EdgeIteratorState e2to1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 1).setDistance(2)); - final EdgeIteratorState e1to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 3).setDistance(1)); - final EdgeIteratorState e3to4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(2)); - final EdgeIteratorState e1to0 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(5)); - final EdgeIteratorState e0to4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 4).setDistance(2)); - final EdgeIteratorState e4to6 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 6).setDistance(1)); - final EdgeIteratorState e4to7 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 7).setDistance(3)); + final EdgeIteratorState e5to1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 1).setDistance(3)); + final EdgeIteratorState e2to1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 1).setDistance(2)); + final EdgeIteratorState e1to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); + final EdgeIteratorState e3to4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(2)); + final EdgeIteratorState e1to0 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(5)); + final EdgeIteratorState e0to4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 4).setDistance(2)); + final EdgeIteratorState e4to6 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 6).setDistance(1)); + final EdgeIteratorState e4to7 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 7).setDistance(3)); GraphWithDetourMultipleInOutEdges(int turnCost20, int turnCost50, int turnCost23, int turnCost53, int turnCost36) { setTurnCost(e1to3, e3to4, 3, 2); @@ -740,12 +746,12 @@ public void testContractNode_loopAvoidance_loopAvoidable() { // | // 5 private class GraphWithLoop { - final EdgeIteratorState e0to1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(2)); - final EdgeIteratorState e1to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - final EdgeIteratorState e2to0 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 0).setDistance(1)); - final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(3)); - final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(5)); - final EdgeIteratorState e5to2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 2).setDistance(2)); + final EdgeIteratorState e0to1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(2)); + final EdgeIteratorState e1to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + final EdgeIteratorState e2to0 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 0).setDistance(1)); + final EdgeIteratorState e3to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(3)); + final EdgeIteratorState e2to4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(5)); + final EdgeIteratorState e5to2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 2).setDistance(2)); GraphWithLoop(int turnCost34) { setTurnCost(e3to2, e2to4, 2, turnCost34); @@ -761,16 +767,16 @@ public void testContractNode_witnessPathsAreFound() { // 0 - 1 3 - 4 | // | | / // 5 - 9 ---- - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 9).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(9, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 7).setDistance(6)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(9, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 10).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 9).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(9, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 7).setDistance(6)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(9, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 10).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 10, 4, 1, 5, 7, 9, 3); @@ -784,13 +790,13 @@ public void testContractNode_noUnnecessaryShortcut_witnessPathOfEqualWeight() { // 0 -> 1 -> 5 <_ // v v \ // 2 -> 3 -> 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 5).setDistance(1)); - EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - EdgeIteratorState e3to4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); - EdgeIteratorState e5to3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 5).setDistance(1)); + EdgeIteratorState e2to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + EdgeIteratorState e3to4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + EdgeIteratorState e5to3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 3).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(3, 2, 0, 1, 5, 4); @@ -812,14 +818,16 @@ public void testContractNode_noUnnecessaryShortcut_differentWitnessesForDifferen // 0 --> 1 ---> 3 ---> 5 --> 6 // \ / // \--> 4 ---/ - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 5).setDistance(1)); // bidirectional - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 5).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(1)); // bidirectional - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 4).setDistance(1)); + // bidirectional + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 5).setDistance(1)); + // bidirectional + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(3, 0, 6, 1, 2, 5, 4); @@ -843,14 +851,16 @@ public void testContractNode_noUnnecessaryShortcut_differentInitialEntriesForDif // 0 --> 1 ---> 3 ---> 5 --> 6 // \ / // \--- 4 ->-/ - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); // bidirectional - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(1)); // bidirectional - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + // bidirectional + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); + // bidirectional + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(3, 0, 6, 1, 2, 5, 4); @@ -871,12 +881,12 @@ public void testContractNode_bidirectional_edge_at_fromNode(boolean edge1to2bidi // 0 -> 1 <-> 5 // v v // 2 --> 3 -> 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, edge1to2bidirectional, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, edge1to2bidirectional, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 3).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 5, 4, 3); @@ -890,12 +900,12 @@ public void testContractNode_bidirectional_edge_at_fromNode_going_to_node() { // 0 -> 1 <-> 5 // v v // 2 --> 3 -> 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 3).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(5, 0, 4, 1, 2, 3); @@ -908,18 +918,18 @@ public void testNodeContraction_directWitness() { // 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 // / \ / \ //10 -> ------> 9 ------> -> 11 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 8).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 9).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(9, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(10, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(7, 11).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 8).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 9).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(9, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(10, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(7, 11).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 6, 3, 5, 4, 0, 8, 10, 11, 1, 7, 9); @@ -941,12 +951,12 @@ public void testNodeContraction_witnessBetterBecauseOfTurnCostAtTargetNode() { // 0 -> 1 -> 2 -> 3 -> 4 // \ / // -- 5 -> - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 5).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 5).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 3).setDistance(1)); setTurnCost(2, 3, 4, 5); setTurnCost(5, 3, 4, 2); freeze(); @@ -965,12 +975,12 @@ public void testNodeContraction_letShortcutsWitnessEachOther_twoIn() { // 0 -> 1 -> 2 -> 3 -> 4 -> 5 // \ | // ------->| - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 3).setDistance(4)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 3).setDistance(4)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); @@ -989,12 +999,12 @@ public void testNodeContraction_letShortcutsWitnessEachOther_twoOut() { // 0 -> 1 -> 2 -> 3 -> 4 -> 5 // | / // -------> - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(4)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(4)); freeze(); setMaxLevelOnAllNodes(); @@ -1008,9 +1018,9 @@ public void testNodeContraction_letShortcutsWitnessEachOther_twoOut() { public void testNodeContraction_parallelEdges_onlyOneLoopShortcutNeeded() { // /--\ // 0 -- 1 -- 2 - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(2)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 0).setDistance(4)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(5)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(2)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 0).setDistance(4)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(5)); setTurnCost(edge0, edge1, 0, 1); setTurnCost(edge1, edge0, 0, 2); freeze(); @@ -1028,12 +1038,12 @@ public void testNodeContraction_duplicateEdge_severalLoops() { // |\ | // | \ / // -- 2 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3).setDistance(47)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4).setDistance(19)); - EdgeIteratorState e2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 5).setDistance(38)); - EdgeIteratorState e3 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 5).setDistance(57)); // note there is a duplicate edge here (with different weight) - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(10)); - EdgeIteratorState e5 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(56)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(47)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 4).setDistance(19)); + EdgeIteratorState e2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 5).setDistance(38)); + EdgeIteratorState e3 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 5).setDistance(57)); // note there is a duplicate edge here (with different weight) + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); + EdgeIteratorState e5 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(56)); setTurnCost(e3, e2, 5, 4); setTurnCost(e2, e3, 5, 5); @@ -1065,9 +1075,9 @@ public void testNodeContraction_duplicateEdge_severalLoops() { @Test public void testNodeContraction_tripleConnection() { - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1.0)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(2.0)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(3.5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1.0)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(2.0)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(3.5)); freeze(); setMaxLevelOnAllNodes(); contractNodes(1, 0); @@ -1085,10 +1095,10 @@ public void testNodeContraction_fromAndToNodesEqual() { // v ^ // \ / // 2 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 3); @@ -1102,11 +1112,11 @@ public void testNodeContraction_node_in_loop() { // 0-4-3 // | // 1 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 4).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 3).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 4).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 3).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 1).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); @@ -1130,11 +1140,11 @@ public void testFindPath_finiteUTurnCost() { // 0-3-4 // |/ // 2 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(100)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(100)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 2).setDistance(500)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(200)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 1).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(100)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(100)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 2).setDistance(500)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(200)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 1).setDistance(100)); freeze(); chStore = CHStorage.fromGraph(graph, chConfigs.get(1)); chBuilder = new CHStorageBuilder(chStore); @@ -1153,11 +1163,11 @@ public void testNodeContraction_turnRestrictionAndLoop() { // /\ /<-3 // 0 1--2 // \/ \->4 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(5)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(6)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(6)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(3)); setRestriction(3, 2, 4); freeze(); setMaxLevelOnAllNodes(); @@ -1170,11 +1180,11 @@ public void testNodeContraction_forwardLoopNeedsToBeRecognizedAsIncoming() { // --- // \ / // 0 -- 1 -- 2 -- 3 -- 4 - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 1).setDistance(1)); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 1).setDistance(1)); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); setRestriction(edge0, edge2, 1); freeze(); setMaxLevelOnAllNodes(); @@ -1190,10 +1200,10 @@ public void testNodeContraction_forwardLoopNeedsToBeRecognizedAsIncoming() { @Test public void testNodeContraction_minorWeightDeviation() { // 0 -> 1 -> 2 -> 3 -> 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(51.401)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(70.041)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(75.806)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(05.003)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(51.401)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(70.041)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(75.806)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(05.003)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 3, 4); @@ -1207,10 +1217,10 @@ public void testNodeContraction_zeroWeightLoop_loopOnly() { // zero weight loops are quite a headache..., also see #1355 // /| // 0 -> 1 -> 2 -> 3 -- - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 3); @@ -1225,11 +1235,11 @@ public void testNodeContraction_zeroWeightLoop_loopAndEdge() { // 0 -> 1 -> 2 -> 3 -- // | // 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 4, 3); @@ -1243,11 +1253,11 @@ public void testNodeContraction_zeroWeightLoop_twoLoops() { // /| // 0 -> 1 -> 2 -> 3 -- // \| - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 3); @@ -1262,12 +1272,12 @@ public void testNodeContraction_zeroWeightLoop_twoLoopsAndEdge_edgeFirst() { // 0 -> 1 -> 2 -> 3 -- // | \| // 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 4, 3); @@ -1282,12 +1292,12 @@ public void testNodeContraction_zeroWeightLoop_twoLoopsAndEdge_loopsFirst() { // 0 -> 1 -> 2 -> 3 -- // | \| // 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 4, 3); @@ -1302,16 +1312,16 @@ public void testNodeContraction_zeroWeightLoop_manyLoops() { // 0 -> 1 -> 2 -> 3 -- // | // 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); freeze(); setMaxLevelOnAllNodes(); contractNodes(2, 0, 1, 4, 3); @@ -1327,14 +1337,22 @@ public void testNodeContraction_zeroWeightLoop_another() { // 0 - 5 - 2 // oo // note there are two (directed) zero weight loops at node 5! - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 1).setDistance(100)); // edgeId=0 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 2).setDistance(100)); // edgeId=1 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(100)); // edgeId=2 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 0).setDistance(100)); // edgeId=3 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 4).setDistance(100)); // edgeId=4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 5).setDistance(0)); // edgeId=5 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(100)); // edgeId=6 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 5).setDistance(0)); // edgeId=7 + // edgeId=0 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 1).setDistance(100)); + // edgeId=1 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 2).setDistance(100)); + // edgeId=2 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(100)); + // edgeId=3 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 0).setDistance(100)); + // edgeId=4 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 4).setDistance(100)); + // edgeId=5 + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 5).setDistance(0)); + // edgeId=6 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(100)); + // edgeId=7 + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 5).setDistance(0)); freeze(); setMaxLevelOnAllNodes(); contractNodes(1, 3, 0, 2, 7, 6, 4); @@ -1354,14 +1372,14 @@ public void testNodeContraction_zeroWeightLoop_twoLoopsAndEdge_withTurnRestricti // 0 -> 1 -> 2 -> 3 -- // | // 4 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(1)); - EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); // add a few more loops to make this test more difficult to pass - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 3).setDistance(0)); // we have to use the zero weight loop so it may not be excluded setTurnCost(edge2, edge3, 3, 5); setRestriction(edge2, edge4, 3); @@ -1377,14 +1395,14 @@ public void testNodeContraction_numPolledEdges() { // | // 0 -> 3 -> 2 <-> 4 -> 5 // \---<----| - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(71.203000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 3).setDistance(79.003000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 0).setDistance(21.328000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 4).setDistance(16.499000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 2).setDistance(16.487000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 1).setDistance(55.603000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 1).setDistance(33.453000)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(29.665000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(71.203000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 3).setDistance(79.003000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 0).setDistance(21.328000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 4).setDistance(16.499000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 2).setDistance(16.487000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 1).setDistance(55.603000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 1).setDistance(33.453000)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(29.665000)); freeze(); setMaxLevelOnAllNodes(); EdgeBasedNodeContractor nodeContractor = createNodeContractor(); diff --git a/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java index df9c9f42388..fe68e2c5fc1 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java @@ -20,7 +20,12 @@ import com.graphhopper.routing.Dijkstra; import com.graphhopper.routing.DijkstraBidirectionCH; import com.graphhopper.routing.Path; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.util.AllEdgesIterator; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -42,6 +47,8 @@ public class NodeBasedNodeContractorTest { private final FlagEncoder encoder = FlagEncoders.createCar(); private final EncodingManager encodingManager = EncodingManager.create(encoder); + private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + private final DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); private final Weighting weighting = new ShortestWeighting(encoder); private final BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); private final CHConfig chConfig = CHConfig.nodeBased("profile", weighting); @@ -72,17 +79,17 @@ public void testDirectedGraph(boolean reverse) { //4-3_1<-\ 10 // \_|/ // 0___2_11 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 2).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(10, 2).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(11, 2).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(10, 2).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(11, 2).setDistance(2)); // create a longer one directional edge => no longish one-dir shortcut should be created - final EdgeIteratorState edge2to1bidirected = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 1).setDistance(2)); - final EdgeIteratorState edge2to1directed = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 1).setDistance(10)); - final EdgeIteratorState edge1to3 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 5).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 6).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 7).setDistance(2)); + final EdgeIteratorState edge2to1bidirected = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 1).setDistance(2)); + final EdgeIteratorState edge2to1directed = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 1).setDistance(10)); + final EdgeIteratorState edge1to3 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 5).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 6).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 7).setDistance(2)); freeze(); setMaxLevelOnAllNodes(); @@ -104,13 +111,13 @@ public void testFindShortcuts_Roundabout() { // 1 -- 3 -- 4 ---> 5 ---> 6 -- 7 // \ / // <--- 8 <--- - final EdgeIteratorState iter1to3 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3).setDistance(1)); - final EdgeIteratorState iter3to4 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(1)); - final EdgeIteratorState iter4to5 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(4, 5).setDistance(1)); - final EdgeIteratorState iter5to6 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(1)); - final EdgeIteratorState iter6to8 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(6, 8).setDistance(2)); - final EdgeIteratorState iter8to4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(8, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(1)); + final EdgeIteratorState iter1to3 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); + final EdgeIteratorState iter3to4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + final EdgeIteratorState iter4to5 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); + final EdgeIteratorState iter5to6 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + final EdgeIteratorState iter6to8 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(6, 8).setDistance(2)); + final EdgeIteratorState iter8to4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(8, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(1)); freeze(); contractInOrder(3, 5, 7, 8, 4, 1, 6); @@ -142,9 +149,9 @@ public void testShortcutMergeBug(boolean reverse) { // where there are two roads from 1 to 2 and the directed road has a smaller weight. to get from 2 to 1 we // have to use the bidirectional edge despite the higher weight and therefore we need an extra shortcut for // this. - final EdgeIteratorState edge1to2bidirected = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(2)); - final EdgeIteratorState edge1to2directed = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(1)); - final EdgeIteratorState edge2to3 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(1)); + final EdgeIteratorState edge1to2bidirected = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(2)); + final EdgeIteratorState edge1to2directed = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + final EdgeIteratorState edge2to3 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); if (reverse) { @@ -165,8 +172,8 @@ public void testShortcutMergeBug(boolean reverse) { @Test public void testContractNode_directed_shortcutRequired() { // 0 --> 1 --> 2 - final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(2)); + final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(2)); freeze(); setMaxLevelOnAllNodes(); contractInOrder(1, 0, 2); @@ -176,8 +183,8 @@ public void testContractNode_directed_shortcutRequired() { @Test public void testContractNode_directed_shortcutRequired_reverse() { // 0 <-- 1 <-- 2 - final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 1).setDistance(1)); - final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 0).setDistance(2)); + final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 1).setDistance(1)); + final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 0).setDistance(2)); freeze(); setMaxLevelOnAllNodes(); contractInOrder(1, 2, 0); @@ -187,8 +194,8 @@ public void testContractNode_directed_shortcutRequired_reverse() { @Test public void testContractNode_bidirected_shortcutsRequired() { // 0 -- 1 -- 2 - final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(2)); + final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(2)); freeze(); contractInOrder(1, 2, 0); checkShortcuts(expectedShortcut(2, 0, edge2, edge1, true, true)); @@ -198,9 +205,9 @@ public void testContractNode_bidirected_shortcutsRequired() { public void testContractNode_directed_withWitness() { // 0 --> 1 --> 2 // \_________/ - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 2).setDistance(1)); freeze(); setMaxLevelOnAllNodes(); createNodeContractor().contractNode(1); @@ -214,11 +221,11 @@ public void testNodeContraction_shortcutDistanceRounding() { // \ / // 1 --> 2 --> 3 double[] distances = {4.019, 1.006, 1.004, 1.006, 1.004}; - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 4).setDistance(distances[0])); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(distances[1])); - EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(distances[2])); - EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(distances[3])); - EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(distances[4])); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 4).setDistance(distances[0])); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(distances[1])); + EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(distances[2])); + EdgeIteratorState edge3 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(distances[3])); + EdgeIteratorState edge4 = GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(distances[4])); freeze(); setMaxLevelOnAllNodes(); @@ -270,11 +277,11 @@ public void testNodeContraction_shortcutWeightRounding() { // 1 --> 2 --> 3 double fac = 60 / 3.6; double[] distances = {fac * 4.019, fac * 1.006, fac * 1.004, fac * 1.006, fac * 1.004}; - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 4).setDistance(distances[0])); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(distances[1])); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(distances[2])); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(distances[3])); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 4).setDistance(distances[4])); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 4).setDistance(distances[0])); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(distances[1])); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(distances[2])); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(distances[3])); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(distances[4])); graph.freeze(); Weighting weighting = new FastestWeighting(encoder); CHConfig chConfig = CHConfig.nodeBased("p1", weighting); @@ -306,11 +313,11 @@ public void testNodeContraction_preventUnnecessaryShortcutWithLoop() { BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); // 0 - 1 - 2 - 3 // o o - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 0).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 0).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 3).setDistance(1)); graph.freeze(); Weighting weighting = new FastestWeighting(encoder); diff --git a/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java b/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java index 797e5331f01..0ecd7a86a0c 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java @@ -22,6 +22,8 @@ import com.graphhopper.routing.Dijkstra; import com.graphhopper.routing.Path; import com.graphhopper.routing.RoutingAlgorithm; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.*; import com.graphhopper.routing.weighting.FastestWeighting; @@ -53,51 +55,55 @@ public class PrepareContractionHierarchiesTest { // | | | // 17-16-...-11<-/ private static void initDirected2(Graph g, FlagEncoder encoder) { - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(6, 7).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(7, 8).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(8, 9).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(9, 10).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(10, 11).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(11, 12).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(11, 9).setDistance(3)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(12, 13).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(13, 14).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(14, 15).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(15, 16).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(16, 17).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(17, 0).setDistance(1)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 9).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(10, 11).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(11, 12).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(11, 9).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(12, 13).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(13, 14).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(14, 15).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(15, 16).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(16, 17).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(17, 0).setDistance(1)); } // prepare-routing.svg private static void initShortcutsGraph(Graph g, FlagEncoder encoder) { - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 3).setDistance(1.5)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 9).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(9, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(10, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(6, 7).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(7, 8).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(8, 9).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(4, 11).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(9, 14).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(10, 14).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(11, 12).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(12, 15).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(12, 13).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(13, 16).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(15, 16).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(14, 16).setDistance(1)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(1.5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 9).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(9, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(10, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 9).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 11).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(9, 14).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(10, 14).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(11, 12).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(12, 15).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(12, 13).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(13, 16).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(15, 16).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(14, 16).setDistance(1)); } private static void initExampleGraph(Graph g, FlagEncoder encoder) { @@ -107,13 +113,15 @@ private static void initExampleGraph(Graph g, FlagEncoder encoder) { // / | // 4-----3 // - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 4).setDistance(3)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 2).setDistance(3)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(4, 3).setDistance(2)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(5, 1).setDistance(2)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 4).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 3).setDistance(2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 1).setDistance(2)); } @BeforeEach @@ -152,12 +160,14 @@ public void testMoreComplexGraph() { @Test public void testDirectedGraph() { - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(5, 4).setDistance(3)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(4, 5).setDistance(10)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(2, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(5, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(3, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(4, 3).setDistance(1)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(5, 4).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(4, 5).setDistance(10)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(2, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(5, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(3, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(4, 3).setDistance(1)); g.freeze(); assertEquals(6, g.getEdges()); PrepareContractionHierarchies prepare = createPrepareContractionHierarchies(g); @@ -201,47 +211,48 @@ private static void initRoundaboutGraph(Graph g, FlagEncoder encoder) { // -15-1--2--3--4 / / // / \-5->6/ / // -14 \________/ - - GHUtility.setSpeed(60, true, true, encoder, g.edge(16, 0).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 9).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 17).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(9, 10).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(10, 11).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(11, 28).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(28, 29).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(29, 30).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(30, 31).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(31, 4).setDistance(1)); - - GHUtility.setSpeed(60, true, true, encoder, g.edge(17, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(15, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(14, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(14, 18).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(18, 19).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(19, 20).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(20, 15).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(19, 21).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(21, 16).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(3, 4).setDistance(1)); - - GHUtility.setSpeed(60, true, false, encoder, g.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(6, 7).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(7, 13).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(13, 12).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(12, 4).setDistance(1)); - - GHUtility.setSpeed(60, true, true, encoder, g.edge(7, 8).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(8, 22).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(22, 23).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(23, 24).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(24, 25).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(25, 27).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(27, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(25, 26).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(26, 25).setDistance(1)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(16, 0).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 9).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 17).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(10, 11).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(11, 28).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(28, 29).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(29, 30).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(30, 31).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(31, 4).setDistance(1)); + + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(17, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(15, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(14, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(14, 18).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(18, 19).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(19, 20).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(20, 15).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(19, 21).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(21, 16).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(1)); + + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(6, 7).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(7, 13).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(13, 12).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(12, 4).setDistance(1)); + + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 22).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(22, 23).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(23, 24).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(24, 25).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(25, 27).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(27, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(25, 26).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(26, 25).setDistance(1)); } @Test @@ -271,14 +282,16 @@ public void testDisconnects() { // 2 // v // 7 - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(8, 3).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(3, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(6, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(1, 5).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(4, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(0, 6).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(6, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(2, 7).setDistance(1)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(8, 3).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(3, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(6, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(1, 5).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(4, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(0, 6).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(6, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(2, 7).setDistance(1)); g.freeze(); PrepareContractionHierarchies prepare = createPrepareContractionHierarchies(g) @@ -331,13 +344,15 @@ public void testStallOnDemandViaVirtuaNode_issue1574() { // start 0 - 3 - x - 1 - 2 // \ | // sc ---- 4 - 5 - 6 - 7 finish - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 3).setDistance(1)); - EdgeIteratorState edge31 = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 2).setDistance(1)); - EdgeIteratorState edge24 = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(4, 5).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(6, 7).setDistance(1)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(1)); + EdgeIteratorState edge31 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); + EdgeIteratorState edge24 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(1)); updateDistancesFor(g, 0, 0.001, 0.0000); updateDistancesFor(g, 3, 0.001, 0.0001); updateDistancesFor(g, 1, 0.001, 0.0002); @@ -352,14 +367,14 @@ public void testStallOnDemandViaVirtuaNode_issue1574() { // at node 2 coming from 3. this happens because due to the virtual node x between 3 and 1, the weight of the // spt entry at 2 is different to the sum of the weights of the spt entry at node 3 and the shortcut edge. this // is due to different floating point rounding arithmetic of shortcuts and virtual edges on the query graph. - edge31.set(carEncoder.getAverageSpeedEnc(), 12, 12); + edge31.set(speedEnc, 12, 12); // just stalling node 2 alone would not lead to connection not found, because the shortcut 3-4 still finds node // 4. however, we can choose the weight of edge 2-4 such that node 4 also gets stalled via node 2. // it is important that node 2 gets stalled before otherwise node 4 would have already be discovered. // note that without the virtual node between 3 and 1 node 2 would not even be explored in the forward search, // but because of the virtual node the strict upward search is modified and goes like 0-3-x-1-2. - edge24.set(carEncoder.getAverageSpeedEnc(), 27.5, 27.5); + edge24.set(speedEnc, 27.5, 27.5); // prepare ch, use node ids as levels PrepareContractionHierarchies pch = createPrepareContractionHierarchies(g, chConfig); @@ -420,10 +435,12 @@ public void testCircleBug() { // /--1 // -0--/ // | - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 1).setDistance(10)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 1).setDistance(4)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 2).setDistance(10)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 3).setDistance(10)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(4)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(10)); PrepareContractionHierarchies prepare = createPrepareContractionHierarchies(g); PrepareContractionHierarchies.Result result = prepare.doWork(); assertEquals(0, result.getShortcuts()); @@ -436,15 +453,17 @@ public void testBug178() { // 0-1->-2--3--4 // \-<-/ // - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(2, 1).setDistance(1)); - - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(5, 0).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(6, 3).setDistance(1)); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(2, 1).setDistance(1)); + + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 0).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 3).setDistance(1)); PrepareContractionHierarchies prepare = createPrepareContractionHierarchies(g); useNodeOrdering(prepare, new int[]{4, 1, 2, 0, 5, 6, 3}); @@ -476,7 +495,7 @@ public void testMultiplePreparationsIdenticalView() { initShortcutsGraph(graph, tmpCarEncoder); AllEdgesIterator iter = graph.getAllEdges(); while (iter.next()) { - GHUtility.setSpeed(18, true, true, tmpBikeEncoder, iter); + GHUtility.setSpeed(18, true, true, tmpBikeEncoder.getAccessEnc(), tmpBikeEncoder.getAverageSpeedEnc(), iter); } graph.freeze(); @@ -497,7 +516,7 @@ public void testMultiplePreparationsDifferentView() { initShortcutsGraph(graph, tmpCarEncoder); AllEdgesIterator iter = graph.getAllEdges(); while (iter.next()) { - GHUtility.setSpeed(18, true, true, tmpBikeEncoder, iter); + GHUtility.setSpeed(18, true, true, tmpBikeEncoder.getAccessEnc(), tmpBikeEncoder.getAverageSpeedEnc(), iter); } GHUtility.getEdge(graph, 9, 14). set(tmpBikeEncoder.getAccessEnc(), false). diff --git a/core/src/test/java/com/graphhopper/routing/lm/LMIssueTest.java b/core/src/test/java/com/graphhopper/routing/lm/LMIssueTest.java index 1944d53b57e..b32f8ce3c75 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/LMIssueTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/LMIssueTest.java @@ -19,6 +19,7 @@ package com.graphhopper.routing.lm; import com.graphhopper.routing.*; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.util.EncodingManager; @@ -45,6 +46,8 @@ public class LMIssueTest { private Directory dir; private BaseGraph graph; private FlagEncoder encoder; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; private Weighting weighting; private LandmarkStorage lm; private EncodingManager encodingManager; @@ -63,6 +66,8 @@ public void init() { dir = new RAMDirectory(); encoder = FlagEncoders.createCar(new PMap("turn_costs=true")); encodingManager = new EncodingManager.Builder().add(encoder).add(Subnetwork.create("car")).build(); + accessEnc = encoder.getAccessEnc(); + speedEnc = encoder.getAverageSpeedEnc(); graph = new BaseGraph.Builder(encodingManager) .setDir(dir) .create(); @@ -115,7 +120,6 @@ public void lm_problem_to_node_of_fallback_approximator(Algo algo) { // \ | | // 3 | // 2 --<---- - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); NodeAccess na = graph.getNodeAccess(); na.setNode(0, 49.405150, 9.709054); na.setNode(1, 49.403705, 9.700517); @@ -123,13 +127,13 @@ public void lm_problem_to_node_of_fallback_approximator(Algo algo) { na.setNode(3, 49.403009, 9.708364); na.setNode(4, 49.409021, 9.703622); // 30s - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 3).setDistance(1000)).set(speedEnc, 120); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 2).setDistance(1000)).set(speedEnc, 120); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 3).setDistance(1000)).set(speedEnc, 120); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 2).setDistance(1000)).set(speedEnc, 120); // 360s - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3).setDistance(1000)).set(speedEnc, 10); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1000)).set(speedEnc, 10); // 80s - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1000)).set(speedEnc, 45); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(1000)).set(speedEnc, 45); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1000)).set(speedEnc, 45); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(1000)).set(speedEnc, 45); preProcessGraph(); int source = 0; @@ -154,7 +158,6 @@ public void lm_issue2(Algo algo) { // \ / // ->- NodeAccess na = graph.getNodeAccess(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); na.setNode(0, 49.406987, 9.709767); na.setNode(1, 49.403612, 9.702953); na.setNode(2, 49.409755, 9.706517); @@ -165,13 +168,13 @@ public void lm_issue2(Algo algo) { na.setNode(7, 49.406965, 9.702660); na.setNode(8, 49.405227, 9.702863); na.setNode(9, 49.409411, 9.709085); - GHUtility.setSpeed(112, true, true, encoder, graph.edge(0, 1).setDistance(623.197000)); - GHUtility.setSpeed(13, true, true, encoder, graph.edge(5, 1).setDistance(741.414000)); - GHUtility.setSpeed(35, true, true, encoder, graph.edge(9, 4).setDistance(1140.835000)); - GHUtility.setSpeed(18, true, true, encoder, graph.edge(5, 6).setDistance(670.689000)); - GHUtility.setSpeed(88, true, false, encoder, graph.edge(5, 9).setDistance(80.731000)); - GHUtility.setSpeed(82, true, true, encoder, graph.edge(0, 9).setDistance(273.948000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 0).setDistance(956.552000)); + GHUtility.setSpeed(112, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(623.197000)); + GHUtility.setSpeed(13, true, true, accessEnc, speedEnc, graph.edge(5, 1).setDistance(741.414000)); + GHUtility.setSpeed(35, true, true, accessEnc, speedEnc, graph.edge(9, 4).setDistance(1140.835000)); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(670.689000)); + GHUtility.setSpeed(88, true, false, accessEnc, speedEnc, graph.edge(5, 9).setDistance(80.731000)); + GHUtility.setSpeed(82, true, true, accessEnc, speedEnc, graph.edge(0, 9).setDistance(273.948000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 0).setDistance(956.552000)); preProcessGraph(); int source = 5; diff --git a/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java b/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java index 62bd1d9eb74..389df1ebb66 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java @@ -19,6 +19,7 @@ import com.graphhopper.routing.RoutingAlgorithmTest; import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.subnetwork.PrepareRoutingSubnetworks; import com.graphhopper.routing.util.AreaIndex; @@ -51,6 +52,8 @@ public class LandmarkStorageTest { private FlagEncoder encoder; private BooleanEncodedValue subnetworkEnc; private EncodingManager encodingManager; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; @BeforeEach public void setUp() { @@ -58,6 +61,8 @@ public void setUp() { subnetworkEnc = Subnetwork.create("car"); encodingManager = new EncodingManager.Builder().add(encoder).add(subnetworkEnc).build(); graph = new BaseGraph.Builder(encodingManager).create(); + accessEnc = encoder.getAccessEnc(); + speedEnc = encoder.getAverageSpeedEnc(); } @AfterEach @@ -90,7 +95,7 @@ public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { @Test public void testSetGetWeight() { - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(40.1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(40.1)); Directory dir = new RAMDirectory(); LandmarkStorage lms = new LandmarkStorage(graph, encodingManager, dir, new LMConfig("c1", new FastestWeighting(encoder)), 4). setMaximumWeight(LandmarkStorage.PRECISION); @@ -116,12 +121,12 @@ public void testSetGetWeight() { @Test public void testWithSubnetworks() { // 0-1-2..4-5->6 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10.1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10.2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10.1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10.2)); - graph.edge(2, 4).set(encoder.getAccessEnc(), false, false); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(10.5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 6).setDistance(10.6)); + graph.edge(2, 4).set(accessEnc, false, false); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(10.5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(10.6)); Weighting weighting = new FastestWeighting(encoder); // 1 means => 2 allowed edge keys => excludes the node 6 @@ -139,11 +144,11 @@ public void testWithSubnetworks() { @Test public void testWithStronglyConnectedComponent() { // 0 - 1 - 2 = 3 - 4 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10.1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(10.2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(10.3)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(3, 2).setDistance(10.2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(10.4)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10.1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10.2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10.3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(10.2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10.4)); Weighting weighting = new FastestWeighting(encoder); @@ -169,12 +174,12 @@ private void subnetworkRemoval(Weighting weighting, int minNodeSize) { public void testWithOnewaySubnetworks() { // 0 -- 1 -> 2 -> 3 // 4 -- 5 ->/ - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(10.1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(10.2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 3).setDistance(10.3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10.1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10.2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10.3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(10.5)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(5, 2).setDistance(10.2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(10.5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 2).setDistance(10.2)); Weighting weighting = new FastestWeighting(encoder); // 1 allowed node => 2 allowed edge keys (exclude 2 and 3 because they are separate too small oneway subnetworks) @@ -192,9 +197,9 @@ public void testWithOnewaySubnetworks() { @Test public void testWeightingConsistence1() { // create an indifferent problem: shortest weighting can pass the speed==0 edge but fastest cannot (?) - graph.edge(0, 1).setDistance(10.1).set(encoder.getAccessEnc(), true, true); - GHUtility.setSpeed(30, true, true, encoder, graph.edge(1, 2).setDistance(10)); - graph.edge(2, 3).setDistance(10.1).set(encoder.getAccessEnc(), true, true); + graph.edge(0, 1).setDistance(10.1).set(accessEnc, true, true); + GHUtility.setSpeed(30, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); + graph.edge(2, 3).setDistance(10.1).set(accessEnc, true, true); LandmarkStorage storage = new LandmarkStorage(graph, encodingManager, new RAMDirectory(), new LMConfig("car", new FastestWeighting(encoder)), 2); storage.setMinimumNodes(2); @@ -206,9 +211,9 @@ public void testWeightingConsistence1() { @Test public void testWeightingConsistence2() { - GHUtility.setSpeed(30, true, true, encoder, graph.edge(0, 1).setDistance(10)); - graph.edge(2, 3).setDistance(10.1).set(encoder.getAccessEnc(), true, true); - GHUtility.setSpeed(30, true, true, encoder, graph.edge(2, 3).setDistance(10)); + GHUtility.setSpeed(30, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); + graph.edge(2, 3).setDistance(10.1).set(accessEnc, true, true); + GHUtility.setSpeed(30, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10)); LandmarkStorage storage = new LandmarkStorage(graph, encodingManager, new RAMDirectory(), new LMConfig("car", new FastestWeighting(encoder)), 2); storage.setMinimumNodes(2); diff --git a/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java b/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java index b9df8f81a32..e0238d0d8f4 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java @@ -25,7 +25,10 @@ import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.querygraph.QueryGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.BaseGraph; @@ -184,8 +187,8 @@ public void testLandmarkStorageAndRouting() { @Test public void testStoreAndLoad() { - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(80_000)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(80_000)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(80_000)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(80_000)); String fileStr = "./target/tmp-lm"; Helper.removeDir(new File(fileStr)); diff --git a/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java b/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java index 57ec089b0f1..6ed17223ab6 100644 --- a/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java @@ -52,12 +52,16 @@ public class QueryGraphTest { private EncodingManager encodingManager; private FlagEncoder encoder; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; private BaseGraph g; @BeforeEach public void setUp() { encoder = FlagEncoders.createCar(); encodingManager = EncodingManager.create(encoder); + accessEnc = encoder.getAccessEnc(); + speedEnc = encoder.getAverageSpeedEnc(); g = new BaseGraph.Builder(encodingManager).create(); } @@ -76,8 +80,8 @@ void initGraph(Graph g) { na.setNode(0, 1, 0); na.setNode(1, 1, 2.5); na.setNode(2, 0, 0); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 2).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(10)). + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)). setWayGeometry(Helper.createPointList(1.5, 1, 1.5, 1.5)); } @@ -157,8 +161,8 @@ public void testFillVirtualEdges() { na.setNode(1, 1, 2.5); na.setNode(2, 0, 0); na.setNode(3, 0, 1); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 2).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(10)).setWayGeometry(Helper.createPointList(1.5, 1, 1.5, 1.5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)).setWayGeometry(Helper.createPointList(1.5, 1, 1.5, 1.5)); g.edge(1, 3); final int baseNode = 1; @@ -238,7 +242,7 @@ public void testOneWay() { NodeAccess na = g.getNodeAccess(); na.setNode(0, 0, 0); na.setNode(1, 0, 1); - GHUtility.setSpeed(60, true, false, encoder, g.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)); EdgeIteratorState edge = GHUtility.getEdge(g, 0, 1); Snap res1 = createLocationResult(0.1, 0.1, edge, 0, EDGE); @@ -301,10 +305,10 @@ public void testLoopStreet_Issue151() { // | | // x--- // - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 3).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(3, 4).setDistance(10)); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 3).setDistance(20)).setWayGeometry(Helper.createPointList(-0.001, 0.001, -0.001, 0.002)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 3).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(10)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 3).setDistance(20)).setWayGeometry(Helper.createPointList(-0.001, 0.001, -0.001, 0.002)); updateDistancesFor(g, 0, 0, 0); updateDistancesFor(g, 1, 0, 0.001); updateDistancesFor(g, 3, 0, 0.002); @@ -333,9 +337,9 @@ public void testOneWayLoop_Issue162() { NodeAccess na = g.getNodeAccess(); na.setNode(0, 0, 0); na.setNode(1, 0, -0.001); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(10)); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue avSpeedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)); + BooleanEncodedValue accessEnc = this.accessEnc; + DecimalEncodedValue avSpeedEnc = speedEnc; // in the case of identical nodes the wayGeometry defines the direction! EdgeIteratorState edge = g.edge(0, 0). setDistance(100). @@ -451,7 +455,7 @@ public void testIteration_Issue163() { */ g.getNodeAccess().setNode(nodeA, 1, 0); g.getNodeAccess().setNode(nodeB, 1, 10); - GHUtility.setSpeed(60, true, false, encoder, g.edge(nodeA, nodeB).setDistance(10)). + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(nodeA, nodeB).setDistance(10)). setWayGeometry(Helper.createPointList(1.5, 3, 1.5, 7)); // assert the behavior for classic edgeIterator @@ -505,8 +509,8 @@ public void testTurnCostsProperlyPropagated_Issue282() { na.setNode(1, .00, .01); na.setNode(2, .01, .01); - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder, graphWithTurnCosts.edge(0, 1).setDistance(10)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder, graphWithTurnCosts.edge(2, 1).setDistance(10)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graphWithTurnCosts.edge(0, 1).setDistance(10)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graphWithTurnCosts.edge(2, 1).setDistance(10)); Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, graphWithTurnCosts.getTurnCostStorage())); @@ -555,7 +559,7 @@ public void testEnforceHeading() { NodeAccess na = g.getNodeAccess(); na.setNode(0, 0, 0); na.setNode(1, 0, 2); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(10)). + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)). setWayGeometry(Helper.createPointList(2, 0, 2, 2)); EdgeIteratorState edge = GHUtility.getEdge(g, 0, 1); @@ -623,7 +627,7 @@ public void testUnfavoredEdgeDirections() { // 2 na.setNode(0, 0, 0); na.setNode(1, 0, 2); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(10)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)); Snap snap = fakeEdgeSnap(edge, 0, 1, 0); QueryGraph queryGraph = QueryGraph.create(g, snap); @@ -653,7 +657,7 @@ public void testUnfavorVirtualEdgePair() { NodeAccess na = g.getNodeAccess(); na.setNode(0, 0, 0); na.setNode(1, 0, 2); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(10)). + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)). setWayGeometry(Helper.createPointList(2, 0, 2, 2)); EdgeIteratorState edge = GHUtility.getEdge(g, 0, 1); @@ -712,12 +716,12 @@ public void testWayGeometry_edge() { NodeAccess na = g.getNodeAccess(); na.setNode(0, 0, 0); na.setNode(1, 0.3, 0.3); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(10)). + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)). setWayGeometry(Helper.createPointList(0.1, 0.1, 0.2, 0.2)); LocationIndexTree locationIndex = new LocationIndexTree(g, new RAMDirectory()); locationIndex.prepareIndex(); - Snap snap = locationIndex.findClosest(0.15, 0.15, AccessFilter.allEdges(encoder.getAccessEnc())); + Snap snap = locationIndex.findClosest(0.15, 0.15, AccessFilter.allEdges(accessEnc)); assertTrue(snap.isValid()); assertEquals(EDGE, snap.getSnappedPosition(), "this test was supposed to test the Position.EDGE case"); QueryGraph queryGraph = lookup(snap); @@ -754,12 +758,12 @@ public void testWayGeometry_pillar() { NodeAccess na = g.getNodeAccess(); na.setNode(0, 0, 0); na.setNode(1, 0.5, 0.1); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(10)). + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)). setWayGeometry(Helper.createPointList(0.1, 0.1, 0.2, 0.2)); LocationIndexTree locationIndex = new LocationIndexTree(g, new RAMDirectory()); locationIndex.prepareIndex(); - Snap snap = locationIndex.findClosest(0.2, 0.21, AccessFilter.allEdges(encoder.getAccessEnc())); + Snap snap = locationIndex.findClosest(0.2, 0.21, AccessFilter.allEdges(accessEnc)); assertTrue(snap.isValid()); assertEquals(PILLAR, snap.getSnappedPosition(), "this test was supposed to test the Position.PILLAR case"); QueryGraph queryGraph = lookup(snap); @@ -800,7 +804,7 @@ public void testVirtualEdgeDistance() { dist += distCalc.calcDist(0, 0, 1, 0); dist += distCalc.calcDist(1, 0, 1, 1); dist += distCalc.calcDist(1, 1, 0, 1); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(dist)). + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(dist)). setWayGeometry(Helper.createPointList(1, 0, 1, 1)); LocationIndexTree index = new LocationIndexTree(g, new RAMDirectory()); index.prepareIndex(); @@ -831,7 +835,7 @@ public void testVirtualEdgeIds() { na.setNode(0, 50.00, 10.10); na.setNode(1, 50.00, 10.20); double dist = DistanceCalcEarth.DIST_EARTH.calcDist(na.getLat(0), na.getLon(0), na.getLat(1), na.getLon(1)); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(dist)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(0, 1).setDistance(dist)); edge.set(speedEnc, 50); edge.setReverse(speedEnc, 100); @@ -906,7 +910,7 @@ public void testVirtualEdgeIds_reverse() { na.setNode(1, 50.00, 10.20); double dist = DistanceCalcEarth.DIST_EARTH.calcDist(na.getLat(0), na.getLon(0), na.getLat(1), na.getLon(1)); // this time we store the edge the other way - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 0).setDistance(dist)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(1, 0).setDistance(dist)); edge.set(speedEnc, 100, 50); // query graph diff --git a/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java b/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java index 714c0668250..6c0dedfec8c 100644 --- a/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java +++ b/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java @@ -110,8 +110,8 @@ public void testPrepareSubnetworks_twoVehicles() { // first we only block the middle edge for cars. this way a subnetwork should be created but only for car EdgeIteratorState edge = GHUtility.getEdge(g, 3, 4); - GHUtility.setSpeed(10, false, false, carEncoder, edge); - GHUtility.setSpeed(5, true, true, bikeEncoder, edge); + GHUtility.setSpeed(10, false, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), edge); + GHUtility.setSpeed(5, true, true, bikeEncoder.getAccessEnc(), bikeEncoder.getAverageSpeedEnc(), edge); List prepareJobs = Arrays.asList( createJob(em, carEncoder, NO_TURN_COST_PROVIDER), createJob(em, bikeEncoder, NO_TURN_COST_PROVIDER) @@ -125,8 +125,8 @@ public void testPrepareSubnetworks_twoVehicles() { // now we block the edge for both vehicles -> there should be a subnetwork for both vehicles g = createSubnetworkTestStorage(em); edge = GHUtility.getEdge(g, 3, 4); - GHUtility.setSpeed(10, false, false, carEncoder, edge); - GHUtility.setSpeed(5, false, false, bikeEncoder, edge); + GHUtility.setSpeed(10, false, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), edge); + GHUtility.setSpeed(5, false, false, bikeEncoder.getAccessEnc(), bikeEncoder.getAverageSpeedEnc(), edge); instance = new PrepareRoutingSubnetworks(g, prepareJobs); instance.setMinNetworkSize(5); assertEquals(6, instance.doWork()); @@ -150,7 +150,7 @@ public void testPrepareSubnetwork_withTurnCosts() { // if we open the edge it won't be a subnetwork anymore g = createSubnetworkTestStorage(em); EdgeIteratorState edge = GHUtility.getEdge(g, 3, 4); - GHUtility.setSpeed(10, true, true, encoder, edge); + GHUtility.setSpeed(10, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge); instance = new PrepareRoutingSubnetworks(g, Collections.singletonList( createJob(em, encoder, new DefaultTurnCostProvider(encoder, g.getTurnCostStorage(), 0)))); instance.setMinNetworkSize(4); @@ -161,7 +161,7 @@ public void testPrepareSubnetwork_withTurnCosts() { // subnetwork again g = createSubnetworkTestStorage(em); edge = GHUtility.getEdge(g, 3, 4); - GHUtility.setSpeed(10, true, true, encoder, edge); + GHUtility.setSpeed(10, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge); DecimalEncodedValue turnCostEnc = em.getDecimalEncodedValue(TurnCost.key(encoder.toString())); g.getTurnCostStorage().set(turnCostEnc, 0, 4, 7, 1); g.getTurnCostStorage().set(turnCostEnc, 0, 4, 9, 1); @@ -179,17 +179,19 @@ private BaseGraph createSubnetworkTestStorageWithOneWays(EncodingManager em, Fla fail("Warning: This method only sets access/speed for a single encoder, but the given encoding manager has multiple encoders"); BaseGraph g = new BaseGraph.Builder(em).create(); // 0 - 1 - 2 - 3 - 4 <- 5 - 6 - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(5, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(5, 6).setDistance(1)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(5, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 6).setDistance(1)); // 7 -> 8 - 9 - 10 - GHUtility.setSpeed(60, true, false, encoder, g.edge(7, 8).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(8, 9).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(9, 10).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(7, 8).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 9).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(1)); return g; } @@ -230,11 +232,13 @@ public void testNodeOrderingRegression() { EncodingManager em = createEncodingManager("car"); BaseGraph g = new BaseGraph.Builder(em).create(); FlagEncoder encoder = em.fetchEdgeEncoders().iterator().next(); - GHUtility.setSpeed(60, true, false, encoder, g.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(2, 0).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(4, 5).setDistance(1)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(2, 0).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(1)); PrepareRoutingSubnetworks.PrepareJob job = createJob(em, encoder, NO_TURN_COST_PROVIDER); PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(job)). diff --git a/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java index 1e7434e6de9..f917787369d 100644 --- a/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java @@ -20,6 +20,8 @@ import com.carrotsearch.hppc.IntHashSet; import com.carrotsearch.hppc.IntSet; import com.graphhopper.routing.ch.PrepareEncoder; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.storage.*; @@ -30,6 +32,8 @@ public class AccessFilterTest { private final FlagEncoder encoder = FlagEncoders.createCar(); + private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + private final DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); private final EncodingManager encodingManager = EncodingManager.create(encoder); private final BaseGraph graph = new BaseGraph.Builder(encodingManager) .withTurnCosts(true) @@ -40,9 +44,9 @@ public void testAccept_fwdLoopShortcut_acceptedByInExplorer() { // 0-1 // \| // 2 - GHUtility.setSpeed(60, true, false, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(1, 2).setDistance(2)); - GHUtility.setSpeed(60, true, false, encoder, graph.edge(2, 0).setDistance(3)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(2)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 0).setDistance(3)); graph.freeze(); // add loop shortcut in 'fwd' direction CHConfig chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage()))); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java index f5bac2c8288..c5a3fab4544 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java @@ -1,6 +1,7 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.OSMTurnRelation; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.util.EncodingManager; @@ -74,15 +75,17 @@ public long getOsmIdOfInternalEdge(int edgeId) { // | | | // 5--6--7 private static void initGraph(BaseGraph graph, FlagEncoder encoder) { - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 5).setDistance(0.5)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 7).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(1)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 5).setDistance(0.5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 7).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(1)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/weighting/BlockAreaWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/BlockAreaWeightingTest.java index 0c1330efadb..410f129e1ba 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/BlockAreaWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/BlockAreaWeightingTest.java @@ -33,7 +33,7 @@ public void setUp() { em = EncodingManager.create(encoder); graph = new BaseGraph.Builder(em).create(); // 0-1 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(1)); updateDistancesFor(graph, 0, 0.00, 0.00); updateDistancesFor(graph, 1, 0.01, 0.01); } diff --git a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java index 962e5aa3749..c00d690d110 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java @@ -108,8 +108,8 @@ public void testTime() { public void calcWeightAndTime_withTurnCosts() { BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage())); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(100)); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(100)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(100)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(100)); // turn costs are given in seconds setTurnCost(graph, 0, 1, 2, 5); assertEquals(6 + 5, GHUtility.calcWeightWithTurnWeight(weighting, edge, false, 0), 1.e-6); @@ -120,7 +120,7 @@ public void calcWeightAndTime_withTurnCosts() { public void calcWeightAndTime_uTurnCosts() { BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage(), 40)); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(100)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(100)); assertEquals(6 + 40, GHUtility.calcWeightWithTurnWeight(weighting, edge, false, 0), 1.e-6); assertEquals((6 + 40) * 1000, GHUtility.calcMillisWithTurnMillis(weighting, edge, false, 0), 1.e-6); } @@ -129,8 +129,8 @@ public void calcWeightAndTime_uTurnCosts() { public void calcWeightAndTime_withTurnCosts_shortest() { BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); Weighting weighting = new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage())); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(100)); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(100)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(100)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(100)); // turn costs are given in seconds setTurnCost(graph, 0, 1, 2, 5); // todo: for the shortest weighting turn costs cannot be interpreted as seconds? at least when they are added diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index 990411127f7..2a1875366ad 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -57,11 +57,11 @@ public void speedOnly() { @Test public void withPriority() { // 25km/h -> 144s per km, 50km/h -> 72s per km, 100km/h -> 36s per km - EdgeIteratorState slow = GHUtility.setSpeed(25, true, true, carFE, graph.edge(0, 1).setDistance(1000)). + EdgeIteratorState slow = GHUtility.setSpeed(25, true, true, accessEnc, avSpeedEnc, graph.edge(0, 1).setDistance(1000)). set(roadClassEnc, SECONDARY); - EdgeIteratorState medium = GHUtility.setSpeed(50, true, true, carFE, graph.edge(0, 1).setDistance(1000)). + EdgeIteratorState medium = GHUtility.setSpeed(50, true, true, accessEnc, avSpeedEnc, graph.edge(0, 1).setDistance(1000)). set(roadClassEnc, SECONDARY); - EdgeIteratorState fast = GHUtility.setSpeed(100, true, true, carFE, graph.edge(0, 1).setDistance(1000)). + EdgeIteratorState fast = GHUtility.setSpeed(100, true, true, accessEnc, avSpeedEnc, graph.edge(0, 1).setDistance(1000)). set(roadClassEnc, SECONDARY); // without priority costs fastest weighting is the same as custom weighting @@ -85,7 +85,6 @@ public void withPriority() { @Test public void withDistanceInfluence() { - BooleanEncodedValue accessEnc = carFE.getAccessEnc(); EdgeIteratorState edge = graph.edge(0, 1).setDistance(10_000).set(avSpeedEnc, 50).set(accessEnc, true, true); assertEquals(720, createWeighting(new CustomModel().setDistanceInfluence(0)).calcEdgeWeight(edge, false), .1); assertEquals(720_000, createWeighting(new CustomModel().setDistanceInfluence(0)).calcEdgeMillis(edge, false), .1); @@ -105,7 +104,7 @@ public void withDistanceInfluence() { @Test public void testSpeedFactorBooleanEV() { - EdgeIteratorState edge = GHUtility.setSpeed(15, true, true, carFE, graph.edge(0, 1).setDistance(10)); + EdgeIteratorState edge = GHUtility.setSpeed(15, true, true, accessEnc, avSpeedEnc, graph.edge(0, 1).setDistance(10)); CustomModel vehicleModel = new CustomModel(); assertEquals(3.1, createWeighting(vehicleModel).calcEdgeWeight(edge, false), 0.01); // here we increase weight for edges that are road class links @@ -121,10 +120,8 @@ public void testBoolean() { carFE = FlagEncoders.createCar(); BooleanEncodedValue specialEnc = new SimpleBooleanEncodedValue("special", true); encodingManager = new EncodingManager.Builder().add(carFE).add(specialEnc).build(); - avSpeedEnc = carFE.getAverageSpeedEnc(); graph = new BaseGraph.Builder(encodingManager).create(); - BooleanEncodedValue accessEnc = carFE.getAccessEnc(); EdgeIteratorState edge = graph.edge(0, 1).set(accessEnc, true).setReverse(accessEnc, true). set(avSpeedEnc, 15).set(specialEnc, false).setReverse(specialEnc, true).setDistance(10); diff --git a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java index 924c8ca4b9c..83cfd305a9a 100644 --- a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java +++ b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java @@ -27,8 +27,6 @@ import org.junit.jupiter.api.Test; import java.io.File; -import java.util.ArrayList; -import java.util.List; import static com.graphhopper.routing.util.EncodingManager.getKey; import static org.junit.jupiter.api.Assertions.*; @@ -659,10 +657,9 @@ public void testEdgeKVStorage() { @Test public void test8AndMoreBytesForEdgeFlags() { - List list = new ArrayList<>(); - list.add(FlagEncoders.createCar(new PMap("name=car0|speed_bits=29|speed_factor=0.001"))); - list.add(FlagEncoders.createCar(new PMap("speed_bits=29|speed_factor=0.001"))); - EncodingManager manager = EncodingManager.create(list); + FlagEncoder car0 = FlagEncoders.createCar(new PMap("name=car0|speed_bits=29|speed_factor=0.001")); + FlagEncoder car = FlagEncoders.createCar(new PMap("speed_bits=29|speed_factor=0.001")); + EncodingManager manager = EncodingManager.create(car0, car); graph = new BaseGraph.Builder(manager).create(); EdgeIteratorState edge = graph.edge(0, 1); @@ -681,14 +678,14 @@ public void test8AndMoreBytesForEdgeFlags() { BooleanEncodedValue access1Enc = manager.getBooleanEncodedValue(getKey("car", "access")); edge = graph.edge(0, 1); - GHUtility.setSpeed(99.123, true, true, list.get(0), edge); + GHUtility.setSpeed(99.123, true, true, access0Enc, avSpeed0Enc, edge); assertEquals(99.123, edge.get(avSpeed0Enc), 1e-3); EdgeIteratorState edgeIter = GHUtility.getEdge(graph, 1, 0); assertEquals(99.123, edgeIter.get(avSpeed0Enc), 1e-3); assertTrue(edgeIter.get(access0Enc)); assertTrue(edgeIter.getReverse(access0Enc)); edge = graph.edge(2, 3); - GHUtility.setSpeed(44.123, true, false, list.get(1), edge); + GHUtility.setSpeed(44.123, true, false, access1Enc, avSpeed1Enc, edge); assertEquals(44.123, edge.get(avSpeed1Enc), 1e-3); edgeIter = GHUtility.getEdge(graph, 3, 2); @@ -697,11 +694,11 @@ public void test8AndMoreBytesForEdgeFlags() { assertFalse(edgeIter.get(access1Enc)); assertTrue(edgeIter.getReverse(access1Enc)); - list.clear(); - list.add(FlagEncoders.createCar(new PMap("name=car0|speed_bits=29|speed_factor=0.001"))); - list.add(FlagEncoders.createCar(new PMap("speed_bits=29|speed_factor=0.001"))); - list.add(FlagEncoders.createCar(new PMap("name=car2|speed_bits=30|speed_factor=0.001"))); - manager = EncodingManager.create(list); + manager = EncodingManager.create( + FlagEncoders.createCar(new PMap("name=car0|speed_bits=29|speed_factor=0.001")), + FlagEncoders.createCar(new PMap("speed_bits=29|speed_factor=0.001")), + FlagEncoders.createCar(new PMap("name=car2|speed_bits=30|speed_factor=0.001")) + ); graph = new BaseGraph.Builder(manager).create(); edgeIter = graph.edge(0, 1).set(access0Enc, true, false); assertTrue(edgeIter.get(access0Enc)); diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java index b6292a64473..939c9d07449 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java @@ -79,7 +79,7 @@ public void testSave_and_fileFormat() { assertEquals("named street1", graph.getEdgeIteratorState(iter1.getEdge(), iter1.getAdjNode()).getName()); assertEquals("named street2", graph.getEdgeIteratorState(iter2.getEdge(), iter2.getAdjNode()).getName()); - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(3, 4).setDistance(123)). + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 4).setDistance(123)). setWayGeometry(Helper.createPointList3D(4.4, 5.5, 0, 6.6, 7.7, 0)); checkGraph(graph); } @@ -200,9 +200,9 @@ public void testDecoupledEdgeIteratorStates() { Graph graph = storage.getBaseGraph(); IntsRef ref = encodingManager.createEdgeFlags(); ref.ints[0] = 12; - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(1, 2).setDistance(10)).setFlags(ref); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(10)).setFlags(ref); ref.ints[0] = 13; - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(1, 3).setDistance(10)).setFlags(ref); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 3).setDistance(10)).setFlags(ref); EdgeIterator iter = graph.createEdgeExplorer().setBaseNode(1); assertTrue(iter.next()); @@ -219,7 +219,7 @@ public void testDecoupledEdgeIteratorStates() { @Test public void testEdgeKey() { BaseGraph g = new BaseGraph.Builder(encodingManager).create(); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(0, 1).setDistance(10)); // storage direction assertEdge(g.getEdgeIteratorState(0, Integer.MIN_VALUE), 0, 1, false, 0, 0); // reverse direction @@ -233,7 +233,7 @@ public void testEdgeKey() { @Test public void testEdgeKey_loop() { BaseGraph g = new BaseGraph.Builder(encodingManager).create(); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 0).setDistance(10)); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(0, 0).setDistance(10)); // storage direction assertEdge(g.getEdgeIteratorState(0, Integer.MIN_VALUE), 0, 0, false, 0, 0); // reverse direction cannot be retrieved, we get forward direction anyway diff --git a/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java b/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java index 675ea269d38..116a2474e9b 100644 --- a/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java +++ b/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java @@ -17,6 +17,8 @@ */ package com.graphhopper.storage; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.*; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.LocationIndexTree; @@ -43,11 +45,13 @@ public void testParseStringHints() { // 0-1-2 // | | // 3-4 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 3).setDistance(1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 4).setDistance(1)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 3).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 4).setDistance(1)); updateDistancesFor(graph, 0, 0.01, 0.00); updateDistancesFor(graph, 1, 0.01, 0.01); updateDistancesFor(graph, 2, 0.01, 0.02); @@ -58,12 +62,12 @@ public void testParseStringHints() { .prepareIndex(); GraphEdgeIdFinder graphFinder = new GraphEdgeIdFinder(graph, locationIndex); - GraphEdgeIdFinder.BlockArea blockArea = graphFinder.parseBlockArea("0.01,0.005,1", AccessFilter.allEdges(encoder.getAccessEnc()), 1000 * 1000); + GraphEdgeIdFinder.BlockArea blockArea = graphFinder.parseBlockArea("0.01,0.005,1", AccessFilter.allEdges(accessEnc), 1000 * 1000); assertEquals("[0]", blockArea.toString(0)); // big area => no edgeIds are collected up-front graphFinder = new GraphEdgeIdFinder(graph, locationIndex); - blockArea = graphFinder.parseBlockArea("0,0,1000", AccessFilter.allEdges(encoder.getAccessEnc()), 1000 * 1000); + blockArea = graphFinder.parseBlockArea("0,0,1000", AccessFilter.allEdges(accessEnc), 1000 * 1000); assertFalse(blockArea.hasCachedEdgeIds(0)); } @@ -78,19 +82,21 @@ public void testBlockAreasWithPolygon() { // 04-05-06-07 // | | // 08-09-10-11 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1).setDistance(1)); // 0 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2).setDistance(1)); // 1 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3).setDistance(1)); // 2 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 4).setDistance(1)); // 3 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 5).setDistance(1)); // 4 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 5).setDistance(1)); // 5 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6).setDistance(1)); // 6 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(6, 7).setDistance(1)); // 7 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(4, 8).setDistance(1)); // 8 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 9).setDistance(1)); // 9 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(8, 9).setDistance(1)); // 10 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(9, 10).setDistance(1)); // 11 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(10, 11).setDistance(1)); // 12 + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); // 0 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); // 1 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); // 2 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 4).setDistance(1)); // 3 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 5).setDistance(1)); // 4 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(1)); // 5 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(1)); // 6 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 7).setDistance(1)); // 7 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 8).setDistance(1)); // 8 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 9).setDistance(1)); // 9 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 9).setDistance(1)); // 10 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(9, 10).setDistance(1)); // 11 + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(10, 11).setDistance(1)); // 12 updateDistancesFor(graph, 0, 2, 0); updateDistancesFor(graph, 1, 2, 1); @@ -111,16 +117,16 @@ public void testBlockAreasWithPolygon() { GraphEdgeIdFinder graphFinder = new GraphEdgeIdFinder(graph, locationIndex); // big value => the polygon is small => force edgeId optimization double area = 500_000L * 500_000L; - GraphEdgeIdFinder.BlockArea blockArea = graphFinder.parseBlockArea("2.1,1, -1.1,2, 2,3", AccessFilter.allEdges(encoder.getAccessEnc()), area); + GraphEdgeIdFinder.BlockArea blockArea = graphFinder.parseBlockArea("2.1,1, -1.1,2, 2,3", AccessFilter.allEdges(accessEnc), area); assertEquals("[1, 2, 6, 7, 11, 12]", blockArea.toString(0)); assertEdges(graph, "[1, 2, 6, 7, 11, 12]", blockArea); // small value => same polygon is now "large" => do not pre-calculate edgeId set => check only geometries - blockArea = graphFinder.parseBlockArea("2.1,1, 0.9,3, 0.9,2, -0.3,0", AccessFilter.allEdges(encoder.getAccessEnc()), 1000 * 1000); + blockArea = graphFinder.parseBlockArea("2.1,1, 0.9,3, 0.9,2, -0.3,0", AccessFilter.allEdges(accessEnc), 1000 * 1000); assertFalse(blockArea.hasCachedEdgeIds(0)); assertEdges(graph, "[0, 1, 4, 5, 6, 7, 9, 10]", blockArea); - blockArea = graphFinder.parseBlockArea("1.5,3,100000", AccessFilter.allEdges(encoder.getAccessEnc()), area); + blockArea = graphFinder.parseBlockArea("1.5,3,100000", AccessFilter.allEdges(accessEnc), area); assertEquals("[2, 7]", blockArea.toString(0)); assertEdges(graph, "[2, 7]", blockArea); } diff --git a/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java b/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java index ab318cd48a8..90393d2f1e2 100644 --- a/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java +++ b/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java @@ -19,6 +19,7 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.*; import com.graphhopper.storage.*; import com.graphhopper.util.*; @@ -96,13 +97,15 @@ Graph createTestGraph(EncodingManager em) { na.setNode(2, -1, -1); na.setNode(3, -0.4, 0.9); na.setNode(4, -0.6, 1.6); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 4)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 4)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 4)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4)); return graph; } @@ -156,9 +159,11 @@ public void testMoreReal() { na.setNode(2, 51.2, 9.4); na.setNode(3, 49, 10); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 0)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 2)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 3)).setWayGeometry(Helper.createPointList(51.21, 9.43)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 0)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 3)).setWayGeometry(Helper.createPointList(51.21, 9.43)); LocationIndex index = createIndexNoPrepare(graph, 500000).prepareIndex(); assertEquals(1, findClosestEdge(index, 51.2, 9.4)); } @@ -181,14 +186,16 @@ private Graph createTestGraphWithWayGeometry() { na.setNode(2, -1, -1); na.setNode(3, -0.4, 0.9); na.setNode(4, -0.6, 1.6); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 2)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2)); // insert A and B, without this we would get 0 for 0,0 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(0, 4)).setWayGeometry(Helper.createPointList(1, 1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 3)).setWayGeometry(Helper.createPointList(0, 0)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(2, 4)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(3, 4)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 4)).setWayGeometry(Helper.createPointList(1, 1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3)).setWayGeometry(Helper.createPointList(0, 0)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 4)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4)); return graph; } @@ -211,9 +218,9 @@ public void testFindingWayGeometry() { na.setNode(20, 52, 9); na.setNode(30, 51.2, 9.4); na.setNode(50, 49, 10); - GHUtility.setSpeed(60, true, true, encoder, g.edge(20, 50)).setWayGeometry(Helper.createPointList(51.25, 9.43)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(10, 20)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(20, 30)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(20, 50)).setWayGeometry(Helper.createPointList(51.25, 9.43)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(10, 20)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(20, 30)); LocationIndex index = createIndexNoPrepare(g, 2000).prepareIndex(); assertEquals(0, findClosestEdge(index, 51.25, 9.43)); @@ -350,10 +357,10 @@ public void testSearchWithFilter_issue318() { int index = lonIdx * 10 + latIdx; na.setNode(index, 0.01 * latIdx, 0.01 * lonIdx); if (latIdx < MAX - 1) - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(index, index + 1)); + GHUtility.setSpeed(60, true, true, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(index, index + 1)); if (lonIdx < MAX - 1) - GHUtility.setSpeed(60, true, true, carEncoder, graph.edge(index, index + 10)); + GHUtility.setSpeed(60, true, true, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(index, index + 10)); } } @@ -414,9 +421,9 @@ public void testCrossBoundaryNetwork_issue667() { // as last edges: create cross boundary edges // See #667 where the recommendation is to adjust the import and introduce two pillar nodes // where the connection is cross boundary and would be okay if ignored as real length is 0 - GHUtility.setSpeed(60, true, true, encoder, graph.edge(1, 2)).setWayGeometry(Helper.createPointList(0, 180, 0, -180)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2)).setWayGeometry(Helper.createPointList(0, 180, 0, -180)); // but this unit test succeeds even without this adjusted import: - GHUtility.setSpeed(60, true, true, encoder, graph.edge(5, 6)); + GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(5, 6)); LocationIndexTree index = createIndexNoPrepare(graph, 500); index.prepareIndex(); @@ -568,26 +575,28 @@ public BaseGraph createSampleGraph(EncodingManager encodingManager) { // => 17 locations FlagEncoder encoder = encodingManager.getEncoder("car"); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(a0, b1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(c2, b1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(c2, d3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(f5, b1)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(e4, f5)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(m12, d3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(e4, k10)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(f5, d3)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(f5, i8)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(f5, j9)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(k10, g6)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(j9, l11)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(i8, l11)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(i8, h7)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(k10, n13)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(k10, o14)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(l11, p15)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(m12, p15)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(q16, p15)); - GHUtility.setSpeed(60, true, true, encoder, graph.edge(q16, m12)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(a0, b1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(c2, b1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(c2, d3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(f5, b1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(e4, f5)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(m12, d3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(e4, k10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(f5, d3)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(f5, i8)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(f5, j9)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(k10, g6)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(j9, l11)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(i8, l11)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(i8, h7)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(k10, n13)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(k10, o14)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(l11, p15)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(m12, p15)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(q16, p15)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(q16, m12)); return graph; } diff --git a/core/src/test/java/com/graphhopper/util/GHUtilityTest.java b/core/src/test/java/com/graphhopper/util/GHUtilityTest.java index 489d89ab0e5..aed7727c678 100644 --- a/core/src/test/java/com/graphhopper/util/GHUtilityTest.java +++ b/core/src/test/java/com/graphhopper/util/GHUtilityTest.java @@ -18,6 +18,8 @@ package com.graphhopper.util; import com.graphhopper.coll.GHIntLongHashMap; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.AllEdgesIterator; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; @@ -58,12 +60,14 @@ Graph initUnsorted(Graph g, FlagEncoder encoder) { na.setNode(6, 2.3, 2.2); na.setNode(7, 5, 1.5); na.setNode(8, 4.6, 4); - GHUtility.setSpeed(60, true, true, encoder, g.edge(8, 2).setDistance(0.5)); - GHUtility.setSpeed(60, true, false, encoder, g.edge(7, 3).setDistance(2.1)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 0).setDistance(3.9)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(7, 5).setDistance(0.7)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 2).setDistance(1.9)); - GHUtility.setSpeed(60, true, true, encoder, g.edge(8, 1).setDistance(2.05)); + BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 2).setDistance(0.5)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(7, 3).setDistance(2.1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 0).setDistance(3.9)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 5).setDistance(0.7)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(1.9)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 1).setDistance(2.05)); return g; } @@ -116,8 +120,8 @@ public void testSortDirected() { na.setNode(0, 0, 1); na.setNode(1, 2.5, 2); na.setNode(2, 3.5, 3); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(0, 1).setDistance(1.1)); - GHUtility.setSpeed(60, true, false, carEncoder, g.edge(2, 1).setDistance(1.1)); + GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), g.edge(0, 1).setDistance(1.1)); + GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), g.edge(2, 1).setDistance(1.1)); GHUtility.sortDFS(g, createGraph()); } diff --git a/core/src/test/java/com/graphhopper/util/InstructionListTest.java b/core/src/test/java/com/graphhopper/util/InstructionListTest.java index 68be9c18bc8..9e4be7e6d14 100644 --- a/core/src/test/java/com/graphhopper/util/InstructionListTest.java +++ b/core/src/test/java/com/graphhopper/util/InstructionListTest.java @@ -22,6 +22,7 @@ import com.graphhopper.routing.Dijkstra; import com.graphhopper.routing.InstructionsFromEdges; import com.graphhopper.routing.Path; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.RoadClass; @@ -56,11 +57,15 @@ public class InstructionListTest { private final TraversalMode tMode = TraversalMode.NODE_BASED; private EncodingManager carManager; private FlagEncoder carEncoder; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; @BeforeEach public void setUp() { carEncoder = FlagEncoders.createCar(); carManager = EncodingManager.create(carEncoder); + accessEnc = carEncoder.getAccessEnc(); + speedEnc = carEncoder.getAverageSpeedEnc(); } private static List getTurnDescriptions(InstructionList instructionList) { @@ -95,27 +100,27 @@ Graph createTestGraph() { na.setNode(6, 1.0, 1.0); na.setNode(7, 1.0, 1.1); na.setNode(8, 1.0, 1.2); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 1).setDistance(10000)).setName("0-1"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 2).setDistance(11000)).setName("1-2"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setName("0-1"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setName("1-2"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(0, 3).setDistance(11000)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 4).setDistance(10000)).setName("1-4"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 5).setDistance(11000)).setName("5-2"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(11000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setName("1-4"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setName("5-2"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 6).setDistance(11000)).setName("3-6"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(4, 7).setDistance(10000)).setName("4-7"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(5, 8).setDistance(10000)).setName("5-8"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setName("3-6"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setName("4-7"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setName("5-8"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(6, 7).setDistance(11000)).setName("6-7"); - EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(7, 8).setDistance(10000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setName("6-7"); + EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(10000)); PointList list = new PointList(); list.add(1.0, 1.15); list.add(1.0, 1.16); iter.setWayGeometry(list); iter.setName("7-8"); // missing edge name - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(9, 10).setDistance(10000)); - EdgeIteratorState iter2 = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(8, 9).setDistance(20000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(10000)); + EdgeIteratorState iter2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 9).setDistance(20000)); list.clear(); list.add(1.0, 1.3); iter2.setName("8-9"); @@ -187,10 +192,10 @@ public void testWayList2() { na.setNode(3, 10.0, 10.08); na.setNode(4, 10.1, 10.10); na.setNode(5, 10.2, 10.13); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 4).setDistance(100)).setName("3-4"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(4, 5).setDistance(100)).setName("4-5"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setName("3-4"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setName("4-5"); - EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 4).setDistance(100)); + EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(100)); iter.setName("2-4"); PointList list = new PointList(); list.add(10.20, 10.05); @@ -226,10 +231,10 @@ public void testNoInstructionIfSameStreet() { na.setNode(3, 10.0, 10.05); na.setNode(4, 10.1, 10.10); na.setNode(5, 10.2, 10.15); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 4).setDistance(100)).setName("street"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(4, 5).setDistance(100)).setName("4-5"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setName("street"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setName("4-5"); - EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 4).setDistance(100)); + EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(100)); iter.setName("street"); PointList list = new PointList(); list.add(10.20, 10.05); @@ -260,9 +265,9 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp() { na.setNode(2, 51.73458, 9.225442); na.setNode(3, 51.734643, 9.22541); na.setNode(4, 51.734451, 9.225436); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 2).setDistance(10)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 3).setDistance(10)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 4).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(10)); FastestWeighting weighting = new FastestWeighting(carEncoder); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 3); @@ -289,9 +294,9 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp2() { na.setNode(2, 48.748577, 9.322152); na.setNode(3, 48.748776, 9.321889); na.setNode(4, 48.74847, 9.322299); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 2).setDistance(10)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 3).setDistance(10)); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 4).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(10)); FastestWeighting weighting = new FastestWeighting(carEncoder); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 3); @@ -321,9 +326,9 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp3() { na.setNode(3, 48.411610, 15.600409); na.setNode(4, 48.411322, 15.600459); - GHUtility.setSpeed(18, true, true, bike, g.edge(1, 2).setDistance(20)); - GHUtility.setSpeed(18, true, true, bike, g.edge(2, 3).setDistance(20)); - GHUtility.setSpeed(4, true, true, bike, g.edge(2, 4).setDistance(20)); + GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(1, 2).setDistance(20)); + GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20)); + GHUtility.setSpeed(4, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20)); g.edge(1, 2).set(rcEV, RoadClass.RESIDENTIAL).setName("pfarr"); g.edge(2, 3).set(rcEV, RoadClass.RESIDENTIAL).setName("pfarr"); @@ -359,9 +364,9 @@ public void testInstructionIfTurn() { na.setNode(3, 48.412614, 15.604872); na.setNode(4, 48.412148, 15.605543); - GHUtility.setSpeed(18, true, true, bike, g.edge(1, 2).setDistance(20)); - GHUtility.setSpeed(18, true, true, bike, g.edge(2, 3).setDistance(20)); - GHUtility.setSpeed(18, true, true, bike, g.edge(2, 4).setDistance(20)); + GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(1, 2).setDistance(20)); + GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20)); + GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20)); g.edge(1, 2).set(rcEV, RoadClass.RESIDENTIAL).setName("land"); g.edge(2, 3).set(rcEV, RoadClass.SECONDARY).setName("ring"); @@ -399,11 +404,11 @@ public void testInstructionIfSlightTurnForCustomProfile() { na.setNode(4, 43.729476, 7.417633); DecimalEncodedValue priorityEnc = tmpEM.getDecimalEncodedValue(EncodingManager.getKey(foot.toString(), "priority")); // default is priority=0 so set it to 1 - GHUtility.setSpeed(5, true, true, foot, g.edge(1, 2).setDistance(20).setName("myroad").set(priorityEnc, 1)); - GHUtility.setSpeed(5, true, true, foot, g.edge(2, 3).setDistance(20).setName("myroad").set(priorityEnc, 1)); + GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(1, 2).setDistance(20).setName("myroad").set(priorityEnc, 1)); + GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20).setName("myroad").set(priorityEnc, 1)); PointList pointList = new PointList(); pointList.add(43.729627, 7.41749); - GHUtility.setSpeed(5, true, true, foot, g.edge(2, 4).setDistance(20).setName("myroad").set(priorityEnc, 1).setWayGeometry(pointList)); + GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20).setName("myroad").set(priorityEnc, 1).setWayGeometry(pointList)); Weighting weighting = CustomModelParser.createWeighting(foot, tmpEM, DefaultTurnCostProvider.NO_TURN_COST_PROVIDER, new CustomModel().setDistanceInfluence(0)); Path p = new Dijkstra(g, weighting, tMode).calcPath(4, 3); @@ -444,10 +449,12 @@ public void testInstructionWithHighlyCustomProfileWithRoadsBase() { na.setNode(4, 55.690849, 12.571004); na.setNode(5, 55.690864, 12.570886); - GHUtility.setSpeed(50, true, true, roads, g.edge(3, 2).setDistance(10)); - GHUtility.setSpeed(40, true, true, roads, g.edge(2, 4).setDistance(10)); - GHUtility.setSpeed(40, true, true, roads, g.edge(2, 1).setDistance(10)); - GHUtility.setSpeed(10, true, true, roads, g.edge(2, 5).setDistance(10).set(rcEV, RoadClass.PEDESTRIAN)); + BooleanEncodedValue roadsAccessEnc = roads.getAccessEnc(); + DecimalEncodedValue roadsSpeedEnc = roads.getAverageSpeedEnc(); + GHUtility.setSpeed(50, true, true, roadsAccessEnc, roadsSpeedEnc, g.edge(3, 2).setDistance(10)); + GHUtility.setSpeed(40, true, true, roadsAccessEnc, roadsSpeedEnc, g.edge(2, 4).setDistance(10)); + GHUtility.setSpeed(40, true, true, roadsAccessEnc, roadsSpeedEnc, g.edge(2, 1).setDistance(10)); + GHUtility.setSpeed(10, true, true, roadsAccessEnc, roadsSpeedEnc, g.edge(2, 5).setDistance(10).set(rcEV, RoadClass.PEDESTRIAN)); CustomModel customModel = new CustomModel(); customModel.addToPriority(Statement.If("road_class == PEDESTRIAN", Statement.Op.MULTIPLY, 0)); @@ -487,12 +494,12 @@ public void testFind() { na.setNode(6, 15.1, 10.1); na.setNode(7, 15.1, 9.8); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(1, 2).setDistance(10000)).setName("1-2"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 3).setDistance(10000)).setName("2-3"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(2, 6).setDistance(10000)).setName("2-6"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 4).setDistance(10000)).setName("3-4").setWayGeometry(waypoint); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(3, 7).setDistance(10000)).setName("3-7"); - GHUtility.setSpeed(60, true, true, carEncoder, g.edge(4, 5).setDistance(10000)).setName("4-5"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(10000)).setName("1-2"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10000)).setName("2-3"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000)).setName("2-6"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(10000)).setName("3-4").setWayGeometry(waypoint); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000)).setName("3-7"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000)).setName("4-5"); FastestWeighting weighting = new FastestWeighting(carEncoder); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 5); diff --git a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java index b9c7c61c361..49dcce6a900 100644 --- a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java +++ b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java @@ -21,6 +21,8 @@ import com.graphhopper.routing.Dijkstra; import com.graphhopper.routing.InstructionsFromEdges; import com.graphhopper.routing.Path; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.util.FlagEncoders; @@ -72,19 +74,21 @@ public void testScenario() { na.setNode(7, 1.0, 1.1); na.setNode(8, 1.0, 1.2); - GHUtility.setSpeed(9, true, true, carEncoder, g.edge(0, 1).setDistance(10000)).setName("0-1"); - GHUtility.setSpeed(9, true, true, carEncoder, g.edge(1, 2).setDistance(11000)).setName("1-2"); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setName("0-1"); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setName("1-2"); - GHUtility.setSpeed(18, true, true, carEncoder, g.edge(0, 3).setDistance(11000)); - GHUtility.setSpeed(18, true, true, carEncoder, g.edge(1, 4).setDistance(10000)).setName("1-4"); - GHUtility.setSpeed(18, true, true, carEncoder, g.edge(2, 5).setDistance(11000)).setName("5-2"); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(11000)); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setName("1-4"); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setName("5-2"); - GHUtility.setSpeed(27, true, true, carEncoder, g.edge(3, 6).setDistance(11000)).setName("3-6"); - GHUtility.setSpeed(27, true, true, carEncoder, g.edge(4, 7).setDistance(10000)).setName("4-7"); - GHUtility.setSpeed(27, true, true, carEncoder, g.edge(5, 8).setDistance(10000)).setName("5-8"); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setName("3-6"); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setName("4-7"); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setName("5-8"); - GHUtility.setSpeed(36, true, true, carEncoder, g.edge(6, 7).setDistance(11000)).setName("6-7"); - EdgeIteratorState tmpEdge = GHUtility.setSpeed(36, true, true, carEncoder, g.edge(7, 8).setDistance(10000)); + GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setName("6-7"); + EdgeIteratorState tmpEdge = GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(10000)); PointList list = new PointList(); list.add(1.0, 1.15); list.add(1.0, 1.16); @@ -92,8 +96,8 @@ public void testScenario() { tmpEdge.setName("7-8"); // missing edge name - GHUtility.setSpeed(45, true, true, carEncoder, g.edge(9, 10).setDistance(10000)); - tmpEdge = GHUtility.setSpeed(45, true, true, carEncoder, g.edge(8, 9).setDistance(20000)); + GHUtility.setSpeed(45, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(10000)); + tmpEdge = GHUtility.setSpeed(45, true, true, accessEnc, speedEnc, g.edge(8, 9).setDistance(20000)); list.clear(); list.add(1.0, 1.3); list.add(1.0, 1.3001); diff --git a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java index f5b557c7f86..a59db457345 100644 --- a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java +++ b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java @@ -21,6 +21,8 @@ import com.graphhopper.routing.Dijkstra; import com.graphhopper.routing.InstructionsFromEdges; import com.graphhopper.routing.Path; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.util.FlagEncoders; @@ -76,12 +78,14 @@ public void testInstructionsWithTimeAndPlace() { na.setNode(6, 15.1, 10.1); na.setNode(7, 15.1, 9.8); - GHUtility.setSpeed(63, true, true, carEncoder, g.edge(1, 2).setDistance(7000).setName("1-2")); - GHUtility.setSpeed(72, true, true, carEncoder, g.edge(2, 3).setDistance(8000).setName("2-3")); - GHUtility.setSpeed(9, true, true, carEncoder, g.edge(2, 6).setDistance(10000).setName("2-6")); - GHUtility.setSpeed(81, true, true, carEncoder, g.edge(3, 4).setDistance(9000).setName("3-4")); - GHUtility.setSpeed(9, true, true, carEncoder, g.edge(3, 7).setDistance(10000).setName("3-7")); - GHUtility.setSpeed(90, true, true, carEncoder, g.edge(4, 5).setDistance(10000).setName("4-5")); + BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); + DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + GHUtility.setSpeed(63, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(7000).setName("1-2")); + GHUtility.setSpeed(72, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(8000).setName("2-3")); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000).setName("2-6")); + GHUtility.setSpeed(81, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(9000).setName("3-4")); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000).setName("3-7")); + GHUtility.setSpeed(90, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000).setName("4-5")); ShortestWeighting weighting = new ShortestWeighting(carEncoder); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); From 48adbf5429652c1c86e2203ac2de871d783a6c52 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 22 Jun 2022 08:34:50 +0200 Subject: [PATCH 059/389] Fix broken imports --- .../routing/DirectedBidirectionalDijkstraTest.java | 5 +---- .../java/com/graphhopper/routing/RandomCHRoutingTest.java | 7 +++---- .../routing/ch/NodeBasedNodeContractorTest.java | 5 +---- .../com/graphhopper/routing/lm/PrepareLandmarksTest.java | 5 +---- 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java index 1046d7eac35..34a9de78433 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java @@ -6,10 +6,7 @@ import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.querygraph.QueryGraph; -import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; +import com.graphhopper.routing.util.*; import com.graphhopper.routing.weighting.AvoidEdgesWeighting; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; diff --git a/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java b/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java index 67d9fc91451..d7822efc3ca 100644 --- a/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java @@ -5,10 +5,7 @@ import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.querygraph.QueryRoutingCHGraph; -import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; +import com.graphhopper.routing.util.*; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -36,6 +33,8 @@ import static com.graphhopper.util.GHUtility.createRandomSnaps; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public class RandomCHRoutingTest { private static final Logger LOGGER = LoggerFactory.getLogger(RandomCHRoutingTest.class); diff --git a/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java index fe68e2c5fc1..53fb5ed8e32 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java @@ -22,10 +22,7 @@ import com.graphhopper.routing.Path; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.util.AllEdgesIterator; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; +import com.graphhopper.routing.util.*; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.routing.weighting.Weighting; diff --git a/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java b/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java index e0238d0d8f4..eb4f63d4f39 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java @@ -25,10 +25,7 @@ import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.querygraph.QueryGraph; -import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; +import com.graphhopper.routing.util.*; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.BaseGraph; From cd0e415288089b4c706ff2a92a390d3212d3b046 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 22 Jun 2022 08:57:24 +0200 Subject: [PATCH 060/389] More use access and speed EVs instead of encoder for GHUtility#setSpeed --- .../java/com/graphhopper/util/GHUtility.java | 37 ++++++--------- .../dem/BridgeElevationInterpolatorTest.java | 2 +- .../dem/TunnelElevationInterpolatorTest.java | 2 +- .../routing/AlternativeRouteCHTest.java | 2 +- .../routing/AlternativeRouteTest.java | 2 +- .../routing/CHQueryWithTurnCostsTest.java | 8 ++-- .../routing/DijkstraBidirectionCHTest.java | 2 +- .../routing/DijkstraOneToManyTest.java | 6 +-- .../DirectedBidirectionalDijkstraTest.java | 2 +- .../routing/DirectedRoutingTest.java | 20 ++++---- .../com/graphhopper/routing/PathTest.java | 12 ++--- .../routing/ch/CHTurnCostTest.java | 46 +++++++++---------- .../ch/EdgeBasedNodeContractorTest.java | 10 ++-- .../routing/util/WheelchairTagParserTest.java | 9 ++-- .../weighting/FastestWeightingTest.java | 6 +-- .../weighting/ShortFastestWeightingTest.java | 2 +- .../weighting/custom/CustomWeightingTest.java | 2 +- .../storage/ShortcutUnpackerTest.java | 6 +-- .../storage/TurnCostStorageTest.java | 2 +- .../storage/index/LocationIndexTreeTest.java | 6 +-- 20 files changed, 91 insertions(+), 93 deletions(-) diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index 56fe03df02a..8ef7448fdbd 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -585,57 +585,48 @@ public static int getEdgeFromEdgeKey(int edgeKey) { return edgeKey / 2; } - public static IntsRef setSpeed(double fwdSpeed, double bwdSpeed, FlagEncoder encoder, IntsRef edgeFlags) { + public static IntsRef setSpeed(double fwdSpeed, double bwdSpeed, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, IntsRef edgeFlags) { if (fwdSpeed < 0 || bwdSpeed < 0) throw new IllegalArgumentException("Speed must be positive but wasn't! fwdSpeed:" + fwdSpeed + ", bwdSpeed:" + bwdSpeed); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue avgSpeedEnc = encoder.getAverageSpeedEnc(); - - avgSpeedEnc.setDecimal(false, edgeFlags, fwdSpeed); + speedEnc.setDecimal(false, edgeFlags, fwdSpeed); if (fwdSpeed > 0) accessEnc.setBool(false, edgeFlags, true); - if (bwdSpeed > 0 && (fwdSpeed != bwdSpeed || avgSpeedEnc.isStoreTwoDirections())) { - if (!avgSpeedEnc.isStoreTwoDirections()) - throw new IllegalArgumentException("EncodedValue " + avgSpeedEnc.getName() + " supports only one direction " + + if (bwdSpeed > 0 && (fwdSpeed != bwdSpeed || speedEnc.isStoreTwoDirections())) { + if (!speedEnc.isStoreTwoDirections()) + throw new IllegalArgumentException("EncodedValue " + speedEnc.getName() + " supports only one direction " + "but two different speeds were specified " + fwdSpeed + " " + bwdSpeed); - avgSpeedEnc.setDecimal(true, edgeFlags, bwdSpeed); + speedEnc.setDecimal(true, edgeFlags, bwdSpeed); } if (bwdSpeed > 0) accessEnc.setBool(true, edgeFlags, true); return edgeFlags; } - public static void setSpeed(double fwdSpeed, double bwdSpeed, FlagEncoder encoder, EdgeIteratorState... edges) { - setSpeed(fwdSpeed, bwdSpeed, encoder, Arrays.asList(edges)); + public static void setSpeed(double fwdSpeed, double bwdSpeed, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, EdgeIteratorState... edges) { + setSpeed(fwdSpeed, bwdSpeed, accessEnc, speedEnc, Arrays.asList(edges)); } - public static void setSpeed(double fwdSpeed, double bwdSpeed, FlagEncoder encoder, Collection edges) { + public static void setSpeed(double fwdSpeed, double bwdSpeed, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, Collection edges) { if (fwdSpeed < 0 || bwdSpeed < 0) throw new IllegalArgumentException("Speed must be positive but wasn't! fwdSpeed:" + fwdSpeed + ", bwdSpeed:" + bwdSpeed); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue avgSpeedEnc = encoder.getAverageSpeedEnc(); for (EdgeIteratorState edge : edges) { - edge.set(avgSpeedEnc, fwdSpeed); + edge.set(speedEnc, fwdSpeed); if (fwdSpeed > 0) edge.set(accessEnc, true); - if (bwdSpeed > 0 && (fwdSpeed != bwdSpeed || avgSpeedEnc.isStoreTwoDirections())) { - if (!avgSpeedEnc.isStoreTwoDirections()) - throw new IllegalArgumentException("EncodedValue " + avgSpeedEnc.getName() + " supports only one direction " + + if (bwdSpeed > 0 && (fwdSpeed != bwdSpeed || speedEnc.isStoreTwoDirections())) { + if (!speedEnc.isStoreTwoDirections()) + throw new IllegalArgumentException("EncodedValue " + speedEnc.getName() + " supports only one direction " + "but two different speeds were specified " + fwdSpeed + " " + bwdSpeed); - edge.setReverse(avgSpeedEnc, bwdSpeed); + edge.setReverse(speedEnc, bwdSpeed); } if (bwdSpeed > 0) edge.setReverse(accessEnc, true); } } - public static EdgeIteratorState setSpeed(double averageSpeed, boolean fwd, boolean bwd, FlagEncoder encoder, EdgeIteratorState edge) { - return setSpeed(averageSpeed, fwd, bwd, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge); - } - public static EdgeIteratorState setSpeed(double averageSpeed, boolean fwd, boolean bwd, BooleanEncodedValue accessEnc, DecimalEncodedValue avSpeedEnc, EdgeIteratorState edge) { if (averageSpeed < 0.0001 && (fwd || bwd)) throw new IllegalStateException("Zero speed is only allowed if edge will get inaccessible. Otherwise Weighting can produce inconsistent results"); diff --git a/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java b/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java index ad0c3e78eeb..10259d5231b 100644 --- a/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java +++ b/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java @@ -73,7 +73,7 @@ public void interpolatesElevationOfPillarNodes() { FlagEncoder encoder = encodingManager.getEncoder("car"); EdgeIteratorState edge01, edge12, edge23, edge34, edge56, edge67, edge78, edge89, edge17, edge27, edge37; - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge01 = graph.edge(0, 1).setDistance(10), edge12 = graph.edge(1, 2).setDistance(10), edge23 = graph.edge(2, 3).setDistance(10), diff --git a/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java b/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java index 1ca67ee4fed..22d75773cfc 100644 --- a/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java +++ b/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java @@ -253,7 +253,7 @@ public void interpolatesElevationOfTunnelWithFourOuterNodes() { na.setNode(9, 40, 10, 0); EdgeIteratorState edge01, edge12, edge23, edge34, edge56, edge67, edge78, edge89, edge27; - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge01 = graph.edge(0, 1).setDistance(10), edge12 = graph.edge(1, 2).setDistance(10), edge23 = graph.edge(2, 3).setDistance(10), diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteCHTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteCHTest.java index ca3cd63148e..d9082ed71e0 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteCHTest.java @@ -56,7 +56,7 @@ public BaseGraph createTestGraph(EncodingManager tmpEM) { // has to be locally-shortest to be considered. // So we get all three alternatives. - GHUtility.setSpeed(60, 60, carFE, + GHUtility.setSpeed(60, 60, carFE.getAccessEnc(), carFE.getAverageSpeedEnc(), graph.edge(5, 6).setDistance(10000), graph.edge(6, 3).setDistance(10000), graph.edge(3, 4).setDistance(10000), diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java index 8d404978af3..e3b5dfb7574 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java @@ -85,7 +85,7 @@ public static void initTestGraph(Graph graph, FlagEncoder encoder) { 5--6-7---8 */ - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 9).setDistance(1), graph.edge(9, 2).setDistance(1), graph.edge(2, 3).setDistance(1), diff --git a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java index b892cd22b04..2525e8233fd 100644 --- a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java @@ -255,7 +255,7 @@ public void testFindPathWithTurnCosts_loopShortcutFwdSearch(Fixture f) { // 1 2 // \ / // 5 - 6 - 4 - 7 - 8 - 0 - GHUtility.setSpeed(60, 0, f.encoder, + GHUtility.setSpeed(60, 0, f.accessEnc, f.speedEnc, f.graph.edge(5, 6).setDistance(1), f.graph.edge(6, 4).setDistance(1), f.graph.edge(4, 1).setDistance(1), @@ -393,7 +393,7 @@ public void testFindPath_upwardSearchRunsIntoTarget(Fixture f) { // | | // v v // 3 -> 4 -> 2 - GHUtility.setSpeed(60, 0, f.encoder, + GHUtility.setSpeed(60, 0, f.accessEnc, f.speedEnc, f.graph.edge(0, 1).setDistance(9), f.graph.edge(1, 5).setDistance(2), f.graph.edge(1, 3).setDistance(2), @@ -546,7 +546,7 @@ public void testFindPathWithTurnCosts_multiple_bridge_nodes(Fixture f) { // 0 --- 3 --- 1 // \ / // --- 4 --- - GHUtility.setSpeed(60, 0, f.encoder, + GHUtility.setSpeed(60, 0, f.accessEnc, f.speedEnc, f.graph.edge(0, 2).setDistance(1), f.graph.edge(0, 3).setDistance(3), f.graph.edge(0, 4).setDistance(2), @@ -671,7 +671,7 @@ private void runTestWithSingleLoop(Fixture f, boolean loopInFwdSearch) { // A-5->2 // | // B-7 - GHUtility.setSpeed(60, 0, f.encoder, + GHUtility.setSpeed(60, 0, f.accessEnc, f.speedEnc, f.graph.edge(4, nodeA).setDistance(1), f.graph.edge(nodeA, 5).setDistance(2), f.graph.edge(5, 2).setDistance(2), diff --git a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java index 6247aacf430..5e6d861945f 100644 --- a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java @@ -116,7 +116,7 @@ public void testBaseGraphMultipleVehicles() { @Test public void testStallingNodesReducesNumberOfVisitedNodes() { BaseGraph graph = createGHStorage(); - GHUtility.setSpeed(60, 0, carEncoder, + GHUtility.setSpeed(60, 0, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(8, 9).setDistance(100), graph.edge(8, 3).setDistance(2), graph.edge(8, 5).setDistance(1), diff --git a/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java b/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java index 958cd39fe5b..977fd49382d 100644 --- a/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java +++ b/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java @@ -59,7 +59,7 @@ private static void initGraphWeightLimit(Graph graph, FlagEncoder encoder) { // | | | // 4---3---2 - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(1), graph.edge(1, 2).setDistance(1), graph.edge(3, 2).setDistance(1), @@ -87,7 +87,7 @@ public void testIssue182() { @Test public void testIssue239_and362() { BaseGraph graph = createGHStorage(); - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(1), graph.edge(1, 2).setDistance(1), graph.edge(2, 0).setDistance(1), @@ -125,7 +125,7 @@ private void initGraph(Graph graph) { // | / // 7-10---- // \-8 - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(1), graph.edge(1, 2).setDistance(1), graph.edge(2, 3).setDistance(1), diff --git a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java index 34a9de78433..ec0101f37ed 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java @@ -239,7 +239,7 @@ public void directedRouting() { // | / \ | // 8 = 7 6 = 5 EdgeIteratorState rightNorth, rightSouth, leftSouth, leftNorth; - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(1), graph.edge(1, 2).setDistance(1), graph.edge(2, 3).setDistance(1), diff --git a/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java b/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java index 8fed14a094b..b1968fec430 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java @@ -20,6 +20,8 @@ import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory; import com.graphhopper.routing.ch.PrepareContractionHierarchies; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.lm.LMConfig; import com.graphhopper.routing.lm.LMRoutingAlgorithmFactory; @@ -309,14 +311,16 @@ public void issue_2581() { // 3-0=1-2=7-5 // | // 4 - GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(0, 1).setDistance(300.186000)); // edgeId=0 - GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(0, 4).setDistance(751.113000)); // edgeId=1 - GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(7, 2).setDistance(113.102000)); // edgeId=2 - GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(3, 0).setDistance(226.030000)); // edgeId=3 - GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(1, 2).setDistance(494.601000)); // edgeId=4 - GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(7, 2).setDistance(113.102000)); // edgeId=5 - GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(5, 7).setDistance(274.848000)); // edgeId=6 - GHUtility.setSpeed(60, 60, f.encoder, f.graph.edge(0, 1).setDistance(300.186000)); // edgeId=7 + BooleanEncodedValue accessEnc = f.encoder.getAccessEnc(); + DecimalEncodedValue speedEnc = f.encoder.getAverageSpeedEnc(); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(0, 1).setDistance(300.186000)); // edgeId=0 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(0, 4).setDistance(751.113000)); // edgeId=1 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(7, 2).setDistance(113.102000)); // edgeId=2 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(3, 0).setDistance(226.030000)); // edgeId=3 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(1, 2).setDistance(494.601000)); // edgeId=4 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(7, 2).setDistance(113.102000)); // edgeId=5 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(5, 7).setDistance(274.848000)); // edgeId=6 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(0, 1).setDistance(300.186000)); // edgeId=7 f.preProcessGraph(); LocationIndexTree index = new LocationIndexTree(f.graph, f.dir); index.prepareIndex(); diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index 4303cf91dac..a41322341aa 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -847,12 +847,12 @@ public void testUTurnLeft() { na.setNode(6, 48.402422, 9.996067); na.setNode(7, 48.402604, 9.994962); - GHUtility.setSpeed(60, 0, encoder, + GHUtility.setSpeed(60, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(1, 2).setDistance(5).setName("Olgastraße"), g.edge(2, 3).setDistance(5).setName("Olgastraße"), g.edge(6, 5).setDistance(5).setName("Olgastraße"), g.edge(5, 4).setDistance(5).setName("Olgastraße")); - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(2, 5).setDistance(5).setName("Neithardtstraße"), g.edge(5, 7).setDistance(5).setName("Neithardtstraße")); @@ -885,12 +885,12 @@ public void testUTurnRight() { na.setNode(6, -33.885692, 151.181445); na.setNode(7, -33.885692, 151.181445); - GHUtility.setSpeed(60, 0, encoder, + GHUtility.setSpeed(60, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(1, 2).setDistance(5).setName("Parramatta Road"), g.edge(2, 3).setDistance(5).setName("Parramatta Road"), g.edge(4, 5).setDistance(5).setName("Parramatta Road"), g.edge(5, 6).setDistance(5).setName("Parramatta Road")); - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(2, 5).setDistance(5).setName("Larkin Street"), g.edge(5, 7).setDistance(5).setName("Larkin Street")); @@ -1075,8 +1075,8 @@ private RoundaboutGraph(EncodingManager em) { for (FlagEncoder encoder : em.fetchEdgeEncoders()) { double speed = encoder.getMaxSpeed() / 2; - GHUtility.setSpeed(speed, speed, encoder, bothDir); - GHUtility.setSpeed(speed, 0, encoder, oneDir); + GHUtility.setSpeed(speed, speed, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), bothDir); + GHUtility.setSpeed(speed, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), oneDir); } setRoundabout(clockwise); diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java index 32d764dcb1d..2229e52b020 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java @@ -809,14 +809,14 @@ void anotherDoubleZeroWeightLoop() { // 0 - 5 - 2 // oo // note there are two (directed) zero weight loops at node 5! - GHUtility.setSpeed(60.000000, 60.000000, encoder, graph.edge(5, 1).setDistance(263.944000)); // edgeId=0 - GHUtility.setSpeed(120.000000, 120.000000, encoder, graph.edge(5, 2).setDistance(315.026000)); // edgeId=1 - GHUtility.setSpeed(40.000000, 40.000000, encoder, graph.edge(1, 4).setDistance(157.012000)); // edgeId=2 - GHUtility.setSpeed(45.000000, 45.000000, encoder, graph.edge(5, 0).setDistance(513.913000)); // edgeId=3 - GHUtility.setSpeed(15.000000, 15.000000, encoder, graph.edge(6, 4).setDistance(678.992000)); // edgeId=4 - GHUtility.setSpeed(60.000000, 0.000000, encoder, graph.edge(5, 5).setDistance(0.000000)); // edgeId=5 - GHUtility.setSpeed(40.000000, 40.000000, encoder, graph.edge(6, 7).setDistance(890.261000)); // edgeId=6 - GHUtility.setSpeed(90.000000, 0.000000, encoder, graph.edge(5, 5).setDistance(0.000000)); // edgeId=7 + GHUtility.setSpeed(60.000000, 60.000000, accessEnc, speedEnc, graph.edge(5, 1).setDistance(263.944000)); // edgeId=0 + GHUtility.setSpeed(120.000000, 120.000000, accessEnc, speedEnc, graph.edge(5, 2).setDistance(315.026000)); // edgeId=1 + GHUtility.setSpeed(40.000000, 40.000000, accessEnc, speedEnc, graph.edge(1, 4).setDistance(157.012000)); // edgeId=2 + GHUtility.setSpeed(45.000000, 45.000000, accessEnc, speedEnc, graph.edge(5, 0).setDistance(513.913000)); // edgeId=3 + GHUtility.setSpeed(15.000000, 15.000000, accessEnc, speedEnc, graph.edge(6, 4).setDistance(678.992000)); // edgeId=4 + GHUtility.setSpeed(60.000000, 0.000000, accessEnc, speedEnc, graph.edge(5, 5).setDistance(0.000000)); // edgeId=5 + GHUtility.setSpeed(40.000000, 40.000000, accessEnc, speedEnc, graph.edge(6, 7).setDistance(890.261000)); // edgeId=6 + GHUtility.setSpeed(90.000000, 0.000000, accessEnc, speedEnc, graph.edge(5, 5).setDistance(0.000000)); // edgeId=7 graph.freeze(); automaticCompareCHWithDijkstra(100); } @@ -1118,13 +1118,13 @@ public void test_astar_issue2061(String algo) { void testZeroUTurnCosts_atBarrier_issue2564() { // lvl: 0 3 2 4 5 1 // nd: 0-1-2-3-4-5 - GHUtility.setSpeed(60, 60, encoder, graph.edge(0, 1).setDistance(100)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); // the original bug was sometimes hidden depending on the exact distance, so we use these odd numbers here - GHUtility.setSpeed(60, 60, encoder, graph.edge(1, 2).setDistance(7.336)); - GHUtility.setSpeed(60, 60, encoder, graph.edge(2, 3).setDistance(10.161)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(1, 2).setDistance(7.336)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10.161)); // a zero distance edge (like a passable barrier)! - GHUtility.setSpeed(60, 60, encoder, graph.edge(3, 4).setDistance(0)); - GHUtility.setSpeed(60, 60, encoder, graph.edge(4, 5).setDistance(100)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(3, 4).setDistance(0)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(4, 5).setDistance(100)); graph.freeze(); // u-turn costs are zero! chConfig = chConfigs.get(1); @@ -1139,11 +1139,11 @@ void testBestFwdBwdEntryUpdate() { // 2-3 // | | // 0-4-1 - GHUtility.setSpeed(60, 60, encoder, graph.edge(2, 0).setDistance(800.22)); - GHUtility.setSpeed(60, 60, encoder, graph.edge(3, 4).setDistance(478.84)); - GHUtility.setSpeed(60, 60, encoder, graph.edge(0, 4).setDistance(547.08)); - GHUtility.setSpeed(60, 60, encoder, graph.edge(4, 1).setDistance(288.95)); - GHUtility.setSpeed(60, 60, encoder, graph.edge(2, 3).setDistance(90)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(2, 0).setDistance(800.22)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(3, 4).setDistance(478.84)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 4).setDistance(547.08)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(4, 1).setDistance(288.95)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(2, 3).setDistance(90)); graph.freeze(); prepareCH(1, 3, 0, 2, 4); compareCHQueryWithDijkstra(1, 2); @@ -1154,11 +1154,11 @@ void testEdgeKeyBug() { // 1 - 2 - 0 - 4 // \ / // 3 - GHUtility.setSpeed(60, 60, encoder, graph.edge(0, 3).setDistance(100)); // edgeId=0 - GHUtility.setSpeed(60, 60, encoder, graph.edge(4, 3).setDistance(100)); // edgeId=1 - GHUtility.setSpeed(60, 60, encoder, graph.edge(0, 4).setDistance(100)); // edgeId=2 - GHUtility.setSpeed(60, 60, encoder, graph.edge(1, 2).setDistance(100)); // edgeId=3 - GHUtility.setSpeed(60, 60, encoder, graph.edge(0, 2).setDistance(100)); // edgeId=4 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 3).setDistance(100)); // edgeId=0 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(4, 3).setDistance(100)); // edgeId=1 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 4).setDistance(100)); // edgeId=2 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(1, 2).setDistance(100)); // edgeId=3 + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 2).setDistance(100)); // edgeId=4 graph.freeze(); prepareCH(2, 0, 1, 3, 4); assertEquals(2, chGraph.getShortcuts()); diff --git a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java index c3f35ad8bad..b6b0583fde6 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java @@ -1414,11 +1414,11 @@ public void testNodeContraction_numPolledEdges() { @Test void issue_2564() { // 0-1-2-3-4-5 - GHUtility.setSpeed(60, 60, encoder, graph.edge(0, 1).setDistance(100)); - GHUtility.setSpeed(60, 60, encoder, graph.edge(1, 2).setDistance(7.336)); - GHUtility.setSpeed(60, 60, encoder, graph.edge(2, 3).setDistance(10.161)); - GHUtility.setSpeed(60, 60, encoder, graph.edge(3, 4).setDistance(0)); - GHUtility.setSpeed(60, 60, encoder, graph.edge(4, 5).setDistance(100)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(1, 2).setDistance(7.336)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10.161)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(3, 4).setDistance(0)); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(4, 5).setDistance(100)); freeze(); chStore = CHStorage.fromGraph(graph, chConfigs.get(2)); chBuilder = new CHStorageBuilder(chStore); diff --git a/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java index 4ec73839e2d..7739ea9f407 100644 --- a/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java @@ -504,21 +504,24 @@ public void testApplyWayTags() { na.setNode(1, 51.1, 12.0015, 55); EdgeIteratorState edge01 = graph.edge(0, 1).setWayGeometry(Helper.createPointList3D(51.1, 12.0011, 49, 51.1, 12.0015, 55)); edge01.setDistance(100); - GHUtility.setSpeed(5, 5, encodingManager.getEncoder("wheelchair"), edge01); + FlagEncoder encoder2 = encodingManager.getEncoder("wheelchair"); + GHUtility.setSpeed(5, 5, encoder2.getAccessEnc(), encoder2.getAverageSpeedEnc(), edge01); // incline of 10% & shorter edge na.setNode(2, 51.2, 12.1010, 50); na.setNode(3, 51.2, 12.1015, 60); EdgeIteratorState edge23 = graph.edge(2, 3).setWayGeometry(Helper.createPointList3D(51.2, 12.1011, 49, 51.2, 12.1015, 55)); edge23.setDistance(30); - GHUtility.setSpeed(5, 5, encodingManager.getEncoder("wheelchair"), edge23); + FlagEncoder encoder1 = encodingManager.getEncoder("wheelchair"); + GHUtility.setSpeed(5, 5, encoder1.getAccessEnc(), encoder1.getAverageSpeedEnc(), edge23); // incline of 10% & longer edge na.setNode(4, 51.2, 12.101, 50); na.setNode(5, 51.2, 12.102, 60); EdgeIteratorState edge45 = graph.edge(2, 3).setWayGeometry(Helper.createPointList3D(51.2, 12.1011, 49, 51.2, 12.1015, 55)); edge45.setDistance(100); - GHUtility.setSpeed(5, 5, encodingManager.getEncoder("wheelchair"), edge45); + FlagEncoder encoder = encodingManager.getEncoder("wheelchair"); + GHUtility.setSpeed(5, 5, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge45); wheelchairParser.applyWayTags(new ReaderWay(1), edge01); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java index c00d690d110..0ad7298d41e 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java @@ -47,7 +47,7 @@ public class FastestWeightingTest { @Test public void testMinWeightHasSameUnitAs_getWeight() { Weighting instance = new FastestWeighting(encoder); - IntsRef flags = GHUtility.setSpeed(encoder.getMaxSpeed(), 0, encoder, encodingManager.createEdgeFlags()); + IntsRef flags = GHUtility.setSpeed(encoder.getMaxSpeed(), 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags()); assertEquals(instance.getMinWeight(10), instance.calcEdgeWeight(createMockedEdgeIteratorState(10, flags), false), 1e-8); } @@ -56,7 +56,7 @@ public void testWeightWrongHeading() { Weighting instance = new FastestWeighting(encoder, new PMap().putObject(Parameters.Routing.HEADING_PENALTY, 100)); VirtualEdgeIteratorState virtEdge = new VirtualEdgeIteratorState(0, GHUtility.createEdgeKey(1, false, false), 1, 2, 10, - GHUtility.setSpeed(10, 0, encoder, encodingManager.createEdgeFlags()), "test", Helper.createPointList(51, 0, 51, 1), false); + GHUtility.setSpeed(10, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags()), "test", Helper.createPointList(51, 0, 51, 1), false); double time = instance.calcEdgeWeight(virtEdge, false); virtEdge.setUnfavored(true); @@ -93,7 +93,7 @@ public void testTime() { BaseGraph g = new BaseGraph.Builder(em).create(); Weighting w = new FastestWeighting(tmpEnc); - IntsRef edgeFlags = GHUtility.setSpeed(15, 15, tmpEnc, em.createEdgeFlags()); + IntsRef edgeFlags = GHUtility.setSpeed(15, 15, tmpEnc.getAccessEnc(), tmpEnc.getAverageSpeedEnc(), em.createEdgeFlags()); tmpEnc.getAverageSpeedEnc().setDecimal(true, edgeFlags, 10.0); EdgeIteratorState edge = GHUtility.createMockedEdgeIteratorState(100000, edgeFlags); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/ShortFastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/ShortFastestWeightingTest.java index ca31be0906f..56cd3d69493 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/ShortFastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/ShortFastestWeightingTest.java @@ -37,7 +37,7 @@ public class ShortFastestWeightingTest { @Test public void testShort() { - EdgeIteratorState edge = createMockedEdgeIteratorState(10, GHUtility.setSpeed(50, 0, encoder, encodingManager.createEdgeFlags())); + EdgeIteratorState edge = createMockedEdgeIteratorState(10, GHUtility.setSpeed(50, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags())); Weighting instance = new ShortFastestWeighting(encoder, 0.03); assertEquals(1.02, instance.calcEdgeWeight(edge, false), 1e-8); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index 2a1875366ad..87e960a943e 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -49,7 +49,7 @@ public void setup() { public void speedOnly() { // 50km/h -> 72s per km, 100km/h -> 36s per km EdgeIteratorState edge; - GHUtility.setSpeed(50, 100, carFE, edge = graph.edge(0, 1).setDistance(1000)); + GHUtility.setSpeed(50, 100, accessEnc, avSpeedEnc, edge = graph.edge(0, 1).setDistance(1000)); assertEquals(72, createWeighting(new CustomModel().setDistanceInfluence(0)).calcEdgeWeight(edge, false), 1.e-6); assertEquals(36, createWeighting(new CustomModel().setDistanceInfluence(0)).calcEdgeWeight(edge, true), 1.e-6); } diff --git a/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java b/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java index 4abf63ef337..c854aea0b41 100644 --- a/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java +++ b/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java @@ -108,7 +108,7 @@ public Stream provideArguments(ExtensionContext context) { @ArgumentsSource(FixtureProvider.class) public void testUnpacking(Fixture f) { // 0-1-2-3-4-5-6 - GHUtility.setSpeed(60, 30, f.encoder, + GHUtility.setSpeed(60, 30, f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), f.graph.edge(0, 1).setDistance(1), f.graph.edge(1, 2).setDistance(1), f.graph.edge(2, 3).setDistance(1), @@ -197,7 +197,7 @@ public void loopShortcut(Fixture f) { // 2 4 // \ / // 0 - 1 - 5 - GHUtility.setSpeed(60, 30, f.encoder, + GHUtility.setSpeed(60, 30, f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), f.graph.edge(0, 1).setDistance(1), f.graph.edge(1, 2).setDistance(1), f.graph.edge(2, 3).setDistance(1), @@ -274,7 +274,7 @@ public void withTurnWeighting(Fixture f) { // prev 0-1-2-3-4-5-6 next // 1 0 1 4 2 3 2 turn costs <- EdgeIteratorState edge0, edge1, edge2, edge3, edge4, edge5; - GHUtility.setSpeed(60, 30, f.encoder, + GHUtility.setSpeed(60, 30, f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), edge0 = f.graph.edge(0, 1).setDistance(1), edge1 = f.graph.edge(1, 2).setDistance(1), edge2 = f.graph.edge(2, 3).setDistance(1), diff --git a/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java b/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java index 588705e4de9..8570ec03808 100644 --- a/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java +++ b/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java @@ -54,7 +54,7 @@ public void setup() { // | // 4 public static void initGraph(BaseGraph g, FlagEncoder encoder) { - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(0, 1).setDistance(3), g.edge(0, 2).setDistance(1), g.edge(1, 3).setDistance(1), diff --git a/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java b/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java index 90393d2f1e2..74343c16343 100644 --- a/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java +++ b/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java @@ -72,7 +72,7 @@ public static void initSimpleGraph(Graph g, EncodingManager em) { g.edge(6, 4)); for (FlagEncoder encoder : em.fetchEdgeEncoders()) { double speed = encoder.getMaxSpeed() / 2; - GHUtility.setSpeed(speed, speed, encoder, list); + GHUtility.setSpeed(speed, speed, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), list); } } @@ -289,7 +289,7 @@ Graph createTestGraph2() { // top right na.setNode(101, 49.96053, 11.58814); - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1), graph.edge(1, 2), graph.edge(2, 3), @@ -407,7 +407,7 @@ public void testCrossBoundaryNetwork_issue667() { na.setNode(7, 0, -179.5); // just use 1 as distance which is incorrect but does not matter in this unit case - GHUtility.setSpeed(60, 60, encoder, + GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1), graph.edge(0, 4), graph.edge(1, 5), From c0b7d6b192d8d3a3a06f15e1a3810d5c51d77fa4 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 22 Jun 2022 09:30:30 +0200 Subject: [PATCH 061/389] Replace flag encoder with turn cost encoded value in turn cost provider --- .../routing/DefaultWeightingFactory.java | 2 +- .../weighting/DefaultTurnCostProvider.java | 19 ++++++++----------- .../routing/AlternativeRouteEdgeCHTest.java | 4 ++-- .../routing/AlternativeRouteTest.java | 2 +- .../routing/CHQueryWithTurnCostsTest.java | 2 +- .../DefaultBidirPathExtractorTest.java | 2 +- .../DirectedBidirectionalDijkstraTest.java | 5 ++--- .../routing/DirectedRoutingTest.java | 2 +- .../EdgeBasedRoutingAlgorithmTest.java | 4 ++-- .../routing/QueryRoutingCHGraphTest.java | 2 +- .../routing/RandomCHRoutingTest.java | 2 +- .../routing/RandomizedRoutingTest.java | 2 +- .../routing/ch/CHTurnCostTest.java | 10 ++++++---- .../ch/EdgeBasedNodeContractorTest.java | 8 +++++--- .../routing/querygraph/QueryGraphTest.java | 2 +- .../PrepareRoutingSubnetworksTest.java | 6 +++--- .../routing/util/AccessFilterTest.java | 2 +- .../weighting/FastestWeightingTest.java | 6 +++--- .../storage/ShortcutUnpackerTest.java | 2 +- 19 files changed, 42 insertions(+), 42 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java index 5737515198f..eb0bcf754b1 100644 --- a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java +++ b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java @@ -60,7 +60,7 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis if (!encoder.supportsTurnCosts()) throw new IllegalArgumentException("Encoder " + encoder + " does not support turn costs"); int uTurnCosts = hints.getInt(Parameters.Routing.U_TURN_COSTS, INFINITE_U_TURN_COSTS); - turnCostProvider = new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage(), uTurnCosts); + turnCostProvider = new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage(), uTurnCosts); } else { turnCostProvider = NO_TURN_COST_PROVIDER; } diff --git a/core/src/main/java/com/graphhopper/routing/weighting/DefaultTurnCostProvider.java b/core/src/main/java/com/graphhopper/routing/weighting/DefaultTurnCostProvider.java index 1377c531553..7f996014c1a 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/DefaultTurnCostProvider.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/DefaultTurnCostProvider.java @@ -19,8 +19,6 @@ package com.graphhopper.routing.weighting; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.TurnCost; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.storage.TurnCostStorage; import com.graphhopper.util.EdgeIterator; @@ -32,19 +30,15 @@ public class DefaultTurnCostProvider implements TurnCostProvider { private final int uTurnCostsInt; private final double uTurnCosts; - public DefaultTurnCostProvider(FlagEncoder encoder, TurnCostStorage turnCostStorage) { - this(encoder, turnCostStorage, Weighting.INFINITE_U_TURN_COSTS); - } - - public DecimalEncodedValue getTurnCostEnc() { - return turnCostEnc; + public DefaultTurnCostProvider(DecimalEncodedValue turnCostEnc, TurnCostStorage turnCostStorage) { + this(turnCostEnc, turnCostStorage, Weighting.INFINITE_U_TURN_COSTS); } /** * @param uTurnCosts the costs of a u-turn in seconds, for {@link Weighting#INFINITE_U_TURN_COSTS} the u-turn costs * will be infinite */ - public DefaultTurnCostProvider(FlagEncoder encoder, TurnCostStorage turnCostStorage, int uTurnCosts) { + public DefaultTurnCostProvider(DecimalEncodedValue turnCostEnc, TurnCostStorage turnCostStorage, int uTurnCosts) { if (uTurnCosts < 0 && uTurnCosts != INFINITE_U_TURN_COSTS) { throw new IllegalArgumentException("u-turn costs must be positive, or equal to " + INFINITE_U_TURN_COSTS + " (=infinite costs)"); } @@ -53,12 +47,15 @@ public DefaultTurnCostProvider(FlagEncoder encoder, TurnCostStorage turnCostStor if (turnCostStorage == null) { throw new IllegalArgumentException("No storage set to calculate turn weight"); } - String key = TurnCost.key(encoder.toString()); // if null the TurnCostProvider can be still useful for edge-based routing - this.turnCostEnc = encoder.hasEncodedValue(key) ? encoder.getDecimalEncodedValue(key) : null; + this.turnCostEnc = turnCostEnc; this.turnCostStorage = turnCostStorage; } + public DecimalEncodedValue getTurnCostEnc() { + return turnCostEnc; + } + @Override public double calcTurnWeight(int edgeFrom, int nodeVia, int edgeTo) { if (!EdgeIterator.Edge.isValid(edgeFrom) || !EdgeIterator.Edge.isValid(edgeTo)) { diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java index 355bd3c353c..0bf2c254a6f 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java @@ -92,7 +92,7 @@ public BaseGraph createTestGraph(EncodingManager tmpEM) { } private RoutingCHGraph prepareCH(BaseGraph graph) { - TurnCostProvider turnCostProvider = new DefaultTurnCostProvider(carFE, graph.getTurnCostStorage()); + TurnCostProvider turnCostProvider = new DefaultTurnCostProvider(carFE.getTurnCostEnc(), graph.getTurnCostStorage()); CHConfig chConfig = CHConfig.edgeBased("profile", new FastestWeighting(carFE, turnCostProvider)); PrepareContractionHierarchies contractionHierarchies = PrepareContractionHierarchies.fromGraph(graph, chConfig); PrepareContractionHierarchies.Result res = contractionHierarchies.doWork(); @@ -102,7 +102,7 @@ private RoutingCHGraph prepareCH(BaseGraph graph) { @Test public void testAssumptions() { BaseGraph g = createTestGraph(em); - TurnCostProvider turnCostProvider = new DefaultTurnCostProvider(carFE, g.getTurnCostStorage()); + TurnCostProvider turnCostProvider = new DefaultTurnCostProvider(carFE.getTurnCostEnc(), g.getTurnCostStorage()); CHConfig chConfig = CHConfig.edgeBased("profile", new FastestWeighting(carFE, turnCostProvider)); CHStorage chStorage = CHStorage.fromGraph(g, chConfig); RoutingCHGraph chGraph = RoutingCHGraphImpl.fromGraph(g, chStorage, chConfig); diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java index e3b5dfb7574..7e9f8ab0c66 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java @@ -56,7 +56,7 @@ public Fixture(TraversalMode tMode) { EncodingManager em = EncodingManager.create(carFE); graph = new BaseGraph.Builder(em).withTurnCosts(true).create(); TurnCostProvider turnCostProvider = tMode.isEdgeBased() - ? new DefaultTurnCostProvider(carFE, graph.getTurnCostStorage()) + ? new DefaultTurnCostProvider(carFE.getTurnCostEnc(), graph.getTurnCostStorage()) : TurnCostProvider.NO_TURN_COST_PROVIDER; weighting = new FastestWeighting(carFE, turnCostProvider); } diff --git a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java index 2525e8233fd..648214574dc 100644 --- a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java @@ -69,7 +69,7 @@ private static class Fixture { public Fixture(String algoString) { this.algoString = algoString; graph = new BaseGraph.Builder(encodingManager).create(); - chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage()))); + chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()))); } @Override diff --git a/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java b/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java index aeda19ea475..8d7cebad2df 100644 --- a/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java @@ -75,7 +75,7 @@ public void testExtract2() { SPTEntry fwdEntry = new SPTEntry(0, 2, 0.6, new SPTEntry(1, 0)); SPTEntry bwdEntry = new SPTEntry(1, 2, 1.2, new SPTEntry(3, 0)); - Path p = DefaultBidirPathExtractor.extractPath(graph, new FastestWeighting(carEncoder, new DefaultTurnCostProvider(carEncoder, turnCostStorage)), fwdEntry, bwdEntry, 0); + Path p = DefaultBidirPathExtractor.extractPath(graph, new FastestWeighting(carEncoder, new DefaultTurnCostProvider(carEncoder.getTurnCostEnc(), turnCostStorage)), fwdEntry, bwdEntry, 0); p.setWeight(5 + 1.8); assertEquals(IntArrayList.from(1, 2, 3), p.calcNodes()); diff --git a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java index ec0101f37ed..20385628f9d 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java @@ -4,7 +4,6 @@ import com.carrotsearch.hppc.IntHashSet; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.*; import com.graphhopper.routing.weighting.AvoidEdgesWeighting; @@ -56,14 +55,14 @@ public void setup() { encodingManager = EncodingManager.create(encoder); accessEnc = encoder.getAccessEnc(); speedEnc = encoder.getAverageSpeedEnc(); + turnCostEnc = encoder.getTurnCostEnc(); graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); turnCostStorage = graph.getTurnCostStorage(); weighting = createWeighting(Weighting.INFINITE_U_TURN_COSTS); - turnCostEnc = encodingManager.getDecimalEncodedValue(TurnCost.key(encoder.toString())); } private Weighting createWeighting(int uTurnCosts) { - return new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, turnCostStorage, uTurnCosts)); + return new FastestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, uTurnCosts)); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java b/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java index b1968fec430..07bd7a1fb35 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java @@ -110,7 +110,7 @@ public Fixture(Algo algo, int uTurnCosts, boolean prepareCH, boolean prepareLM) encodingManager = EncodingManager.start().add(encoder).add(Subnetwork.create("c2")).build(); graph = new BaseGraph.Builder(encodingManager).setDir(dir).withTurnCosts(true).create(); turnCostStorage = graph.getTurnCostStorage(); - weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, turnCostStorage, uTurnCosts)); + weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), turnCostStorage, uTurnCosts)); chConfig = CHConfig.edgeBased("p1", weighting); // important: for LM preparation we need to use a weighting without turn costs #1960 lmConfig = new LMConfig("c2", new FastestWeighting(encoder)); diff --git a/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java b/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java index 08d668e736c..99cc4769034 100644 --- a/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java +++ b/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java @@ -157,7 +157,7 @@ private Weighting createWeighting() { } private Weighting createWeighting(int uTurnCosts) { - return new FastestWeighting(carEncoder, new DefaultTurnCostProvider(carEncoder, tcs, uTurnCosts)); + return new FastestWeighting(carEncoder, new DefaultTurnCostProvider(turnCostEnc, tcs, uTurnCosts)); } @ParameterizedTest @@ -418,7 +418,7 @@ public void testTurnCostsBug_991(String algoStr) { setTurnCost(g, 2, 5, 6, 3); setTurnCost(g, 1, 6, 7, 4); - FastestWeighting weighting = new FastestWeighting(carEncoder, new DefaultTurnCostProvider(carEncoder, tcs) { + FastestWeighting weighting = new FastestWeighting(carEncoder, new DefaultTurnCostProvider(turnCostEnc, tcs) { @Override public double calcTurnWeight(int edgeFrom, int nodeVia, int edgeTo) { if (edgeFrom >= 0) diff --git a/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java b/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java index c94deb7e817..caf2aa32d64 100644 --- a/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java @@ -55,7 +55,7 @@ public void setup() { encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", 5).putObject("speed_two_directions", true)); encodingManager = EncodingManager.create(encoder); graph = new BaseGraph.Builder(encodingManager).create(); - weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage())); + weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage())); na = graph.getNodeAccess(); } diff --git a/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java b/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java index d7822efc3ca..840347c8947 100644 --- a/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java @@ -63,7 +63,7 @@ private static final class Fixture { void freeze() { graph.freeze(); chConfig = traversalMode.isEdgeBased() - ? CHConfig.edgeBased("p", new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage(), uTurnCosts))) + ? CHConfig.edgeBased("p", new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage(), uTurnCosts))) : CHConfig.nodeBased("p", new FastestWeighting(encoder)); weighting = chConfig.getWeighting(); } diff --git a/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java b/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java index aa34b1b3eba..8c1ef5bd1c9 100644 --- a/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java @@ -125,7 +125,7 @@ private static class Fixture { turnCostStorage = graph.getTurnCostStorage(); chConfigs = Arrays.asList( CHConfig.nodeBased("p1", new FastestWeighting(encoder)), - CHConfig.edgeBased("p2", new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage()))) + CHConfig.edgeBased("p2", new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()))) ); // important: for LM preparation we need to use a weighting without turn costs #1960 lmConfig = new LMConfig("car", chConfigs.get(0).getWeighting()); diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java index 2229e52b020..ee54cb81d8a 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java @@ -71,6 +71,7 @@ public class CHTurnCostTest { private FlagEncoder encoder; private BooleanEncodedValue accessEnc; private DecimalEncodedValue speedEnc; + private DecimalEncodedValue turnCostEnc; private EncodingManager encodingManager; private BaseGraph graph; private TurnCostStorage turnCostStorage; @@ -85,6 +86,7 @@ public void init() { encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxCost)); accessEnc = encoder.getAccessEnc(); speedEnc = encoder.getAverageSpeedEnc(); + turnCostEnc = encoder.getTurnCostEnc(); encodingManager = EncodingManager.create(encoder); graph = new BaseGraph.Builder(encodingManager).build(); turnCostStorage = graph.getTurnCostStorage(); @@ -102,17 +104,17 @@ public void init() { private List createCHConfigs() { Set configs = new LinkedHashSet<>(5); // the first one is always the one with infinite u-turn costs - configs.add(CHConfig.edgeBased("p0", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, turnCostStorage, INFINITE_U_TURN_COSTS)))); + configs.add(CHConfig.edgeBased("p0", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, INFINITE_U_TURN_COSTS)))); // this one we also always add - configs.add(CHConfig.edgeBased("p1", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, turnCostStorage, 0)))); + configs.add(CHConfig.edgeBased("p1", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, 0)))); // ... and this one - configs.add(CHConfig.edgeBased("p2", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, turnCostStorage, 50)))); + configs.add(CHConfig.edgeBased("p2", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, 50)))); // add more (distinct) profiles long seed = System.nanoTime(); Random rnd = new Random(seed); while (configs.size() < 6) { int uTurnCosts = 10 + rnd.nextInt(90); - configs.add(CHConfig.edgeBased("p" + configs.size(), new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, turnCostStorage, uTurnCosts)))); + configs.add(CHConfig.edgeBased("p" + configs.size(), new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, uTurnCosts)))); } return new ArrayList<>(configs); } diff --git a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java index b6b0583fde6..03c8f67ed29 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java @@ -52,6 +52,7 @@ public class EdgeBasedNodeContractorTest { private FlagEncoder encoder; private BooleanEncodedValue accessEnc; private DecimalEncodedValue speedEnc; + private DecimalEncodedValue turnCostEnc; private BaseGraph graph; private Weighting weighting; private CHStorage chStore; @@ -69,11 +70,12 @@ private void initialize() { EncodingManager encodingManager = EncodingManager.create(encoder); accessEnc = encoder.getAccessEnc(); speedEnc = encoder.getAverageSpeedEnc(); + turnCostEnc = encoder.getTurnCostEnc(); graph = new BaseGraph.Builder(encodingManager).create(); chConfigs = Arrays.asList( - CHConfig.edgeBased("p1", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage()))), - CHConfig.edgeBased("p2", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage(), 60))), - CHConfig.edgeBased("p3", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage(), 0))) + CHConfig.edgeBased("p1", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage()))), + CHConfig.edgeBased("p2", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage(), 60))), + CHConfig.edgeBased("p3", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage(), 0))) ); } diff --git a/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java b/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java index 6ed17223ab6..5cec19ae916 100644 --- a/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java @@ -512,7 +512,7 @@ public void testTurnCostsProperlyPropagated_Issue282() { EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graphWithTurnCosts.edge(0, 1).setDistance(10)); EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graphWithTurnCosts.edge(2, 1).setDistance(10)); - Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, graphWithTurnCosts.getTurnCostStorage())); + Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graphWithTurnCosts.getTurnCostStorage())); // no turn costs initially assertEquals(0, weighting.calcTurnWeight(edge0.getEdge(), 1, edge1.getEdge()), .1); diff --git a/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java b/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java index 6c0dedfec8c..16e1a19feb5 100644 --- a/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java +++ b/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java @@ -142,7 +142,7 @@ public void testPrepareSubnetwork_withTurnCosts() { // since the middle edge is blocked the upper component is a subnetwork (regardless of turn costs) BaseGraph g = createSubnetworkTestStorage(em); PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList( - createJob(em, encoder, new DefaultTurnCostProvider(encoder, g.getTurnCostStorage(), 0)))); + createJob(em, encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), g.getTurnCostStorage(), 0)))); instance.setMinNetworkSize(4); assertEquals(3, instance.doWork()); assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, encoder)); @@ -152,7 +152,7 @@ public void testPrepareSubnetwork_withTurnCosts() { EdgeIteratorState edge = GHUtility.getEdge(g, 3, 4); GHUtility.setSpeed(10, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge); instance = new PrepareRoutingSubnetworks(g, Collections.singletonList( - createJob(em, encoder, new DefaultTurnCostProvider(encoder, g.getTurnCostStorage(), 0)))); + createJob(em, encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), g.getTurnCostStorage(), 0)))); instance.setMinNetworkSize(4); assertEquals(0, instance.doWork()); assertEquals(IntArrayList.from(), getSubnetworkEdges(g, encoder)); @@ -166,7 +166,7 @@ public void testPrepareSubnetwork_withTurnCosts() { g.getTurnCostStorage().set(turnCostEnc, 0, 4, 7, 1); g.getTurnCostStorage().set(turnCostEnc, 0, 4, 9, 1); instance = new PrepareRoutingSubnetworks(g, Collections.singletonList( - createJob(em, encoder, new DefaultTurnCostProvider(encoder, g.getTurnCostStorage(), 0)))); + createJob(em, encoder, new DefaultTurnCostProvider(turnCostEnc, g.getTurnCostStorage(), 0)))); instance.setMinNetworkSize(4); assertEquals(3, instance.doWork()); assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, encoder)); diff --git a/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java index f917787369d..a4c5f49fd1f 100644 --- a/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java @@ -49,7 +49,7 @@ public void testAccept_fwdLoopShortcut_acceptedByInExplorer() { GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 0).setDistance(3)); graph.freeze(); // add loop shortcut in 'fwd' direction - CHConfig chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage()))); + CHConfig chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()))); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); chBuilder.setIdentityLevels(); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java index 0ad7298d41e..1dfe8c6bc71 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java @@ -107,7 +107,7 @@ public void testTime() { @Test public void calcWeightAndTime_withTurnCosts() { BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); - Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage())); + Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage())); GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(100)); EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(100)); // turn costs are given in seconds @@ -119,7 +119,7 @@ public void calcWeightAndTime_withTurnCosts() { @Test public void calcWeightAndTime_uTurnCosts() { BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); - Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage(), 40)); + Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage(), 40)); EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(100)); assertEquals(6 + 40, GHUtility.calcWeightWithTurnWeight(weighting, edge, false, 0), 1.e-6); assertEquals((6 + 40) * 1000, GHUtility.calcMillisWithTurnMillis(weighting, edge, false, 0), 1.e-6); @@ -128,7 +128,7 @@ public void calcWeightAndTime_uTurnCosts() { @Test public void calcWeightAndTime_withTurnCosts_shortest() { BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); - Weighting weighting = new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage())); + Weighting weighting = new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage())); GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(100)); EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(100)); // turn costs are given in seconds diff --git a/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java b/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java index c854aea0b41..6add1ee811c 100644 --- a/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java +++ b/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java @@ -53,7 +53,7 @@ public String toString() { private void freeze() { graph.freeze(); - TurnCostProvider turnCostProvider = edgeBased ? new DefaultTurnCostProvider(encoder, graph.getTurnCostStorage()) : NO_TURN_COST_PROVIDER; + TurnCostProvider turnCostProvider = edgeBased ? new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()) : NO_TURN_COST_PROVIDER; CHConfig chConfig = new CHConfig("profile", new FastestWeighting(encoder, turnCostProvider), edgeBased); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); chBuilder = new CHStorageBuilder(chStore); From 15426ef4588797f3c0031722ecb64297b98bfc1c Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 22 Jun 2022 10:35:59 +0200 Subject: [PATCH 062/389] Remove FlagEncoder from ShortestWeighting and CustomWeighting --- .../routing/DefaultWeightingFactory.java | 2 +- .../routing/weighting/AbstractWeighting.java | 22 ++---- .../routing/weighting/FastestWeighting.java | 4 +- .../routing/weighting/ShortestWeighting.java | 13 ++-- .../weighting/custom/CustomModelParser.java | 2 +- .../weighting/custom/CustomWeighting.java | 8 +-- .../routing/AStarBidirectionTest.java | 2 +- .../routing/CHQueryWithTurnCostsTest.java | 2 +- .../routing/DijkstraBidirectionCHTest.java | 4 +- .../routing/DijkstraOneToManyTest.java | 2 +- .../com/graphhopper/routing/PathTest.java | 69 +++++++++++-------- .../routing/RoutingAlgorithmTest.java | 10 +-- ...fficChangeWithNodeOrderingReusingTest.java | 3 +- .../routing/ch/CHTurnCostTest.java | 8 +-- .../ch/EdgeBasedNodeContractorTest.java | 6 +- .../ch/NodeBasedNodeContractorTest.java | 2 +- .../ch/PrepareContractionHierarchiesTest.java | 6 +- .../routing/lm/LMPreparationHandlerTest.java | 2 +- .../routing/util/AccessFilterTest.java | 2 +- .../weighting/FastestWeightingTest.java | 13 ++-- .../util/PathSimplificationTest.java | 2 +- .../graphhopper/gpx/GpxConversionsTest.java | 2 +- 22 files changed, 90 insertions(+), 96 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java index eb0bcf754b1..df708867a5a 100644 --- a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java +++ b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java @@ -78,7 +78,7 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis queryCustomModel = CustomModel.merge(customProfile.getCustomModel(), queryCustomModel); weighting = CustomModelParser.createWeighting(encoder, encodingManager, turnCostProvider, queryCustomModel); } else if ("shortest".equalsIgnoreCase(weightingStr)) { - weighting = new ShortestWeighting(encoder, turnCostProvider); + weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), turnCostProvider); } else if ("fastest".equalsIgnoreCase(weightingStr)) { if (encoder.getPriorityEnc() != null) weighting = new PriorityWeighting(encoder, hints, turnCostProvider); diff --git a/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java index ecbb77f2869..158ed8af145 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java @@ -19,7 +19,6 @@ import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.FetchMode; @@ -29,24 +28,15 @@ * @author Peter Karich */ public abstract class AbstractWeighting implements Weighting { - protected final DecimalEncodedValue avSpeedEnc; protected final BooleanEncodedValue accessEnc; + protected final DecimalEncodedValue speedEnc; private final TurnCostProvider turnCostProvider; - protected AbstractWeighting(FlagEncoder encoder) { - this(encoder, NO_TURN_COST_PROVIDER); - } - - protected AbstractWeighting(FlagEncoder encoder, TurnCostProvider turnCostProvider) { - this(encoder.getAverageSpeedEnc(), encoder.getAccessEnc(), turnCostProvider); - } - - protected AbstractWeighting(DecimalEncodedValue avSpeedEnc, BooleanEncodedValue accessEnc, TurnCostProvider turnCostProvider) { + protected AbstractWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, TurnCostProvider turnCostProvider) { if (!isValidName(getName())) throw new IllegalStateException("Not a valid name for a Weighting: " + getName()); - - this.avSpeedEnc = avSpeedEnc; this.accessEnc = accessEnc; + this.speedEnc = speedEnc; this.turnCostProvider = turnCostProvider; } @@ -73,9 +63,9 @@ public long calcEdgeMillis(EdgeIteratorState edgeState, boolean reverse) { throw new IllegalStateException("Calculating time should not require to read speed from edge in wrong direction. " + "(" + edgeState.getBaseNode() + " - " + edgeState.getAdjNode() + ") " + edgeState.fetchWayGeometry(FetchMode.ALL) + ", dist: " + edgeState.getDistance() + " " - + "Reverse:" + reverse + ", fwd:" + edgeState.get(accessEnc) + ", bwd:" + edgeState.getReverse(accessEnc) + ", fwd-speed: " + edgeState.get(avSpeedEnc) + ", bwd-speed: " + edgeState.getReverse(avSpeedEnc)); + + "Reverse:" + reverse + ", fwd:" + edgeState.get(accessEnc) + ", bwd:" + edgeState.getReverse(accessEnc) + ", fwd-speed: " + edgeState.get(speedEnc) + ", bwd-speed: " + edgeState.getReverse(speedEnc)); - double speed = reverse ? edgeState.getReverse(avSpeedEnc) : edgeState.get(avSpeedEnc); + double speed = reverse ? edgeState.getReverse(speedEnc) : edgeState.get(speedEnc); if (Double.isInfinite(speed) || Double.isNaN(speed) || speed < 0) throw new IllegalStateException("Invalid speed stored in edge! " + speed); if (speed == 0) @@ -112,7 +102,7 @@ static boolean isValidName(String name) { @Override public String toString() { - return getName() + "|" + avSpeedEnc.getName().split("$")[0]; + return getName() + "|" + speedEnc.getName().split("$")[0]; } } diff --git a/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java index 9b9069ec603..c302384c51c 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java @@ -59,7 +59,7 @@ public FastestWeighting(FlagEncoder encoder, PMap map) { } public FastestWeighting(FlagEncoder encoder, PMap map, TurnCostProvider turnCostProvider) { - super(encoder, turnCostProvider); + super(encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), turnCostProvider); headingPenalty = map.getDouble(Routing.HEADING_PENALTY, Routing.DEFAULT_HEADING_PENALTY); headingPenaltyMillis = Math.round(headingPenalty * 1000); maxSpeed = encoder.getMaxSpeed() / SPEED_CONV; @@ -82,7 +82,7 @@ public double getMinWeight(double distance) { @Override public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { - double speed = reverse ? edgeState.getReverse(avSpeedEnc) : edgeState.get(avSpeedEnc); + double speed = reverse ? edgeState.getReverse(speedEnc) : edgeState.get(speedEnc); if (speed == 0) return Double.POSITIVE_INFINITY; diff --git a/core/src/main/java/com/graphhopper/routing/weighting/ShortestWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/ShortestWeighting.java index ba7a8bbdd52..5950173e9a0 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/ShortestWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/ShortestWeighting.java @@ -19,7 +19,6 @@ import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.util.EdgeIteratorState; import static com.graphhopper.routing.weighting.TurnCostProvider.NO_TURN_COST_PROVIDER; @@ -32,16 +31,12 @@ * @author Peter Karich */ public class ShortestWeighting extends AbstractWeighting { - public ShortestWeighting(FlagEncoder flagEncoder) { - this(flagEncoder, NO_TURN_COST_PROVIDER); + public ShortestWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { + this(accessEnc, speedEnc, NO_TURN_COST_PROVIDER); } - public ShortestWeighting(FlagEncoder flagEncoder, TurnCostProvider turnCostProvider) { - this(flagEncoder.getAverageSpeedEnc(), flagEncoder.getAccessEnc(), turnCostProvider); - } - - public ShortestWeighting(DecimalEncodedValue avgSpeedEnc, BooleanEncodedValue accessEnc, TurnCostProvider turnCostProvider) { - super(avgSpeedEnc, accessEnc, turnCostProvider); + public ShortestWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, TurnCostProvider turnCostProvider) { + super(accessEnc, speedEnc, turnCostProvider); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java index cba92ecb3ea..82c64f28ab8 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java @@ -80,7 +80,7 @@ public static CustomWeighting createWeighting(FlagEncoder baseFlagEncoder, Encod CustomWeighting.Parameters parameters = createWeightingParameters(customModel, lookup, avgSpeedEnc, baseFlagEncoder.getMaxSpeed(), priorityEnc); - return new CustomWeighting(baseFlagEncoder, turnCostProvider, parameters); + return new CustomWeighting(baseFlagEncoder.getAccessEnc(), baseFlagEncoder.getAverageSpeedEnc(), turnCostProvider, parameters); } /** diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java index 6d18985ef1e..a945061d5b6 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java @@ -18,7 +18,7 @@ package com.graphhopper.routing.weighting.custom; import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.weighting.AbstractWeighting; import com.graphhopper.routing.weighting.TurnCostProvider; import com.graphhopper.util.CustomModel; @@ -85,11 +85,11 @@ public final class CustomWeighting extends AbstractWeighting { private final EdgeToDoubleMapping edgeToSpeedMapping; private final EdgeToDoubleMapping edgeToPriorityMapping; - public CustomWeighting(FlagEncoder baseFlagEncoder, TurnCostProvider turnCostProvider, Parameters parameters) { - super(baseFlagEncoder, turnCostProvider); + public CustomWeighting(BooleanEncodedValue baseAccessEnc, DecimalEncodedValue baseSpeedEnc, TurnCostProvider turnCostProvider, Parameters parameters) { + super(baseAccessEnc, baseSpeedEnc, turnCostProvider); this.edgeToSpeedMapping = parameters.getEdgeToSpeedMapping(); this.edgeToPriorityMapping = parameters.getEdgeToPriorityMapping(); - this.baseVehicleAccessEnc = baseFlagEncoder.getAccessEnc(); + this.baseVehicleAccessEnc = baseAccessEnc; this.headingPenaltySeconds = parameters.getHeadingPenaltySeconds(); this.maxSpeed = parameters.getMaxSpeed() / SPEED_CONV; this.maxPriority = parameters.getMaxPriority(); diff --git a/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java b/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java index dce8e6281f5..a65ccbe324d 100644 --- a/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java +++ b/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java @@ -70,7 +70,7 @@ void infeasibleApproximator_noException() { GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 10).setDistance(100)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(10, 2).setDistance(100)); - Weighting weighting = new ShortestWeighting(encoder); + Weighting weighting = new ShortestWeighting(accessEnc, speedEnc); AStarBidirection algo = new AStarBidirection(graph, weighting, TraversalMode.NODE_BASED); algo.setApproximation(new InfeasibleApproximator()); Path path = algo.calcPath(0, 9); diff --git a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java index 648214574dc..497a9eb8a83 100644 --- a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java @@ -69,7 +69,7 @@ private static class Fixture { public Fixture(String algoString) { this.algoString = algoString; graph = new BaseGraph.Builder(encodingManager).create(); - chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()))); + chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()))); } @Override diff --git a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java index 5e6d861945f..5c7fb6c11a5 100644 --- a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java @@ -62,7 +62,7 @@ public void testBaseGraph() { RoutingAlgorithmTest.initDirectedAndDiffSpeed(graph, carEncoder); // do CH preparation for car - ShortestWeighting weighting = new ShortestWeighting(carEncoder); + ShortestWeighting weighting = new ShortestWeighting(carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc()); prepareCH(graph, CHConfig.nodeBased(weighting.getName(), weighting)); // use base graph for solving normal Dijkstra @@ -132,7 +132,7 @@ public void testStallingNodesReducesNumberOfVisitedNodes() { GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(3, 9).setDistance(200)); graph.freeze(); - ShortestWeighting weighting = new ShortestWeighting(carEncoder); + ShortestWeighting weighting = new ShortestWeighting(carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc()); CHConfig chConfig = CHConfig.nodeBased(weighting.getName(), weighting); CHStorage store = CHStorage.fromGraph(graph, chConfig); diff --git a/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java b/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java index 977fd49382d..204045bc984 100644 --- a/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java +++ b/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java @@ -47,7 +47,7 @@ public class DijkstraOneToManyTest { public DijkstraOneToManyTest() { encodingManager = EncodingManager.create("car"); encoder = encodingManager.getEncoder("car"); - defaultWeighting = new ShortestWeighting(encoder); + defaultWeighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); } private static void initGraphWeightLimit(Graph graph, FlagEncoder encoder) { diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index a41322341aa..1f788bfecf7 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -209,7 +209,7 @@ public void testFindInstruction() { @Test public void testCalcInstructionsRoundabout() { for (FlagEncoder encoder : mixedEncoders.fetchEdgeEncoders()) { - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 8); assertTrue(p.isFound()); @@ -244,7 +244,8 @@ public void testCalcInstructionsRoundabout() { @Test public void testCalcInstructionsRoundaboutBegin() { - ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car")); + FlagEncoder encoder = mixedEncoders.getEncoder("car"); + ShortestWeighting weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(2, 8); assertTrue(p.isFound()); @@ -258,7 +259,8 @@ public void testCalcInstructionsRoundaboutBegin() { @Test public void testCalcInstructionsRoundaboutDirectExit() { roundaboutGraph.inverse3to9(); - ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car")); + FlagEncoder encoder = mixedEncoders.getEncoder("car"); + ShortestWeighting weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(6, 8); assertTrue(p.isFound()); @@ -273,7 +275,7 @@ public void testCalcInstructionsRoundaboutDirectExit() { @Test public void testCalcAverageSpeedDetails() { - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); assertTrue(p.isFound()); @@ -297,7 +299,7 @@ public void testCalcAverageSpeedDetails() { @Test public void testCalcAverageSpeedDetailsWithShortDistances_issue1848() { - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(1, 6); assertTrue(p.isFound()); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, @@ -319,7 +321,7 @@ public void testCalcAverageSpeedDetailsWithShortDistances_issue1848() { @Test public void testCalcStreetNameDetails() { - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); assertTrue(p.isFound()); @@ -345,7 +347,7 @@ public void testCalcStreetNameDetails() { @Test public void testCalcEdgeIdDetails() { - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); assertTrue(p.isFound()); @@ -370,7 +372,7 @@ public void testCalcEdgeIdDetails() { @Test public void testCalcEdgeKeyDetailsForward() { - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); assertTrue(p.isFound()); @@ -387,7 +389,7 @@ public void testCalcEdgeKeyDetailsForward() { @Test public void testCalcEdgeKeyDetailsBackward() { - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(5, 1); assertTrue(p.isFound()); @@ -404,7 +406,7 @@ public void testCalcEdgeKeyDetailsBackward() { @Test public void testCalcTimeDetails() { - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); assertTrue(p.isFound()); @@ -428,7 +430,7 @@ public void testCalcTimeDetails() { @Test public void testCalcDistanceDetails() { - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); assertTrue(p.isFound()); @@ -449,7 +451,8 @@ public void testCalcDistanceDetails() { @Test public void testCalcInstructionsRoundabout2() { roundaboutGraph.inverse3to6(); - ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car")); + FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 8); assertTrue(p.isFound()); @@ -521,7 +524,7 @@ public void testCalcInstructionsRoundaboutIssue353() { GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 8).setDistance(5)).setName("5-8"); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 6).setDistance(5)).setName("3-6"); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) .calcPath(6, 11); assertTrue(p.isFound()); @@ -535,7 +538,8 @@ public void testCalcInstructionsRoundaboutIssue353() { @Test public void testCalcInstructionsRoundaboutClockwise() { roundaboutGraph.setRoundabout(true); - ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car")); + FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 8); assertTrue(p.isFound()); @@ -554,7 +558,8 @@ public void testCalcInstructionsRoundaboutClockwise() { @Test public void testCalcInstructionsIgnoreContinue() { // Follow a couple of straight edges, including a name change - ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car")); + FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(4, 11); assertTrue(p.isFound()); @@ -567,7 +572,8 @@ public void testCalcInstructionsIgnoreContinue() { @Test public void testCalcInstructionsIgnoreTurnIfNoAlternative() { // The street turns left, but there is not turn - ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car")); + FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(10, 12); assertTrue(p.isFound()); @@ -599,7 +605,7 @@ public void testCalcInstructionForForkWithSameName() { GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setName("Regener Weg"); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) .calcPath(1, 4); assertTrue(p.isFound()); @@ -632,7 +638,7 @@ public void testCalcInstructionForMotorwayFork() { GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setName("A 8").set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, true); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) .calcPath(1, 4); assertTrue(p.isFound()); @@ -660,7 +666,7 @@ public void testCalcInstructionsEnterMotorway() { GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setName("A 8"); GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 2).setDistance(5)).setName("A 8"); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) .calcPath(4, 3); assertTrue(p.isFound()); @@ -689,7 +695,7 @@ public void testCalcInstructionsMotorwayJunction() { GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("A 8"); GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setName("A 8"); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 3); assertTrue(p.isFound()); @@ -719,7 +725,7 @@ public void testCalcInstructionsOntoOneway() { GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("Pacific Highway"); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(4, 2).setDistance(5)).setName("Greenwich Road"); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) .calcPath(4, 3); assertTrue(p.isFound()); @@ -754,7 +760,7 @@ public void testCalcInstructionIssue1047() { GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setName("S 108").set(roadClassEnc, RoadClass.SECONDARY).set(roadClassLinkEnc, false); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("B 156").set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 4); assertTrue(p.isFound()); @@ -788,7 +794,7 @@ public void testCalcInstructionContinueLeavingStreet() { GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("Regener Weg"); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 4); assertTrue(p.isFound()); @@ -818,7 +824,7 @@ public void testCalcInstructionSlightTurn() { GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setName("Stöhrgasse"); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) .calcPath(4, 1); assertTrue(p.isFound()); @@ -856,7 +862,7 @@ public void testUTurnLeft() { g.edge(2, 5).setDistance(5).setName("Neithardtstraße"), g.edge(5, 7).setDistance(5).setName("Neithardtstraße")); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 4); assertTrue(p.isFound()); @@ -894,7 +900,7 @@ public void testUTurnRight() { g.edge(2, 5).setDistance(5).setName("Larkin Street"), g.edge(5, 7).setDistance(5).setName("Larkin Street")); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 6); assertTrue(p.isFound()); @@ -907,7 +913,8 @@ public void testUTurnRight() { @Test public void testCalcInstructionsForTurn() { // The street turns left, but there is not turn - ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car")); + FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(11, 13); assertTrue(p.isFound()); @@ -922,7 +929,8 @@ public void testCalcInstructionsForTurn() { @Test public void testCalcInstructionsForSlightTurnWithOtherSlightTurn() { // Test for a fork with two sligh turns. Since there are two sligh turns, show the turn instruction - ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car")); + FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(12, 16); assertTrue(p.isFound()); @@ -953,7 +961,7 @@ public void testCalcInstructionsForSlightTurnOntoDifferentStreet() { GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("Calmbacher Straße, K 4312"); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(3, 4).setDistance(5)).setName("Calmbacher Straße, K 4312"); - ShortestWeighting weighting = new ShortestWeighting(encoder); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 2); assertTrue(p.isFound()); @@ -966,7 +974,8 @@ public void testCalcInstructionsForSlightTurnOntoDifferentStreet() { @Test public void testIgnoreInstructionsForSlightTurnWithOtherTurn() { // Test for a fork with one sligh turn and one actual turn. We are going along the slight turn. No turn instruction needed in this case - ShortestWeighting weighting = new ShortestWeighting(mixedEncoders.getEncoder("car")); + FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(16, 19); assertTrue(p.isFound()); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java index 56ea6b63a78..9cb1bcfe23f 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java @@ -105,12 +105,12 @@ public Fixture(PathCalculator pathCalculator, TraversalMode traversalMode) { carEncoder = encodingManager.getEncoder("car"); footEncoder = encodingManager.getEncoder("foot"); bike2Encoder = encodingManager.getEncoder("bike2"); + carAccessEnc = carEncoder.getAccessEnc(); + carSpeedEnc = carEncoder.getAverageSpeedEnc(); // most tests use the default weighting, but this can be chosen for each test separately - defaultWeighting = new ShortestWeighting(carEncoder); + defaultWeighting = new ShortestWeighting(carAccessEnc, carSpeedEnc); // most tests do not limit the number of visited nodes, but this can be chosen for each test separately defaultMaxVisitedNodes = Integer.MAX_VALUE; - carAccessEnc = carEncoder.getAccessEnc(); - carSpeedEnc = carEncoder.getAverageSpeedEnc(); } @Override @@ -343,7 +343,7 @@ static void initDirectedAndDiffSpeed(Graph graph, FlagEncoder enc) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testCalcFootPath(Fixture f) { - ShortestWeighting shortestWeighting = new ShortestWeighting(f.footEncoder); + ShortestWeighting shortestWeighting = new ShortestWeighting(f.footEncoder.getAccessEnc(), f.footEncoder.getAverageSpeedEnc()); BaseGraph graph = f.createGHStorage(false); initFootVsCar(f.carEncoder, f.footEncoder, graph); Path p1 = f.calcPath(graph, shortestWeighting, 0, 7); @@ -755,7 +755,7 @@ public void testDirectedGraphBug2(Fixture f) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testWithCoordinates(Fixture f) { - Weighting weighting = new ShortestWeighting(f.carEncoder); + Weighting weighting = new ShortestWeighting(f.carAccessEnc, f.carSpeedEnc); BaseGraph graph = f.createGHStorage(false); GHUtility.setSpeed(60, true, true, f.carAccessEnc, f.carSpeedEnc, graph.edge(0, 1).setDistance(2)). setWayGeometry(Helper.createPointList(1.5, 1)); diff --git a/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java b/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java index fe81932c04b..d0ea3eaf111 100644 --- a/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java +++ b/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java @@ -7,6 +7,7 @@ import com.graphhopper.routing.util.*; import com.graphhopper.routing.weighting.AbstractWeighting; import com.graphhopper.routing.weighting.FastestWeighting; +import com.graphhopper.routing.weighting.TurnCostProvider; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.*; import com.graphhopper.util.EdgeIteratorState; @@ -193,7 +194,7 @@ private static class RandomDeviationWeighting extends AbstractWeighting { private final double maxDeviationPercentage; public RandomDeviationWeighting(Weighting baseWeighting, FlagEncoder encoder, double maxDeviationPercentage) { - super(encoder); + super(encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), TurnCostProvider.NO_TURN_COST_PROVIDER); this.baseWeighting = baseWeighting; this.maxDeviationPercentage = maxDeviationPercentage; } diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java index ee54cb81d8a..a0975512b0a 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java @@ -104,17 +104,17 @@ public void init() { private List createCHConfigs() { Set configs = new LinkedHashSet<>(5); // the first one is always the one with infinite u-turn costs - configs.add(CHConfig.edgeBased("p0", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, INFINITE_U_TURN_COSTS)))); + configs.add(CHConfig.edgeBased("p0", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, INFINITE_U_TURN_COSTS)))); // this one we also always add - configs.add(CHConfig.edgeBased("p1", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, 0)))); + configs.add(CHConfig.edgeBased("p1", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, 0)))); // ... and this one - configs.add(CHConfig.edgeBased("p2", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, 50)))); + configs.add(CHConfig.edgeBased("p2", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, 50)))); // add more (distinct) profiles long seed = System.nanoTime(); Random rnd = new Random(seed); while (configs.size() < 6) { int uTurnCosts = 10 + rnd.nextInt(90); - configs.add(CHConfig.edgeBased("p" + configs.size(), new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, uTurnCosts)))); + configs.add(CHConfig.edgeBased("p" + configs.size(), new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, uTurnCosts)))); } return new ArrayList<>(configs); } diff --git a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java index 03c8f67ed29..15f2baac8b9 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java @@ -73,9 +73,9 @@ private void initialize() { turnCostEnc = encoder.getTurnCostEnc(); graph = new BaseGraph.Builder(encodingManager).create(); chConfigs = Arrays.asList( - CHConfig.edgeBased("p1", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage()))), - CHConfig.edgeBased("p2", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage(), 60))), - CHConfig.edgeBased("p3", new ShortestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage(), 0))) + CHConfig.edgeBased("p1", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage()))), + CHConfig.edgeBased("p2", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage(), 60))), + CHConfig.edgeBased("p3", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage(), 0))) ); } diff --git a/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java index 53fb5ed8e32..58ff8b62df1 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java @@ -46,7 +46,7 @@ public class NodeBasedNodeContractorTest { private final EncodingManager encodingManager = EncodingManager.create(encoder); private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); private final DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); - private final Weighting weighting = new ShortestWeighting(encoder); + private final Weighting weighting = new ShortestWeighting(accessEnc, speedEnc); private final BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); private final CHConfig chConfig = CHConfig.nodeBased("profile", weighting); private CHStorage store; diff --git a/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java b/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java index 0ecd7a86a0c..997af933d0d 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java @@ -46,7 +46,7 @@ public class PrepareContractionHierarchiesTest { private final FlagEncoder carEncoder = FlagEncoders.createCar(new PMap().putObject("speed_two_directions", true)); private final EncodingManager encodingManager = EncodingManager.create(carEncoder); - private final Weighting weighting = new ShortestWeighting(carEncoder); + private final Weighting weighting = new ShortestWeighting(carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc()); private final CHConfig chConfig = CHConfig.nodeBased("c", weighting); private BaseGraph g; @@ -488,8 +488,8 @@ public void testMultiplePreparationsIdenticalView() { EncodingManager tmpEncodingManager = EncodingManager.create(tmpCarEncoder, tmpBikeEncoder); // FastestWeighting would lead to different shortcuts due to different default speeds for bike and car - CHConfig carProfile = CHConfig.nodeBased("c1", new ShortestWeighting(tmpCarEncoder)); - CHConfig bikeProfile = CHConfig.nodeBased("c2", new ShortestWeighting(tmpBikeEncoder)); + CHConfig carProfile = CHConfig.nodeBased("c1", new ShortestWeighting(tmpCarEncoder.getAccessEnc(), tmpCarEncoder.getAverageSpeedEnc())); + CHConfig bikeProfile = CHConfig.nodeBased("c2", new ShortestWeighting(tmpBikeEncoder.getAccessEnc(), tmpBikeEncoder.getAverageSpeedEnc())); BaseGraph graph = new BaseGraph.Builder(tmpEncodingManager).create(); initShortcutsGraph(graph, tmpCarEncoder); diff --git a/core/src/test/java/com/graphhopper/routing/lm/LMPreparationHandlerTest.java b/core/src/test/java/com/graphhopper/routing/lm/LMPreparationHandlerTest.java index 1c221ad22ac..c8968e5b3c2 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/LMPreparationHandlerTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/LMPreparationHandlerTest.java @@ -39,7 +39,7 @@ public void maximumLMWeight() { EncodingManager em = EncodingManager.create(car); List lmConfigs = Arrays.asList( new LMConfig("conf1", new FastestWeighting(car)), - new LMConfig("conf2", new ShortestWeighting(car)) + new LMConfig("conf2", new ShortestWeighting(car.getAccessEnc(), car.getAverageSpeedEnc())) ); List preparations = handler.createPreparations(lmConfigs, new BaseGraph.Builder(em).build(), em, null); assertEquals(1, preparations.get(0).getLandmarkStorage().getFactor(), .1); diff --git a/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java index a4c5f49fd1f..ff4606da89c 100644 --- a/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java @@ -49,7 +49,7 @@ public void testAccept_fwdLoopShortcut_acceptedByInExplorer() { GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 0).setDistance(3)); graph.freeze(); // add loop shortcut in 'fwd' direction - CHConfig chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()))); + CHConfig chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()))); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); chBuilder.setIdentityLevels(); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java index 1dfe8c6bc71..625784a0732 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java @@ -18,10 +18,7 @@ package com.graphhopper.routing.weighting; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.RoadAccess; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.VirtualEdgeIteratorState; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; @@ -43,6 +40,8 @@ public class FastestWeightingTest { private final FlagEncoder encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", 10)); private final EncodingManager encodingManager = EncodingManager.create(encoder); + private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); + private final DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); @Test public void testMinWeightHasSameUnitAs_getWeight() { @@ -128,9 +127,9 @@ public void calcWeightAndTime_uTurnCosts() { @Test public void calcWeightAndTime_withTurnCosts_shortest() { BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); - Weighting weighting = new ShortestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage())); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(100)); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(100)); + Weighting weighting = new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage())); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(100)); // turn costs are given in seconds setTurnCost(graph, 0, 1, 2, 5); // todo: for the shortest weighting turn costs cannot be interpreted as seconds? at least when they are added diff --git a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java index 49dcce6a900..cff4cb26800 100644 --- a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java +++ b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java @@ -107,7 +107,7 @@ public void testScenario() { tmpEdge.setWayGeometry(list); // Path is: [0 0-1, 3 1-4, 6 4-7, 9 7-8, 11 8-9, 10 9-10] - ShortestWeighting weighting = new ShortestWeighting(carEncoder); + ShortestWeighting weighting = new ShortestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(0, 10); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, usTR); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, diff --git a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java index a59db457345..9053834d1f2 100644 --- a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java +++ b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java @@ -87,7 +87,7 @@ public void testInstructionsWithTimeAndPlace() { GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000).setName("3-7")); GHUtility.setSpeed(90, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000).setName("4-5")); - ShortestWeighting weighting = new ShortestWeighting(carEncoder); + ShortestWeighting weighting = new ShortestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, trMap.getWithFallBack(Locale.US)); PointList points = p.calcPoints(); From 91a80a4f3974174dda981e841324a1c86d4f5b17 Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Wed, 22 Jun 2022 12:40:11 +0200 Subject: [PATCH 063/389] Find strongly-connected components of station (stop) graph (#2608) --- .../graphhopper/gtfs/analysis/Analysis.java | 59 ++++ .../gtfs/analysis/PtGraphAsAdjacencyList.java | 320 ++++++++++++++++++ .../gtfs/analysis/AnalysisTest.java | 78 +++++ 3 files changed, 457 insertions(+) create mode 100644 reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/Analysis.java create mode 100644 reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java create mode 100644 reader-gtfs/src/test/java/com/graphhopper/gtfs/analysis/AnalysisTest.java diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/Analysis.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/Analysis.java new file mode 100644 index 00000000000..3fb84fdae45 --- /dev/null +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/Analysis.java @@ -0,0 +1,59 @@ +package com.graphhopper.gtfs.analysis; + +import com.carrotsearch.hppc.BitSetIterator; +import com.carrotsearch.hppc.IntArrayList; +import com.carrotsearch.hppc.cursors.IntCursor; +import com.graphhopper.gtfs.GtfsStorage; +import com.graphhopper.gtfs.PtGraph; +import com.graphhopper.routing.subnetwork.TarjanSCC; +import com.graphhopper.routing.util.EdgeFilter; + +import java.util.*; + +import static com.graphhopper.gtfs.GtfsStorage.EdgeType.ENTER_PT; + +public class Analysis { + + + public static List> findStronglyConnectedComponentsOfStopGraph(PtGraph ptGraph) { + PtGraphAsAdjacencyList ptGraphAsAdjacencyList = new PtGraphAsAdjacencyList(ptGraph); + TarjanSCC.ConnectedComponents components = TarjanSCC.findComponents(ptGraphAsAdjacencyList, EdgeFilter.ALL_EDGES, false); + List> stronglyConnectedComponentsOfStopGraph = new ArrayList<>(); + for (IntArrayList component : components.getComponents()) { + ArrayList stopsOfComponent = new ArrayList<>(); + for (IntCursor intCursor : component) { + stopsOfComponent.addAll(getStopsForNode(ptGraph, intCursor.value)); + } + if (!stopsOfComponent.isEmpty()) { + stronglyConnectedComponentsOfStopGraph.add(stopsOfComponent); + } + } + BitSetIterator iter = components.getSingleNodeComponents().iterator(); + for (int i = iter.nextSetBit(); i >= 0; i = iter.nextSetBit()) { + List stopsForNode = getStopsForNode(ptGraph, i); + if (!stopsForNode.isEmpty()) { + stronglyConnectedComponentsOfStopGraph.add(stopsForNode); + } + } + return stronglyConnectedComponentsOfStopGraph; + } + + public static List getStopsForNode(PtGraph ptGraph, int i) { + EnumSet inEdgeTypes = EnumSet.noneOf(GtfsStorage.EdgeType.class); + for (PtGraph.PtEdge ptEdge : ptGraph.backEdgesAround(i)) { + inEdgeTypes.add(ptEdge.getType()); + } + EnumSet outEdgeTypes = EnumSet.noneOf(GtfsStorage.EdgeType.class); + for (PtGraph.PtEdge ptEdge : ptGraph.edgesAround(i)) { + outEdgeTypes.add(ptEdge.getType()); + } + if (inEdgeTypes.equals(EnumSet.of(GtfsStorage.EdgeType.EXIT_PT)) && outEdgeTypes.equals((EnumSet.of(ENTER_PT)))) { + Set stops = new HashSet<>(); + ptGraph.backEdgesAround(i).forEach(e -> stops.add(new GtfsStorage.FeedIdWithStopId(e.getAttrs().platformDescriptor.feed_id, e.getAttrs().platformDescriptor.stop_id))); + ptGraph.edgesAround(i).forEach(e -> stops.add(new GtfsStorage.FeedIdWithStopId(e.getAttrs().platformDescriptor.feed_id, e.getAttrs().platformDescriptor.stop_id))); + return new ArrayList<>(stops); + } else { + return Collections.emptyList(); + } + } +} diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java new file mode 100644 index 00000000000..705703e65e4 --- /dev/null +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java @@ -0,0 +1,320 @@ +package com.graphhopper.gtfs.analysis; + +import com.graphhopper.gtfs.PtGraph; +import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.util.AllEdgesIterator; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.storage.*; +import com.graphhopper.util.*; +import com.graphhopper.util.shapes.BBox; + +import java.util.Iterator; + +class PtGraphAsAdjacencyList implements Graph { + private final PtGraph ptGraph; + + public PtGraphAsAdjacencyList(PtGraph ptGraph) { + this.ptGraph = ptGraph; + } + + @Override + public BaseGraph getBaseGraph() { + throw new RuntimeException(); + } + + @Override + public int getNodes() { + return ptGraph.getNodeCount(); + } + + @Override + public int getEdges() { + throw new RuntimeException(); + } + + @Override + public NodeAccess getNodeAccess() { + throw new RuntimeException(); + } + + @Override + public BBox getBounds() { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState edge(int a, int b) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState getEdgeIteratorState(int edgeId, int adjNode) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState getEdgeIteratorStateForKey(int edgeKey) { + throw new RuntimeException(); + } + + @Override + public int getOtherNode(int edge, int node) { + throw new RuntimeException(); + } + + @Override + public boolean isAdjacentToNode(int edge, int node) { + throw new RuntimeException(); + } + + @Override + public AllEdgesIterator getAllEdges() { + throw new RuntimeException(); + } + + @Override + public EdgeExplorer createEdgeExplorer(EdgeFilter filter) { + return new StationGraphEdgeExplorer(); + } + + @Override + public TurnCostStorage getTurnCostStorage() { + throw new RuntimeException(); + } + + @Override + public Weighting wrapWeighting(Weighting weighting) { + throw new RuntimeException(); + } + + private class StationGraphEdgeExplorer implements EdgeExplorer { + private int baseNode; + + @Override + public EdgeIterator setBaseNode(int baseNode) { + this.baseNode = baseNode; + return new StationGraphEdgeIterator(ptGraph.edgesAround(baseNode).iterator()); + } + + private class StationGraphEdgeIterator implements EdgeIterator { + private final Iterator iterator; + private PtGraph.PtEdge currentElement; + + public StationGraphEdgeIterator(Iterator iterator) { + this.iterator = iterator; + } + + @Override + public boolean next() { + if (iterator.hasNext()) { + this.currentElement = iterator.next(); + return true; + } else { + return false; + } + } + + @Override + public int getEdge() { + throw new RuntimeException(); + } + + @Override + public int getEdgeKey() { + throw new RuntimeException(); + } + + @Override + public int getReverseEdgeKey() { + throw new RuntimeException(); + } + + @Override + public int getBaseNode() { + throw new RuntimeException(); + } + + @Override + public int getAdjNode() { + assert currentElement.getBaseNode() == baseNode; + return currentElement.getAdjNode(); + } + + @Override + public PointList fetchWayGeometry(FetchMode mode) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState setWayGeometry(PointList list) { + throw new RuntimeException(); + } + + @Override + public double getDistance() { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState setDistance(double dist) { + throw new RuntimeException(); + } + + @Override + public IntsRef getFlags() { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState setFlags(IntsRef edgeFlags) { + throw new RuntimeException(); + } + + @Override + public boolean get(BooleanEncodedValue property) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState set(BooleanEncodedValue property, boolean value) { + throw new RuntimeException(); + } + + @Override + public boolean getReverse(BooleanEncodedValue property) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState setReverse(BooleanEncodedValue property, boolean value) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState set(BooleanEncodedValue property, boolean fwd, boolean bwd) { + throw new RuntimeException(); + } + + @Override + public int get(IntEncodedValue property) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState set(IntEncodedValue property, int value) { + throw new RuntimeException(); + } + + @Override + public int getReverse(IntEncodedValue property) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState setReverse(IntEncodedValue property, int value) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState set(IntEncodedValue property, int fwd, int bwd) { + throw new RuntimeException(); + } + + @Override + public double get(DecimalEncodedValue property) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState set(DecimalEncodedValue property, double value) { + throw new RuntimeException(); + } + + @Override + public double getReverse(DecimalEncodedValue property) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState setReverse(DecimalEncodedValue property, double value) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState set(DecimalEncodedValue property, double fwd, double bwd) { + throw new RuntimeException(); + } + + @Override + public > T get(EnumEncodedValue property) { + throw new RuntimeException(); + } + + @Override + public > EdgeIteratorState set(EnumEncodedValue property, T value) { + throw new RuntimeException(); + } + + @Override + public > T getReverse(EnumEncodedValue property) { + throw new RuntimeException(); + } + + @Override + public > EdgeIteratorState setReverse(EnumEncodedValue property, T value) { + throw new RuntimeException(); + } + + @Override + public > EdgeIteratorState set(EnumEncodedValue property, T fwd, T bwd) { + throw new RuntimeException(); + } + + @Override + public String get(StringEncodedValue property) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState set(StringEncodedValue property, String value) { + throw new RuntimeException(); + } + + @Override + public String getReverse(StringEncodedValue property) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState setReverse(StringEncodedValue property, String value) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState set(StringEncodedValue property, String fwd, String bwd) { + throw new RuntimeException(); + } + + @Override + public String getName() { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState setName(String name) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState detach(boolean reverse) { + throw new RuntimeException(); + } + + @Override + public EdgeIteratorState copyPropertiesFrom(EdgeIteratorState e) { + throw new RuntimeException(); + } + } + } +} diff --git a/reader-gtfs/src/test/java/com/graphhopper/gtfs/analysis/AnalysisTest.java b/reader-gtfs/src/test/java/com/graphhopper/gtfs/analysis/AnalysisTest.java new file mode 100644 index 00000000000..924d155efa6 --- /dev/null +++ b/reader-gtfs/src/test/java/com/graphhopper/gtfs/analysis/AnalysisTest.java @@ -0,0 +1,78 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.gtfs.analysis; + +import com.graphhopper.GraphHopperConfig; +import com.graphhopper.config.Profile; +import com.graphhopper.gtfs.GraphHopperGtfs; +import com.graphhopper.gtfs.GtfsStorage; +import com.graphhopper.gtfs.PtGraph; +import com.graphhopper.util.Helper; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class AnalysisTest { + + private static final String GRAPH_LOC = "target/AnotherAgencyIT"; + private static GraphHopperGtfs graphHopperGtfs; + + @BeforeAll + public static void init() { + GraphHopperConfig ghConfig = new GraphHopperConfig(); + ghConfig.putObject("graph.location", GRAPH_LOC); + ghConfig.putObject("datareader.file", "files/beatty.osm"); + ghConfig.putObject("gtfs.file", "files/sample-feed,files/another-sample-feed"); + ghConfig.setProfiles(Arrays.asList( + new Profile("foot").setVehicle("foot").setWeighting("fastest"), + new Profile("car").setVehicle("car").setWeighting("fastest"))); + Helper.removeDir(new File(GRAPH_LOC)); + graphHopperGtfs = new GraphHopperGtfs(ghConfig); + graphHopperGtfs.init(ghConfig); + graphHopperGtfs.importOrLoad(); + } + + @AfterAll + public static void close() { + graphHopperGtfs.close(); + } + + @Test + public void testStronglyConnectedComponentsOfStopGraph() { + PtGraph ptGraph = graphHopperGtfs.getPtGraph(); + List> stronglyConnectedComponentsOfStopGraph = Analysis.findStronglyConnectedComponentsOfStopGraph(ptGraph); + List largestComponent = stronglyConnectedComponentsOfStopGraph.get(0); + + assertThat(largestComponent) + .extracting("stopId") + .containsExactlyInAnyOrder("EMSI", "DADAN", "NADAV", "NANAA", "STAGECOACH", "AMV", "FUR_CREEK_RES", "BULLFROG", "BEATTY_AIRPORT", "AIRPORT"); + + List> singleElementComponents = stronglyConnectedComponentsOfStopGraph.subList(1, 4); + assertThat(singleElementComponents.stream().map(it -> it.get(0))) + .extracting("stopId") + .containsExactlyInAnyOrder("JUSTICE_COURT", "MUSEUM", "NEXT_TO_MUSEUM"); + } + +} From 3f7383a487ebbd942a9eb8a34985917ac3f21471 Mon Sep 17 00:00:00 2001 From: Andi Date: Thu, 23 Jun 2022 16:12:49 +0200 Subject: [PATCH 064/389] Load EncodingManager from properties instead of config (#2607) --- .../java/com/graphhopper/GraphHopper.java | 128 +++++++++++------- .../routing/ev/DecimalEncodedValueImpl.java | 25 ++-- .../graphhopper/routing/ev/EncodedValue.java | 9 -- .../routing/ev/EncodedValueSerializer.java | 28 ++-- .../routing/ev/EnumEncodedValue.java | 21 +-- .../routing/ev/IntEncodedValueImpl.java | 124 ++--------------- .../routing/ev/SimpleBooleanEncodedValue.java | 16 ++- .../routing/ev/StringEncodedValue.java | 29 ++-- .../util/DefaultFlagEncoderFactory.java | 24 ++++ .../routing/util/EncodingManager.java | 40 ++++-- .../routing/util/FlagEncoderFactory.java | 5 + .../routing/util/VehicleEncodedValues.java | 14 +- .../storage/StorableProperties.java | 7 +- .../java/com/graphhopper/util/Constants.java | 2 + .../graphhopper/util/EdgeIteratorState.java | 5 - .../graphhopper/GraphHopperProfileTest.java | 20 +-- .../java/com/graphhopper/GraphHopperTest.java | 10 +- .../reader/osm/GraphHopperOSMTest.java | 94 ++++++------- .../graphhopper/reader/osm/OSMReaderTest.java | 19 ++- .../ev/EncodedValueSerializerTest.java | 50 +++++-- 20 files changed, 332 insertions(+), 338 deletions(-) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index db7a5a79dd9..8582b1f9e00 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -18,10 +18,13 @@ package com.graphhopper; import com.bedatadriven.jackson.datatype.jts.JtsModule; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; +import com.graphhopper.jackson.Jackson; import com.graphhopper.reader.dem.*; import com.graphhopper.reader.osm.OSMReader; import com.graphhopper.reader.osm.conditional.DateRangeParser; @@ -63,6 +66,7 @@ import java.text.DateFormat; import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.graphhopper.util.GHUtility.readCountries; import static com.graphhopper.util.Helper.*; @@ -498,13 +502,10 @@ public GraphHopper init(GraphHopperConfig ghConfig) { if (!ghConfig.getString("spatial_rules.max_bbox", "").isEmpty()) throw new IllegalArgumentException("spatial_rules.max_bbox has been deprecated. There is no replacement, all custom areas will be considered."); - if (encodingManager != null) - throw new IllegalStateException("Cannot call init twice. EncodingManager was already initialized."); setProfiles(ghConfig.getProfiles()); flagEncodersString = ghConfig.getString("graph.flag_encoders", flagEncodersString); encodedValuesString = ghConfig.getString("graph.encoded_values", encodedValuesString); dateRangeParserString = ghConfig.getString("datareader.date_range_parser_day", dateRangeParserString); - buildEncodingManagerAndOSMParsers(flagEncodersString, encodedValuesString, dateRangeParserString, profilesByName.values()); if (ghConfig.getString("graph.locktype", "native").equals("simple")) lockFactory = new SimpleFSLockFactory(); @@ -729,11 +730,21 @@ public void importAndClose() { * Creates the graph from OSM data. */ private void process(boolean closeEarly) { + GHDirectory directory = new GHDirectory(ghLocation, dataAccessDefaultType); + directory.configure(dataAccessConfig); + buildEncodingManagerAndOSMParsers(flagEncodersString, encodedValuesString, dateRangeParserString, profilesByName.values()); + baseGraph = new BaseGraph.Builder(getEncodingManager()) + .setDir(directory) + .set3D(hasElevation()) + .withTurnCosts(encodingManager.needsTurnCostsSupport()) + .setSegmentSize(defaultSegmentSize) + .build(); + properties = new StorableProperties(directory); + checkProfilesConsistency(); + GHLock lock = null; try { - if (baseGraph == null) - throw new IllegalStateException("BaseGraph must be initialized before starting the import"); - if (baseGraph.getDirectory().getDefaultType().isStoring()) { + if (directory.getDefaultType().isStoring()) { lockFactory.setLockDir(new File(ghLocation)); lock = lockFactory.create(fileLockName, true); if (!lock.tryLock()) @@ -807,6 +818,9 @@ protected void createBaseGraphAndProperties() { baseGraph.getDirectory().create(); baseGraph.create(100); properties.create(100); + properties.put("graph.em.version", Constants.VERSION_EM); + properties.put("graph.em.edge_config", encodingManager.toEdgeConfigAsString()); + properties.put("graph.em.turn_cost_config", encodingManager.toTurnCostConfigAsString()); properties.put("graph.encoded_values", encodingManager.toEncodedValuesAsString()); properties.put("graph.flag_encoders", encodingManager.toFlagEncodersAsString()); } @@ -863,41 +877,40 @@ public boolean load() { } } + // todo: this does not really belong here, we abuse the load method to derive the dataAccessDefaultType setting from others if (!allowWrites && dataAccessDefaultType.isMMap()) dataAccessDefaultType = DAType.MMAP_RO; - if (encodingManager == null) - // we did not call init(), so we build the encoding manager now. - // just like when calling init, users have to make sure they use the same setup for import and load - buildEncodingManagerAndOSMParsers(flagEncodersString, encodedValuesString, dateRangeParserString, profilesByName.values()); - - GHDirectory directory = new GHDirectory(ghLocation, dataAccessDefaultType); - directory.configure(dataAccessConfig); - baseGraph = new BaseGraph.Builder(getEncodingManager()) - .setDir(directory) - .set3D(hasElevation()) - .withTurnCosts(encodingManager.needsTurnCostsSupport()) - .setSegmentSize(defaultSegmentSize) - .build(); - properties = new StorableProperties(directory); - checkProfilesConsistency(); if (!new File(ghLocation).exists()) + // there is just nothing to load return false; + GHDirectory directory = new GHDirectory(ghLocation, dataAccessDefaultType); + directory.configure(dataAccessConfig); GHLock lock = null; try { // create locks only if writes are allowed, if they are not allowed a lock cannot be created // (e.g. on a read only filesystem locks would fail) - if (baseGraph.getDirectory().getDefaultType().isStoring() && isAllowWrites()) { + if (directory.getDefaultType().isStoring() && isAllowWrites()) { lockFactory.setLockDir(new File(ghLocation)); lock = lockFactory.create(fileLockName, false); if (!lock.tryLock()) throw new RuntimeException("To avoid reading partial data we need to obtain the read lock but it failed. In " + ghLocation, lock.getObtainFailedReason()); } - - if (!loadBaseGraphAndProperties()) + properties = new StorableProperties(directory); + if (!properties.loadExisting()) + // the -gh folder exists, but there is no properties file. it might be just empty, so let's act as if + // the import did not run yet or is not complete for some reason return false; - + loadEncodingManagerFromProperties(properties); + baseGraph = new BaseGraph.Builder(getEncodingManager()) + .setDir(directory) + .set3D(hasElevation()) + .withTurnCosts(encodingManager.needsTurnCostsSupport()) + .setSegmentSize(defaultSegmentSize) + .build(); + baseGraph.loadExisting(); + checkProfilesConsistency(); String storedProfiles = properties.get("profiles"); String configuredProfiles = getProfilesString(); if (!storedProfiles.equals(configuredProfiles)) @@ -916,32 +929,49 @@ public boolean load() { } } - private boolean loadBaseGraphAndProperties() { - if (properties.loadExisting()) { - if (properties.containsVersion()) - throw new IllegalStateException("The GraphHopper file format is not compatible with the data you are " + - "trying to load. You either need to use an older version of GraphHopper or run a new import"); - // check encoding for compatibility - String flagEncodersStr = properties.get("graph.flag_encoders"); - - if (!encodingManager.toFlagEncodersAsString().equalsIgnoreCase(flagEncodersStr)) { - throw new IllegalStateException("Flag encoders do not match:" - + "\nGraphhopper config: " + encodingManager.toFlagEncodersAsString() - + "\nLoaded graph: " + flagEncodersStr - + "\nChange configuration to match the graph or delete " + baseGraph.getDirectory().getLocation()); - } + private void loadEncodingManagerFromProperties(StorableProperties properties) { + if (properties.containsVersion()) + throw new IllegalStateException("The GraphHopper file format is not compatible with the data you are " + + "trying to load. You either need to use an older version of GraphHopper or run a new import"); + + String versionStr = properties.get("graph.em.version"); + if (versionStr.isEmpty() || !String.valueOf(Constants.VERSION_EM).equals(versionStr)) + throw new IllegalStateException("Incompatible encoding version. You need to use the same GraphHopper version you used to import the graph, or run a new import. " + + " Stored encoding version: " + (versionStr.isEmpty() ? "missing" : versionStr) + ", used encoding version: " + Constants.VERSION_EM); + String encodedValueStr = properties.get("graph.encoded_values"); + ArrayNode evList = deserializeEncodedValueList(encodedValueStr); + LinkedHashMap encodedValues = new LinkedHashMap<>(); + evList.forEach(serializedEV -> { + EncodedValue encodedValue = EncodedValueSerializer.deserializeEncodedValue(serializedEV.textValue()); + if (encodedValues.put(encodedValue.getName(), encodedValue) != null) + throw new IllegalStateException("Duplicate encoded value name: " + encodedValue.getName() + " in: graph.encoded_values=" + encodedValueStr); + }); - String encodedValueStr = properties.get("graph.encoded_values"); - if (!encodingManager.toEncodedValuesAsString().equalsIgnoreCase(encodedValueStr)) { - throw new IllegalStateException("Encoded values do not match:" - + "\nGraphhopper config: " + encodingManager.toEncodedValuesAsString() - + "\nLoaded graph: " + encodedValueStr - + "\nChange configuration to match the graph or delete " + baseGraph.getDirectory().getLocation()); - } - baseGraph.loadExisting(); - return true; + String flagEncodersStr = properties.get("graph.flag_encoders"); + LinkedHashMap flagEncoders = Stream.of(flagEncodersStr.split(",")) + .map(str -> flagEncoderFactory.deserializeFlagEncoder(str, name -> { + EncodedValue ev = encodedValues.get(name); + if (ev == null) + throw new IllegalStateException("FlagEncoder " + str + " uses unknown encoded value: " + name); + return ev; + })) + .collect(Collectors.toMap(FlagEncoder::getName, f -> (VehicleEncodedValues) f, + (f1, f2) -> { + throw new IllegalStateException("Duplicate flag encoder: " + f1.getName() + " in: " + flagEncodersStr); + }, + LinkedHashMap::new)); + + EncodedValue.InitializerConfig edgeConfig = EncodedValueSerializer.deserializeInitializerConfig(properties.get("graph.em.edge_config")); + EncodedValue.InitializerConfig turnCostConfig = EncodedValueSerializer.deserializeInitializerConfig(properties.get("graph.em.turn_cost_config")); + encodingManager = new EncodingManager(encodedValues, flagEncoders, edgeConfig, turnCostConfig); + } + + private ArrayNode deserializeEncodedValueList(String encodedValueStr) { + try { + return Jackson.newObjectMapper().readValue(encodedValueStr, ArrayNode.class); + } catch (JsonProcessingException e) { + throw new UncheckedIOException(e); } - return false; } private String getProfilesString() { diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java index 450afe71eff..bc77b721d8d 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java @@ -77,11 +77,17 @@ public DecimalEncodedValueImpl(String name, int bits, double minValue, double fa @JsonProperty("max_value") int maxValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, + @JsonProperty("fwd_data_index") int fwdDataIndex, + @JsonProperty("bwd_data_index") int bwdDataIndex, + @JsonProperty("fwd_shift") int fwdShift, + @JsonProperty("bwd_shift") int bwdShift, + @JsonProperty("fwd_mask") int fwdMask, + @JsonProperty("bwd_mask") int bwdMask, @JsonProperty("factor") double factor, @JsonProperty("default_is_infinity") boolean defaultIsInfinity, @JsonProperty("use_maximum_as_infinity") boolean useMaximumAsInfinity) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections); + super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); this.factor = factor; this.defaultIsInfinity = defaultIsInfinity; this.useMaximumAsInfinity = useMaximumAsInfinity; @@ -90,7 +96,7 @@ public DecimalEncodedValueImpl(String name, int bits, double minValue, double fa @Override public void setDecimal(boolean reverse, IntsRef ref, double value) { if (!isInitialized()) - throw new IllegalStateException("Call init before usage for EncodedValue " + toString()); + throw new IllegalStateException("Call init before using EncodedValue " + getName()); if (Double.isInfinite(value)) { if (useMaximumAsInfinity) { super.setInt(reverse, ref, maxValue); @@ -143,19 +149,4 @@ public double getMaxDecimal() { return maxValue * factor; } - @Override - public boolean equals(Object o) { - if (!super.equals(o)) return false; - DecimalEncodedValueImpl that = (DecimalEncodedValueImpl) o; - return Double.compare(that.factor, factor) == 0 && useMaximumAsInfinity == that.useMaximumAsInfinity - && defaultIsInfinity == that.defaultIsInfinity; - } - - @Override - public int getVersion() { - int version = 31 * super.getVersion() + staticHashCode(factor); - if (useMaximumAsInfinity) return 31 * version + 13; - if (defaultIsInfinity) return 31 * version + 17; - return version; - } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/EncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/EncodedValue.java index 063747c6652..6f8040b00af 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/EncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/EncodedValue.java @@ -41,13 +41,6 @@ public interface EncodedValue { */ String getName(); - /** - * The return value represents the state of this EncodedValue and it can be assumed that two JVMs return the - * same version when the EncodedValue has the same state unlike the hashCode method. Same version ensures - * compatibility when reading values. - */ - int getVersion(); - /** * @return true if this EncodedValue can store a different value for its reverse direction */ @@ -61,8 +54,6 @@ class InitializerConfig { /** * This method determines a space of the specified bits and sets shift and dataIndex accordingly - * - * @param usedBits */ void next(int usedBits) { shift = nextShift; diff --git a/core/src/main/java/com/graphhopper/routing/ev/EncodedValueSerializer.java b/core/src/main/java/com/graphhopper/routing/ev/EncodedValueSerializer.java index d34c4086803..df92b020855 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/EncodedValueSerializer.java +++ b/core/src/main/java/com/graphhopper/routing/ev/EncodedValueSerializer.java @@ -24,7 +24,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.node.ObjectNode; public class EncodedValueSerializer { private final static ObjectMapper MAPPER = new ObjectMapper(); @@ -38,7 +37,6 @@ public class EncodedValueSerializer { public static String serializeEncodedValue(EncodedValue encodedValue) { try { JsonNode tree = MAPPER.valueToTree(encodedValue); - ((ObjectNode) tree).put("version", encodedValue.getVersion()); return MAPPER.writeValueAsString(tree); } catch (JsonProcessingException e) { throw new IllegalStateException("Could not serialize encoded value: " + encodedValue + ", error: " + e.getMessage()); @@ -48,15 +46,27 @@ public static String serializeEncodedValue(EncodedValue encodedValue) { public static EncodedValue deserializeEncodedValue(String serializedEncodedValue) { try { JsonNode jsonNode = MAPPER.readTree(serializedEncodedValue); - int storedVersion = jsonNode.get("version").asInt(); - ((ObjectNode) jsonNode).remove("version"); - EncodedValue encodedValue = MAPPER.treeToValue(jsonNode, EncodedValue.class); - if (storedVersion != encodedValue.getVersion()) - throw new IllegalStateException("Version does not match. Cannot properly read encoded value: " + encodedValue.getName() + ". " + - "You need to use the same version of GraphHopper you used to import the data"); - return encodedValue; + return MAPPER.treeToValue(jsonNode, EncodedValue.class); } catch (JsonProcessingException e) { throw new IllegalStateException("Could not deserialize encoded value: " + serializedEncodedValue + ", error: " + e.getMessage()); } } + + public static String serializeInitializerConfig(EncodedValue.InitializerConfig initializerConfig) { + try { + JsonNode tree = MAPPER.valueToTree(initializerConfig); + return MAPPER.writeValueAsString(tree); + } catch (JsonProcessingException e) { + throw new IllegalStateException("Could not serialize initializer config: " + e.getMessage()); + } + } + + public static EncodedValue.InitializerConfig deserializeInitializerConfig(String serializedInitializerConfig) { + try { + JsonNode jsonNode = MAPPER.readTree(serializedInitializerConfig); + return MAPPER.treeToValue(jsonNode, EncodedValue.InitializerConfig.class); + } catch (JsonProcessingException e) { + throw new IllegalStateException("Could not deserialize initializer config: " + serializedInitializerConfig + ", error: " + e.getMessage()); + } + } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java index f5d8bc19a04..a6947a5e0cb 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java @@ -22,8 +22,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.graphhopper.storage.IntsRef; -import java.util.Arrays; - /** * This class allows to store distinct values via an enum. I.e. it stores just the indices */ @@ -50,9 +48,15 @@ public EnumEncodedValue(String name, Class enumType, boolean storeTwoDirectio @JsonProperty("max_value") int maxValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, + @JsonProperty("fwd_data_index") int fwdDataIndex, + @JsonProperty("bwd_data_index") int bwdDataIndex, + @JsonProperty("fwd_shift") int fwdShift, + @JsonProperty("bwd_shift") int bwdShift, + @JsonProperty("fwd_mask") int fwdMask, + @JsonProperty("bwd_mask") int bwdMask, @JsonProperty("enum_type") Class enumType) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections); + super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); this.enumType = enumType; arr = enumType.getEnumConstants(); } @@ -71,15 +75,4 @@ public final E getEnum(boolean reverse, IntsRef ref) { return arr[value]; } - @Override - public boolean equals(Object o) { - if (!super.equals(o)) return false; - EnumEncodedValue that = (EnumEncodedValue) o; - return Arrays.equals(arr, that.arr); - } - - @Override - public int getVersion() { - return 31 * super.getVersion() + staticHashCode(arr); - } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java index 09f7114fb39..c7434dabfd9 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java @@ -18,15 +18,9 @@ package com.graphhopper.routing.ev; import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.Helper; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Objects; /** * Implementation of the IntEncodedValue via a certain number of bits (that determines the maximum value) and @@ -45,22 +39,14 @@ public class IntEncodedValueImpl implements IntEncodedValue { final int minValue; final int maxValue; - // the following fields will be set by the init() method and we do not store them on disk, because they will be - // set again when we create the EncodingManager /** * There are multiple int values possible per edge. Here we specify the index into this integer array. */ - @JsonIgnore private int fwdDataIndex; - @JsonIgnore private int bwdDataIndex; - @JsonIgnore int fwdShift = -1; - @JsonIgnore int bwdShift = -1; - @JsonIgnore int fwdMask; - @JsonIgnore int bwdMask; /** @@ -110,7 +96,14 @@ public IntEncodedValueImpl(String name, int bits, int minValue, boolean negateRe @JsonProperty("min_value") int minValue, @JsonProperty("max_value") int maxValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, - @JsonProperty("store_two_directions") boolean storeTwoDirections) { + @JsonProperty("store_two_directions") boolean storeTwoDirections, + @JsonProperty("fwd_data_index") int fwdDataIndex, + @JsonProperty("bwd_data_index") int bwdDataIndex, + @JsonProperty("fwd_shift") int fwdShift, + @JsonProperty("bwd_shift") int bwdShift, + @JsonProperty("fwd_mask") int fwdMask, + @JsonProperty("bwd_mask") int bwdMask + ) { // we need this constructor for Jackson this.name = name; this.storeTwoDirections = storeTwoDirections; @@ -118,6 +111,12 @@ public IntEncodedValueImpl(String name, int bits, int minValue, boolean negateRe this.negateReverseDirection = negateReverseDirection; this.minValue = minValue; this.maxValue = maxValue; + this.fwdDataIndex = fwdDataIndex; + this.bwdDataIndex = bwdDataIndex; + this.fwdShift = fwdShift; + this.bwdShift = bwdShift; + this.fwdMask = fwdMask; + this.bwdMask = bwdMask; } @Override @@ -212,100 +211,7 @@ public final String getName() { @Override public final String toString() { - return getName() + "|version=" + getVersion() + "|bits=" + bits + "|min_value=" + minValue - + "|negate_reverse_direction" + negateReverseDirection + "|index=" + fwdDataIndex - + "|shift=" + fwdShift + "|store_both_directions=" + storeTwoDirections; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - IntEncodedValueImpl that = (IntEncodedValueImpl) o; - return fwdDataIndex == that.fwdDataIndex && - bwdDataIndex == that.bwdDataIndex && - bits == that.bits && - maxValue == that.maxValue && - minValue == that.minValue && - fwdShift == that.fwdShift && - bwdShift == that.bwdShift && - fwdMask == that.fwdMask && - bwdMask == that.bwdMask && - negateReverseDirection == that.negateReverseDirection && - storeTwoDirections == that.storeTwoDirections && - Objects.equals(name, that.name); - } - - @Override - public final int hashCode() { - return getVersion(); - } - - @Override - public int getVersion() { - int val = Helper.staticHashCode(name); - val = 31 * val + (storeTwoDirections ? 1231 : 1237); - val = 31 * val + (negateReverseDirection ? 13 : 17); - return staticHashCode(val, fwdDataIndex, bwdDataIndex, bits, minValue, maxValue, fwdShift, bwdShift, fwdMask, bwdMask); - } - - /** - * Produces a static hashcode for an integer arrays that is platform independent and still compatible to the default - * of openjdk. - * - * @see Arrays#hashCode(int[]) - */ - static int staticHashCode(int... vals) { - if (vals == null) - return 0; - int len = vals.length; - int val = 1; - for (int idx = 0; idx < len; ++idx) { - val = 31 * val + vals[idx]; - } - - return val; + return getName(); } - /** - * Produces a static hashcode for an Enum arrays that is platform independent and still compatible to the default - * of openjdk. - */ - static int staticHashCode(Enum... vals) { - if (vals == null) - return 0; - int len = vals.length; - int val = 1; - for (int idx = 0; idx < len; ++idx) { - val = 31 * val + vals[idx].ordinal(); - } - - return val; - } - - /** - * Produces a static hashcode for a collection of Strings that is platform independent and still compatible to the default - * of openjdk. - */ - static int staticHashCode(Collection vals) { - if (vals == null) - return 0; - int val = 1; - for (String str : vals) { - val = 31 * val + Helper.staticHashCode(str); - } - - return val; - } - - /** - * Produces a static hashcode for an integer arrays that is platform independent and still compatible to the default - * of openjdk - * - * @see Double#hashCode - */ - static int staticHashCode(double val) { - long var2 = Double.doubleToLongBits(val); - return (int) (var2 ^ var2 >>> 32); - } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java index 095f1507cb8..4d5ecb2d455 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java @@ -37,13 +37,19 @@ public SimpleBooleanEncodedValue(String name, boolean storeBothDirections) { SimpleBooleanEncodedValue( @JsonProperty("name") String name, @JsonProperty("bits") int bits, - @JsonProperty("minValue") int minValue, - @JsonProperty("maxValue") int maxValue, - @JsonProperty("negateReverseDirection") boolean negateReverseDirection, - @JsonProperty("storeTwoDirections") boolean storeTwoDirections + @JsonProperty("min_value") int minValue, + @JsonProperty("max_value") int maxValue, + @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, + @JsonProperty("store_two_directions") boolean storeTwoDirections, + @JsonProperty("fwd_data_index") int fwdDataIndex, + @JsonProperty("bwd_data_index") int bwdDataIndex, + @JsonProperty("fwd_shift") int fwdShift, + @JsonProperty("bwd_shift") int bwdShift, + @JsonProperty("fwd_mask") int fwdMask, + @JsonProperty("bwd_mask") int bwdMask ) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections); + super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java index c70c207fa37..54a81d0e5a7 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java @@ -54,11 +54,17 @@ public StringEncodedValue(String name, int bits, List values, boolean st @JsonProperty("max_value") int maxValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, + @JsonProperty("fwd_data_index") int fwdDataIndex, + @JsonProperty("bwd_data_index") int bwdDataIndex, + @JsonProperty("fwd_shift") int fwdShift, + @JsonProperty("bwd_shift") int bwdShift, + @JsonProperty("fwd_mask") int fwdMask, + @JsonProperty("bwd_mask") int bwdMask, @JsonProperty("max_values") int maxValues, @JsonProperty("values") List values, @JsonProperty("index_map") HashMap indexMap) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections); + super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); if (values.size() > maxValues) throw new IllegalArgumentException("Number of values is higher than the maximum value count: " + values.size() + " > " + maxValues); @@ -115,23 +121,4 @@ public List getValues() { return Collections.unmodifiableList(values); } - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof StringEncodedValue)) { - return false; - } - StringEncodedValue other = (StringEncodedValue) obj; - if (this.bits != other.bits) { - return false; - } - return Objects.equals(values, other.values); - } - - @Override - public int getVersion() { - return 31 * super.getVersion() + staticHashCode(values); - } -} +} \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java index 4bbc8526cdf..c55c424416a 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java @@ -17,8 +17,13 @@ */ package com.graphhopper.routing.util; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EncodedValue; import com.graphhopper.util.PMap; +import java.util.function.Function; + /** * This class creates FlagEncoders that are already included in the GraphHopper distribution. * @@ -62,4 +67,23 @@ public FlagEncoder createFlagEncoder(String name, PMap configuration) { throw new IllegalArgumentException("entry in encoder list not supported: " + name); } + + @Override + public FlagEncoder deserializeFlagEncoder(String serializedFlagEncoder, Function evLookup) { + String[] strings = serializedFlagEncoder.split("\\|"); + if (strings.length != 9) + throw new IllegalStateException("Deserialized FlagEncoders should consist of nine pipe-separated strings"); + String name = strings[0]; + BooleanEncodedValue accessEnc = strings[1].equals("null") ? null : (BooleanEncodedValue) evLookup.apply(strings[1]); + DecimalEncodedValue avgSpeedEnc = strings[2].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[2]); + DecimalEncodedValue priorityEnc = strings[3].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[3]); + DecimalEncodedValue curvatureEnc = strings[4].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[4]); + DecimalEncodedValue turnCostEnc = strings[5].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[5]); + double maxPossibleSpeed = Double.parseDouble(strings[6]); + boolean isMotorVehicle = Boolean.parseBoolean(strings[7]); + boolean isHGV = Boolean.parseBoolean(strings[8]); + return new VehicleEncodedValues( + name, accessEnc, avgSpeedEnc, priorityEnc, curvatureEnc, turnCostEnc, maxPossibleSpeed, isMotorVehicle, isHGV + ); + } } diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java index 8756739c54b..99aea6e686b 100644 --- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java +++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java @@ -17,10 +17,13 @@ */ package com.graphhopper.routing.util; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.graphhopper.jackson.Jackson; import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PMap; +import java.io.UncheckedIOException; import java.util.*; import java.util.stream.Collectors; @@ -36,10 +39,10 @@ * @author Nop */ public class EncodingManager implements EncodedValueLookup { - private final Map flagEncoders; - private final Map encodedValueMap; - private final EncodedValue.InitializerConfig turnCostConfig; + private final LinkedHashMap encodedValueMap; + private final LinkedHashMap flagEncoders; private final EncodedValue.InitializerConfig edgeConfig; + private final EncodedValue.InitializerConfig turnCostConfig; /** * Instantiate manager with the given list of encoders. The manager knows several default @@ -83,11 +86,16 @@ public static Builder start() { return new Builder(); } + public EncodingManager(LinkedHashMap encodedValueMap, LinkedHashMap flagEncoders, EncodedValue.InitializerConfig edgeConfig, EncodedValue.InitializerConfig turnCostConfig) { + this.flagEncoders = flagEncoders; + this.encodedValueMap = encodedValueMap; + this.turnCostConfig = turnCostConfig; + this.edgeConfig = edgeConfig; + flagEncoders.values().forEach(f -> f.setEncodedValueLookup(this)); + } + private EncodingManager() { - flagEncoders = new LinkedHashMap<>(); - encodedValueMap = new LinkedHashMap<>(); - edgeConfig = new EncodedValue.InitializerConfig(); - turnCostConfig = new EncodedValue.InitializerConfig(); + this(new LinkedHashMap<>(), new LinkedHashMap<>(), new EncodedValue.InitializerConfig(), new EncodedValue.InitializerConfig()); } public static class Builder { @@ -99,7 +107,6 @@ public Builder add(FlagEncoder encoder) { throw new IllegalArgumentException("FlagEncoder already exists: " + encoder.getName()); VehicleEncodedValues v = (VehicleEncodedValues) encoder; v.setEncodedValueLookup(em); - List list = new ArrayList<>(); v.createEncodedValues(list); list.forEach(this::add); @@ -218,11 +225,24 @@ private FlagEncoder getEncoder(String name, boolean throwExc) { } public String toFlagEncodersAsString() { - return flagEncoders.values().stream().map(fe -> fe.getName() + "|" + fe.getSharedEncodedValueString()).collect(Collectors.joining(",")); + return flagEncoders.values().stream().map(VehicleEncodedValues::toSerializationString).collect(Collectors.joining(",")); } public String toEncodedValuesAsString() { - return encodedValueMap.values().stream().map(Object::toString).collect(Collectors.joining(",")); + List serializedEVsList = encodedValueMap.values().stream().map(EncodedValueSerializer::serializeEncodedValue).collect(Collectors.toList()); + try { + return Jackson.newObjectMapper().writeValueAsString(serializedEVsList); + } catch (JsonProcessingException e) { + throw new UncheckedIOException(e); + } + } + + public String toEdgeConfigAsString() { + return EncodedValueSerializer.serializeInitializerConfig(edgeConfig); + } + + public String toTurnCostConfigAsString() { + return EncodedValueSerializer.serializeInitializerConfig(turnCostConfig); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/util/FlagEncoderFactory.java b/core/src/main/java/com/graphhopper/routing/util/FlagEncoderFactory.java index b6efa42a716..6131a6b1405 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FlagEncoderFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/FlagEncoderFactory.java @@ -17,8 +17,11 @@ */ package com.graphhopper.routing.util; +import com.graphhopper.routing.ev.EncodedValue; import com.graphhopper.util.PMap; +import java.util.function.Function; + /** * @author Peter Karich */ @@ -36,4 +39,6 @@ public interface FlagEncoderFactory { String WHEELCHAIR = "wheelchair"; FlagEncoder createFlagEncoder(String name, PMap configuration); + + FlagEncoder deserializeFlagEncoder(String serializedFlagEncoder, Function evLookup); } diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index 2b5846eb7f9..b9f90151209 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -22,7 +22,6 @@ import com.graphhopper.util.PMap; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -218,11 +217,14 @@ public DecimalEncodedValue getTurnCostEnc() { return turnCostEnc; } - public String getSharedEncodedValueString() { - return Stream.of(accessEnc, avgSpeedEnc, priorityEnc, curvatureEnc, turnCostEnc) - .filter(Objects::nonNull) - .map(EncodedValueSerializer::serializeEncodedValue) - .collect(Collectors.joining(",")); + public String toSerializationString() { + return + String.join("|", + name, + Stream.of(accessEnc, avgSpeedEnc, priorityEnc, curvatureEnc, turnCostEnc) + .map(ev -> ev == null ? "null" : ev.getName()) + .collect(Collectors.joining("|")), + String.valueOf(maxPossibleSpeed), String.valueOf(isMotorVehicle), String.valueOf(isHGV)); } @Override diff --git a/core/src/main/java/com/graphhopper/storage/StorableProperties.java b/core/src/main/java/com/graphhopper/storage/StorableProperties.java index d928385c629..73519d33a94 100644 --- a/core/src/main/java/com/graphhopper/storage/StorableProperties.java +++ b/core/src/main/java/com/graphhopper/storage/StorableProperties.java @@ -102,12 +102,7 @@ public synchronized StorableProperties put(String key, Object val) { public synchronized String get(String key) { if (!key.equals(toLowerCase(key))) throw new IllegalArgumentException("Do not use upper case keys (" + key + ") for StorableProperties since 0.7"); - - String ret = map.get(key); - if (ret == null) - return ""; - - return ret; + return map.getOrDefault(key, ""); } public synchronized Map getAll() { diff --git a/core/src/main/java/com/graphhopper/util/Constants.java b/core/src/main/java/com/graphhopper/util/Constants.java index 8d39fa9b52b..7ebfa321af0 100644 --- a/core/src/main/java/com/graphhopper/util/Constants.java +++ b/core/src/main/java/com/graphhopper/util/Constants.java @@ -68,6 +68,8 @@ public class Constants { public static final int VERSION_NODE = 9; public static final int VERSION_EDGE = 21; + // this should be increased whenever the format of the serialized EncodingManager is changed + public static final int VERSION_EM = 0; public static final int VERSION_SHORTCUT = 9; public static final int VERSION_NODE_CH = 0; public static final int VERSION_GEOMETRY = 6; diff --git a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java index 8b2f0166cdf..571fa99f632 100644 --- a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java @@ -52,11 +52,6 @@ public String getName() { return "reverse"; } - @Override - public int getVersion() { - return 1; - } - @Override public boolean getBool(boolean reverse, IntsRef ref) { return reverse; diff --git a/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java b/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java index 6ba160ba7ab..71d95c9f3d4 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java @@ -63,14 +63,14 @@ public void vehicleDoesNotExist_error() { final GraphHopper hopper = new GraphHopper(); hopper.setGraphHopperLocation(GH_LOCATION).setStoreOnFlush(false). setProfiles(new Profile("profile").setVehicle("your_car")); - assertIllegalArgument(hopper::load, "entry in encoder list not supported: your_car"); + assertIllegalArgument(hopper::importOrLoad, "entry in encoder list not supported: your_car"); } @Test public void vehicleDoesNotExist_error2() { final GraphHopper hopper = new GraphHopper().setGraphHopperLocation(GH_LOCATION).setStoreOnFlush(false). setProfiles(new Profile("profile").setVehicle("your_car")); - assertIllegalArgument(hopper::load, "entry in encoder list not supported: your_car"); + assertIllegalArgument(hopper::importOrLoad, "entry in encoder list not supported: your_car"); } @Test @@ -95,7 +95,7 @@ public void oneVehicleTwoProfilesWithAndWithoutTC2_noError() { public void profileWithUnknownWeighting_error() { final GraphHopper hopper = createHopper(); hopper.setProfiles(new Profile("profile").setVehicle("car").setWeighting("your_weighting")); - assertIllegalArgument(hopper::load, + assertIllegalArgument(hopper::importOrLoad, "Could not create weighting for profile: 'profile'", "Weighting 'your_weighting' not supported" ); @@ -106,7 +106,7 @@ public void chProfileDoesNotExist_error() { final GraphHopper hopper = createHopper(); hopper.setProfiles(new Profile("profile1").setVehicle("car")); hopper.getCHPreparationHandler().setCHProfiles(new CHProfile("other_profile")); - assertIllegalArgument(hopper::load, "CH profile references unknown profile 'other_profile'"); + assertIllegalArgument(hopper::importOrLoad, "CH profile references unknown profile 'other_profile'"); } @Test @@ -117,7 +117,7 @@ public void duplicateCHProfile_error() { new CHProfile("profile"), new CHProfile("profile") ); - assertIllegalArgument(hopper::load, "Duplicate CH reference to profile 'profile'"); + assertIllegalArgument(hopper::importOrLoad, "Duplicate CH reference to profile 'profile'"); } @Test @@ -125,7 +125,7 @@ public void lmProfileDoesNotExist_error() { final GraphHopper hopper = createHopper(); hopper.setProfiles(new Profile("profile1").setVehicle("car")); hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("other_profile")); - assertIllegalArgument(hopper::load, "LM profile references unknown profile 'other_profile'"); + assertIllegalArgument(hopper::importOrLoad, "LM profile references unknown profile 'other_profile'"); } @Test @@ -136,7 +136,7 @@ public void duplicateLMProfile_error() { new LMProfile("profile"), new LMProfile("profile") ); - assertIllegalArgument(hopper::load, "Multiple LM profiles are using the same profile 'profile'"); + assertIllegalArgument(hopper::importOrLoad, "Multiple LM profiles are using the same profile 'profile'"); } @Test @@ -146,7 +146,7 @@ public void unknownLMPreparationProfile_error() { hopper.getLMPreparationHandler().setLMProfiles( new LMProfile("profile").setPreparationProfile("xyz") ); - assertIllegalArgument(hopper::load, "LM profile references unknown preparation profile 'xyz'"); + assertIllegalArgument(hopper::importOrLoad, "LM profile references unknown preparation profile 'xyz'"); } @Test @@ -162,7 +162,7 @@ public void lmPreparationProfileChain_error() { new LMProfile("profile2").setPreparationProfile("profile1"), new LMProfile("profile3").setPreparationProfile("profile2") ); - assertIllegalArgument(hopper::load, "Cannot use 'profile2' as preparation_profile for LM profile 'profile3', because it uses another profile for preparation itself."); + assertIllegalArgument(hopper::importOrLoad, "Cannot use 'profile2' as preparation_profile for LM profile 'profile3', because it uses another profile for preparation itself."); } @Test @@ -176,7 +176,7 @@ public void noLMProfileForPreparationProfile_error() { hopper.getLMPreparationHandler().setLMProfiles( new LMProfile("profile1").setPreparationProfile("profile2") ); - assertIllegalArgument(hopper::load, "Unknown LM preparation profile 'profile2' in LM profile 'profile1' cannot be used as preparation_profile"); + assertIllegalArgument(hopper::importOrLoad, "Unknown LM preparation profile 'profile2' in LM profile 'profile1' cannot be used as preparation_profile"); } private GraphHopper createHopper() { diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 281f086f18f..5c2b70a486c 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -2572,7 +2572,7 @@ public void testLoadGraph_implicitEncodedValues_issue1862() { } @Test - void testLoadingWithAnotherSpeedFactorFails() { + void testLoadingWithAnotherSpeedFactorWorks() { { GraphHopper hopper = new GraphHopper() .setFlagEncodersString("car|speed_factor=7") @@ -2582,12 +2582,16 @@ void testLoadingWithAnotherSpeedFactorFails() { hopper.importOrLoad(); } { + // now we use another speed_factor, but changing the flag encoder string has no effect when we are loading + // a graph. This API is a bit confusing, but we have been mixing configuration options that only matter + // during import with those that only matter when routing for some time already. At some point we should + // separate the 'import' from the 'routing' config (and split the GraphHopper class). GraphHopper hopper = new GraphHopper() .setFlagEncodersString("car|speed_factor=9") .setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")) .setGraphHopperLocation(GH_LOCATION); - IllegalStateException ex = assertThrows(IllegalStateException.class, hopper::load); - assertTrue(ex.getMessage().contains("Flag encoders do not match"), ex.getMessage()); + hopper.load(); + assertEquals(1942, hopper.getBaseGraph().getNodes()); } } diff --git a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java index d5a92ed4f89..903084643ea 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java @@ -23,8 +23,10 @@ import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; +import com.graphhopper.routing.ev.EncodedValue; import com.graphhopper.routing.lm.LandmarkStorage; import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.storage.*; import com.graphhopper.storage.index.LocationIndexTree; @@ -40,6 +42,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; import static com.graphhopper.util.Parameters.Algorithms.DIJKSTRA_BI; import static org.junit.jupiter.api.Assertions.*; @@ -454,7 +457,7 @@ public void testFootAndCar() { } @Test - public void testFailsForWrongConfig() { + public void testNothingHappensWhenFlagEncodersAreChangedForLoad() { instance = new GraphHopper().init( new GraphHopperConfig(). putObject("datareader.file", testOsm3). @@ -469,43 +472,35 @@ public void testFailsForWrongConfig() { assertEquals(5, instance.getBaseGraph().getNodes()); instance.close(); - // different config (flagEncoder list) - try { - GraphHopper tmpGH = new GraphHopper().init( - new GraphHopperConfig(). - putObject("datareader.file", testOsm3). - putObject("datareader.dataaccess", "RAM"). - putObject("graph.flag_encoders", "foot"). - setProfiles(Collections.singletonList( - new Profile("foot").setVehicle("foot").setWeighting("fastest") - ))). - setOSMFile(testOsm3). - setGraphHopperLocation(ghLoc); - tmpGH.load(); - fail(); - } catch (Exception ex) { - assertTrue(ex.getMessage().startsWith("Flag encoders do not match"), ex.getMessage()); - } - - // different order is no longer okay, see #350 - try { - GraphHopper tmpGH = new GraphHopper().init(new GraphHopperConfig(). - putObject("datareader.file", testOsm3). - putObject("datareader.dataaccess", "RAM"). - putObject("graph.flag_encoders", "car,foot"). - setProfiles(Arrays.asList( - new Profile("car").setVehicle("car").setWeighting("fastest"), - new Profile("foot").setVehicle("foot").setWeighting("fastest") - ))). - setOSMFile(testOsm3) - .setGraphHopperLocation(ghLoc); - tmpGH.load(); - fail(); - } catch (Exception ex) { - assertTrue(ex.getMessage().startsWith("Flag encoders do not match"), ex.getMessage()); - } + // different flagEncoder list has no effect when loading, so it does not matter, but the profiles must be the same + GraphHopper tmpGH = new GraphHopper().init( + new GraphHopperConfig(). + putObject("datareader.file", testOsm3). + putObject("datareader.dataaccess", "RAM"). + putObject("graph.flag_encoders", "foot"). + setProfiles(Collections.singletonList( + new Profile("foot").setVehicle("foot").setWeighting("fastest") + ))). + setOSMFile(testOsm3). + setGraphHopperLocation(ghLoc); + IllegalStateException e = assertThrows(IllegalStateException.class, tmpGH::load); + assertTrue(e.getMessage().contains("Profiles do not match"), e.getMessage()); - // different encoded values should fail to load + // different order of flag_encoders is also fine, but profiles must be in same order + tmpGH = new GraphHopper().init(new GraphHopperConfig(). + putObject("datareader.file", testOsm3). + putObject("datareader.dataaccess", "RAM"). + putObject("graph.flag_encoders", "car,foot"). + setProfiles(Arrays.asList( + new Profile("car").setVehicle("car").setWeighting("fastest"), + new Profile("foot").setVehicle("foot").setWeighting("fastest") + ))). + setOSMFile(testOsm3) + .setGraphHopperLocation(ghLoc); + e = assertThrows(IllegalStateException.class, tmpGH::load); + assertTrue(e.getMessage().contains("Profiles do not match"), e.getMessage()); + + // different encoded values do not matter either instance = new GraphHopper().init( new GraphHopperConfig(). putObject("datareader.file", testOsm3). @@ -518,12 +513,11 @@ public void testFailsForWrongConfig() { ))). setOSMFile(testOsm3). setGraphHopperLocation(ghLoc); - try { - instance.load(); - fail(); - } catch (Exception ex) { - assertTrue(ex.getMessage().startsWith("Encoded values do not match"), ex.getMessage()); - } + instance.load(); + assertEquals(5, instance.getBaseGraph().getNodes()); + assertEquals("foot,car", instance.getEncodingManager().fetchEdgeEncoders().stream().map(FlagEncoder::getName).collect(Collectors.joining(","))); + assertEquals("foot_access,foot_average_speed,foot_priority,car_access,car_average_speed,foot_subnetwork,car_subnetwork,roundabout,road_class,road_class_link,road_environment,max_speed,road_access,foot_network", + instance.getEncodingManager().getEncodedValues().stream().map(EncodedValue::getName).collect(Collectors.joining(","))); } @Test @@ -545,7 +539,7 @@ public void testFailsForWrongEVConfig() { assertEquals(5, instance.getBaseGraph().getNodes()); instance.close(); - // different encoded values should fail to load + // different encoded values are ignored anyway instance = new GraphHopper().init( new GraphHopperConfig(). putObject("datareader.file", testOsm3). @@ -558,8 +552,10 @@ public void testFailsForWrongEVConfig() { new Profile("car").setVehicle("car").setWeighting("fastest") ))). setOSMFile(testOsm3); - Exception ex = assertThrows(Exception.class, () -> instance.load()); - assertTrue(ex.getMessage().startsWith("Encoded values do not match"), ex.getMessage()); + instance.load(); + assertEquals(5, instance.getBaseGraph().getNodes()); + assertEquals("foot,car", instance.getEncodingManager().fetchEdgeEncoders().stream().map(FlagEncoder::getName).collect(Collectors.joining(","))); + assertEquals("foot_access,foot_average_speed,foot_priority,car_access,car_average_speed,foot_subnetwork,car_subnetwork,roundabout,road_class,road_class_link,road_environment,max_speed,road_access,foot_network", instance.getEncodingManager().getEncodedValues().stream().map(EncodedValue::getName).collect(Collectors.joining(","))); } @Test @@ -846,9 +842,7 @@ public void testProfilesMustNotBeChanged() { new Profile("car2").setVehicle("car").setWeighting("fastest") )); IllegalStateException e = assertThrows(IllegalStateException.class, hopper::importOrLoad); - // so far we get another error message in this case, because we check the encoded values (and encoders) first, - // for example here the encoded values are different, because of the extra car2_subnetwork EV - assertTrue(e.getMessage().contains("Encoded values do not match"), e.getMessage()); + assertTrue(e.getMessage().contains("Profiles do not match"), e.getMessage()); hopper.close(); } { @@ -858,7 +852,7 @@ public void testProfilesMustNotBeChanged() { new Profile("car").setVehicle("car").setWeighting("shortest") )); IllegalStateException e = assertThrows(IllegalStateException.class, hopper::importOrLoad); - assertTrue(e.getMessage().contains("Encoded values do not match"), e.getMessage()); + assertTrue(e.getMessage().contains("Profiles do not match"), e.getMessage()); hopper.close(); } } diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 25ea3b1402b..0c4081b39f0 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -46,6 +46,7 @@ import java.io.IOException; import java.util.Collections; import java.util.List; +import java.util.function.Function; import static com.graphhopper.util.GHUtility.readCountries; import static org.junit.jupiter.api.Assertions.*; @@ -666,11 +667,19 @@ public void testReadEleFromDataProvider() { @Test public void testTurnFlagCombination() { GraphHopper hopper = new GraphHopper(); - hopper.setFlagEncoderFactory((name, config) -> { - if (name.equals("truck")) { - return FlagEncoders.createCar(new PMap(config).putObject("name", "truck")); - } else { - return new DefaultFlagEncoderFactory().createFlagEncoder(name, config); + hopper.setFlagEncoderFactory(new FlagEncoderFactory() { + @Override + public FlagEncoder createFlagEncoder(String name, PMap config) { + if (name.equals("truck")) { + return FlagEncoders.createCar(new PMap(config).putObject("name", "truck")); + } else { + return new DefaultFlagEncoderFactory().createFlagEncoder(name, config); + } + } + + @Override + public FlagEncoder deserializeFlagEncoder(String serializedFlagEncoder, Function evLookup) { + return null; } }); hopper.setVehicleTagParserFactory((lookup, name, config) -> { diff --git a/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java b/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java index 97849f09ce1..d65e5f4f93a 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java @@ -23,8 +23,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; class EncodedValueSerializerTest { @Test @@ -64,14 +66,42 @@ public void serializationAndDeserialization() { } @Test - void wrongVersion() { - String serializedEV = "{\"className\":\"com.graphhopper.routing.ev.EnumEncodedValue\",\"name\":\"road_class\",\"bits\":5," + - "\"min_value\":0,\"max_value\":31,\"negate_reverse_direction\":false,\"store_two_directions\":false," + - "\"enum_type\":\"com.graphhopper.routing.ev.RoadClass\",\"version\":"; - // this fails, because the version is wrong - IllegalStateException e = assertThrows(IllegalStateException.class, () -> EncodedValueSerializer.deserializeEncodedValue(serializedEV + "404}")); - assertTrue(e.getMessage().contains("Version does not match"), e.getMessage()); - // this works - assertEquals("road_class", EncodedValueSerializer.deserializeEncodedValue(serializedEV + "979560347}").getName()); + void explicitString() { + EncodedValue.InitializerConfig initializerConfig = new EncodedValue.InitializerConfig(); + List evs = Arrays.asList(Lanes.create(), MaxWidth.create(), GetOffBike.create()); + evs.forEach(ev -> ev.init(initializerConfig)); + + List serialized = evs.stream().map(EncodedValueSerializer::serializeEncodedValue).collect(Collectors.toList()); + assertEquals("{\"className\":\"com.graphhopper.routing.ev.IntEncodedValueImpl\",\"name\":\"lanes\",\"bits\":3," + + "\"min_value\":0,\"max_value\":7,\"negate_reverse_direction\":false,\"store_two_directions\":false," + + "\"fwd_data_index\":0,\"bwd_data_index\":0,\"fwd_shift\":0,\"bwd_shift\":-1,\"fwd_mask\":7,\"bwd_mask\":0}", serialized.get(0)); + assertEquals("{\"className\":\"com.graphhopper.routing.ev.DecimalEncodedValueImpl\",\"name\":\"max_width\",\"bits\":7," + + "\"min_value\":0,\"max_value\":127,\"negate_reverse_direction\":false,\"store_two_directions\":false," + + "\"fwd_data_index\":0,\"bwd_data_index\":0,\"fwd_shift\":3,\"bwd_shift\":-1,\"fwd_mask\":1016,\"bwd_mask\":0," + + "\"factor\":0.1,\"default_is_infinity\":true,\"use_maximum_as_infinity\":false}", serialized.get(1)); + assertEquals("{\"className\":\"com.graphhopper.routing.ev.SimpleBooleanEncodedValue\",\"name\":\"get_off_bike\",\"bits\":1," + + "\"min_value\":0,\"max_value\":1,\"negate_reverse_direction\":false,\"store_two_directions\":false,\"fwd_data_index\":0," + + "\"bwd_data_index\":0,\"fwd_shift\":10,\"bwd_shift\":-1,\"fwd_mask\":1024,\"bwd_mask\":0}", serialized.get(2)); + + EncodedValue ev0 = EncodedValueSerializer.deserializeEncodedValue(serialized.get(0)); + assertEquals("lanes", ev0.getName()); + EncodedValue ev1 = EncodedValueSerializer.deserializeEncodedValue(serialized.get(1)); + assertEquals("max_width", ev1.getName()); + EncodedValue ev2 = EncodedValueSerializer.deserializeEncodedValue(serialized.get(2)); + assertEquals("get_off_bike", ev2.getName()); + } + + @Test + void initializerConfig() { + EncodedValue.InitializerConfig initializerConfig = new EncodedValue.InitializerConfig(); + Lanes.create().init(initializerConfig); + MaxWidth.create().init(initializerConfig); + String s = EncodedValueSerializer.serializeInitializerConfig(initializerConfig); + assertEquals("{\"data_index\":0,\"shift\":3,\"next_shift\":10,\"bit_mask\":1016}", s); + EncodedValue.InitializerConfig deserialized = EncodedValueSerializer.deserializeInitializerConfig(s); + assertEquals(0, deserialized.dataIndex); + assertEquals(3, deserialized.shift); + assertEquals(10, deserialized.nextShift); + assertEquals(1016, deserialized.bitMask); } } \ No newline at end of file From b62dfbac89a4a79eb5bab305707c528e7bef35f5 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 23 Jun 2022 16:52:27 +0200 Subject: [PATCH 065/389] Helper.cutString should be only for KVStorage and reduce length to 250 to fix #2609 --- .../com/graphhopper/reader/osm/OSMReader.java | 4 +- .../com/graphhopper/search/EdgeKVStorage.java | 10 +++-- .../graphhopper/search/EdgeKVStorageTest.java | 4 -- .../java/com/graphhopper/util/Helper.java | 10 +++-- .../java/com/graphhopper/util/HelperTest.java | 41 +++++++++++++++++++ 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 76b7ff0aaf7..a664df30839 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -332,8 +332,8 @@ protected void addEdge(int fromIndex, int toIndex, PointList pointList, ReaderWa if (edgeFlags.isEmpty()) return; - // the storage does not accept too long strings - String name = Helper.cutString(way.getTag("way_name", ""), 255); + // the storage does not allow too long Strings + String name = Helper.cutStringForKV(way.getTag("way_name", "")); EdgeIteratorState edge = baseGraph.edge(fromIndex, toIndex).setDistance(distance).setFlags(edgeFlags).setName(name); // If the entire way is just the first and last point, do not waste space storing an empty way geometry diff --git a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java index 4aeca75e415..463e40f6270 100644 --- a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java +++ b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java @@ -324,6 +324,12 @@ private byte[] getBytesForValue(Class clazz, Object value) { byte[] bytes; if (clazz.equals(String.class)) { bytes = ((String) value).getBytes(Helper.UTF_CS); + if (bytes.length > MAX_LENGTH) + throw new IllegalArgumentException("bytes.length cannot be > " + MAX_LENGTH + " but was " + bytes.length + ". String:" + value); + } else if (clazz.equals(byte[].class)) { + bytes = (byte[]) value; + if (bytes.length > MAX_LENGTH) + throw new IllegalArgumentException("bytes.length cannot be > " + MAX_LENGTH + " but was " + bytes.length); } else if (clazz.equals(Integer.class)) { return bitUtil.fromInt((int) value); } else if (clazz.equals(Long.class)) { @@ -332,12 +338,8 @@ private byte[] getBytesForValue(Class clazz, Object value) { return bitUtil.fromFloat((float) value); } else if (clazz.equals(Double.class)) { return bitUtil.fromDouble((double) value); - } else if (clazz.equals(byte[].class)) { - bytes = (byte[]) value; } else throw new IllegalArgumentException("The Class of a value was " + clazz.getSimpleName() + ", currently supported: byte[], String, int, long, float and double"); - if (bytes.length > MAX_LENGTH) - throw new IllegalArgumentException("bytes.length cannot be > " + MAX_LENGTH + " but was " + bytes.length); return bytes; } diff --git a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java index 5f92e7c1ce0..34d315f7825 100644 --- a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java +++ b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java @@ -151,10 +151,6 @@ public void testTooLongStringValueError() { } final String finalStr = str; assertThrows(IllegalArgumentException.class, () -> index.add(createMap("", finalStr))); - - long pointer = index.add(createMap("", Helper.cutString("Бухарестская улица (http://ru.wikipedia.org/wiki/" + - "%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))", 255))); - assertTrue(((String) index.get(pointer, "")).startsWith("Бухарестская улица (h")); } @Test diff --git a/web-api/src/main/java/com/graphhopper/util/Helper.java b/web-api/src/main/java/com/graphhopper/util/Helper.java index 3311d9fdd0e..e50de6cdc86 100644 --- a/web-api/src/main/java/com/graphhopper/util/Helper.java +++ b/web-api/src/main/java/com/graphhopper/util/Helper.java @@ -21,6 +21,7 @@ import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; @@ -31,7 +32,7 @@ * @author Peter Karich */ public class Helper { - public static final Charset UTF_CS = Charset.forName("UTF-8"); + public static final Charset UTF_CS = StandardCharsets.UTF_8; public static final TimeZone UTC = TimeZone.getTimeZone("UTC"); public static final long MB = 1L << 20; // we keep the first seven decimal places of lat/lon coordinates. this corresponds to ~1cm precision ('pointing to waldo on a page') @@ -477,10 +478,11 @@ public static int staticHashCode(String str) { } /** - * This method limits the specified String value to the specified maxBytes. + * This method limits the specified String value to the length currently accepted for values in the EdgeKVStorage. */ - public static String cutString(String value, int maxBytes) { + public static String cutStringForKV(String value) { byte[] bytes = value.getBytes(UTF_CS); - return bytes.length > maxBytes ? new String(bytes, 0, maxBytes, UTF_CS) : value; + // See #2609 and test why we use a value < 255 + return bytes.length > 250 ? new String(bytes, 0, 250, UTF_CS) : value; } } diff --git a/web-api/src/test/java/com/graphhopper/util/HelperTest.java b/web-api/src/test/java/com/graphhopper/util/HelperTest.java index e3ce76bac9b..83bf0f54ab4 100644 --- a/web-api/src/test/java/com/graphhopper/util/HelperTest.java +++ b/web-api/src/test/java/com/graphhopper/util/HelperTest.java @@ -20,7 +20,9 @@ import org.junit.jupiter.api.Test; import java.util.Locale; +import java.util.Random; +import static com.graphhopper.util.Helper.UTF_CS; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -104,4 +106,43 @@ public void testUnderscoreToCamelCase() { assertEquals("testCaseTBD", Helper.underScoreToCamelCase("test_case_t_b_d")); assertEquals("TestCase_", Helper.underScoreToCamelCase("_test_case_")); } + + // @RepeatedTest(1000) + public void ignoreRandomString() { + String s = ""; + long seed = new Random().nextLong(); + Random rand = new Random(seed); + for (int i = 0; i < 255; i++) { + s += (char) rand.nextInt(); + } + + s = Helper.cutStringForKV(s); + assertTrue(s.getBytes(UTF_CS).length <= 255, s.getBytes(UTF_CS).length + " -> seed " + seed); + } + + @Test + public void testIssue2609() { + String s = ""; + for (int i = 0; i < 128; i++) { + s += "ä"; + } + + // all chars are 2 bytes so at 255 we cut the char into an invalid character and this is probably automatically + // corrected leading to a longer string (or do chars have special marker bits to indicate their byte length?) + assertEquals(257, new String(s.getBytes(UTF_CS), 0, 255, UTF_CS).getBytes(UTF_CS).length); + + // see this in action: + byte[] bytes = "a".getBytes(UTF_CS); + assertEquals(1, new String(bytes, 0, 1, UTF_CS).getBytes(UTF_CS).length); + // force incorrect char: + bytes[0] = -25; + assertEquals(3, new String(bytes, 0, 1, UTF_CS).getBytes(UTF_CS).length); + } + + @Test + public void testCutString() { + String s = Helper.cutStringForKV("Бухарестская улица (http://ru.wikipedia.org/wiki/" + + "%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))"); + assertEquals(250, s.getBytes(UTF_CS).length); + } } From 7bb8ff7d4581e8f34baf574fb470816f3adfcc64 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 26 Jun 2022 01:22:55 +0200 Subject: [PATCH 066/389] CHPreparationGraph bug fix: unsigned shift required (and increase limit for getKeyWithFlags #2567) --- .../java/com/graphhopper/routing/ch/CHPreparationGraph.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java index 403d9428734..66d6c9b143b 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java @@ -905,7 +905,7 @@ OrigGraph build() { private int getKeyWithFlags(int key, boolean fwd, boolean bwd) { // we use only 30 bits for the key and store two access flags along with the same int - if (key >= Integer.MAX_VALUE >> 2) + if (key >= Integer.MAX_VALUE >> 1) throw new IllegalArgumentException("Maximum edge ID exceeded: " + Integer.MAX_VALUE); key <<= 1; if (fwd) @@ -983,7 +983,7 @@ public int getAdjNode() { @Override public int getOrigEdgeKeyFirst() { - return graph.keysAndFlags.get(index) >> 2; + return graph.keysAndFlags.get(index) >>> 2; } @Override From 88bd67e7fa684df41b20aee0acf861ab0150e722 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 26 Jun 2022 01:28:08 +0200 Subject: [PATCH 067/389] make error message more clear --- .../java/com/graphhopper/routing/ch/CHPreparationGraph.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java index 66d6c9b143b..97fcd516ab9 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java @@ -906,7 +906,7 @@ OrigGraph build() { private int getKeyWithFlags(int key, boolean fwd, boolean bwd) { // we use only 30 bits for the key and store two access flags along with the same int if (key >= Integer.MAX_VALUE >> 1) - throw new IllegalArgumentException("Maximum edge ID exceeded: " + Integer.MAX_VALUE); + throw new IllegalArgumentException("Maximum edge key exceeded: " + key); key <<= 1; if (fwd) key++; From 47c57118423b57f302ab1a021b00b913f80e527a Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 26 Jun 2022 01:58:02 +0200 Subject: [PATCH 068/389] CHPreparationGraph: revert to previously correct signed shift --- .../java/com/graphhopper/routing/ch/CHPreparationGraph.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java index 97fcd516ab9..033cf3c9f54 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java @@ -983,7 +983,7 @@ public int getAdjNode() { @Override public int getOrigEdgeKeyFirst() { - return graph.keysAndFlags.get(index) >>> 2; + return graph.keysAndFlags.get(index) >> 2; } @Override From 8698e38653ac68fe9e09e7d3096c72b0f006c8bf Mon Sep 17 00:00:00 2001 From: Andi Date: Sun, 26 Jun 2022 10:02:13 +0200 Subject: [PATCH 069/389] Increase maximum edge-based CH key for preparation to 2^30 again (#2612) --- .../routing/ch/CHPreparationGraph.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java index 033cf3c9f54..a71a16ac179 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java @@ -903,10 +903,13 @@ OrigGraph build() { return new OrigGraph(buildFirstEdgesByNode(), toNodes, keysAndFlags); } - private int getKeyWithFlags(int key, boolean fwd, boolean bwd) { + private static int getKeyWithFlags(int key, boolean fwd, boolean bwd) { // we use only 30 bits for the key and store two access flags along with the same int - if (key >= Integer.MAX_VALUE >> 1) - throw new IllegalArgumentException("Maximum edge key exceeded: " + key); + // this allows for a maximum of 536mio edges in base graph which is still enough for planet-wide OSM, + // but if we exceed this limit we should probably move one of the fwd/bwd bits to the nodes field or + // store the edge instead of the key as we did before #2567 (only here) + if (key > Integer.MAX_VALUE >> 1) + throw new IllegalArgumentException("Maximum edge key exceeded: " + key + ", max: " + (Integer.MAX_VALUE >> 1)); key <<= 1; if (fwd) key++; @@ -983,7 +986,7 @@ public int getAdjNode() { @Override public int getOrigEdgeKeyFirst() { - return graph.keysAndFlags.get(index) >> 2; + return graph.keysAndFlags.get(index) >>> 2; } @Override @@ -993,11 +996,10 @@ public int getOrigEdgeKeyLast() { private boolean hasAccess() { int e = graph.keysAndFlags.get(index); - if (reverse) { + if (reverse) return (e & 0b01) == 0b01; - } else { + else return (e & 0b10) == 0b10; - } } @Override From 3c2dfd1aedf8ba6881353456117ca5ec486f20a7 Mon Sep 17 00:00:00 2001 From: easbar Date: Sun, 26 Jun 2022 10:55:55 +0200 Subject: [PATCH 070/389] Add test for large edge ID, #2612 --- .../routing/ch/CHPreparationGraph.java | 2 +- .../routing/ch/CHPreparationGraphTest.java | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java index a71a16ac179..ac10b55d5de 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java @@ -853,7 +853,7 @@ public String toString() { * edge-based CH. In principle we could use base graph for this, but it turned out it is faster to use this * graph (because it does not need to read all the edge flags to determine the access flags). */ - private static class OrigGraph { + static class OrigGraph { // we store a list of 'edges' in the format: adjNode|edgeId|accessFlags, we use two ints for each edge private final IntArrayList adjNodes; private final IntArrayList keysAndFlags; diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHPreparationGraphTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHPreparationGraphTest.java index 3edd86c0c79..a23638ed5ee 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHPreparationGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHPreparationGraphTest.java @@ -18,9 +18,10 @@ package com.graphhopper.routing.ch; +import com.graphhopper.util.GHUtility; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; /** * So far there aren't many tests but the graph should be very easy to test as it has basically no dependencies and @@ -53,4 +54,24 @@ void basic() { } assertEquals("3-4 16.0,", res.toString()); } + + @Test + void useLargeEdgeId() { + CHPreparationGraph.OrigGraph.Builder builder = new CHPreparationGraph.OrigGraph.Builder(); + int largeEdgeID = Integer.MAX_VALUE >> 2; + assertEquals(536_870_911, largeEdgeID); + // 0->1 + builder.addEdge(0, 1, largeEdgeID, true, false); + CHPreparationGraph.OrigGraph g = builder.build(); + PrepareGraphOrigEdgeIterator iter = g.createOutOrigEdgeExplorer().setBaseNode(0); + assertTrue(iter.next()); + assertEquals(largeEdgeID, GHUtility.getEdgeFromEdgeKey(iter.getOrigEdgeKeyFirst())); + iter = g.createInOrigEdgeExplorer().setBaseNode(0); + assertFalse(iter.next()); + + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> + new CHPreparationGraph.OrigGraph.Builder().addEdge(0, 1, largeEdgeID + 1, true, false) + ); + assertTrue(e.getMessage().contains("Maximum edge key exceeded: 1073741824, max: 1073741823"), e.getMessage()); + } } \ No newline at end of file From 9bbf9ee2b1f2adfbd707a543ef39c12fce7ef6f1 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 26 Jun 2022 12:01:18 +0200 Subject: [PATCH 071/389] custom_model: introduce value expression (#2568) * value expression: findMax needs to be evaluated * less strict if * or + operator * refactored to findMinMax * made core tests pass * fix some more tests * fix more tests * add encoded values to initialization plus tests * check minimum for custom_model of query * improve on check of minimum and negative factors * less overhead for constant values * use Double.parse instead of ExpressionEvaluator if number to significantly improve speed * minor cosmetics * clarify LATER and removed TODO NOW * adapted docs * minor optimization and cleanup * fix FindMinMax.checkLMConstraints call * do not allow / as operation * reduce power and complexity of right hand side a bit more and allow only a single EncodedValue for now * better readable via extra MinMax class instead of double[] * exclude changes from master * a bit more comments --- .../graphhopper/api/GraphHopperWebTest.java | 10 +- .../routing/DefaultWeightingFactory.java | 2 + .../java/com/graphhopper/routing/Router.java | 3 +- .../routing/ev/DecimalEncodedValue.java | 5 + .../routing/ev/DecimalEncodedValueImpl.java | 4 + .../routing/ev/IntEncodedValue.java | 7 +- .../routing/ev/IntEncodedValueImpl.java | 5 + ...java => ConditionalExpressionVisitor.java} | 52 +---- .../weighting/custom/CustomModelParser.java | 120 +++++++++--- .../custom/CustomWeightingHelper.java | 8 + .../routing/weighting/custom/FindMinMax.java | 100 ++++++++++ .../weighting/custom/NameValidator.java | 5 + .../routing/weighting/custom/ParseResult.java | 11 ++ .../custom/ValueExpressionVisitor.java | 180 ++++++++++++++++++ .../java/com/graphhopper/GraphHopperTest.java | 8 +- .../routing/PriorityRoutingTest.java | 2 +- .../ConditionalExpressionVisitorTest.java | 135 +++++++++++++ .../custom/CustomModelParserTest.java | 125 +++++++++--- .../weighting/custom/CustomWeightingTest.java | 71 +++---- .../custom/ExpressionVisitorTest.java | 164 ---------------- .../weighting/custom/FindMinMaxTest.java | 114 +++++++++++ .../custom/ValueExpressionVisitorTest.java | 110 +++++++++++ .../graphhopper/util/InstructionListTest.java | 2 +- docs/core/custom-models.md | 142 +++++++------- .../graphhopper/example/RoutingExample.java | 4 +- .../jackson/StatementDeserializer.java | 12 +- .../jackson/StatementSerializer.java | 2 +- .../java/com/graphhopper/json/MinMax.java | 11 ++ .../java/com/graphhopper/json/Statement.java | 36 ++-- .../com/graphhopper/util/CustomModel.java | 84 +------- .../com/graphhopper/util/CustomModelTest.java | 108 ++--------- .../resources/RouteResourceClientHCTest.java | 2 +- .../RouteResourceCustomModelTest.java | 12 +- 33 files changed, 1077 insertions(+), 579 deletions(-) rename core/src/main/java/com/graphhopper/routing/weighting/custom/{ExpressionVisitor.java => ConditionalExpressionVisitor.java} (78%) create mode 100644 core/src/main/java/com/graphhopper/routing/weighting/custom/FindMinMax.java create mode 100644 core/src/main/java/com/graphhopper/routing/weighting/custom/NameValidator.java create mode 100644 core/src/main/java/com/graphhopper/routing/weighting/custom/ParseResult.java create mode 100644 core/src/main/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitor.java create mode 100644 core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java delete mode 100644 core/src/test/java/com/graphhopper/routing/weighting/custom/ExpressionVisitorTest.java create mode 100644 core/src/test/java/com/graphhopper/routing/weighting/custom/FindMinMaxTest.java create mode 100644 core/src/test/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitorTest.java create mode 100644 web-api/src/main/java/com/graphhopper/json/MinMax.java diff --git a/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java b/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java index 6c3d8cbe02e..7be93260a08 100644 --- a/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java +++ b/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java @@ -92,9 +92,9 @@ public void customModel() throws JsonProcessingException { new GeometryFactory().createPolygon(area_2_coordinates), new HashMap<>())); CustomModel customModel = new CustomModel() - .addToSpeed(Statement.If("road_class == MOTORWAY", Statement.Op.LIMIT, 80)) - .addToPriority(Statement.If("surface == DIRT", Statement.Op.MULTIPLY, 0.7)) - .addToPriority(Statement.If("surface == SAND", Statement.Op.MULTIPLY, 0.6)) + .addToSpeed(Statement.If("road_class == MOTORWAY", Statement.Op.LIMIT, "80")) + .addToPriority(Statement.If("surface == DIRT", Statement.Op.MULTIPLY, "0.7")) + .addToPriority(Statement.If("surface == SAND", Statement.Op.MULTIPLY, "0.6")) .setDistanceInfluence(69) .setHeadingPenalty(22) .setAreas(areas); @@ -111,8 +111,8 @@ public void customModel() throws JsonProcessingException { JsonNode expected = objectMapper.readTree("{\"distance_influence\":69.0,\"heading_penalty\":22.0,\"internal\":false,\"areas\":{" + "\"area_1\":{\"id\":\"area_1\",\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[48.019324184801185,11.28021240234375],[48.019324184801185,11.53564453125],[48.11843396091691,11.53564453125],[48.11843396091691,11.28021240234375],[48.019324184801185,11.28021240234375]]]},\"properties\":{}}," + "\"area_2\":{\"id\":\"area_2\",\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[48.15509285476017,11.53289794921875],[48.15509285476017,11.8212890625],[48.281365151571755,11.8212890625],[48.281365151571755,11.53289794921875],[48.15509285476017,11.53289794921875]]]},\"properties\":{}}}," + - "\"speed\":[{\"if\":\"road_class == MOTORWAY\",\"limit_to\":80.0}]," + - "\"priority\":[{\"if\":\"surface == DIRT\",\"multiply_by\":0.7},{\"if\":\"surface == SAND\",\"multiply_by\":0.6}]}"); + "\"speed\":[{\"if\":\"road_class == MOTORWAY\",\"limit_to\":\"80\"}]," + + "\"priority\":[{\"if\":\"surface == DIRT\",\"multiply_by\":\"0.7\"},{\"if\":\"surface == SAND\",\"multiply_by\":\"0.6\"}]}"); assertEquals(expected, objectMapper.valueToTree(customModelJson)); } } \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java index df708867a5a..9d1dbe6c1a7 100644 --- a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java +++ b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java @@ -25,6 +25,7 @@ import com.graphhopper.routing.weighting.custom.CustomModelParser; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.routing.weighting.custom.CustomWeighting; +import com.graphhopper.routing.weighting.custom.FindMinMax; import com.graphhopper.storage.BaseGraph; import com.graphhopper.util.CustomModel; import com.graphhopper.util.PMap; @@ -75,6 +76,7 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis throw new IllegalArgumentException("custom weighting requires a CustomProfile but was profile=" + profile.getName()); CustomModel queryCustomModel = requestHints.getObject(CustomModel.KEY, null); CustomProfile customProfile = (CustomProfile) profile; + queryCustomModel = CustomModel.merge(customProfile.getCustomModel(), queryCustomModel); weighting = CustomModelParser.createWeighting(encoder, encodingManager, turnCostProvider, queryCustomModel); } else if ("shortest".equalsIgnoreCase(weightingStr)) { diff --git a/core/src/main/java/com/graphhopper/routing/Router.java b/core/src/main/java/com/graphhopper/routing/Router.java index feb1a394345..542b2e91dc7 100644 --- a/core/src/main/java/com/graphhopper/routing/Router.java +++ b/core/src/main/java/com/graphhopper/routing/Router.java @@ -34,6 +34,7 @@ import com.graphhopper.routing.weighting.BlockAreaWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.routing.weighting.custom.CustomProfile; +import com.graphhopper.routing.weighting.custom.FindMinMax; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.storage.GraphEdgeIdFinder; @@ -561,7 +562,7 @@ protected FlexiblePathCalculator createPathCalculator(QueryGraph queryGraph) { "\navailable LM profiles: " + landmarks.keySet()); if (profile instanceof CustomProfile && request.getCustomModel() != null && !request.getHints().getBool("lm.disable", false)) - request.getCustomModel().checkLMConstraints(((CustomProfile) profile).getCustomModel()); + FindMinMax.checkLMConstraints(((CustomProfile) profile).getCustomModel(), request.getCustomModel(), lookup); RoutingAlgorithmFactory routingAlgorithmFactory = new LMRoutingAlgorithmFactory(landmarkStorage).setDefaultActiveLandmarks(routerConfig.getActiveLandmarkCount()); return new FlexiblePathCalculator(queryGraph, routingAlgorithmFactory, weighting, getAlgoOpts()); } diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java index 7eac24edaa9..09e9f72b5a7 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java @@ -26,6 +26,11 @@ public interface DecimalEncodedValue extends EncodedValue { */ double getMaxDecimal(); + /** + * The minimum double value this EncodedValue accepts for setDecimal without throwing an exception. + */ + double getMinDecimal(); + /** * @return the smallest decimal value that is larger or equal to the given value and that can be stored exactly, * i.e. for which {@link #getDecimal} returns the same value that we put in using {@link #setDecimal}. diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java index bc77b721d8d..dab62919e14 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java @@ -149,4 +149,8 @@ public double getMaxDecimal() { return maxValue * factor; } + @Override + public double getMinDecimal() { + return minValue * factor; + } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java index 8c0731e96eb..f3c72c036ed 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java @@ -22,10 +22,15 @@ public interface IntEncodedValue extends EncodedValue { void setInt(boolean reverse, IntsRef ref, int value); /** - * The int value this EncodedValue accepts for setInt without throwing an exception. + * The maximum int value this EncodedValue accepts for setInt without throwing an exception. */ int getMaxInt(); + /** + * The minimum int value this EncodedValue accepts for setInt without throwing an exception. + */ + int getMinInt(); + /** * @return true if this EncodedValue can store a different value for its reverse direction */ diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java index c7434dabfd9..63b44f16a99 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java @@ -199,6 +199,11 @@ public int getMaxInt() { return maxValue; } + @Override + public int getMinInt() { + return minValue; + } + @Override public final boolean isStoreTwoDirections() { return storeTwoDirections; diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/ExpressionVisitor.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitor.java similarity index 78% rename from core/src/main/java/com/graphhopper/routing/weighting/custom/ExpressionVisitor.java rename to core/src/main/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitor.java index 333295023ba..8d76fa76eeb 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/ExpressionVisitor.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitor.java @@ -17,7 +17,6 @@ */ package com.graphhopper.routing.weighting.custom; -import com.graphhopper.json.Statement; import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.ev.RouteNetwork; import com.graphhopper.routing.ev.StringEncodedValue; @@ -30,7 +29,10 @@ import static com.graphhopper.routing.weighting.custom.CustomModelParser.IN_AREA_PREFIX; -class ExpressionVisitor implements Visitor.AtomVisitor { +/** + * Expression visitor for the if or else_if condition. + */ +class ConditionalExpressionVisitor implements Visitor.AtomVisitor { private final ParseResult result; private final EncodedValueLookup lookup; @@ -40,7 +42,7 @@ class ExpressionVisitor implements Visitor.AtomVisitor { "contains", "sqrt", "abs")); private String invalidMessage; - public ExpressionVisitor(ParseResult result, NameValidator nameValidator, EncodedValueLookup lookup) { + public ConditionalExpressionVisitor(ParseResult result, NameValidator nameValidator, EncodedValueLookup lookup) { this.result = result; this.nameValidator = nameValidator; this.lookup = lookup; @@ -94,7 +96,7 @@ public Boolean visitRvalue(Java.Rvalue rv) throws Exception { if (n.identifiers.length == 2 && isValidIdentifier(n.identifiers[0])) return true; } } - invalidMessage = mi.methodName + " is illegal method"; + invalidMessage = mi.methodName + " is an illegal method"; return false; } else if (rv instanceof Java.ParenthesizedExpression) { return ((Java.ParenthesizedExpression) rv).value.accept(this); @@ -146,31 +148,6 @@ public Boolean visitConstructorInvocation(Java.ConstructorInvocation ci) { return false; } - static void parseExpressions(StringBuilder expressions, NameValidator nameInConditionValidator, String exceptionInfo, - Set createObjects, List list, EncodedValueLookup lookup, String lastStmt) { - - for (Statement statement : list) { - if (statement.getKeyword() == Statement.Keyword.ELSE) { - if (!Helper.isEmpty(statement.getCondition())) - throw new IllegalArgumentException("expression must be empty but was " + statement.getCondition()); - - expressions.append("else {" + statement.getOperation().build(statement.getValue()) + "; }\n"); - } else if (statement.getKeyword() == Statement.Keyword.ELSEIF || statement.getKeyword() == Statement.Keyword.IF) { - ExpressionVisitor.ParseResult parseResult = parseExpression(statement.getCondition(), nameInConditionValidator, lookup); - if (!parseResult.ok) - throw new IllegalArgumentException(exceptionInfo + " invalid expression \"" + statement.getCondition() + "\"" + - (parseResult.invalidMessage == null ? "" : ": " + parseResult.invalidMessage)); - createObjects.addAll(parseResult.guessedVariables); - if (statement.getKeyword() == Statement.Keyword.ELSEIF) - expressions.append("else "); - expressions.append("if (" + parseResult.converted + ") {" + statement.getOperation().build(statement.getValue()) + "; }\n"); - } else { - throw new IllegalArgumentException("The statement must be either 'if', 'else_if' or 'else'"); - } - } - expressions.append(lastStmt); - } - /** * Enforce simple expressions of user input to increase security. * @@ -178,7 +155,7 @@ static void parseExpressions(StringBuilder expressions, NameValidator nameInCond * converted expression that includes class names for constants to avoid conflicts e.g. when doing "toll == Toll.NO" * instead of "toll == NO". */ - static ParseResult parseExpression(String expression, NameValidator validator, EncodedValueLookup lookup) { + static ParseResult parse(String expression, NameValidator validator, EncodedValueLookup lookup) { ParseResult result = new ParseResult(); try { Parser parser = new Parser(new Scanner("ignore", new StringReader(expression))); @@ -186,7 +163,7 @@ static ParseResult parseExpression(String expression, NameValidator validator, E // after parsing the expression the input should end (otherwise it is not "simple") if (parser.peek().type == TokenType.END_OF_INPUT) { result.guessedVariables = new LinkedHashSet<>(); - ExpressionVisitor visitor = new ExpressionVisitor(result, validator, lookup); + ConditionalExpressionVisitor visitor = new ConditionalExpressionVisitor(result, validator, lookup); result.ok = atom.accept(visitor); result.invalidMessage = visitor.invalidMessage; if (result.ok) { @@ -211,18 +188,7 @@ static String toEncodedValueClassName(String arg) { return Character.toUpperCase(clazz.charAt(0)) + clazz.substring(1); } - static class ParseResult { - StringBuilder converted; - boolean ok; - String invalidMessage; - Set guessedVariables; - } - - interface NameValidator { - boolean isValid(String name); - } - - static class Replacement { + class Replacement { int start; int oldLength; String newString; diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java index 82c64f28ab8..1ba7a6a1fb3 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java @@ -17,15 +17,13 @@ */ package com.graphhopper.routing.weighting.custom; +import com.graphhopper.json.MinMax; import com.graphhopper.json.Statement; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.TurnCostProvider; -import com.graphhopper.util.CustomModel; -import com.graphhopper.util.EdgeIteratorState; -import com.graphhopper.util.GHUtility; -import com.graphhopper.util.JsonFeature; +import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; import com.graphhopper.util.shapes.Polygon; import org.codehaus.commons.compiler.CompileException; @@ -45,7 +43,7 @@ public class CustomModelParser { private static final AtomicLong longVal = new AtomicLong(1); static final String IN_AREA_PREFIX = "in_"; - private static final Set allowedNames = new HashSet<>(Arrays.asList("edge", "Math")); + private static final Set allowedNamesInCondition = new HashSet<>(Arrays.asList("edge", "Math")); private static final boolean JANINO_DEBUG = Boolean.getBoolean(Scanner.SYSTEM_PROPERTY_SOURCE_DEBUGGING_ENABLE); private static final String SCRIPT_FILE_DIR = System.getProperty(Scanner.SYSTEM_PROPERTY_SOURCE_DEBUGGING_DIR, "./src/main/java/com/graphhopper/routing/weighting/custom"); @@ -86,29 +84,31 @@ public static CustomWeighting createWeighting(FlagEncoder baseFlagEncoder, Encod /** * This method compiles a new subclass of CustomWeightingHelper composed from the provided CustomModel caches this * and returns an instance. + * * @param priorityEnc can be null */ static CustomWeighting.Parameters createWeightingParameters(CustomModel customModel, EncodedValueLookup lookup, DecimalEncodedValue avgSpeedEnc, double globalMaxSpeed, DecimalEncodedValue priorityEnc) { - final double maxSpeed = customModel.findMaxSpeed(globalMaxSpeed); // globalMaxSpeed can be lower than avgSpeedEnc.getMaxDecimal() - final double maxPriority = customModel.findMaxPriority(priorityEnc == null ? 1 : priorityEnc.getMaxDecimal()); - String key = customModel.toString() + ",maxSpeed:" + maxSpeed + ",maxPriority:" + maxPriority; + double globalMaxPriority = priorityEnc == null ? 1 : priorityEnc.getMaxDecimal(); + // if the same custom model is used with a different base profile we cannot use the cached version + String key = customModel + ",speed:" + avgSpeedEnc.getName() + ",global_max_speed:" + globalMaxSpeed + + (priorityEnc == null ? "" : "prio:" + priorityEnc.getName() + ",global_max_priority:" + globalMaxPriority); if (key.length() > 100_000) throw new IllegalArgumentException("Custom Model too big: " + key.length()); Class clazz = customModel.isInternal() ? INTERNAL_CACHE.get(key) : null; if (CACHE_SIZE > 0 && clazz == null) clazz = CACHE.get(key); if (clazz == null) { - clazz = createClazz(customModel, lookup, maxSpeed); + clazz = createClazz(customModel, lookup, globalMaxSpeed, globalMaxPriority); if (customModel.isInternal()) { INTERNAL_CACHE.put(key, clazz); if (INTERNAL_CACHE.size() > 100) { CACHE.putAll(INTERNAL_CACHE); INTERNAL_CACHE.clear(); LoggerFactory.getLogger(CustomModelParser.class).warn("Internal cache must stay small but was " - + INTERNAL_CACHE.size() + ". Cleared it. Misuse of CustomModel::__internal_cache?"); + + INTERNAL_CACHE.size() + ". Cleared it. Misuse of CustomModel::internal?"); } } else if (CACHE_SIZE > 0) { CACHE.put(key, clazz); @@ -119,24 +119,57 @@ static CustomWeighting.Parameters createWeightingParameters(CustomModel customMo // The class does not need to be thread-safe as we create an instance per request CustomWeightingHelper prio = (CustomWeightingHelper) clazz.getDeclaredConstructor().newInstance(); prio.init(lookup, avgSpeedEnc, priorityEnc, customModel.getAreas()); - return new CustomWeighting.Parameters(prio::getSpeed, prio::getPriority, maxSpeed, maxPriority, + return new CustomWeighting.Parameters(prio::getSpeed, prio::getPriority, prio.getMaxSpeed(), prio.getMaxPriority(), customModel.getDistanceInfluence(), customModel.getHeadingPenalty()); } catch (ReflectiveOperationException ex) { throw new IllegalArgumentException("Cannot compile expression " + ex.getMessage(), ex); } } - private static Class createClazz(CustomModel customModel, EncodedValueLookup lookup, double globalMaxSpeed) { + /** + * This method does the following: + *

+ */ + private static Class createClazz(CustomModel customModel, EncodedValueLookup lookup, + double globalMaxSpeed, double globalMaxPriority) { try { HashSet priorityVariables = new LinkedHashSet<>(); + // initial value of minimum has to be >0 so that multiple_by with a negative value leads to a negative value and not 0 + MinMax minMaxPriority = new MinMax(1, globalMaxPriority); + FindMinMax.findMinMax(priorityVariables, minMaxPriority, customModel.getPriority(), lookup); + if (minMaxPriority.min < 0) + throw new IllegalArgumentException("priority has to be >=0 but can be negative (" + minMaxPriority.min + ")"); + if (minMaxPriority.max < 0) + throw new IllegalArgumentException("maximum priority has to be >=0 but was " + minMaxPriority.max); List priorityStatements = createGetPriorityStatements(priorityVariables, customModel, lookup); + HashSet speedVariables = new LinkedHashSet<>(); - List speedStatements = createGetSpeedStatements(speedVariables, customModel, lookup, globalMaxSpeed); + MinMax minMaxSpeed = new MinMax(1, globalMaxSpeed); + FindMinMax.findMinMax(speedVariables, minMaxSpeed, customModel.getSpeed(), lookup); + if (minMaxSpeed.min < 0) + throw new IllegalArgumentException("speed has to be >=0 but can be negative (" + minMaxSpeed.min + ")"); + if (minMaxSpeed.max <= 0) + throw new IllegalArgumentException("maximum speed has to be >0 but was " + minMaxSpeed.max); + List speedStatements = createGetSpeedStatements(speedVariables, customModel, lookup, minMaxSpeed.max); // Create different class name, which is required only for debugging. // TODO does it improve performance too? I.e. it could be that the JIT is confused if different classes // have the same name and it mixes performance stats. See https://github.com/janino-compiler/janino/issues/137 long counter = longVal.incrementAndGet(); - String classTemplate = createClassTemplate(counter, priorityVariables, speedVariables, lookup, customModel); + String classTemplate = createClassTemplate(counter, priorityVariables, minMaxPriority.max, speedVariables, minMaxSpeed.max, + lookup, customModel.getAreas()); Java.CompilationUnit cu = (Java.CompilationUnit) new Parser(new Scanner("source", new StringReader(classTemplate))). parseAbstractCompilationUnit(); cu = injectStatements(priorityStatements, speedStatements, cu); @@ -144,8 +177,6 @@ private static Class createClazz(CustomModel customModel, EncodedValueLookup return sc.getClassLoader().loadClass("com.graphhopper.routing.weighting.custom.JaninoCustomWeightingHelperSubclass" + counter); } catch (Exception ex) { String errString = "Cannot compile expression"; - if (ex instanceof CompileException) - errString += ", in " + ((CompileException) ex).getLocation().getFileName(); throw new IllegalArgumentException(errString + ": " + ex.getMessage(), ex); } } @@ -157,10 +188,10 @@ private static Class createClazz(CustomModel customModel, EncodedValueLookup */ private static List createGetSpeedStatements(Set speedVariables, CustomModel customModel, EncodedValueLookup lookup, - double globalMaxSpeed) throws Exception { + double maxSpeed) throws Exception { List speedStatements = new ArrayList<>(); - speedStatements.addAll(verifyExpressions(new StringBuilder(), "in 'speed' entry, ", speedVariables, - customModel.getSpeed(), lookup, "return Math.min(value, " + globalMaxSpeed + ");\n")); + speedStatements.addAll(verifyExpressions(new StringBuilder(), "speed entry", speedVariables, + customModel.getSpeed(), lookup, "return Math.min(value, " + maxSpeed + ");\n")); String speedMethodStartBlock = "double value = super.getRawSpeed(edge, reverse);\n"; // a bit inefficient to possibly define variables twice, but for now we have two separate methods for (String arg : speedVariables) { @@ -179,7 +210,7 @@ private static List createGetSpeedStatements(Set sp private static List createGetPriorityStatements(Set priorityVariables, CustomModel customModel, EncodedValueLookup lookup) throws Exception { List priorityStatements = new ArrayList<>(); - priorityStatements.addAll(verifyExpressions(new StringBuilder(), "in 'priority' entry, ", + priorityStatements.addAll(verifyExpressions(new StringBuilder(), "priority entry, ", priorityVariables, customModel.getPriority(), lookup, "return value;")); String priorityMethodStartBlock = "double value = super.getRawPriority(edge, reverse);\n"; for (String arg : priorityVariables) { @@ -191,7 +222,7 @@ private static List createGetPriorityStatements(Set } static boolean isValidVariableName(String name) { - return name.startsWith(IN_AREA_PREFIX) || allowedNames.contains(name); + return name.startsWith(IN_AREA_PREFIX) || allowedNamesInCondition.contains(name); } /** @@ -238,8 +269,10 @@ private static String getReturnType(EncodedValue encodedValue) { * means that the source file is free from user input and could be directly compiled. Before we do this we still * have to inject that parsed and safe user expressions in a later step. */ - private static String createClassTemplate(long counter, Set priorityVariables, Set speedVariables, - EncodedValueLookup lookup, CustomModel customModel) { + private static String createClassTemplate(long counter, + Set priorityVariables, double maxPriority, + Set speedVariables, double maxSpeed, + EncodedValueLookup lookup, Map areas) { final StringBuilder importSourceCode = new StringBuilder("import com.graphhopper.routing.ev.*;\n"); importSourceCode.append("import java.util.Map;\n"); final StringBuilder classSourceCode = new StringBuilder(100); @@ -270,7 +303,7 @@ private static String createClassTemplate(long counter, Set priorityVari String id = arg.substring(IN_AREA_PREFIX.length()); if (!EncodingManager.isValidEncodedValue(id)) throw new IllegalArgumentException("Area has invalid name: " + arg); - JsonFeature feature = customModel.getAreas().get(id); + JsonFeature feature = areas.get(id); if (feature == null) throw new IllegalArgumentException("Area '" + id + "' wasn't found"); if (feature.getGeometry() == null) @@ -310,6 +343,14 @@ private static String createClassTemplate(long counter, Set priorityVari + " public double getSpeed(EdgeIteratorState edge, boolean reverse) {\n" + " return getRawSpeed(edge, reverse); //will be overwritten by code injected in DeepCopier\n" + " }\n" + + " @Override\n" + + " protected double getMaxSpeed() {\n" + + " return " + maxSpeed + ";" + + " }\n" + + " @Override\n" + + " protected double getMaxPriority() {\n" + + " return " + maxPriority + ";" + + " }\n" + "}"; } @@ -325,13 +366,40 @@ private static List verifyExpressions(StringBuilder express List list, EncodedValueLookup lookup, String lastStmt) throws Exception { // allow variables, all encoded values, constants - ExpressionVisitor.NameValidator nameInConditionValidator = name -> lookup.hasEncodedValue(name) + NameValidator nameInConditionValidator = name -> lookup.hasEncodedValue(name) || name.toUpperCase(Locale.ROOT).equals(name) || isValidVariableName(name); - ExpressionVisitor.parseExpressions(expressions, nameInConditionValidator, info, createObjects, list, lookup, lastStmt); + + parseExpressions(expressions, nameInConditionValidator, lookup, info, createObjects, list, lastStmt); return new Parser(new org.codehaus.janino.Scanner(info, new StringReader(expressions.toString()))). parseBlockStatements(); } + static void parseExpressions(StringBuilder expressions, NameValidator nameInConditionValidator, EncodedValueLookup lookup, + String exceptionInfo, Set createObjects, List list, String lastStmt) { + + for (Statement statement : list) { + // avoid parsing the RHS value expression again as we just did it to get the maximum values in createClazz + if (statement.getKeyword() == Statement.Keyword.ELSE) { + if (!Helper.isEmpty(statement.getCondition())) + throw new IllegalArgumentException("condition must be empty but was " + statement.getCondition()); + + expressions.append("else {" + statement.getOperation().build(statement.getValue()) + "; }\n"); + } else if (statement.getKeyword() == Statement.Keyword.ELSEIF || statement.getKeyword() == Statement.Keyword.IF) { + ParseResult parseResult = ConditionalExpressionVisitor.parse(statement.getCondition(), nameInConditionValidator, lookup); + if (!parseResult.ok) + throw new IllegalArgumentException(exceptionInfo + " invalid condition \"" + statement.getCondition() + "\"" + + (parseResult.invalidMessage == null ? "" : ": " + parseResult.invalidMessage)); + createObjects.addAll(parseResult.guessedVariables); + if (statement.getKeyword() == Statement.Keyword.ELSEIF) + expressions.append("else "); + expressions.append("if (" + parseResult.converted + ") {" + statement.getOperation().build(statement.getValue()) + "; }\n"); + } else { + throw new IllegalArgumentException("The statement must be either 'if', 'else_if' or 'else'"); + } + } + expressions.append(lastStmt); + } + /** * Injects the already parsed expressions (converted to BlockStatement) via janinos DeepCopier to the provided * CompilationUnit cu (a class file). diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeightingHelper.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeightingHelper.java index d295143626d..543fc9fbc02 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeightingHelper.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeightingHelper.java @@ -67,6 +67,14 @@ protected final double getRawPriority(EdgeIteratorState edge, boolean reverse) { return priority; } + protected double getMaxPriority() { + return 1; + } + + protected double getMaxSpeed() { + return 1; + } + public static boolean in(Polygon p, EdgeIteratorState edge) { BBox bbox = GHUtility.createBBox(edge); if (!p.getBounds().intersects(bbox)) diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/FindMinMax.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/FindMinMax.java new file mode 100644 index 00000000000..40b0117cf75 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/FindMinMax.java @@ -0,0 +1,100 @@ +package com.graphhopper.routing.weighting.custom; + +import com.graphhopper.json.MinMax; +import com.graphhopper.json.Statement; +import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.util.CustomModel; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static com.graphhopper.json.Statement.Keyword.ELSE; +import static com.graphhopper.json.Statement.Keyword.IF; + +public class FindMinMax { + + /** + * This method throws an exception when this CustomModel would decrease the edge weight compared to the specified + * baseModel as in such a case the optimality of A* with landmarks can no longer be guaranteed (as the preparation + * is based on baseModel). + */ + public static void checkLMConstraints(CustomModel baseModel, CustomModel queryModel, EncodedValueLookup lookup) { + if (queryModel.isInternal()) + throw new IllegalArgumentException("CustomModel of query cannot be internal"); + if (queryModel.hasDistanceInfluence() && queryModel.getDistanceInfluence() < baseModel.getDistanceInfluence()) + throw new IllegalArgumentException("CustomModel in query can only use " + + "distance_influence bigger or equal to " + baseModel.getDistanceInfluence() + + ", but was: " + queryModel.getDistanceInfluence()); + + checkMultiplyValue(queryModel.getPriority(), lookup); + checkMultiplyValue(queryModel.getSpeed(), lookup); + } + + private static void checkMultiplyValue(List list, EncodedValueLookup lookup) { + Set createdObjects = new HashSet<>(); + for (Statement statement : list) { + if (statement.getOperation() == Statement.Op.MULTIPLY) { + MinMax minMax = ValueExpressionVisitor.findMinMax(createdObjects, statement.getValue(), lookup); + if (minMax.max > 1) + throw new IllegalArgumentException("maximum of value '" + statement.getValue() + "'cannot be larger than 1, but was: " + minMax.max); + else if (minMax.min < 0) + throw new IllegalArgumentException("minimum of value '" + statement.getValue() + "' cannot be smaller than 0, but was: " + minMax.min); + } + } + } + + /** + * This method returns the smallest value possible in "min" and the smallest value that cannot be + * exceeded by any edge in max. + */ + static MinMax findMinMax(Set createdObjects, MinMax minMax, List statements, EncodedValueLookup lookup) { + // 'blocks' of the statements are applied one after the other. A block consists of one (if) or more statements (elseif+else) + List> blocks = splitIntoBlocks(statements); + for (List block : blocks) findMinMaxForBlock(createdObjects, minMax, block, lookup); + return minMax; + } + + private static void findMinMaxForBlock(Set createdObjects, final MinMax minMax, List block, EncodedValueLookup lookup) { + if (block.isEmpty() || !IF.equals(block.get(0).getKeyword())) + throw new IllegalArgumentException("Every block must start with an if-statement"); + + MinMax minMaxBlock; + if (block.get(0).getCondition().trim().equals("true")) { + minMaxBlock = block.get(0).getOperation().apply(minMax, ValueExpressionVisitor.findMinMax(createdObjects, block.get(0).getValue(), lookup)); + } else { + minMaxBlock = new MinMax(Double.MAX_VALUE, 0); + boolean foundElse = false; + for (Statement s : block) { + if (s.getKeyword() == ELSE) foundElse = true; + MinMax tmp = s.getOperation().apply(minMax, ValueExpressionVisitor.findMinMax(createdObjects, s.getValue(), lookup)); + minMaxBlock.min = Math.min(minMaxBlock.min, tmp.min); + minMaxBlock.max = Math.max(minMaxBlock.max, tmp.max); + } + + // if there is no 'else' statement it's like there is a 'neutral' branch that leaves the initial value as is + if (!foundElse) { + minMaxBlock.min = Math.min(minMaxBlock.min, minMax.min); + minMaxBlock.max = Math.max(minMaxBlock.max, minMax.max); + } + } + + minMax.min = minMaxBlock.min; + minMax.max = minMaxBlock.max; + } + + /** + * Splits the specified list into several list of statements starting with if + */ + private static List> splitIntoBlocks(List statements) { + List> result = new ArrayList<>(); + List block = null; + for (Statement st : statements) { + if (IF.equals(st.getKeyword())) result.add(block = new ArrayList<>()); + if (block == null) throw new IllegalArgumentException("Every block must start with an if-statement"); + block.add(st); + } + return result; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/NameValidator.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/NameValidator.java new file mode 100644 index 00000000000..058e7ce8022 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/NameValidator.java @@ -0,0 +1,5 @@ +package com.graphhopper.routing.weighting.custom; + +interface NameValidator { + boolean isValid(String name); +} diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/ParseResult.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/ParseResult.java new file mode 100644 index 00000000000..9adaca5e75e --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/ParseResult.java @@ -0,0 +1,11 @@ +package com.graphhopper.routing.weighting.custom; + +import java.util.Set; + +class ParseResult { + StringBuilder converted; + boolean ok; + String invalidMessage; + Set guessedVariables; + Set operators; +} diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitor.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitor.java new file mode 100644 index 00000000000..9318c74a1e7 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitor.java @@ -0,0 +1,180 @@ +package com.graphhopper.routing.weighting.custom; + +import com.graphhopper.json.MinMax; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EncodedValue; +import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.IntEncodedValue; +import org.codehaus.commons.compiler.CompileException; +import org.codehaus.janino.*; + +import java.io.StringReader; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * Expression visitor for right-hand side value of limit_to or multiply_by. + */ +public class ValueExpressionVisitor implements Visitor.AtomVisitor { + + private final ParseResult result; + private final NameValidator nameValidator; + private final Set allowedMethods = new HashSet<>(Arrays.asList("sqrt", "abs")); + private String invalidMessage; + + public ValueExpressionVisitor(ParseResult result, NameValidator nameValidator) { + this.result = result; + this.nameValidator = nameValidator; + } + + // allow only methods and other identifiers (constants and encoded values) + boolean isValidIdentifier(String identifier) { + if (nameValidator.isValid(identifier)) { + if (!Character.isUpperCase(identifier.charAt(0))) + result.guessedVariables.add(identifier); + return true; + } + return false; + } + + @Override + public Boolean visitRvalue(Java.Rvalue rv) throws Exception { + if (rv instanceof Java.AmbiguousName) { + Java.AmbiguousName n = (Java.AmbiguousName) rv; + if (n.identifiers.length == 1) { + String arg = n.identifiers[0]; + // e.g. like road_class + if (isValidIdentifier(arg)) return true; + invalidMessage = "'" + arg + "' not available"; + return false; + } + invalidMessage = "identifier " + n + " invalid"; + return false; + } + if (rv instanceof Java.Literal) { + return true; + } else if (rv instanceof Java.UnaryOperation) { + Java.UnaryOperation uop = (Java.UnaryOperation) rv; + result.operators.add(uop.operator); + if (uop.operator.equals("-")) + return uop.operand.accept(this); + return false; + } else if (rv instanceof Java.MethodInvocation) { + Java.MethodInvocation mi = (Java.MethodInvocation) rv; + if (allowedMethods.contains(mi.methodName)) { + // skip methods like this.in() for now + if (mi.target != null) { + // edge.getDistance, Math.sqrt => check target name (edge or Math) + Java.AmbiguousName n = (Java.AmbiguousName) mi.target.toRvalue(); + if (n.identifiers.length == 2 && isValidIdentifier(n.identifiers[0])) return true; + } + } + invalidMessage = mi.methodName + " is an illegal method"; + return false; + } else if (rv instanceof Java.ParenthesizedExpression) { + return ((Java.ParenthesizedExpression) rv).value.accept(this); + } else if (rv instanceof Java.BinaryOperation) { + Java.BinaryOperation binOp = (Java.BinaryOperation) rv; + String op = binOp.operator; + result.operators.add(op); + if (op.equals("*") || op.equals("+") || binOp.operator.equals("-")) { + return binOp.lhs.accept(this) && binOp.rhs.accept(this); + } + invalidMessage = "invalid operation '" + op + "'"; + return false; + } + return false; + } + + @Override + public Boolean visitPackage(Java.Package p) { + return false; + } + + @Override + public Boolean visitType(Java.Type t) { + return false; + } + + @Override + public Boolean visitConstructorInvocation(Java.ConstructorInvocation ci) { + return false; + } + + static ParseResult parse(String expression, NameValidator validator) { + ParseResult result = new ParseResult(); + try { + Parser parser = new Parser(new Scanner("ignore", new StringReader(expression))); + Java.Atom atom = parser.parseConditionalExpression(); + if (parser.peek().type == TokenType.END_OF_INPUT) { + result.guessedVariables = new LinkedHashSet<>(); + result.operators = new LinkedHashSet<>(); + ValueExpressionVisitor visitor = new ValueExpressionVisitor(result, validator); + result.ok = atom.accept(visitor); + result.invalidMessage = visitor.invalidMessage; + } + } catch (Exception ex) { + } + return result; + } + + static MinMax findMinMax(Set createdObjects, String valueExpression, EncodedValueLookup lookup) { + ParseResult result = parse(valueExpression, lookup::hasEncodedValue); + if (!result.ok) + throw new IllegalArgumentException(result.invalidMessage); + if (result.guessedVariables.size() > 1) + throw new IllegalArgumentException("Currently only a single EncodedValue is allowed on the right-hand side, but was " + result.guessedVariables.size() + ". Value expression: " + valueExpression); + + try { + // Speed optimization for numbers only as its over 200x faster than ExpressionEvaluator+cook+evaluate! + // We still call the parse() method before as it is only ~3x slower and might increase security slightly. Because certain + // expressions are accepted from Double.parseDouble but parse() rejects them. With this call order we avoid unexpected security problems. + double val = Double.parseDouble(valueExpression); + return new MinMax(val, val); + } catch (NumberFormatException ex) { + } + + try { + if (result.guessedVariables.isEmpty()) { // without encoded values + ExpressionEvaluator ee = new ExpressionEvaluator(); + ee.cook(valueExpression); + double val = ((Number) ee.evaluate()).doubleValue(); + return new MinMax(val, val); + } + + createdObjects.addAll(result.guessedVariables); + if (lookup.hasEncodedValue(valueExpression)) { // speed up for common case that complete right-hand side is the encoded value + EncodedValue enc = lookup.getEncodedValue(valueExpression, EncodedValue.class); + double min = getMin(enc), max = getMax(enc); + return new MinMax(min, max); + } + + ExpressionEvaluator ee = new ExpressionEvaluator(); + String var = result.guessedVariables.iterator().next(); + ee.setParameters(new String[]{var}, new Class[]{double.class}); + ee.cook(valueExpression); + double max = getMax(lookup.getEncodedValue(var, EncodedValue.class)); + Number val1 = (Number) ee.evaluate(max); + double min = getMin(lookup.getEncodedValue(var, EncodedValue.class)); + Number val2 = (Number) ee.evaluate(min); + return new MinMax(Math.min(val1.doubleValue(), val2.doubleValue()), Math.max(val1.doubleValue(), val2.doubleValue())); + } catch (CompileException | InvocationTargetException ex) { + throw new IllegalArgumentException(ex); + } + } + + static double getMin(EncodedValue enc) { + if (enc instanceof DecimalEncodedValue) return ((DecimalEncodedValue) enc).getMinDecimal(); + else if (enc instanceof IntEncodedValue) return ((IntEncodedValue) enc).getMinInt(); + throw new IllegalArgumentException("Cannot use non-number data '" + enc.getName() + "' in value expression"); + } + + static double getMax(EncodedValue enc) { + if (enc instanceof DecimalEncodedValue) return ((DecimalEncodedValue) enc).getMaxDecimal(); + else if (enc instanceof IntEncodedValue) return ((IntEncodedValue) enc).getMaxInt(); + throw new IllegalArgumentException("Cannot use non-number data '" + enc.getName() + "' in value expression"); + } +} diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 5c2b70a486c..1320ce8043e 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -270,7 +270,7 @@ private void testImportCloseAndLoad(boolean ch, boolean lm, boolean sort, boolea new Coordinate(7.4207, 43.7344), new Coordinate(7.4174, 43.7345)})); CustomModel customModel = new CustomModel().setDistanceInfluence(0); - customModel.getPriority().add(Statement.If("in_area51", Statement.Op.MULTIPLY, 0.1)); + customModel.getPriority().add(Statement.If("in_area51", Statement.Op.MULTIPLY, "0.1")); customModel.getAreas().put("area51", area51Feature); profile = new CustomProfile(profileName).setCustomModel(customModel).setVehicle(vehicle); } @@ -636,7 +636,7 @@ public void testCustomModel() { final String customCar = "custom_car"; final String emptyCar = "empty_car"; CustomModel customModel = new CustomModel(); - customModel.addToSpeed(Statement.If("road_class == TERTIARY || road_class == TRACK", Statement.Op.MULTIPLY, 0.1)); + customModel.addToSpeed(Statement.If("road_class == TERTIARY || road_class == TRACK", Statement.Op.MULTIPLY, "0.1")); GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). setOSMFile(BAYREUTH). @@ -654,11 +654,11 @@ public void testCustomModel() { assertDistance(hopper, emptyCar, new CustomModel(customModel), 13223); // now we prevent using unclassified roads as well and the route goes even further north CustomModel strictCustomModel = new CustomModel().addToSpeed( - Statement.If("road_class == TERTIARY || road_class == TRACK || road_class == UNCLASSIFIED", Statement.Op.MULTIPLY, 0.1)); + Statement.If("road_class == TERTIARY || road_class == TRACK || road_class == UNCLASSIFIED", Statement.Op.MULTIPLY, "0.1")); assertDistance(hopper, emptyCar, strictCustomModel, 19289); // we can achieve the same by 'adding' a rule to the server-side custom model CustomModel customModelWithUnclassifiedRule = new CustomModel().addToSpeed( - Statement.If("road_class == UNCLASSIFIED", Statement.Op.MULTIPLY, 0.1) + Statement.If("road_class == UNCLASSIFIED", Statement.Op.MULTIPLY, "0.1") ); assertDistance(hopper, customCar, customModelWithUnclassifiedRule, 19289); // now we use distance influence to avoid the detour diff --git a/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java b/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java index e91480ca35a..0f5ae3dfaac 100644 --- a/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java @@ -92,7 +92,7 @@ void testMaxPriority() { { CustomModel customModel = new CustomModel(); // now we even increase the priority in the custom model, which also needs to be accounted for in weighting.getMinWeight - customModel.addToPriority(Statement.If("road_class == MOTORWAY", Statement.Op.MULTIPLY, 3)); + customModel.addToPriority(Statement.If("road_class == MOTORWAY", Statement.Op.MULTIPLY, "3")); CustomWeighting weighting = CustomModelParser.createWeighting(encoder, em, TurnCostProvider.NO_TURN_COST_PROVIDER, customModel); Path pathDijkstra = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED).calcPath(0, 3); Path pathAStar = new AStar(graph, weighting, TraversalMode.NODE_BASED).calcPath(0, 3); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java new file mode 100644 index 00000000000..4b5caec9940 --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java @@ -0,0 +1,135 @@ +package com.graphhopper.routing.weighting.custom; + +import com.graphhopper.json.Statement; +import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.StringEncodedValue; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.Helper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.HashSet; + +import static com.graphhopper.json.Statement.If; +import static com.graphhopper.routing.weighting.custom.ConditionalExpressionVisitor.parse; +import static com.graphhopper.routing.weighting.custom.CustomModelParser.isValidVariableName; +import static org.junit.jupiter.api.Assertions.*; + +public class ConditionalExpressionVisitorTest { + + private EncodedValueLookup lookup; + + @BeforeEach + public void before() { + StringEncodedValue sev = new StringEncodedValue("country", 10); + lookup = new EncodingManager.Builder().add(sev).build(); + sev.setString(false, new IntsRef(1), "DEU"); + } + + @Test + public void protectUsFromStuff() { + NameValidator allNamesInvalid = s -> false; + for (String toParse : Arrays.asList( + "", + "new Object()", + "java.lang.Object", + "Test.class", + "new Object(){}.toString().length", + "{ 5}", + "{ 5, 7 }", + "Object.class", + "System.out.println(\"\")", + "something.newInstance()", + "e.getClass ( )", + "edge.getDistance()*7/*test", + "edge.getDistance()//*test", + "edge . getClass()", + "(edge = edge) == edge", + ") edge (", + "in(area_blup(), edge)", + "s -> truevalue")) { + ParseResult res = parse(toParse, allNamesInvalid, lookup); + assertFalse(res.ok, "should not be simple condition: " + toParse); + assertTrue(res.guessedVariables == null || res.guessedVariables.isEmpty()); + } + + assertFalse(parse("edge; getClass()", allNamesInvalid, lookup).ok); + } + + @Test + public void testConvertExpression() { + NameValidator validVariable = s -> isValidVariableName(s) + || Helper.toUpperCase(s).equals(s) || s.equals("road_class") || s.equals("toll"); + + ParseResult result = parse("toll == NO", validVariable, lookup); + assertTrue(result.ok); + assertEquals("[toll]", result.guessedVariables.toString()); + + assertEquals("road_class == RoadClass.PRIMARY", + parse("road_class == PRIMARY", validVariable, lookup).converted.toString()); + assertEquals("toll == Toll.NO", parse("toll == NO", validVariable, lookup).converted.toString()); + assertEquals("toll == Toll.NO || road_class == RoadClass.NO", parse("toll == NO || road_class == NO", validVariable, lookup).converted.toString()); + + // convert in_area variable to function call: + assertEquals(CustomWeightingHelper.class.getSimpleName() + ".in(this.in_custom_1, edge)", + parse("in_custom_1", validVariable, lookup).converted.toString()); + + // no need to inject: + assertNull(parse("toll == Toll.NO", validVariable, lookup).converted); + } + + @Test + public void testStringExpression() { + NameValidator validVariable = s -> isValidVariableName(s) || s.equals("country"); + + ParseResult result = parse("country == \"DEU\"", validVariable, lookup); + assertTrue(result.ok); + assertEquals("[country]", result.guessedVariables.toString()); + assertEquals("country == 1", result.converted.toString()); + + // unknown String should result in a negative integer. If we would throw an Exception here the same script that + // works on a global map will not work on a smaller map where the "blup" String is missing + result = parse("country == \"blup\"", validVariable, lookup); + assertTrue(result.ok); + assertEquals("[country]", result.guessedVariables.toString()); + assertEquals("country == -1", result.converted.toString()); + } + + @Test + public void isValidAndSimpleCondition() { + NameValidator validVariable = s -> isValidVariableName(s) + || Helper.toUpperCase(s).equals(s) || s.equals("road_class") || s.equals("toll"); + ParseResult result = parse("edge == edge", validVariable, lookup); + assertTrue(result.ok); + assertEquals("[edge]", result.guessedVariables.toString()); + + result = parse("Math.sqrt(2)", validVariable, lookup); + assertTrue(result.ok); + assertTrue(result.guessedVariables.isEmpty()); + + result = parse("edge.blup()", validVariable, lookup); + assertFalse(result.ok); + assertTrue(result.guessedVariables.isEmpty()); + + result = parse("edge.getDistance()", validVariable, lookup); + assertTrue(result.ok); + assertEquals("[edge]", result.guessedVariables.toString()); + assertFalse(parse("road_class == PRIMARY", s -> false, lookup).ok); + result = parse("road_class == PRIMARY", validVariable, lookup); + assertTrue(result.ok); + assertEquals("[road_class]", result.guessedVariables.toString()); + + result = parse("toll == Toll.NO", validVariable, lookup); + assertFalse(result.ok); + assertEquals("[toll]", result.guessedVariables.toString()); + + assertTrue(parse("road_class.ordinal()*2 == PRIMARY.ordinal()*2", validVariable, lookup).ok); + assertTrue(parse("Math.sqrt(road_class.ordinal()) > 1", validVariable, lookup).ok); + + result = parse("(toll == NO || road_class == PRIMARY) && toll == NO", validVariable, lookup); + assertTrue(result.ok); + assertEquals("[toll, road_class]", result.guessedVariables.toString()); + } +} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java index 79aefa7a3b1..b78b575dbc0 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java @@ -31,13 +31,16 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.GeometryFactory; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import static com.graphhopper.json.Statement.*; import static com.graphhopper.json.Statement.Op.LIMIT; import static com.graphhopper.json.Statement.Op.MULTIPLY; import static com.graphhopper.routing.ev.RoadClass.*; +import static com.graphhopper.routing.weighting.custom.CustomModelParser.parseExpressions; import static org.junit.jupiter.api.Assertions.*; class CustomModelParserTest { @@ -53,7 +56,8 @@ class CustomModelParserTest { void setup() { encoder = FlagEncoders.createCar(); countryEnc = new StringEncodedValue("country", 10); - encodingManager = new EncodingManager.Builder().add(encoder).add(countryEnc).add(new EnumEncodedValue<>(Surface.KEY, Surface.class)).build(); + encodingManager = new EncodingManager.Builder().add(encoder).add(countryEnc). + add(MaxSpeed.create()).add(new EnumEncodedValue<>(Surface.KEY, Surface.class)).build(); graph = new BaseGraph.Builder(encodingManager).create(); avgSpeedEnc = encoder.getAverageSpeedEnc(); roadClassEnc = encodingManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); @@ -62,7 +66,7 @@ void setup() { @Test void setPriorityForRoadClass() { CustomModel customModel = new CustomModel(); - customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, 0.5)); + customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.5")); CustomWeighting.EdgeToDoubleMapping priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToPriorityMapping(); @@ -84,10 +88,10 @@ void testPriority() { set(roadClassEnc, TERTIARY).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); CustomModel customModel = new CustomModel(); - customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, 0.5)); - customModel.addToPriority(ElseIf("road_class == SECONDARY", MULTIPLY, 0.7)); - customModel.addToPriority(Else(MULTIPLY, 0.9)); - customModel.addToPriority(If("road_environment != FERRY", MULTIPLY, 0.8)); + customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.5")); + customModel.addToPriority(ElseIf("road_class == SECONDARY", MULTIPLY, "0.7")); + customModel.addToPriority(Else(MULTIPLY, "0.9")); + customModel.addToPriority(If("road_environment != FERRY", MULTIPLY, "0.8")); CustomWeighting.EdgeToDoubleMapping priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToPriorityMapping(); @@ -98,8 +102,8 @@ void testPriority() { // force integer value customModel = new CustomModel(); - customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, 1)); - customModel.addToPriority(If("road_class == SECONDARY", MULTIPLY, 0.9)); + customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "1")); + customModel.addToPriority(If("road_class == SECONDARY", MULTIPLY, "0.9")); priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToPriorityMapping(); assertEquals(1, priorityMapping.get(primary, false), 0.01); @@ -114,7 +118,7 @@ public void testBrackets() { set(roadClassEnc, SECONDARY).set(avgSpeedEnc, 40); CustomModel customModel = new CustomModel(); - customModel.addToPriority(If("(road_class == PRIMARY || car_access == true) && car_average_speed > 50", MULTIPLY, 0.9)); + customModel.addToPriority(If("(road_class == PRIMARY || car_access == true) && car_average_speed > 50", MULTIPLY, "0.9")); CustomWeighting.Parameters parameters = CustomModelParser.createWeightingParameters(customModel, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null); assertEquals(0.9, parameters.getEdgeToPriorityMapping().get(primary, false), 0.01); @@ -129,8 +133,8 @@ public void testSpeedFactorAndPriorityAndMaxSpeed() { set(roadClassEnc, SECONDARY).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); CustomModel customModel = new CustomModel(); - customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, 0.9)); - customModel.addToSpeed(If("road_class == PRIMARY", MULTIPLY, 0.8)); + customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.9")); + customModel.addToSpeed(If("road_class == PRIMARY", MULTIPLY, "0.8")); CustomWeighting.Parameters parameters = CustomModelParser.createWeightingParameters(customModel, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null); assertEquals(0.9, parameters.getEdgeToPriorityMapping().get(primary, false), 0.01); @@ -139,7 +143,7 @@ public void testSpeedFactorAndPriorityAndMaxSpeed() { assertEquals(1, parameters.getEdgeToPriorityMapping().get(secondary, false), 0.01); assertEquals(70, parameters.getEdgeToSpeedMapping().get(secondary, false), 0.01); - customModel.addToSpeed(If("road_class != PRIMARY", LIMIT, 50)); + customModel.addToSpeed(If("road_class != PRIMARY", LIMIT, "50")); CustomWeighting.EdgeToDoubleMapping speedMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToSpeedMapping(); assertEquals(64, speedMapping.get(primary, false), 0.01); @@ -154,9 +158,9 @@ public void testString() { set(countryEnc, "blup").set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); CustomModel customModel = new CustomModel(); - customModel.addToPriority(If("country == \"DEU\"", MULTIPLY, 0.9)); - customModel.addToPriority(ElseIf("country == \"blup\"", MULTIPLY, 0.7)); - customModel.addToPriority(Else(MULTIPLY, 0.5)); + customModel.addToPriority(If("country == \"DEU\"", MULTIPLY, "0.9")); + customModel.addToPriority(ElseIf("country == \"blup\"", MULTIPLY, "0.7")); + customModel.addToPriority(Else(MULTIPLY, "0.5")); CustomWeighting.EdgeToDoubleMapping priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToPriorityMapping(); assertEquals(0.9, priorityMapping.get(deu, false), 0.01); @@ -166,14 +170,14 @@ public void testString() { @Test void testIllegalOrder() { CustomModel customModel = new CustomModel(); - customModel.addToPriority(Else(MULTIPLY, 0.9)); - customModel.addToPriority(If("road_environment != FERRY", MULTIPLY, 0.8)); + customModel.addToPriority(Else(MULTIPLY, "0.9")); + customModel.addToPriority(If("road_environment != FERRY", MULTIPLY, "0.8")); assertThrows(IllegalArgumentException.class, () -> CustomModelParser.createWeightingParameters(customModel, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null)); CustomModel customModel2 = new CustomModel(); - customModel2.addToPriority(ElseIf("road_environment != FERRY", MULTIPLY, 0.9)); - customModel2.addToPriority(If("road_class != PRIMARY", MULTIPLY, 0.8)); + customModel2.addToPriority(ElseIf("road_environment != FERRY", MULTIPLY, "0.9")); + customModel2.addToPriority(If("road_class != PRIMARY", MULTIPLY, "0.8")); assertThrows(IllegalArgumentException.class, () -> CustomModelParser.createWeightingParameters(customModel2, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null)); } @@ -208,9 +212,9 @@ public void multipleAreas() { new HashMap<>())); customModel.setAreas(areas); - customModel.addToSpeed(If("in_area_1", LIMIT, 100)); - customModel.addToSpeed(If("!in_area_2", LIMIT, 25)); - customModel.addToSpeed(Else(LIMIT, 15)); + customModel.addToSpeed(If("in_area_1", LIMIT, "100")); + customModel.addToSpeed(If("!in_area_2", LIMIT, "25")); + customModel.addToSpeed(Else(LIMIT, "15")); // No exception is thrown during createWeightingParameters assertAll(() -> @@ -220,13 +224,82 @@ public void multipleAreas() { CustomModel customModel2 = new CustomModel(); customModel2.setAreas(areas); - customModel2.addToSpeed(If("in_area_1", LIMIT, 100)); - customModel2.addToSpeed(If("in_area_2", LIMIT, 25)); - customModel2.addToSpeed(If("in_area_3", LIMIT, 150)); - customModel2.addToSpeed(Else(LIMIT, 15)); + customModel2.addToSpeed(If("in_area_1", LIMIT, "100")); + customModel2.addToSpeed(If("in_area_2", LIMIT, "25")); + customModel2.addToSpeed(If("in_area_3", LIMIT, "150")); + customModel2.addToSpeed(Else(LIMIT, "15")); assertThrows(IllegalArgumentException.class, () -> CustomModelParser.createWeightingParameters(customModel2, encodingManager, avgSpeedEnc, encoder.getMaxSpeed(), null)); } + + @Test + public void parseValue() { + DecimalEncodedValue maxSpeed = encodingManager.getDecimalEncodedValue(MaxSpeed.KEY); + EdgeIteratorState maxLower = graph.edge(0, 1).setDistance(10). + set(maxSpeed, 60).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); + EdgeIteratorState maxSame = graph.edge(1, 2).setDistance(10). + set(maxSpeed, 70).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); + + CustomModel customModel = new CustomModel(); + customModel.addToSpeed(If("true", LIMIT, "max_speed * 1.1")); + CustomWeighting.EdgeToDoubleMapping speedMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, + avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToSpeedMapping(); + assertEquals(70.0, speedMapping.get(maxSame, false), 0.01); + assertEquals(66.0, speedMapping.get(maxLower, false), 0.01); + } + + @Test + public void parseValueWithError() { + CustomModel customModel1 = new CustomModel(); + customModel1.addToSpeed(If("true", LIMIT, "unknown")); + + IllegalArgumentException ret = assertThrows(IllegalArgumentException.class, + () -> CustomModelParser.createWeightingParameters(customModel1, encodingManager, + avgSpeedEnc, encoder.getMaxSpeed(), null)); + assertTrue(ret.getMessage().startsWith("Cannot compile expression: 'unknown' not available"), ret.getMessage()); + + CustomModel customModel2 = new CustomModel(); + customModel2.addToSpeed(If("road_class == PRIMARY", MULTIPLY, "0.5")); + customModel2.addToSpeed(Else(MULTIPLY, "-0.5")); + ret = assertThrows(IllegalArgumentException.class, + () -> CustomModelParser.createWeightingParameters(customModel2, encodingManager, + avgSpeedEnc, encoder.getMaxSpeed(), null)); + assertTrue(ret.getMessage().startsWith("Cannot compile expression: speed has to be >=0 but can be negative (-0.5)"), ret.getMessage()); + + CustomModel customModel3 = new CustomModel(); + customModel3.addToSpeed(If("road_class == PRIMARY", MULTIPLY, "0.5")); + customModel3.addToSpeed(Else(MULTIPLY, "road_class")); + ret = assertThrows(IllegalArgumentException.class, + () -> CustomModelParser.createWeightingParameters(customModel3, encodingManager, + avgSpeedEnc, encoder.getMaxSpeed(), null)); + assertTrue(ret.getMessage().contains("Binary numeric promotion not possible on types \"double\" and \"java.lang.Enum\""), ret.getMessage()); + } + + @Test + public void parseConditionWithError() { + NameValidator validVariable = s -> encodingManager.hasEncodedValue(s); + + // existing encoded value but not added + IllegalArgumentException ret = assertThrows(IllegalArgumentException.class, + () -> parseExpressions(new StringBuilder(), + validVariable, encodingManager, "[HERE]", new HashSet<>(), + Arrays.asList(If("max_weight > 10", MULTIPLY, "0")), "")); + assertTrue(ret.getMessage().startsWith("[HERE] invalid condition \"max_weight > 10\": 'max_weight' not available"), ret.getMessage()); + + // invalid variable or constant (NameValidator returns false) + ret = assertThrows(IllegalArgumentException.class, + () -> parseExpressions(new StringBuilder(), + validVariable, encodingManager, "[HERE]", new HashSet<>(), + Arrays.asList(If("country == GERMANY", MULTIPLY, "0")), "")); + assertTrue(ret.getMessage().startsWith("[HERE] invalid condition \"country == GERMANY\": 'GERMANY' not available"), ret.getMessage()); + + // not whitelisted method + ret = assertThrows(IllegalArgumentException.class, + () -> parseExpressions(new StringBuilder(), + validVariable, encodingManager, "[HERE]", new HashSet<>(), + Arrays.asList(If("edge.fetchWayGeometry().size() > 2", MULTIPLY, "0")), "")); + assertTrue(ret.getMessage().startsWith("[HERE] invalid condition \"edge.fetchWayGeometry().size() > 2\": size is an illegal method"), ret.getMessage()); + } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index 87e960a943e..abda7281a49 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -75,7 +75,7 @@ public void withPriority() { assertEquals(36, createWeighting(model).calcEdgeWeight(fast, false), .1); // if we reduce the priority we get higher edge weights - model.addToPriority(If("road_class == SECONDARY", MULTIPLY, 0.5)); + model.addToPriority(If("road_class == SECONDARY", MULTIPLY, "0.5")); // the absolute priority costs depend on the speed, so setting priority=0.5 means a lower absolute weight // weight increase for fast edges and a higher absolute increase for slower edges assertEquals(2 * 144, createWeighting(model).calcEdgeWeight(slow, false), .1); @@ -108,7 +108,7 @@ public void testSpeedFactorBooleanEV() { CustomModel vehicleModel = new CustomModel(); assertEquals(3.1, createWeighting(vehicleModel).calcEdgeWeight(edge, false), 0.01); // here we increase weight for edges that are road class links - vehicleModel.addToPriority(If(RoadClassLink.KEY, MULTIPLY, 0.5)); + vehicleModel.addToPriority(If(RoadClassLink.KEY, MULTIPLY, "0.5")); Weighting weighting = createWeighting(vehicleModel); BooleanEncodedValue rcLinkEnc = encodingManager.getBooleanEncodedValue(RoadClassLink.KEY); assertEquals(3.1, weighting.calcEdgeWeight(edge.set(rcLinkEnc, false), false), 0.01); @@ -127,8 +127,8 @@ public void testBoolean() { CustomModel vehicleModel = new CustomModel(); assertEquals(3.1, createWeighting(vehicleModel).calcEdgeWeight(edge, false), 0.01); - vehicleModel.addToPriority(If("special == true", MULTIPLY, 0.8)); - vehicleModel.addToPriority(If("special == false", MULTIPLY, 0.4)); + vehicleModel.addToPriority(If("special == true", MULTIPLY, "0.8")); + vehicleModel.addToPriority(If("special == false", MULTIPLY, "0.4")); Weighting weighting = createWeighting(vehicleModel); assertEquals(6.7, weighting.calcEdgeWeight(edge, false), 0.01); assertEquals(3.7, weighting.calcEdgeWeight(edge, true), 0.01); @@ -142,15 +142,15 @@ public void testSpeedFactorAndPriority() { set(roadClassEnc, SECONDARY).set(avSpeedEnc, 70).set(accessEnc, true, true); CustomModel vehicleModel = new CustomModel(); - vehicleModel.addToPriority(If("road_class != PRIMARY", MULTIPLY, 0.5)); - vehicleModel.addToSpeed(If("road_class != PRIMARY", MULTIPLY, 0.9)); + vehicleModel.addToPriority(If("road_class != PRIMARY", MULTIPLY, "0.5")); + vehicleModel.addToSpeed(If("road_class != PRIMARY", MULTIPLY, "0.9")); assertEquals(1.15, createWeighting(vehicleModel).calcEdgeWeight(primary, false), 0.01); assertEquals(1.84, createWeighting(vehicleModel).calcEdgeWeight(secondary, false), 0.01); vehicleModel = new CustomModel(); - vehicleModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, 1.0)); - vehicleModel.addToPriority(Else(MULTIPLY, 0.5)); - vehicleModel.addToSpeed(If("road_class != PRIMARY", MULTIPLY, 0.9)); + vehicleModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "1.0")); + vehicleModel.addToPriority(Else(MULTIPLY, "0.5")); + vehicleModel.addToSpeed(If("road_class != PRIMARY", MULTIPLY, "0.9")); assertEquals(1.15, createWeighting(vehicleModel).calcEdgeWeight(primary, false), 0.01); assertEquals(1.84, createWeighting(vehicleModel).calcEdgeWeight(secondary, false), 0.01); } @@ -163,13 +163,13 @@ public void testIssueSameKey() { set(avSpeedEnc, 80).set(accessEnc, true, true); CustomModel vehicleModel = new CustomModel(); - vehicleModel.addToSpeed(If("toll == HGV || toll == ALL", MULTIPLY, 0.8)); - vehicleModel.addToSpeed(If("hazmat != NO", MULTIPLY, 0.8)); + vehicleModel.addToSpeed(If("toll == HGV || toll == ALL", MULTIPLY, "0.8")); + vehicleModel.addToSpeed(If("hazmat != NO", MULTIPLY, "0.8")); assertEquals(1.26, createWeighting(vehicleModel).calcEdgeWeight(withToll, false), 0.01); assertEquals(1.26, createWeighting(vehicleModel).calcEdgeWeight(noToll, false), 0.01); vehicleModel = new CustomModel(); - vehicleModel.addToSpeed(If("bike_network != OTHER", MULTIPLY, 0.8)); + vehicleModel.addToSpeed(If("bike_network != OTHER", MULTIPLY, "0.8")); assertEquals(1.26, createWeighting(vehicleModel).calcEdgeWeight(withToll, false), 0.01); assertEquals(1.26, createWeighting(vehicleModel).calcEdgeWeight(noToll, false), 0.01); } @@ -182,12 +182,12 @@ public void testFirstMatch() { set(roadClassEnc, SECONDARY).set(avSpeedEnc, 70).set(accessEnc, true, true); CustomModel vehicleModel = new CustomModel(); - vehicleModel.addToSpeed(If("road_class == PRIMARY", MULTIPLY, 0.8)); + vehicleModel.addToSpeed(If("road_class == PRIMARY", MULTIPLY, "0.8")); assertEquals(1.26, createWeighting(vehicleModel).calcEdgeWeight(primary, false), 0.01); assertEquals(1.21, createWeighting(vehicleModel).calcEdgeWeight(secondary, false), 0.01); - vehicleModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, 0.9)); - vehicleModel.addToPriority(ElseIf("road_class == SECONDARY", MULTIPLY, 0.8)); + vehicleModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.9")); + vehicleModel.addToPriority(ElseIf("road_class == SECONDARY", MULTIPLY, "0.8")); assertEquals(1.33, createWeighting(vehicleModel).calcEdgeWeight(primary, false), 0.01); assertEquals(1.34, createWeighting(vehicleModel).calcEdgeWeight(secondary, false), 0.01); @@ -199,20 +199,20 @@ public void testCarAccess() { EdgeIteratorState edge50 = graph.edge(1, 2).setDistance(10).set(avSpeedEnc, 50).set(accessEnc, true, true); CustomModel vehicleModel = new CustomModel(); - vehicleModel.addToPriority(If("car_average_speed > 40", MULTIPLY, 0.5)); + vehicleModel.addToPriority(If("car_average_speed > 40", MULTIPLY, "0.5")); assertEquals(1.60, createWeighting(vehicleModel).calcEdgeWeight(edge40, false), 0.01); assertEquals(2.14, createWeighting(vehicleModel).calcEdgeWeight(edge50, false), 0.01); } @Test - public void testRoadClass() throws Exception { + public void testRoadClass() { EdgeIteratorState primary = graph.edge(0, 1).setDistance(10). set(roadClassEnc, PRIMARY).set(avSpeedEnc, 80).set(accessEnc, true, true); EdgeIteratorState secondary = graph.edge(1, 2).setDistance(10). set(roadClassEnc, SECONDARY).set(avSpeedEnc, 80).set(accessEnc, true, true); CustomModel vehicleModel = new CustomModel(); - vehicleModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, 0.5)); + vehicleModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.5")); assertEquals(1.6, createWeighting(vehicleModel).calcEdgeWeight(primary, false), 0.01); assertEquals(1.15, createWeighting(vehicleModel).calcEdgeWeight(secondary, false), 0.01); } @@ -228,7 +228,7 @@ public void testArea() throws Exception { graph.getNodeAccess().setNode(2, 40.0, 8.0); graph.getNodeAccess().setNode(3, 40.1, 8.1); CustomModel vehicleModel = new CustomModel(); - vehicleModel.addToPriority(If("in_custom1", MULTIPLY, 0.5)); + vehicleModel.addToPriority(If("in_custom1", MULTIPLY, "0.5")); ObjectMapper om = new ObjectMapper().registerModule(new JtsModule()); JsonFeature json = om.readValue("{ \"geometry\":{ \"type\": \"Polygon\", \"coordinates\": " + @@ -245,43 +245,48 @@ public void testMaxSpeed() { assertEquals(140, carFE.getMaxSpeed(), 0.1); assertEquals(1000.0 / 72 * 3.6, createWeighting(new CustomModel(). - addToSpeed(If("true", LIMIT, 72)).setDistanceInfluence(0)).getMinWeight(1000)); + addToSpeed(If("true", LIMIT, "72")).setDistanceInfluence(0)).getMinWeight(1000)); // ignore too big limit to let custom model compatibility not break when max speed of encoder later decreases assertEquals(1000.0 / 140 * 3.6, createWeighting(new CustomModel(). - addToSpeed(If("true", LIMIT, 150)).setDistanceInfluence(0)).getMinWeight(1000)); + addToSpeed(If("true", LIMIT, "150")).setDistanceInfluence(0)).getMinWeight(1000)); // a speed bigger than the allowed stored speed is fine, see discussion in #2335 assertEquals(1000.0 / 150 * 3.6, createWeighting(new CustomModel(). - addToSpeed(If("road_class == SERVICE", MULTIPLY, 1.5)). - addToSpeed(If("true", LIMIT, 150)).setDistanceInfluence(0)).getMinWeight(1000)); + addToSpeed(If("road_class == SERVICE", MULTIPLY, "1.5")). + addToSpeed(If("true", LIMIT, "150")).setDistanceInfluence(0)).getMinWeight(1000)); } @Test public void testMaxPriority() { assertEquals(1000.0 / 140 / 0.5 * 3.6, createWeighting(new CustomModel(). - addToPriority(If("true", MULTIPLY, 0.5)).setDistanceInfluence(0)).getMinWeight(1000)); + addToPriority(If("true", MULTIPLY, "0.5")).setDistanceInfluence(0)).getMinWeight(1000)); // ignore too big limit assertEquals(1000.0 / 140 / 1.0 * 3.6, createWeighting(new CustomModel(). - addToPriority(If("true", LIMIT, 2.0)).setDistanceInfluence(0)).getMinWeight(1000)); + addToPriority(If("true", LIMIT, "2.0")).setDistanceInfluence(0)).getMinWeight(1000)); // priority bigger 1 is fine (if CustomModel not in query) assertEquals(1000.0 / 140 / 2.0 * 3.6, createWeighting(new CustomModel(). - addToPriority(If("true", MULTIPLY, 3.0)). - addToPriority(If("true", LIMIT, 2.0)).setDistanceInfluence(0)).getMinWeight(1000)); + addToPriority(If("true", MULTIPLY, "3.0")). + addToPriority(If("true", LIMIT, "2.0")).setDistanceInfluence(0)).getMinWeight(1000)); assertEquals(1000.0 / 140 / 1.5 * 3.6, createWeighting(new CustomModel(). - addToPriority(If("true", MULTIPLY, 1.5)).setDistanceInfluence(0)).getMinWeight(1000)); - // pick maximum priority from value even if this is for a very special case + addToPriority(If("true", MULTIPLY, "1.5")).setDistanceInfluence(0)).getMinWeight(1000)); + + // pick maximum priority from value even if this is for a special case assertEquals(1000.0 / 140 / 3.0 * 3.6, createWeighting(new CustomModel(). - addToPriority(If("road_class == SERVICE", MULTIPLY, 3.0)).setDistanceInfluence(0)).getMinWeight(1000)); + addToPriority(If("road_class == SERVICE", MULTIPLY, "3.0")).setDistanceInfluence(0)).getMinWeight(1000)); + + // do NOT pick maximum priority when it is for a special case + assertEquals(1000.0 / 140 / 1.0 * 3.6, createWeighting(new CustomModel(). + addToPriority(If("road_class == SERVICE", MULTIPLY, "0.5")).setDistanceInfluence(0)).getMinWeight(1000)); } @Test public void tooManyStatements() { CustomModel customModel = new CustomModel(); for (int i = 0; i < 1050; i++) { - customModel.addToPriority(If("road_class == MOTORWAY || road_class == SECONDARY || road_class == PRIMARY", MULTIPLY, 0.1)); + customModel.addToPriority(If("road_class == MOTORWAY || road_class == SECONDARY || road_class == PRIMARY", MULTIPLY, "0.1")); } IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> createWeighting(customModel)); assertTrue(ex.getMessage().startsWith("Custom Model too big"), ex.getMessage()); @@ -292,8 +297,8 @@ public void maxSpeedViolated_bug_2307() { EdgeIteratorState motorway = graph.edge(0, 1).setDistance(10). set(roadClassEnc, MOTORWAY).set(avSpeedEnc, 80).set(accessEnc, true, true); CustomModel customModel = new CustomModel() - .addToSpeed(Statement.If("road_class == MOTORWAY", Statement.Op.MULTIPLY, 0.7)) - .addToSpeed(Statement.Else(LIMIT, 30)); + .addToSpeed(Statement.If("road_class == MOTORWAY", Statement.Op.MULTIPLY, "0.7")) + .addToSpeed(Statement.Else(LIMIT, "30")); Weighting weighting = createWeighting(customModel); assertEquals(1.3429, weighting.calcEdgeWeight(motorway, false), 1e-4); assertEquals(10 / (80 * 0.7 / 3.6) * 1000, weighting.calcEdgeMillis(motorway, false), 1); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/ExpressionVisitorTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/ExpressionVisitorTest.java deleted file mode 100644 index 0c143cdee03..00000000000 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/ExpressionVisitorTest.java +++ /dev/null @@ -1,164 +0,0 @@ -package com.graphhopper.routing.weighting.custom; - -import com.graphhopper.json.Statement; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.StringEncodedValue; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.Helper; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; -import java.util.HashSet; - -import static com.graphhopper.json.Statement.If; -import static com.graphhopper.routing.weighting.custom.CustomModelParser.isValidVariableName; -import static com.graphhopper.routing.weighting.custom.ExpressionVisitor.parseExpression; -import static org.junit.jupiter.api.Assertions.*; - -public class ExpressionVisitorTest { - - private EncodedValueLookup lookup; - - @BeforeEach - public void before() { - StringEncodedValue sev = new StringEncodedValue("country", 10); - lookup = new EncodingManager.Builder().add(sev).build(); - sev.setString(false, new IntsRef(1), "DEU"); - } - - @Test - public void protectUsFromStuff() { - ExpressionVisitor.NameValidator allNamesInvalid = s -> false; - for (String toParse : Arrays.asList( - "", - "new Object()", - "java.lang.Object", - "Test.class", - "new Object(){}.toString().length", - "{ 5}", - "{ 5, 7 }", - "Object.class", - "System.out.println(\"\")", - "something.newInstance()", - "e.getClass ( )", - "edge.getDistance()*7/*test", - "edge.getDistance()//*test", - "edge . getClass()", - "(edge = edge) == edge", - ") edge (", - "in(area_blup(), edge)", - "s -> truevalue")) { - ExpressionVisitor.ParseResult res = parseExpression(toParse, allNamesInvalid, lookup); - assertFalse(res.ok, "should not be simple condition: " + toParse); - assertTrue(res.guessedVariables == null || res.guessedVariables.isEmpty()); - } - - assertFalse(parseExpression("edge; getClass()", allNamesInvalid, lookup).ok); - } - - @Test - public void testConvertExpression() { - ExpressionVisitor.NameValidator validVariable = s -> isValidVariableName(s) - || Helper.toUpperCase(s).equals(s) || s.equals("road_class") || s.equals("toll"); - - ExpressionVisitor.ParseResult result = parseExpression("toll == NO", validVariable, lookup); - assertTrue(result.ok); - assertEquals("[toll]", result.guessedVariables.toString()); - - assertEquals("road_class == RoadClass.PRIMARY", - parseExpression("road_class == PRIMARY", validVariable, lookup).converted.toString()); - assertEquals("toll == Toll.NO", parseExpression("toll == NO", validVariable, lookup).converted.toString()); - assertEquals("toll == Toll.NO || road_class == RoadClass.NO", parseExpression("toll == NO || road_class == NO", validVariable, lookup).converted.toString()); - - // convert in_area variable to function call: - assertEquals(CustomWeightingHelper.class.getSimpleName() + ".in(this.in_custom_1, edge)", - parseExpression("in_custom_1", validVariable, lookup).converted.toString()); - - // no need to inject: - assertNull(parseExpression("toll == Toll.NO", validVariable, lookup).converted); - } - - @Test - public void testStringExpression() { - ExpressionVisitor.NameValidator validVariable = s -> isValidVariableName(s) || s.equals("country"); - - ExpressionVisitor.ParseResult result = parseExpression("country == \"DEU\"", validVariable, lookup); - assertTrue(result.ok); - assertEquals("[country]", result.guessedVariables.toString()); - assertEquals("country == 1", result.converted.toString()); - - // unknown String should result in a negative integer. If we would throw an Exception here the same script that - // works on a global map will not work on a smaller map where the "blup" String is missing - result = parseExpression("country == \"blup\"", validVariable, lookup); - assertTrue(result.ok); - assertEquals("[country]", result.guessedVariables.toString()); - assertEquals("country == -1", result.converted.toString()); - } - - @Test - public void isValidAndSimpleCondition() { - ExpressionVisitor.NameValidator validVariable = s -> isValidVariableName(s) - || Helper.toUpperCase(s).equals(s) || s.equals("road_class") || s.equals("toll"); - ExpressionVisitor.ParseResult result = parseExpression("edge == edge", validVariable, lookup); - assertTrue(result.ok); - assertEquals("[edge]", result.guessedVariables.toString()); - - result = parseExpression("Math.sqrt(2)", validVariable, lookup); - assertTrue(result.ok); - assertTrue(result.guessedVariables.isEmpty()); - - result = parseExpression("edge.blup()", validVariable, lookup); - assertFalse(result.ok); - assertTrue(result.guessedVariables.isEmpty()); - - result = parseExpression("edge.getDistance()", validVariable, lookup); - assertTrue(result.ok); - assertEquals("[edge]", result.guessedVariables.toString()); - assertFalse(parseExpression("road_class == PRIMARY", s -> false, lookup).ok); - result = parseExpression("road_class == PRIMARY", validVariable, lookup); - assertTrue(result.ok); - assertEquals("[road_class]", result.guessedVariables.toString()); - - result = parseExpression("toll == Toll.NO", validVariable, lookup); - assertFalse(result.ok); - assertEquals("[toll]", result.guessedVariables.toString()); - - assertTrue(parseExpression("road_class.ordinal()*2 == PRIMARY.ordinal()*2", validVariable, lookup).ok); - assertTrue(parseExpression("Math.sqrt(road_class.ordinal()) > 1", validVariable, lookup).ok); - - result = parseExpression("(toll == NO || road_class == PRIMARY) && toll == NO", validVariable, lookup); - assertTrue(result.ok); - assertEquals("[toll, road_class]", result.guessedVariables.toString()); - } - - @Test - public void errorMessage() { - ExpressionVisitor.NameValidator validVariable = s -> lookup.hasEncodedValue(s); - - // existing encoded value but not added - IllegalArgumentException ret = assertThrows(IllegalArgumentException.class, - () -> ExpressionVisitor.parseExpressions(new StringBuilder(), - validVariable, "[HERE]", new HashSet<>(), - Arrays.asList(If("max_weight > 10", Statement.Op.MULTIPLY, 0)), - lookup, "")); - assertTrue(ret.getMessage().startsWith("[HERE] invalid expression \"max_weight > 10\": 'max_weight' not available"), ret.getMessage()); - - // invalid variable or constant (NameValidator returns false) - ret = assertThrows(IllegalArgumentException.class, - () -> ExpressionVisitor.parseExpressions(new StringBuilder(), - validVariable, "[HERE]", new HashSet<>(), - Arrays.asList(If("country == GERMANY", Statement.Op.MULTIPLY, 0)), - lookup, "")); - assertTrue(ret.getMessage().startsWith("[HERE] invalid expression \"country == GERMANY\": 'GERMANY' not available"), ret.getMessage()); - - // not whitelisted method - ret = assertThrows(IllegalArgumentException.class, - () -> ExpressionVisitor.parseExpressions(new StringBuilder(), - validVariable, "[HERE]", new HashSet<>(), - Arrays.asList(If("edge.fetchWayGeometry().size() > 2", Statement.Op.MULTIPLY, 0)), - lookup, "")); - assertTrue(ret.getMessage().startsWith("[HERE] invalid expression \"edge.fetchWayGeometry().size() > 2\": size is illegal method"), ret.getMessage()); - } -} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/FindMinMaxTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/FindMinMaxTest.java new file mode 100644 index 00000000000..1d0452710e7 --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/FindMinMaxTest.java @@ -0,0 +1,114 @@ +package com.graphhopper.routing.weighting.custom; + +import com.graphhopper.json.MinMax; +import com.graphhopper.json.Statement; +import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.util.CustomModel; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import static com.graphhopper.json.Statement.*; +import static com.graphhopper.json.Statement.Op.LIMIT; +import static com.graphhopper.json.Statement.Op.MULTIPLY; +import static com.graphhopper.routing.weighting.custom.FindMinMax.findMinMax; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class FindMinMaxTest { + + private EncodedValueLookup lookup; + + @BeforeEach + void setup() { + lookup = new EncodingManager.Builder().build(); + } + + @Test + public void testCheck() { + CustomModel queryModel = new CustomModel(); + queryModel.addToPriority(If("max_width < 3", MULTIPLY, "10")); + assertEquals(1, CustomModel.merge(new CustomModel(), queryModel).getPriority().size()); + // priority bigger than 1 is not ok for CustomModel of query + assertThrows(IllegalArgumentException.class, () -> FindMinMax.checkLMConstraints(new CustomModel(), queryModel, lookup)); + } + + @Test + public void testFindMax() { + List statements = new ArrayList<>(); + statements.add(If("true", LIMIT, "100")); + assertEquals(100, findMinMax(new HashSet<>(), new MinMax(0, 120), statements, lookup).max); + + statements.add(Else(LIMIT, "20")); + assertEquals(100, findMinMax(new HashSet<>(), new MinMax(0, 120), statements, lookup).max); + + statements = new ArrayList<>(); + statements.add(If("road_environment == BRIDGE", LIMIT, "85")); + statements.add(Else(LIMIT, "100")); + assertEquals(100, findMinMax(new HashSet<>(), new MinMax(0, 120), statements, lookup).max); + + // find bigger speed than stored max_speed (30) in server-side custom_models + statements = new ArrayList<>(); + statements.add(If("true", MULTIPLY, "2")); + statements.add(If("true", LIMIT, "35")); + assertEquals(35, findMinMax(new HashSet<>(), new MinMax(0, 30), statements, lookup).max); + } + + @Test + public void findMax_limitAndMultiply() { + List statements = Arrays.asList( + If("road_class == TERTIARY", LIMIT, "90"), + ElseIf("road_class == SECONDARY", MULTIPLY, "1.0"), + ElseIf("road_class == PRIMARY", LIMIT, "30"), + Else(LIMIT, "3") + ); + assertEquals(140, findMinMax(new HashSet<>(), new MinMax(0, 140), statements, lookup).max); + } + + @Test + public void testFindMaxPriority() { + List statements = new ArrayList<>(); + statements.add(If("true", MULTIPLY, "2")); + assertEquals(2, findMinMax(new HashSet<>(), new MinMax(0, 1), statements, lookup).max); + + statements = new ArrayList<>(); + statements.add(If("true", MULTIPLY, "0.5")); + assertEquals(0.5, findMinMax(new HashSet<>(), new MinMax(0, 1), statements, lookup).max); + + statements = new ArrayList<>(); + statements.add(If("road_class == MOTORWAY", MULTIPLY, "0.5")); + statements.add(Else(MULTIPLY, "-0.5")); + MinMax minMax = findMinMax(new HashSet<>(), new MinMax(1, 1), statements, lookup); + assertEquals(-0.5, minMax.min); + assertEquals(0.5, minMax.max); + } + + @Test + public void findMax_multipleBlocks() { + List statements = Arrays.asList( + If("road_class == TERTIARY", MULTIPLY, "0.2"), + ElseIf("road_class == SECONDARY", LIMIT, "25"), + If("road_environment == TUNNEL", LIMIT, "60"), + ElseIf("road_environment == BRIDGE", LIMIT, "50"), + Else(MULTIPLY, "0.8") + ); + assertEquals(120, findMinMax(new HashSet<>(), new MinMax(0, 150), statements, lookup).max); + assertEquals(80, findMinMax(new HashSet<>(), new MinMax(0, 100), statements, lookup).max); + assertEquals(60, findMinMax(new HashSet<>(), new MinMax(0, 60), statements, lookup).max); + + statements = Arrays.asList( + If("road_class == TERTIARY", MULTIPLY, "0.2"), + ElseIf("road_class == SECONDARY", LIMIT, "25"), + Else(LIMIT, "40"), + If("road_environment == TUNNEL", MULTIPLY, "0.8"), + ElseIf("road_environment == BRIDGE", LIMIT, "30") + ); + assertEquals(40, findMinMax(new HashSet<>(), new MinMax(0, 150), statements, lookup).max); + assertEquals(40, findMinMax(new HashSet<>(), new MinMax(0, 40), statements, lookup).max); + } +} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitorTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitorTest.java new file mode 100644 index 00000000000..855df508aaa --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitorTest.java @@ -0,0 +1,110 @@ +package com.graphhopper.routing.weighting.custom; + +import com.graphhopper.json.MinMax; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.IntEncodedValueImpl; +import com.graphhopper.routing.util.EncodingManager; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import static com.graphhopper.routing.weighting.custom.ValueExpressionVisitor.findMinMax; +import static com.graphhopper.routing.weighting.custom.ValueExpressionVisitor.parse; +import static org.junit.jupiter.api.Assertions.*; + +class ValueExpressionVisitorTest { + + @Test + public void protectUsFromStuff() { + NameValidator allNamesInvalid = s -> false; + for (String toParse : Arrays.asList("", "new Object()", "java.lang.Object", "Test.class", + "new Object(){}.toString().length", "{ 5}", "{ 5, 7 }", "Object.class", "System.out.println(\"\")", + "something.newInstance()", "e.getClass ( )", "edge.getDistance()*7/*test", "edge.getDistance()//*test", + "edge . getClass()", "(edge = edge) == edge", ") edge (", "in(area_blup(), edge)", "s -> truevalue")) { + ParseResult res = parse(toParse, allNamesInvalid); + assertFalse(res.ok, "should not be simple condition: " + toParse); + assertTrue(res.guessedVariables == null || res.guessedVariables.isEmpty()); + } + + assertFalse(parse("edge; getClass()", allNamesInvalid).ok); + } + + @Test + public void isValidAndSimpleCondition() { + NameValidator validVariable = s -> s.equals("edge") || s.equals("Math") || s.equals("priority"); + ParseResult result = parse("edge == edge", validVariable); + assertFalse(result.ok); + + result = parse("Math.sqrt(2)", validVariable); + assertTrue(result.ok, result.invalidMessage); + assertTrue(result.guessedVariables.isEmpty()); + + result = parse("edge.getDistance()", validVariable); + assertFalse(result.ok); + + result = parse("road_class == PRIMARY", validVariable); + assertFalse(result.ok); + + result = parse("toll == Toll.NO", validVariable); + assertFalse(result.ok); + + result = parse("priority * 2", validVariable); + assertTrue(result.ok, result.invalidMessage); + assertEquals("[priority]", result.guessedVariables.toString()); + + // LATER but requires accepting also EnumEncodedValue for value expression + // result = parse("road_class.ordinal()*2", validVariable); + // assertTrue(result.ok, result.invalidMessage); + // assertTrue(parse("Math.sqrt(road_class.ordinal())", validVariable).ok); + } + + + @Test + public void testErrors() { + Set objs = new HashSet<>(); + DecimalEncodedValue prio1 = new DecimalEncodedValueImpl("my_priority", 5, 1, false); + IntEncodedValueImpl prio2 = new IntEncodedValueImpl("my_priority2", 5, -5, false, false); + EncodedValueLookup lookup = new EncodingManager.Builder().add(prio1).add(prio2).build(); + + String msg = assertThrows(IllegalArgumentException.class, () -> findMinMax(objs, "unknown*3", lookup)).getMessage(); + assertTrue(msg.contains("'unknown' not available"), msg); + + msg = assertThrows(IllegalArgumentException.class, () -> findMinMax(objs, "my_priority - my_priority2 * 3", lookup)).getMessage(); + assertTrue(msg.contains("a single EncodedValue"), msg); + // unary minus is also a minus operator + msg = assertThrows(IllegalArgumentException.class, () -> findMinMax(objs, "-my_priority + my_priority2 * 3", lookup)).getMessage(); + assertTrue(msg.contains("a single EncodedValue"), msg); + + msg = assertThrows(IllegalArgumentException.class, () -> findMinMax(objs, "1/my_priority", lookup)).getMessage(); + assertTrue(msg.contains("invalid operation '/'"), msg); + + msg = assertThrows(IllegalArgumentException.class, () -> findMinMax(objs, "my_priority*my_priority2 * 3", lookup)).getMessage(); + assertTrue(msg.contains("Currently only a single EncodedValue is allowed on the right-hand side"), msg); + } + + @Test + public void runMaxMin() { + long x = 6_000_000_000L; + System.out.println((int)x); + + DecimalEncodedValue prio1 = new DecimalEncodedValueImpl("my_priority", 5, 1, false); + IntEncodedValueImpl prio2 = new IntEncodedValueImpl("my_priority2", 5, -5, false, false); + EncodedValueLookup lookup = new EncodingManager.Builder().add(prio1).add(prio2).build(); + + assertInterval(2, 2, "2", lookup); + + assertInterval(0, 62, "2*my_priority", lookup); + + assertInterval(-52, 10, "-2*my_priority2", lookup); + } + + void assertInterval(double min, double max, String expression, EncodedValueLookup lookup) { + MinMax minmax = findMinMax(new HashSet<>(), expression, lookup); + assertEquals(min, minmax.min, 0.1, expression); + assertEquals(max, minmax.max, 0.1, expression); + } +} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/util/InstructionListTest.java b/core/src/test/java/com/graphhopper/util/InstructionListTest.java index 9e4be7e6d14..f5f5fbf7d46 100644 --- a/core/src/test/java/com/graphhopper/util/InstructionListTest.java +++ b/core/src/test/java/com/graphhopper/util/InstructionListTest.java @@ -457,7 +457,7 @@ public void testInstructionWithHighlyCustomProfileWithRoadsBase() { GHUtility.setSpeed(10, true, true, roadsAccessEnc, roadsSpeedEnc, g.edge(2, 5).setDistance(10).set(rcEV, RoadClass.PEDESTRIAN)); CustomModel customModel = new CustomModel(); - customModel.addToPriority(Statement.If("road_class == PEDESTRIAN", Statement.Op.MULTIPLY, 0)); + customModel.addToPriority(Statement.If("road_class == PEDESTRIAN", Statement.Op.MULTIPLY, "0")); Weighting weighting = CustomModelParser.createWeighting(roads, tmpEM, TurnCostProvider.NO_TURN_COST_PROVIDER, customModel); Path p = new Dijkstra(g, weighting, tMode).calcPath(3, 4); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, tmpEM, usTR); diff --git a/docs/core/custom-models.md b/docs/core/custom-models.md index 94a56c4d3ea..f871a704808 100644 --- a/docs/core/custom-models.md +++ b/docs/core/custom-models.md @@ -82,6 +82,7 @@ boolean value (they are either true or false for a given edge), like: There are also some that take on a numeric value, like: +- max_speed - max_weight - max_height - max_width @@ -106,14 +107,8 @@ Here is a complete request example for a POST /route query in berlin that includ ```json { "points": [ - [ - 13.31543, - 52.509535 - ], - [ - 13.29779, - 52.512434 - ] + [ 13.31543, 52.509535 ], + [ 13.29779, 52.512434 ] ], "profile": "car", "ch.disable": true, @@ -121,13 +116,13 @@ Here is a complete request example for a POST /route query in berlin that includ "speed": [ { "if": "true", - "limit_to": 100 + "limit_to": "100" } ], "priority": [ { "if": "road_class == MOTORWAY", - "multiply_by": 0 + "multiply_by": "0" } ], "distance_influence": 100 @@ -138,7 +133,7 @@ Here is a complete request example for a POST /route query in berlin that includ Note that this only works for custom profiles and so far only for POST /route (but not GET /route or /isochrone, /spt or /map-matching). -GraphHopper maps offers an interactive text editor that can be used to comfortably enter custom models. You can open it +GraphHopper Maps offers an interactive text editor that can be used to comfortably enter custom models. You can open it by pressing the 'custom' button. It will check the syntax of your custom model and mark errors in red. You can press Ctrl+Space or Alt+Enter to retrieve auto-complete suggestions. Pressing Ctrl+Enter will send a routing request for the custom model you entered. @@ -151,7 +146,7 @@ same way for priority as well. When using custom models you do not need to define rules that specify a speed for every edge, but rather GraphHopper assumes a default speed that is set on the server-side. All you need to do is adjust this default speed to your -use-case. Typically, you will use the custom model in conjunction with a routing profile or vehicle which is used to +use-case. Typically, you will use the custom model in conjunction with a routing profile which is used to determine the default speed. The custom model is a JSON object and the first property we will learn about here is the `speed` property. The `speed` @@ -163,8 +158,8 @@ examples. Currently the custom model language supports two operators: -- `multiply_by` multiplies the speed value with a given number -- `limit_to` limits the speed value to a given number +- `multiply_by` multiplies the speed value with a given number or expression +- `limit_to` limits the speed value to a given number or expression #### `if` statements and the `multiply_by` operation @@ -175,7 +170,7 @@ Let's start with a simple example using `multiply_by`: "speed": [ { "if": "road_class == MOTORWAY", - "multiply_by": 0.5 + "multiply_by": "0.5" } ] } @@ -198,11 +193,11 @@ There can be multiple such 'if statements' in the speed section, and they are ev "speed": [ { "if": "road_class == MOTORWAY", - "multiply_by": 0.5 + "multiply_by": "0.5" }, { "if": "road_class == PRIMARY || road_environment == TUNNEL", - "multiply_by": 0.7 + "multiply_by": "0.7" } ] } @@ -225,7 +220,7 @@ Other categories like `get_off_bike` are of `boolean` type. They can be used as "speed": [ { "if": "get_off_bike", - "multiply_by": 0.6 + "multiply_by": "0.6" } ] } @@ -242,7 +237,7 @@ inequality) operators, but the numerical comparison operators "bigger" `>`, "big "speed": [ { "if": "max_width < 2.5", - "multiply_by": 0.8 + "multiply_by": "0.8" } ] } @@ -257,7 +252,7 @@ Categories of `string` type are used like this (note the quotes ''): "speed": [ { "if": "country == 'DEU'", - "multiply_by": 0 + "multiply_by": "0" } ] } @@ -273,11 +268,11 @@ current value to the given value. Take this example: "speed": [ { "if": "road_class == MOTORWAY", - "multiply_by": 0.8 + "multiply_by": "0.8" }, { "if": "surface == GRAVEL", - "limit_to": 60 + "limit_to": "60" } ] } @@ -289,17 +284,14 @@ regardless of the default speed and the previous rules. So for a road segment wi statement further reduces the speed from `80` to `60`. If the `road_class` was `PRIMARY` and the default speed was `50` the first rule would not apply and the second rule would do nothing, because limiting `50` to `60` still yields `50`. -Note that all values used for `limit_to` must be in the range `[0, max_vehicle_speed]` where `max_vehicle_speed` is the -maximum speed that is set for the base vehicle and cannot be changed. - A common use-case for the `limit_to` operation is the following pattern: ```json { "speed": [ { - "if": true, - "limit_to": 90 + "if": "true", + "limit_to": "90" } ] } @@ -318,11 +310,11 @@ condition. So this example: "speed": [ { "if": "road_class == MOTORWAY", - "multiply_by": 0.5 + "multiply_by": "0.5" }, { "else": "", - "limit_to": 50 + "limit_to": "50" } ] } @@ -339,15 +331,15 @@ statements which are only evaluated in case the previous `if` or `else_if` state "speed": [ { "if": "road_class == MOTORWAY", - "multiply_by": 0.5 + "multiply_by": "0.5" }, { "else_if": "road_environment == TUNNEL", - "limit_to": 70 + "limit_to": "70" }, { "else": "", - "multiply_by": 0.9 + "multiply_by": "0.9" } ] } @@ -369,11 +361,11 @@ gets reduced by all of them. For the following model "speed": [ { "if": "road_class == MOTORWAY", - "multiply_by": 0.5 + "multiply_by": "0.5" }, { "else_if": "road_environment == TUNNEL", - "multiply_by": 0.8 + "multiply_by": "0.8" } ] } @@ -396,11 +388,11 @@ to `50km/h`. Note that each area's name needs to be prefixed with `in_`: "speed": [ { "if": "in_custom1", - "multiply_by": 0.7 + "multiply_by": "0.7" }, { "if": "in_custom1", - "limit_to": 50 + "limit_to": "50" } ], "areas": { @@ -412,26 +404,11 @@ to `50km/h`. Note that each area's name needs to be prefixed with `in_`: "type": "Polygon", "coordinates": [ [ - [ - 1.525, - 42.511 - ], - [ - 1.510, - 42.503 - ], - [ - 1.531, - 42.495 - ], - [ - 1.542, - 42.505 - ], - [ - 1.525, - 42.511 - ] + [ 1.525, 42.511 ], + [ 1.510, 42.503 ], + [ 1.531, 42.495 ], + [ 1.542, 42.505 ], + [ 1.525, 42.511 ] ] ] } @@ -465,15 +442,15 @@ Customizing the `priority` works very much like changing the `speed`, so in case "priority": [ { "if": "road_class == MOTORWAY", - "multiply_by": 0.5 + "multiply_by": "0.5" }, { "else_if": "road_class == SECONDARY", - "multiply_by": 0.9 + "multiply_by": "0.9" }, { "if": "road_environment == TUNNEL", - "multiply_by": 0.1 + "multiply_by": "0.1" } ] } @@ -491,7 +468,7 @@ rather which ones shall be preferred, you need to **decrease** the priority of o "priority": [ { "if": "road_class != CYCLEWAY", - "multiply_by": 0.8 + "multiply_by": "0.8" } ] } @@ -507,7 +484,7 @@ same way: "priority": [ { "if": "in_custom1", - "multiply_by": 0.7 + "multiply_by": "0.7" } ] } @@ -521,7 +498,7 @@ like this: "priority": [ { "if": "road_class == MOTORWAY && in_custom1", - "multiply_by": 0.1 + "multiply_by": "0.1" } ] } @@ -535,15 +512,15 @@ following: "priority": [ { "if": "max_width < 2.5", - "multiply_by": 0 + "multiply_by": "0" }, { "if": "max_length < 10", - "multiply_by": 0 + "multiply_by": "0" }, { "if": "max_weight < 3.5", - "multiply_by": 0 + "multiply_by": "0" } ] } @@ -553,6 +530,41 @@ which means that the priority for all road segments that allow a maximum vehicle length of `10m` or a maximum vehicle weight of `3.5tons`, or less, is zero, i.e. these "narrow" road segments are blocked. +### The value expression + +The value of `limit_to` or `multiply_by` is usually only a number and can be a more complex expression like +`Math.sqrt(2)`. You can even specify dynamic values like `max_speed`. This can be useful if the base profile does +not restrict this like it is the case for the `roads` profile. See this example: + +```json +{ + "speed": [ + { + "if": "true", + "limit_to": "max_speed * 0.9" + } + ] +} +``` + +This limits the speed on all roads to 90% of the maximum speed value if it exists. It can be also useful to set a +start value of the priority to a value that you pre-populated based on your algorithm: + +```json +{ + "priority": [ + { + "if": "true", + "limit_to": "my_precalculated_value" + } + ] +} +``` + +Note that when using a dynamic value like `my_precalculated_value` the maximum value correlates strongly with +the response time of A-star routing requests (i.e. when CH and LM are disabled). This means that if you pick a +smaller or more narrow range, or if you can avoid them entirely, then these requests might get faster. + ### Customizing `distance_influence` We already explained the meaning of `distance_influence` in one of the previous sections. To specify its value simply diff --git a/example/src/main/java/com/graphhopper/example/RoutingExample.java b/example/src/main/java/com/graphhopper/example/RoutingExample.java index 6d749c78262..8489adb940d 100644 --- a/example/src/main/java/com/graphhopper/example/RoutingExample.java +++ b/example/src/main/java/com/graphhopper/example/RoutingExample.java @@ -140,10 +140,10 @@ public static void customizableRouting(String ghLoc) { // 2. now avoid primary roads and reduce maximum speed, see docs/core/custom-models.md for an in-depth explanation // and also the blog posts https://www.graphhopper.com/?s=customizable+routing CustomModel model = new CustomModel(); - model.addToPriority(If("road_class == PRIMARY", MULTIPLY, 0.5)); + model.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.5")); // unconditional limit to 100km/h - model.addToPriority(If("true", LIMIT, 100)); + model.addToPriority(If("true", LIMIT, "100")); req.setCustomModel(model); res = hopper.route(req); diff --git a/web-api/src/main/java/com/graphhopper/jackson/StatementDeserializer.java b/web-api/src/main/java/com/graphhopper/jackson/StatementDeserializer.java index 33c14e6679d..5821d16d93f 100644 --- a/web-api/src/main/java/com/graphhopper/jackson/StatementDeserializer.java +++ b/web-api/src/main/java/com/graphhopper/jackson/StatementDeserializer.java @@ -17,24 +17,22 @@ class StatementDeserializer extends JsonDeserializer { public Statement deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode treeNode = p.readValueAsTree(); Statement.Op jsonOp = null; - double value = Double.NaN; + String value = null; if (treeNode.size() != 2) throw new IllegalArgumentException("Statement expects two entries but was " + treeNode.size() + " for " + treeNode); for (Statement.Op op : Statement.Op.values()) { if (treeNode.has(op.getName())) { - if (!treeNode.get(op.getName()).isNumber()) - throw new IllegalArgumentException("Operations " + op.getName() + " expects a number but was " + treeNode.get(op.getName())); if (jsonOp != null) throw new IllegalArgumentException("Multiple operations are not allowed. Statement: " + treeNode); jsonOp = op; - value = treeNode.get(op.getName()).asDouble(); + value = treeNode.get(op.getName()).asText(); } } if (jsonOp == null) throw new IllegalArgumentException("Cannot find an operation in " + treeNode + ". Must be one of: " + Arrays.stream(Statement.Op.values()).map(Statement.Op::getName).collect(Collectors.joining(","))); - if (Double.isNaN(value)) - throw new IllegalArgumentException("Value of operation " + jsonOp.getName() + " is not a number"); + if (value == null) + throw new IllegalArgumentException("Cannot find a value in " + treeNode); if (treeNode.has(IF.getName())) return Statement.If(treeNode.get(IF.getName()).asText(), jsonOp, value); @@ -47,6 +45,6 @@ else if (treeNode.has(ELSE.getName())) { throw new IllegalArgumentException("else cannot have expression but was " + treeNode.get(ELSE.getName())); } - throw new IllegalArgumentException("Cannot find if, else_if or else for " + treeNode.toString()); + throw new IllegalArgumentException("Cannot find if, else_if or else for " + treeNode); } } diff --git a/web-api/src/main/java/com/graphhopper/jackson/StatementSerializer.java b/web-api/src/main/java/com/graphhopper/jackson/StatementSerializer.java index 1b6c5bc1680..cb1702ad704 100644 --- a/web-api/src/main/java/com/graphhopper/jackson/StatementSerializer.java +++ b/web-api/src/main/java/com/graphhopper/jackson/StatementSerializer.java @@ -29,7 +29,7 @@ class StatementSerializer extends JsonSerializer { public void serialize(Statement statement, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeStartObject(); jsonGenerator.writeStringField(statement.getKeyword().getName(), statement.getCondition()); - jsonGenerator.writeNumberField(statement.getOperation().getName(), statement.getValue()); + jsonGenerator.writeStringField(statement.getOperation().getName(), statement.getValue()); jsonGenerator.writeEndObject(); } } diff --git a/web-api/src/main/java/com/graphhopper/json/MinMax.java b/web-api/src/main/java/com/graphhopper/json/MinMax.java new file mode 100644 index 00000000000..bcd5c7a691c --- /dev/null +++ b/web-api/src/main/java/com/graphhopper/json/MinMax.java @@ -0,0 +1,11 @@ +package com.graphhopper.json; + +public class MinMax { + public double min; + public double max; + + public MinMax(double min, double max) { + this.min = min; + this.max = max; + } +} diff --git a/web-api/src/main/java/com/graphhopper/json/Statement.java b/web-api/src/main/java/com/graphhopper/json/Statement.java index 4e780ec27ea..42e01b71b88 100644 --- a/web-api/src/main/java/com/graphhopper/json/Statement.java +++ b/web-api/src/main/java/com/graphhopper/json/Statement.java @@ -21,9 +21,9 @@ public class Statement { private final Keyword keyword; private final String condition; private final Op operation; - private final double value; + private final String value; - private Statement(Keyword keyword, String condition, Op operation, double value) { + private Statement(Keyword keyword, String condition, Op operation, String value) { this.keyword = keyword; this.condition = condition; this.value = value; @@ -42,21 +42,10 @@ public Op getOperation() { return operation; } - public double getValue() { + public String getValue() { return value; } - public double apply(double externValue) { - switch (operation) { - case MULTIPLY: - return value * externValue; - case LIMIT: - return Math.min(value, externValue); - default: - throw new IllegalArgumentException(); - } - } - public enum Keyword { IF("if"), ELSEIF("else_if"), ELSE("else"); @@ -84,7 +73,7 @@ public String getName() { return name; } - public String build(double value) { + public String build(String value) { switch (this) { case MULTIPLY: return "value *= " + value; @@ -94,6 +83,17 @@ public String build(double value) { throw new IllegalArgumentException(); } } + + public MinMax apply(MinMax minMax1, MinMax minMax2) { + switch (this) { + case MULTIPLY: + return new MinMax(minMax1.min * minMax2.min, minMax1.max * minMax2.max); + case LIMIT: + return new MinMax(Math.min(minMax1.min, minMax2.min), Math.min(minMax1.max, minMax2.max)); + default: + throw new IllegalArgumentException(); + } + } } @Override @@ -105,15 +105,15 @@ private String str(String str) { return "\"" + str + "\""; } - public static Statement If(String expression, Op op, double value) { + public static Statement If(String expression, Op op, String value) { return new Statement(Keyword.IF, expression, op, value); } - public static Statement ElseIf(String expression, Op op, double value) { + public static Statement ElseIf(String expression, Op op, String value) { return new Statement(Keyword.ELSEIF, expression, op, value); } - public static Statement Else(Op op, double value) { + public static Statement Else(Op op, String value) { return new Statement(Keyword.ELSE, null, op, value); } } diff --git a/web-api/src/main/java/com/graphhopper/util/CustomModel.java b/web-api/src/main/java/com/graphhopper/util/CustomModel.java index ab1a2dd8f79..5e5d7c8bcf2 100644 --- a/web-api/src/main/java/com/graphhopper/util/CustomModel.java +++ b/web-api/src/main/java/com/graphhopper/util/CustomModel.java @@ -21,9 +21,6 @@ import java.util.*; -import static com.graphhopper.json.Statement.Keyword.ELSE; -import static com.graphhopper.json.Statement.Keyword.IF; - /** * This class is used in combination with CustomProfile. */ @@ -120,8 +117,12 @@ public CustomModel setDistanceInfluence(double distanceFactor) { return this; } + public boolean hasDistanceInfluence() { + return distanceInfluence != null; + } + public double getDistanceInfluence() { - return distanceInfluence == null ? DEFAULT_DISTANCE_INFLUENCE : distanceInfluence; + return hasDistanceInfluence() ? distanceInfluence : DEFAULT_DISTANCE_INFLUENCE; } public CustomModel setHeadingPenalty(double headingPenalty) { @@ -144,81 +145,6 @@ private String createContentString() { + "|speedStatements=" + speedStatements + "|priorityStatements=" + priorityStatements + "|areas=" + areas; } - /** - * This method throws an exception when this CustomModel would decrease the edge weight compared to the specified - * baseModel as in such a case the optimality of A* with landmarks can no longer be guaranteed (as the preparation - * is based on baseModel). - */ - public void checkLMConstraints(CustomModel baseModel) { - if (isInternal()) - throw new IllegalArgumentException("CustomModel of query cannot be internal"); - if (distanceInfluence != null && distanceInfluence < baseModel.getDistanceInfluence()) - throw new IllegalArgumentException("CustomModel in query can only use " + - "distance_influence bigger or equal to " + baseModel.getDistanceInfluence() + - ", given: " + distanceInfluence); - - checkMultiplyValue(getPriority()); - double maxPrio = findMaxPriority(1); - if (maxPrio > 1) - throw new IllegalArgumentException("priority of CustomModel in query cannot be bigger than 1. Was: " + maxPrio); - - checkMultiplyValue(getSpeed()); - } - - private static void checkMultiplyValue(List list) { - for (Statement statement : list) { - if (statement.getOperation() == Statement.Op.MULTIPLY && statement.getValue() > 1) - throw new IllegalArgumentException("factor cannot be larger than 1 but was " + statement.getValue()); - } - } - - static double findMax(List statements, double max, String type) { - // we want to find the smallest value that cannot be exceeded by any edge. the 'blocks' of speed statements - // are applied one after the other. - List> blocks = splitIntoBlocks(statements); - for (List block : blocks) max = findMaxForBlock(block, max); - if (max <= 0) throw new IllegalArgumentException(type + " cannot be negative or 0 (was " + max + ")"); - return max; - } - - public double findMaxPriority(final double maxPriority) { - return findMax(getPriority(), maxPriority, "priority"); - } - - public double findMaxSpeed(final double maxSpeed) { - return findMax(getSpeed(), maxSpeed, "vehicle speed"); - } - - static double findMaxForBlock(List block, final double max) { - if (block.isEmpty() || !IF.equals(block.get(0).getKeyword())) - throw new IllegalArgumentException("Every block must start with an if-statement"); - if (block.get(0).getCondition().trim().equals("true")) - return block.get(0).apply(max); - - double blockMax = block.stream() - .mapToDouble(statement -> statement.apply(max)) - .max() - .orElse(max); - // if there is no 'else' statement it's like there is a 'neutral' branch that leaves the initial value as is - if (block.stream().noneMatch(st -> ELSE.equals(st.getKeyword()))) - blockMax = Math.max(blockMax, max); - return blockMax; - } - - /** - * Splits the specified list into several list of statements starting with if - */ - static List> splitIntoBlocks(List statements) { - List> result = new ArrayList<>(); - List block = null; - for (Statement st : statements) { - if (IF.equals(st.getKeyword())) result.add(block = new ArrayList<>()); - if (block == null) throw new IllegalArgumentException("Every block must start with an if-statement"); - block.add(st); - } - return result; - } - /** * A new CustomModel is created from the baseModel merged with the specified queryModel. Returns the baseModel if * queryModel is null. diff --git a/web-api/src/test/java/com/graphhopper/util/CustomModelTest.java b/web-api/src/test/java/com/graphhopper/util/CustomModelTest.java index 8e12c970be2..89269202821 100644 --- a/web-api/src/test/java/com/graphhopper/util/CustomModelTest.java +++ b/web-api/src/test/java/com/graphhopper/util/CustomModelTest.java @@ -21,105 +21,23 @@ import com.graphhopper.json.Statement; import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Iterator; -import java.util.List; -import static com.graphhopper.json.Statement.*; -import static com.graphhopper.json.Statement.Op.LIMIT; +import static com.graphhopper.json.Statement.ElseIf; +import static com.graphhopper.json.Statement.If; import static com.graphhopper.json.Statement.Op.MULTIPLY; -import static com.graphhopper.util.CustomModel.findMax; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; public class CustomModelTest { - @Test - public void testCheck() { - CustomModel queryModel = new CustomModel(); - queryModel.addToPriority(If("max_width < 3", MULTIPLY, 10)); - assertEquals(1, CustomModel.merge(queryModel, new CustomModel()).getPriority().size()); - // priority bigger than 1 is not ok for CustomModel of query - assertThrows(IllegalArgumentException.class, () -> queryModel.checkLMConstraints(new CustomModel())); - } - - @Test - public void testFindMax() { - List statements = new ArrayList<>(); - statements.add(If("true", LIMIT, 100)); - assertEquals(100, findMax(statements, 120, "speed")); - - statements.add(Else(LIMIT, 20)); - assertEquals(100, findMax(statements, 120, "speed")); - - statements = new ArrayList<>(); - statements.add(If("road_environment == BRIDGE", LIMIT, 85)); - statements.add(Else(LIMIT, 100)); - assertEquals(100, findMax(statements, 120, "speed")); - - // find bigger speed than stored max_speed in server-side custom_models - double storedMaxSpeed = 30; - statements = new ArrayList<>(); - statements.add(If("true", MULTIPLY, 2)); - statements.add(If("true", LIMIT, 35)); - assertEquals(35, findMax(statements, 30, "speed")); - } - - @Test - public void findMax_limitAndMultiply() { - List statements = Arrays.asList( - If("road_class == TERTIARY", LIMIT, 90), - ElseIf("road_class == SECONDARY", MULTIPLY, 1.0), - ElseIf("road_class == PRIMARY", LIMIT, 30), - Else(LIMIT, 3) - ); - assertEquals(140, findMax(statements, 140, "speed")); - } - - @Test - public void testFindMaxPriority() { - List statements = new ArrayList<>(); - statements.add(If("true", MULTIPLY, 2)); - assertEquals(2, findMax(statements, 1, "priority")); - - statements = new ArrayList<>(); - statements.add(If("true", MULTIPLY, 0.5)); - assertEquals(0.5, findMax(statements, 1, "priority")); - } - - @Test - public void findMax_multipleBlocks() { - List statements = Arrays.asList( - If("road_class == TERTIARY", MULTIPLY, 0.2), - ElseIf("road_class == SECONDARY", LIMIT, 25), - If("road_environment == TUNNEL", LIMIT, 60), - ElseIf("road_environment == BRIDGE", LIMIT, 50), - Else(MULTIPLY, 0.8) - ); - assertEquals(120, findMax(statements, 150, "speed")); - assertEquals(80, findMax(statements, 100, "speed")); - assertEquals(60, findMax(statements, 60, "speed")); - - statements = Arrays.asList( - If("road_class == TERTIARY", MULTIPLY, 0.2), - ElseIf("road_class == SECONDARY", LIMIT, 25), - Else(LIMIT, 40), - If("road_environment == TUNNEL", MULTIPLY, 0.8), - ElseIf("road_environment == BRIDGE", LIMIT, 30) - ); - assertEquals(40, findMax(statements, 150, "speed")); - assertEquals(40, findMax(statements, 40, "speed")); - } - @Test public void testMergeComparisonKeys() { CustomModel truck = new CustomModel(); - truck.addToPriority(If("max_width < 3", MULTIPLY, 0)); + truck.addToPriority(If("max_width < 3", MULTIPLY, "0")); CustomModel car = new CustomModel(); - car.addToPriority(If("max_width<2", MULTIPLY, 0)); + car.addToPriority(If("max_width<2", MULTIPLY, "0")); CustomModel bike = new CustomModel(); - bike.addToPriority(If("max_weight<0.02", MULTIPLY, 0)); + bike.addToPriority(If("max_weight<0.02", MULTIPLY, "0")); assertEquals(2, CustomModel.merge(bike, car).getPriority().size()); assertEquals(1, bike.getPriority().size()); @@ -129,10 +47,10 @@ public void testMergeComparisonKeys() { @Test public void testMergeElse() { CustomModel truck = new CustomModel(); - truck.addToPriority(If("max_width < 3", MULTIPLY, 0)); + truck.addToPriority(If("max_width < 3", MULTIPLY, "0")); CustomModel car = new CustomModel(); - car.addToPriority(If("max_width < 2", MULTIPLY, 0)); + car.addToPriority(If("max_width < 2", MULTIPLY, "0")); CustomModel merged = CustomModel.merge(truck, car); assertEquals(2, merged.getPriority().size()); @@ -143,15 +61,15 @@ public void testMergeElse() { public void testMergeEmptyModel() { CustomModel emptyCar = new CustomModel(); CustomModel car = new CustomModel(); - car.addToPriority(If("road_class==primary", MULTIPLY, 0.5)); - car.addToPriority(ElseIf("road_class==tertiary", MULTIPLY, 0.8)); + car.addToPriority(If("road_class==primary", MULTIPLY, "0.5")); + car.addToPriority(ElseIf("road_class==tertiary", MULTIPLY, "0.8")); Iterator iter = CustomModel.merge(emptyCar, car).getPriority().iterator(); - assertEquals(0.5, iter.next().getValue()); - assertEquals(0.8, iter.next().getValue()); + assertEquals("0.5", iter.next().getValue()); + assertEquals("0.8", iter.next().getValue()); iter = CustomModel.merge(car, emptyCar).getPriority().iterator(); - assertEquals(0.5, iter.next().getValue()); - assertEquals(0.8, iter.next().getValue()); + assertEquals("0.5", iter.next().getValue()); + assertEquals("0.8", iter.next().getValue()); } } \ No newline at end of file diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java index d99b4feee03..e95e7eb230c 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java @@ -365,7 +365,7 @@ public void testCustomModel() { addPoint(new GHPoint(42.532022, 1.519504)). setCustomModel(new CustomModel() // we reduce the speed in the long tunnel - .addToSpeed(Statement.If("road_environment == TUNNEL", Statement.Op.MULTIPLY, 0.1))). + .addToSpeed(Statement.If("road_environment == TUNNEL", Statement.Op.MULTIPLY, "0.1"))). setProfile("my_custom_car"). putHint("ch.disable", true); GHResponse rsp = gh.route(req); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java index 0bdf791a7e6..ee0f8478bfb 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java @@ -80,21 +80,21 @@ private static GraphHopperServerConfiguration createConfig() { new Profile("foot_profile").setVehicle("foot").setWeighting("fastest"), new CustomProfile("car_no_unclassified").setCustomModel( new CustomModel(new CustomModel(). - addToPriority(If("road_class == UNCLASSIFIED", LIMIT, 0)))). + addToPriority(If("road_class == UNCLASSIFIED", LIMIT, "0")))). setVehicle("car"), new CustomProfile("custom_bike"). setCustomModel(new CustomModel(). - addToSpeed(If("road_class == PRIMARY", LIMIT, 28)). - addToPriority(If("max_width < 1.2", MULTIPLY, 0))). + addToSpeed(If("road_class == PRIMARY", LIMIT, "28")). + addToPriority(If("max_width < 1.2", MULTIPLY, "0"))). setVehicle("bike"), new CustomProfile("custom_bike2").setCustomModel( new CustomModel(new CustomModel(). - addToPriority(If("road_class == TERTIARY || road_class == TRACK", MULTIPLY, 0)))). + addToPriority(If("road_class == TERTIARY || road_class == TRACK", MULTIPLY, "0")))). setVehicle("bike"), new CustomProfile("custom_bike3").setCustomModel( new CustomModel(new CustomModel(). - addToSpeed(If("road_class == TERTIARY || road_class == TRACK", MULTIPLY, 10)). - addToSpeed(If("true", LIMIT, 40)))). + addToSpeed(If("road_class == TERTIARY || road_class == TRACK", MULTIPLY, "10")). + addToSpeed(If("true", LIMIT, "40")))). setVehicle("bike"))). setCHProfiles(Arrays.asList(new CHProfile("truck"), new CHProfile("car_no_unclassified"))); return config; From 89c426748536c2d769bf0b5275c6dd05e1f3e5c7 Mon Sep 17 00:00:00 2001 From: easbar Date: Sun, 26 Jun 2022 21:29:41 +0200 Subject: [PATCH 072/389] Create weighting after graph in two tests --- .../routing/DirectedRoutingTest.java | 12 +++++------- .../routing/RandomizedRoutingTest.java | 19 +++++++------------ 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java b/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java index 07bd7a1fb35..72636589930 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java @@ -85,12 +85,10 @@ private static class Fixture { private final boolean prepareLM; private final Directory dir; private final BaseGraph graph; - private final CHConfig chConfig; - private final LMConfig lmConfig; private final FlagEncoder encoder; private final TurnCostStorage turnCostStorage; private final int maxTurnCosts; - private final Weighting weighting; + private Weighting weighting; private final EncodingManager encodingManager; private RoutingCHGraph routingCHGraph; private LandmarkStorage lm; @@ -110,10 +108,6 @@ public Fixture(Algo algo, int uTurnCosts, boolean prepareCH, boolean prepareLM) encodingManager = EncodingManager.start().add(encoder).add(Subnetwork.create("c2")).build(); graph = new BaseGraph.Builder(encodingManager).setDir(dir).withTurnCosts(true).create(); turnCostStorage = graph.getTurnCostStorage(); - weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), turnCostStorage, uTurnCosts)); - chConfig = CHConfig.edgeBased("p1", weighting); - // important: for LM preparation we need to use a weighting without turn costs #1960 - lmConfig = new LMConfig("c2", new FastestWeighting(encoder)); } @Override @@ -123,15 +117,19 @@ public String toString() { private void preProcessGraph() { graph.freeze(); + weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), turnCostStorage, uTurnCosts)); if (!prepareCH && !prepareLM) { return; } if (prepareCH) { + CHConfig chConfig = CHConfig.edgeBased("p1", weighting); PrepareContractionHierarchies pch = PrepareContractionHierarchies.fromGraph(graph, chConfig); PrepareContractionHierarchies.Result res = pch.doWork(); routingCHGraph = RoutingCHGraphImpl.fromGraph(graph, res.getCHStorage(), res.getCHConfig()); } if (prepareLM) { + // important: for LM preparation we need to use a weighting without turn costs #1960 + LMConfig lmConfig = new LMConfig("c2", new FastestWeighting(encoder)); // we need the subnetwork EV for LM PrepareRoutingSubnetworks preparation = new PrepareRoutingSubnetworks(graph, Arrays.asList(new PrepareRoutingSubnetworks.PrepareJob(encodingManager.getBooleanEncodedValue(Subnetwork.key("c2")), lmConfig.getWeighting()))); diff --git a/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java b/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java index 8c1ef5bd1c9..11c506c25ef 100644 --- a/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java @@ -43,7 +43,6 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.function.Supplier; @@ -97,12 +96,10 @@ private static class Fixture { private final TraversalMode traversalMode; private final Directory dir; private final BaseGraph graph; - private final List chConfigs; - private final LMConfig lmConfig; private final FlagEncoder encoder; private final TurnCostStorage turnCostStorage; private final int maxTurnCosts; - private final Weighting weighting; + private Weighting weighting; private final EncodingManager encodingManager; private RoutingCHGraph routingCHGraph; private LandmarkStorage lm; @@ -123,13 +120,6 @@ private static class Fixture { .setDir(dir) .create(); turnCostStorage = graph.getTurnCostStorage(); - chConfigs = Arrays.asList( - CHConfig.nodeBased("p1", new FastestWeighting(encoder)), - CHConfig.edgeBased("p2", new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()))) - ); - // important: for LM preparation we need to use a weighting without turn costs #1960 - lmConfig = new LMConfig("car", chConfigs.get(0).getWeighting()); - weighting = traversalMode.isEdgeBased() ? chConfigs.get(1).getWeighting() : chConfigs.get(0).getWeighting(); } @Override @@ -139,13 +129,18 @@ public String toString() { private void preProcessGraph() { graph.freeze(); + weighting = traversalMode.isEdgeBased() + ? new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage())) + : new FastestWeighting(encoder); if (prepareCH) { - CHConfig chConfig = !traversalMode.isEdgeBased() ? chConfigs.get(0) : chConfigs.get(1); + CHConfig chConfig = traversalMode.isEdgeBased() ? CHConfig.edgeBased("p", weighting) : CHConfig.nodeBased("p", weighting); PrepareContractionHierarchies pch = PrepareContractionHierarchies.fromGraph(graph, chConfig); PrepareContractionHierarchies.Result res = pch.doWork(); routingCHGraph = RoutingCHGraphImpl.fromGraph(graph, res.getCHStorage(), res.getCHConfig()); } if (prepareLM) { + // important: for LM preparation we need to use a weighting without turn costs #1960 + LMConfig lmConfig = new LMConfig("car", new FastestWeighting(encoder)); PrepareLandmarks prepare = new PrepareLandmarks(dir, graph, encodingManager, lmConfig, 16); prepare.setMaximumWeight(10000); prepare.doWork(); From 2140131ec079e21b7e7f05865a3b77913b0d9acc Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 28 Jun 2022 22:24:16 +0200 Subject: [PATCH 073/389] Update custom model editor: operator values are strings now --- .../jackson/StatementDeserializerTest.java | 60 +++++++++++++++++++ web-bundle/package.json | 2 +- .../com/graphhopper/maps/js/main-template.js | 6 +- 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 web-api/src/test/java/com/graphhopper/jackson/StatementDeserializerTest.java diff --git a/web-api/src/test/java/com/graphhopper/jackson/StatementDeserializerTest.java b/web-api/src/test/java/com/graphhopper/jackson/StatementDeserializerTest.java new file mode 100644 index 00000000000..ef930cca70a --- /dev/null +++ b/web-api/src/test/java/com/graphhopper/jackson/StatementDeserializerTest.java @@ -0,0 +1,60 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.jackson; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.graphhopper.json.Statement; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class StatementDeserializerTest { + + @Test + void conditionAsBoolean_expressionAsNumber() throws JsonProcessingException { + SimpleModule module = new SimpleModule(); + module.addDeserializer(Statement.class, new StatementDeserializer()); + ObjectMapper objectMapper = new ObjectMapper().registerModule(module); + // true instead of "true" or 100 instead of "100" also work because they are parsed to strings + // We probably need to accept numbers instead of strings for legacy support, but maybe we should reject true/false + Statement statement = objectMapper.readValue("{\"if\":true,\"limit_to\":100}", Statement.class); + assertEquals(Statement.Keyword.IF, statement.getKeyword()); + assertEquals("true", statement.getCondition()); + assertEquals(Statement.Op.LIMIT, statement.getOperation()); + assertEquals("100", statement.getValue()); + } + + @Test + void else_null() throws JsonProcessingException { + SimpleModule module = new SimpleModule(); + module.addDeserializer(Statement.class, new StatementDeserializer()); + ObjectMapper objectMapper = new ObjectMapper().registerModule(module); + // There is no error for `"else": null` currently, even though there is no real reason to support this. + // The value will actually be null, but the way we use it at the moment this is not a problem. + Statement statement = objectMapper.readValue("{\"else\":null,\"limit_to\":\"abc\"}", Statement.class); + assertEquals(Statement.Keyword.ELSE, statement.getKeyword()); + assertNull(statement.getCondition()); + assertEquals(Statement.Op.LIMIT, statement.getOperation()); + assertEquals("abc", statement.getValue()); + } + +} \ No newline at end of file diff --git a/web-bundle/package.json b/web-bundle/package.json index e4dcf01a7c3..d8a1ae3b6f2 100644 --- a/web-bundle/package.json +++ b/web-bundle/package.json @@ -25,7 +25,7 @@ } }, "dependencies": { - "custom-model-editor": "github:graphhopper/custom-model-editor#693a44097271ed84f603f46efbfcfc56ab97b608", + "custom-model-editor": "github:graphhopper/custom-model-editor#804566f0b11add4688692499fee95d1f1ac3a02d", "flatpickr": "4.4.6", "jquery": "3.5.0", "leaflet": "1.5.1", diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js index 6622bb9fad9..e000a00c83d 100644 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js +++ b/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js @@ -102,17 +102,17 @@ $(document).ready(function (e) { + "\n \"speed\": [" + "\n {" + "\n \"if\": \"road_class == MOTORWAY\"," - + "\n \"multiply_by\": 0.8" + + "\n \"multiply_by\": \"0.8\"" + "\n }" + "\n ]," + "\n \"priority\": [" + "\n {" + "\n \"if\": \"road_environment == TUNNEL\"," - + "\n \"multiply_by\": 0.5" + + "\n \"multiply_by\": \"0.5\"" + "\n }," + "\n {" + "\n \"if\": \"max_weight < 3\"," - + "\n \"multiply_by\": 0.0" + + "\n \"multiply_by\": \"0.0\"" + "\n }" + "\n ]" + "\n}"; From fa1b12661fecf1e60974e490269aa618cadf63a4 Mon Sep 17 00:00:00 2001 From: Andi Date: Wed, 29 Jun 2022 22:13:14 +0200 Subject: [PATCH 074/389] Update custom model editor: validation + auto-complete for rhs expressions (#2615) --- web-bundle/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web-bundle/package.json b/web-bundle/package.json index d8a1ae3b6f2..89dc56bd928 100644 --- a/web-bundle/package.json +++ b/web-bundle/package.json @@ -25,7 +25,7 @@ } }, "dependencies": { - "custom-model-editor": "github:graphhopper/custom-model-editor#804566f0b11add4688692499fee95d1f1ac3a02d", + "custom-model-editor": "github:graphhopper/custom-model-editor#a8c97e4ef8e76c963be375984a3c08ff3c1e8288", "flatpickr": "4.4.6", "jquery": "3.5.0", "leaflet": "1.5.1", From 7ca1b2575ecc499396d619bc441fb157fec6ec9b Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 30 Jun 2022 08:25:05 +0200 Subject: [PATCH 075/389] Allow graph.encoded_values for which there is no tag parser --- core/src/main/java/com/graphhopper/GraphHopper.java | 6 +++++- .../routing/util/parsers/DefaultTagParserFactory.java | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 8582b1f9e00..50cbdfa0e6c 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -586,7 +586,11 @@ private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String en encodingManager = emBuilder.build(); osmParsers = new OSMParsers(); - encodedValueStrings.forEach(s -> osmParsers.addWayTagParser(tagParserFactory.create(encodingManager, s))); + for (String s : encodedValueStrings) { + TagParser tagParser = tagParserFactory.create(encodingManager, s); + if (tagParser != null) + osmParsers.addWayTagParser(tagParser); + } // this needs to be in sync with the default EVs added in EncodingManager.Builder#build. ideally I would like to remove // all these defaults and just use the config as the single source of truth diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java index 74b92d3a48d..b9f023818f2 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java @@ -75,7 +75,6 @@ else if (name.equals(HorseRating.KEY)) return new OSMHorseRatingParser(lookup.getIntEncodedValue(HorseRating.KEY)); else if (name.equals(Country.KEY)) return new CountryParser(lookup.getEnumEncodedValue(Country.KEY, Country.class)); - - throw new IllegalArgumentException("DefaultTagParserFactory cannot find: " + name); + return null; } } From 22e3da67c7eba7d14f1d14df3b92b98ee57da31b Mon Sep 17 00:00:00 2001 From: Andi Date: Thu, 30 Jun 2022 12:53:27 +0200 Subject: [PATCH 076/389] Use actual speed maximum rather than flagEncoder#getMaxSpeed() for weighting.getMinWeight() (#2614) --- .../java/com/graphhopper/GraphHopper.java | 5 ++++ .../routing/ev/DecimalEncodedValue.java | 6 ++++ .../routing/ev/DecimalEncodedValueImpl.java | 10 ++++++- .../routing/ev/EnumEncodedValue.java | 3 +- .../routing/ev/IntEncodedValue.java | 8 +++++ .../routing/ev/IntEncodedValueImpl.java | 15 +++++++++- .../routing/ev/SimpleBooleanEncodedValue.java | 3 +- .../routing/ev/StringEncodedValue.java | 3 +- .../routing/weighting/CurvatureWeighting.java | 3 +- .../routing/weighting/FastestWeighting.java | 2 +- .../weighting/custom/CustomModelParser.java | 3 +- .../java/com/graphhopper/GraphHopperTest.java | 14 ++++----- .../ev/DecimalEncodedValueImplTest.java | 17 +++++++++++ .../ev/EncodedValueSerializerTest.java | 6 ++-- .../routing/lm/PrepareLandmarksTest.java | 6 ++-- .../weighting/FastestWeightingTest.java | 2 +- .../weighting/custom/CustomWeightingTest.java | 29 ++++++++++--------- .../com/graphhopper/gtfs/GraphHopperGtfs.java | 1 + 18 files changed, 100 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 50cbdfa0e6c..0094932ae0e 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -816,12 +816,17 @@ protected void importOSM() { properties.put("datareader.import.date", f.format(new Date())); if (reader.getDataDate() != null) properties.put("datareader.data.date", f.format(reader.getDataDate())); + + writeEncodingManagerToProperties(); } protected void createBaseGraphAndProperties() { baseGraph.getDirectory().create(); baseGraph.create(100); properties.create(100); + } + + protected void writeEncodingManagerToProperties() { properties.put("graph.em.version", Constants.VERSION_EM); properties.put("graph.em.edge_config", encodingManager.toEdgeConfigAsString()); properties.put("graph.em.turn_cost_config", encodingManager.toTurnCostConfigAsString()); diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java index 09e9f72b5a7..1a066ecec1c 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java @@ -31,6 +31,11 @@ public interface DecimalEncodedValue extends EncodedValue { */ double getMinDecimal(); + /** + * @see IntEncodedValue#getMaxSetValueOrMaxInt() + */ + double getMaxSetValueOrMaxDecimal(); + /** * @return the smallest decimal value that is larger or equal to the given value and that can be stored exactly, * i.e. for which {@link #getDecimal} returns the same value that we put in using {@link #setDecimal}. @@ -40,4 +45,5 @@ public interface DecimalEncodedValue extends EncodedValue { double getNextStorableValue(double value); double getSmallestNonZeroValue(); + } diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java index dab62919e14..c137a401979 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java @@ -75,6 +75,7 @@ public DecimalEncodedValueImpl(String name, int bits, double minValue, double fa @JsonProperty("bits") int bits, @JsonProperty("min_value") int minValue, @JsonProperty("max_value") int maxValue, + @JsonProperty("max_set_value") int maxSetValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, @JsonProperty("fwd_data_index") int fwdDataIndex, @@ -87,7 +88,7 @@ public DecimalEncodedValueImpl(String name, int bits, double minValue, double fa @JsonProperty("default_is_infinity") boolean defaultIsInfinity, @JsonProperty("use_maximum_as_infinity") boolean useMaximumAsInfinity) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); + super(name, bits, minValue, maxValue, maxSetValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); this.factor = factor; this.defaultIsInfinity = defaultIsInfinity; this.useMaximumAsInfinity = useMaximumAsInfinity; @@ -153,4 +154,11 @@ public double getMaxDecimal() { public double getMinDecimal() { return minValue * factor; } + + @Override + public double getMaxSetValueOrMaxDecimal() { + if (useMaximumAsInfinity || defaultIsInfinity) + throw new IllegalStateException("getMaxSetValueOrMaxDecimal() is not implemented for useMaximumAsInfinity or defaultIsInfinity"); + return getMaxSetValueOrMaxInt() * factor; + } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java index a6947a5e0cb..c114a2bfffa 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java @@ -46,6 +46,7 @@ public EnumEncodedValue(String name, Class enumType, boolean storeTwoDirectio @JsonProperty("bits") int bits, @JsonProperty("min_value") int minValue, @JsonProperty("max_value") int maxValue, + @JsonProperty("max_set_value") int maxSetValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, @JsonProperty("fwd_data_index") int fwdDataIndex, @@ -56,7 +57,7 @@ public EnumEncodedValue(String name, Class enumType, boolean storeTwoDirectio @JsonProperty("bwd_mask") int bwdMask, @JsonProperty("enum_type") Class enumType) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); + super(name, bits, minValue, maxValue, maxSetValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); this.enumType = enumType; arr = enumType.getEnumConstants(); } diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java index f3c72c036ed..6334e066d74 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java @@ -31,6 +31,14 @@ public interface IntEncodedValue extends EncodedValue { */ int getMinInt(); + /** + * Returns the maximum value set using this encoded value or the physical storage limit if no value has been set + * at all yet. Note that even when some values were set this is not equal to the global maximum across all values in + * the graph if values are set multiple times for the same edge and they are decreasing. However, the returned value + * will always be equal to or larger than the global maximum. + */ + int getMaxSetValueOrMaxInt(); + /** * @return true if this EncodedValue can store a different value for its reverse direction */ diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java index 63b44f16a99..5216cf96745 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java @@ -38,6 +38,7 @@ public class IntEncodedValueImpl implements IntEncodedValue { final boolean negateReverseDirection; final int minValue; final int maxValue; + int maxSetValue; /** * There are multiple int values possible per edge. Here we specify the index into this integer array. @@ -78,13 +79,16 @@ public IntEncodedValueImpl(String name, int bits, int minValue, boolean negateRe if (negateReverseDirection && (minValue != 0 || storeTwoDirections)) throw new IllegalArgumentException(name + ": negating value for reverse direction only works for minValue == 0 " + "and !storeTwoDirections but was minValue=" + minValue + ", storeTwoDirections=" + storeTwoDirections); - this.name = name; this.storeTwoDirections = storeTwoDirections; int max = (1 << bits) - 1; // negateReverseDirection: store the negative value only once, but for that we need the same range as maxValue for negative values this.minValue = negateReverseDirection ? -max : minValue; this.maxValue = max + minValue; + if (minValue == Integer.MIN_VALUE) + // we do not allow this because we use this value to represent maxSetValue = untouched, i.e. no value has been set yet + throw new IllegalArgumentException(Integer.MIN_VALUE + " is not allowed for minValue"); + this.maxSetValue = Integer.MIN_VALUE; // negateReverseDirection: we need twice the integer range, i.e. 1 more bit this.bits = negateReverseDirection ? bits + 1 : bits; this.negateReverseDirection = negateReverseDirection; @@ -95,6 +99,7 @@ public IntEncodedValueImpl(String name, int bits, int minValue, boolean negateRe @JsonProperty("bits") int bits, @JsonProperty("min_value") int minValue, @JsonProperty("max_value") int maxValue, + @JsonProperty("max_set_value") int maxSetValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, @JsonProperty("fwd_data_index") int fwdDataIndex, @@ -111,6 +116,7 @@ public IntEncodedValueImpl(String name, int bits, int minValue, boolean negateRe this.negateReverseDirection = negateReverseDirection; this.minValue = minValue; this.maxValue = maxValue; + this.maxSetValue = maxSetValue; this.fwdDataIndex = fwdDataIndex; this.bwdDataIndex = bwdDataIndex; this.fwdShift = fwdShift; @@ -166,6 +172,8 @@ final void uncheckedSet(boolean reverse, IntsRef ref, int value) { } else if (reverse && !storeTwoDirections) throw new IllegalArgumentException(getName() + ": value for reverse direction would overwrite forward direction. Enable storeTwoDirections for this EncodedValue or don't use setReverse"); + maxSetValue = Math.max(maxSetValue, value); + value -= minValue; if (reverse) { int flags = ref.ints[bwdDataIndex + ref.offset]; @@ -204,6 +212,11 @@ public int getMinInt() { return minValue; } + @Override + public int getMaxSetValueOrMaxInt() { + return maxSetValue == Integer.MIN_VALUE ? getMaxInt() : maxSetValue; + } + @Override public final boolean isStoreTwoDirections() { return storeTwoDirections; diff --git a/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java index 4d5ecb2d455..180bada4491 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java @@ -39,6 +39,7 @@ public SimpleBooleanEncodedValue(String name, boolean storeBothDirections) { @JsonProperty("bits") int bits, @JsonProperty("min_value") int minValue, @JsonProperty("max_value") int maxValue, + @JsonProperty("max_set_value") int maxSetValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, @JsonProperty("fwd_data_index") int fwdDataIndex, @@ -49,7 +50,7 @@ public SimpleBooleanEncodedValue(String name, boolean storeBothDirections) { @JsonProperty("bwd_mask") int bwdMask ) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); + super(name, bits, minValue, maxValue, maxSetValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java index 54a81d0e5a7..29f58535f50 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java @@ -52,6 +52,7 @@ public StringEncodedValue(String name, int bits, List values, boolean st @JsonProperty("bits") int bits, @JsonProperty("min_value") int minValue, @JsonProperty("max_value") int maxValue, + @JsonProperty("max_set_value") int maxSetValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, @JsonProperty("fwd_data_index") int fwdDataIndex, @@ -64,7 +65,7 @@ public StringEncodedValue(String name, int bits, List values, boolean st @JsonProperty("values") List values, @JsonProperty("index_map") HashMap indexMap) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); + super(name, bits, minValue, maxValue, maxSetValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); if (values.size() > maxValues) throw new IllegalArgumentException("Number of values is higher than the maximum value count: " + values.size() + " > " + maxValues); diff --git a/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java index 8528277264a..cc313f6ca1a 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java @@ -47,7 +47,8 @@ public CurvatureWeighting(FlagEncoder flagEncoder, PMap pMap, TurnCostProvider t curvatureEnc = flagEncoder.getDecimalEncodedValue(EncodingManager.getKey(flagEncoder, "curvature")); avSpeedEnc = flagEncoder.getDecimalEncodedValue(EncodingManager.getKey(flagEncoder, "average_speed")); double minBendiness = 1; // see correctErrors - minFactor = minBendiness / Math.log(flagEncoder.getMaxSpeed()) / PriorityCode.getValue(BEST.getValue()); + double maxSpeed = avSpeedEnc.getMaxSetValueOrMaxDecimal(); + minFactor = minBendiness / Math.log(maxSpeed) / PriorityCode.getValue(BEST.getValue()); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java index c302384c51c..2a8cee9f718 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java @@ -62,7 +62,7 @@ public FastestWeighting(FlagEncoder encoder, PMap map, TurnCostProvider turnCost super(encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), turnCostProvider); headingPenalty = map.getDouble(Routing.HEADING_PENALTY, Routing.DEFAULT_HEADING_PENALTY); headingPenaltyMillis = Math.round(headingPenalty * 1000); - maxSpeed = encoder.getMaxSpeed() / SPEED_CONV; + maxSpeed = speedEnc.getMaxSetValueOrMaxDecimal() / SPEED_CONV; if (!encoder.hasEncodedValue(RoadAccess.KEY)) throw new IllegalArgumentException("road_access is not available but expected for FastestWeighting"); diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java index 1ba7a6a1fb3..1e0118eb6e6 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java @@ -76,8 +76,9 @@ public static CustomWeighting createWeighting(FlagEncoder baseFlagEncoder, Encod final String pKey = EncodingManager.getKey(baseFlagEncoder.toString(), "priority"); DecimalEncodedValue priorityEnc = lookup.hasEncodedValue(pKey) ? lookup.getDecimalEncodedValue(pKey) : null; + double maxSpeed = avgSpeedEnc.getMaxSetValueOrMaxDecimal(); CustomWeighting.Parameters parameters = createWeightingParameters(customModel, lookup, - avgSpeedEnc, baseFlagEncoder.getMaxSpeed(), priorityEnc); + avgSpeedEnc, maxSpeed, priorityEnc); return new CustomWeighting(baseFlagEncoder.getAccessEnc(), baseFlagEncoder.getAverageSpeedEnc(), turnCostProvider, parameters); } diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 1320ce8043e..1577484ce7e 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -97,10 +97,10 @@ public void setup() { @ParameterizedTest @CsvSource({ DIJKSTRA + ",false,511", - ASTAR + ",false,444", + ASTAR + ",false,256", DIJKSTRA_BI + ",false,228", - ASTAR_BI + ",false,184", - ASTAR_BI + ",true,49", + ASTAR_BI + ",false,142", + ASTAR_BI + ",true,41", DIJKSTRA_BI + ",true,48" }) public void testMonacoDifferentAlgorithms(String algo, boolean withCH, int expectedVisitedNodes) { @@ -1577,9 +1577,9 @@ public void testCrossQuery() { hopper.importOrLoad(); // flex - testCrossQueryAssert(profile1, hopper, 528.3, 166, true); - testCrossQueryAssert(profile2, hopper, 635.8, 160, true); - testCrossQueryAssert(profile3, hopper, 815.2, 158, true); + testCrossQueryAssert(profile1, hopper, 528.3, 138, true); + testCrossQueryAssert(profile2, hopper, 635.8, 138, true); + testCrossQueryAssert(profile3, hopper, 815.2, 140, true); // LM (should be the same as flex, but with less visited nodes!) testCrossQueryAssert(profile1, hopper, 528.3, 74, false); @@ -1744,7 +1744,7 @@ public void testDisablingLM() { req.putHint(Landmark.DISABLE, true); res = hopper.route(req); - assertTrue(res.getHints().getInt("visited_nodes.sum", 0) > 200); + assertTrue(res.getHints().getInt("visited_nodes.sum", 0) > 170); } @ParameterizedTest diff --git a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java index bc107187260..2e0343a2234 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java @@ -160,4 +160,21 @@ public void testNextStorableValue_maxInfinity() { assertEquals(Double.POSITIVE_INFINITY, enc.getDecimal(false, intsRef)); } + @Test + public void lowestUpperBound_with_negateReverseDirection() { + DecimalEncodedValueImpl enc = new DecimalEncodedValueImpl("test", 4, 0, 3, false, true, false, false); + enc.init(new EncodedValue.InitializerConfig()); + assertEquals(15 * 3, enc.getMaxSetValueOrMaxDecimal()); + IntsRef ints = new IntsRef(1); + enc.setDecimal(false, ints, 3); + assertEquals(3, enc.getDecimal(false, ints)); + assertEquals(3, enc.getMaxSetValueOrMaxDecimal()); + enc.setDecimal(true, ints, -6); + assertEquals(6, enc.getDecimal(false, ints)); + assertEquals(6, enc.getMaxSetValueOrMaxDecimal()); + // note that the maximum is never lowered, even when we lower the value for the 'same' edge flags + enc.setDecimal(false, ints, 0); + assertEquals(0, enc.getDecimal(false, ints)); + assertEquals(6, enc.getMaxSetValueOrMaxDecimal()); + } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java b/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java index d65e5f4f93a..211f11024b2 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java @@ -73,14 +73,14 @@ void explicitString() { List serialized = evs.stream().map(EncodedValueSerializer::serializeEncodedValue).collect(Collectors.toList()); assertEquals("{\"className\":\"com.graphhopper.routing.ev.IntEncodedValueImpl\",\"name\":\"lanes\",\"bits\":3," + - "\"min_value\":0,\"max_value\":7,\"negate_reverse_direction\":false,\"store_two_directions\":false," + + "\"min_value\":0,\"max_value\":7,\"max_set_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false," + "\"fwd_data_index\":0,\"bwd_data_index\":0,\"fwd_shift\":0,\"bwd_shift\":-1,\"fwd_mask\":7,\"bwd_mask\":0}", serialized.get(0)); assertEquals("{\"className\":\"com.graphhopper.routing.ev.DecimalEncodedValueImpl\",\"name\":\"max_width\",\"bits\":7," + - "\"min_value\":0,\"max_value\":127,\"negate_reverse_direction\":false,\"store_two_directions\":false," + + "\"min_value\":0,\"max_value\":127,\"max_set_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false," + "\"fwd_data_index\":0,\"bwd_data_index\":0,\"fwd_shift\":3,\"bwd_shift\":-1,\"fwd_mask\":1016,\"bwd_mask\":0," + "\"factor\":0.1,\"default_is_infinity\":true,\"use_maximum_as_infinity\":false}", serialized.get(1)); assertEquals("{\"className\":\"com.graphhopper.routing.ev.SimpleBooleanEncodedValue\",\"name\":\"get_off_bike\",\"bits\":1," + - "\"min_value\":0,\"max_value\":1,\"negate_reverse_direction\":false,\"store_two_directions\":false,\"fwd_data_index\":0," + + "\"min_value\":0,\"max_value\":1,\"max_set_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false,\"fwd_data_index\":0," + "\"bwd_data_index\":0,\"fwd_shift\":10,\"bwd_shift\":-1,\"fwd_mask\":1024,\"bwd_mask\":0}", serialized.get(2)); EncodedValue ev0 = EncodedValueSerializer.deserializeEncodedValue(serialized.get(0)); diff --git a/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java b/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java index eb4f63d4f39..debbe49a8b3 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java @@ -156,7 +156,7 @@ public void testLandmarkStorageAndRouting() { assertEquals(expectedPath.getWeight(), path.getWeight(), .1); assertEquals(expectedPath.calcNodes(), path.calcNodes()); - assertEquals(expectedAlgo.getVisitedNodes() - 135, oneDirAlgoWithLandmarks.getVisitedNodes()); + assertEquals(expectedAlgo.getVisitedNodes() - 72, oneDirAlgoWithLandmarks.getVisitedNodes()); // landmarks with bidir A* RoutingAlgorithm biDirAlgoWithLandmarks = new LMRoutingAlgorithmFactory(lms).createAlgo(graph, weighting, @@ -164,7 +164,7 @@ public void testLandmarkStorageAndRouting() { path = biDirAlgoWithLandmarks.calcPath(41, 183); assertEquals(expectedPath.getWeight(), path.getWeight(), .1); assertEquals(expectedPath.calcNodes(), path.calcNodes()); - assertEquals(expectedAlgo.getVisitedNodes() - 162, biDirAlgoWithLandmarks.getVisitedNodes()); + assertEquals(expectedAlgo.getVisitedNodes() - 99, biDirAlgoWithLandmarks.getVisitedNodes()); // landmarks with A* and a QueryGraph. We expect slightly less optimal as two more cycles needs to be traversed // due to the two more virtual nodes but this should not harm in practise @@ -179,7 +179,7 @@ public void testLandmarkStorageAndRouting() { expectedPath = expectedAlgo.calcPath(fromSnap.getClosestNode(), toSnap.getClosestNode()); assertEquals(expectedPath.getWeight(), path.getWeight(), .1); assertEquals(expectedPath.calcNodes(), path.calcNodes()); - assertEquals(expectedAlgo.getVisitedNodes() - 135, qGraphOneDirAlgo.getVisitedNodes()); + assertEquals(expectedAlgo.getVisitedNodes() - 72, qGraphOneDirAlgo.getVisitedNodes()); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java index 625784a0732..da3740f2a84 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java @@ -45,8 +45,8 @@ public class FastestWeightingTest { @Test public void testMinWeightHasSameUnitAs_getWeight() { - Weighting instance = new FastestWeighting(encoder); IntsRef flags = GHUtility.setSpeed(encoder.getMaxSpeed(), 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags()); + Weighting instance = new FastestWeighting(encoder); assertEquals(instance.getMinWeight(10), instance.calcEdgeWeight(createMockedEdgeIteratorState(10, flags), false), 1e-8); } diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index abda7281a49..b07e51ae824 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -248,8 +248,8 @@ public void testMaxSpeed() { addToSpeed(If("true", LIMIT, "72")).setDistanceInfluence(0)).getMinWeight(1000)); // ignore too big limit to let custom model compatibility not break when max speed of encoder later decreases - assertEquals(1000.0 / 140 * 3.6, createWeighting(new CustomModel(). - addToSpeed(If("true", LIMIT, "150")).setDistanceInfluence(0)).getMinWeight(1000)); + assertEquals(1000.0 / 155 * 3.6, createWeighting(new CustomModel(). + addToSpeed(If("true", LIMIT, "180")).setDistanceInfluence(0)).getMinWeight(1000)); // a speed bigger than the allowed stored speed is fine, see discussion in #2335 assertEquals(1000.0 / 150 * 3.6, createWeighting(new CustomModel(). @@ -259,27 +259,28 @@ public void testMaxSpeed() { @Test public void testMaxPriority() { - assertEquals(1000.0 / 140 / 0.5 * 3.6, createWeighting(new CustomModel(). - addToPriority(If("true", MULTIPLY, "0.5")).setDistanceInfluence(0)).getMinWeight(1000)); + double maxSpeed = 155; + assertEquals(1000.0 / maxSpeed / 0.5 * 3.6, createWeighting(new CustomModel(). + addToPriority(If("true", MULTIPLY, "0.5")).setDistanceInfluence(0)).getMinWeight(1000), 1.e-6); // ignore too big limit - assertEquals(1000.0 / 140 / 1.0 * 3.6, createWeighting(new CustomModel(). - addToPriority(If("true", LIMIT, "2.0")).setDistanceInfluence(0)).getMinWeight(1000)); + assertEquals(1000.0 / maxSpeed / 1.0 * 3.6, createWeighting(new CustomModel(). + addToPriority(If("true", LIMIT, "2.0")).setDistanceInfluence(0)).getMinWeight(1000), 1.e-6); // priority bigger 1 is fine (if CustomModel not in query) - assertEquals(1000.0 / 140 / 2.0 * 3.6, createWeighting(new CustomModel(). + assertEquals(1000.0 / maxSpeed / 2.0 * 3.6, createWeighting(new CustomModel(). addToPriority(If("true", MULTIPLY, "3.0")). - addToPriority(If("true", LIMIT, "2.0")).setDistanceInfluence(0)).getMinWeight(1000)); - assertEquals(1000.0 / 140 / 1.5 * 3.6, createWeighting(new CustomModel(). - addToPriority(If("true", MULTIPLY, "1.5")).setDistanceInfluence(0)).getMinWeight(1000)); + addToPriority(If("true", LIMIT, "2.0")).setDistanceInfluence(0)).getMinWeight(1000), 1.e-6); + assertEquals(1000.0 / maxSpeed / 1.5 * 3.6, createWeighting(new CustomModel(). + addToPriority(If("true", MULTIPLY, "1.5")).setDistanceInfluence(0)).getMinWeight(1000), 1.e-6); // pick maximum priority from value even if this is for a special case - assertEquals(1000.0 / 140 / 3.0 * 3.6, createWeighting(new CustomModel(). - addToPriority(If("road_class == SERVICE", MULTIPLY, "3.0")).setDistanceInfluence(0)).getMinWeight(1000)); + assertEquals(1000.0 / maxSpeed / 3.0 * 3.6, createWeighting(new CustomModel(). + addToPriority(If("road_class == SERVICE", MULTIPLY, "3.0")).setDistanceInfluence(0)).getMinWeight(1000), 1.e-6); // do NOT pick maximum priority when it is for a special case - assertEquals(1000.0 / 140 / 1.0 * 3.6, createWeighting(new CustomModel(). - addToPriority(If("road_class == SERVICE", MULTIPLY, "0.5")).setDistanceInfluence(0)).getMinWeight(1000)); + assertEquals(1000.0 / maxSpeed / 1.0 * 3.6, createWeighting(new CustomModel(). + addToPriority(If("road_class == SERVICE", MULTIPLY, "0.5")).setDistanceInfluence(0)).getMinWeight(1000), 1.e-6); } @Test diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java index 1fb4b40283b..5d69cc6eed7 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GraphHopperGtfs.java @@ -56,6 +56,7 @@ protected void importOSM() { super.importOSM(); } else { createBaseGraphAndProperties(); + writeEncodingManagerToProperties(); } } From b0ed2d822760abd47c34730318f6dc51b281b948 Mon Sep 17 00:00:00 2001 From: Andi Date: Thu, 30 Jun 2022 13:17:32 +0200 Subject: [PATCH 077/389] Rename getMin/MaxInt -> getMin/MaxStorableInt, getMaxSetValueOrMax -> getMaxOrMaxStorable (#2616) --- .../routing/ev/DecimalEncodedValue.java | 10 +-- .../routing/ev/DecimalEncodedValueImpl.java | 54 ++++++++-------- .../routing/ev/EnumEncodedValue.java | 6 +- .../routing/ev/IntEncodedValue.java | 6 +- .../routing/ev/IntEncodedValueImpl.java | 62 +++++++++---------- .../routing/ev/SimpleBooleanEncodedValue.java | 6 +- .../routing/ev/StringEncodedValue.java | 6 +- .../parsers/helpers/OSMValueExtractor.java | 36 +++++------ .../routing/weighting/CurvatureWeighting.java | 2 +- .../routing/weighting/FastestWeighting.java | 2 +- .../weighting/custom/CustomModelParser.java | 4 +- .../custom/ValueExpressionVisitor.java | 8 +-- .../java/com/graphhopper/util/Constants.java | 2 +- .../ev/DecimalEncodedValueImplTest.java | 10 +-- .../ev/EncodedValueSerializerTest.java | 6 +- .../parsers/OSMMaxAxleLoadParserTest.java | 2 +- .../util/parsers/OSMMaxWeightParserTest.java | 2 +- 17 files changed, 112 insertions(+), 112 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java index 1a066ecec1c..ffa890274c6 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValue.java @@ -15,7 +15,7 @@ public interface DecimalEncodedValue extends EncodedValue { /** * This method stores the specified double value (rounding with a previously defined factor) into the IntsRef. * - * @see #getMaxDecimal() + * @see #getMaxStorableDecimal() */ void setDecimal(boolean reverse, IntsRef ref, double value); @@ -24,17 +24,17 @@ public interface DecimalEncodedValue extends EncodedValue { /** * The maximum double value this EncodedValue accepts for setDecimal without throwing an exception. */ - double getMaxDecimal(); + double getMaxStorableDecimal(); /** * The minimum double value this EncodedValue accepts for setDecimal without throwing an exception. */ - double getMinDecimal(); + double getMinStorableDecimal(); /** - * @see IntEncodedValue#getMaxSetValueOrMaxInt() + * @see IntEncodedValue#getMaxOrMaxStorableInt() */ - double getMaxSetValueOrMaxDecimal(); + double getMaxOrMaxStorableDecimal(); /** * @return the smallest decimal value that is larger or equal to the given value and that can be stored exactly, diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java index c137a401979..72a33341030 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java @@ -48,7 +48,7 @@ public DecimalEncodedValueImpl(String name, int bits, double factor, boolean def * @param name the key to identify this EncodedValue * @param bits the bits that should be reserved for storing the integer value. This determines the * maximum value. - * @param minValue the minimum value. Use e.g. 0 if no negative values are needed. + * @param minStorableValue the minimum storable value. Use e.g. 0 if no negative values are needed. * @param factor the precision factor, i.e. store = (int) Math.round(value / factor) * @param defaultIsInfinity true if default should be Double.Infinity. False if 0 should be default. * @param negateReverseDirection true if the reverse direction should be always negative of the forward direction. @@ -56,26 +56,26 @@ public DecimalEncodedValueImpl(String name, int bits, double factor, boolean def * @param storeTwoDirections true if forward and backward direction of the edge should get two independent values. * @param useMaximumAsInfinity true if the maximum value should be treated as Double.Infinity */ - public DecimalEncodedValueImpl(String name, int bits, double minValue, double factor, boolean defaultIsInfinity, + public DecimalEncodedValueImpl(String name, int bits, double minStorableValue, double factor, boolean defaultIsInfinity, boolean negateReverseDirection, boolean storeTwoDirections, boolean useMaximumAsInfinity) { - super(name, bits, (int) Math.round(minValue / factor), negateReverseDirection, storeTwoDirections); - if (!negateReverseDirection && super.minValue * factor != minValue) - throw new IllegalArgumentException("minValue " + minValue + " is not a multiple of the specified factor " + factor); + super(name, bits, (int) Math.round(minStorableValue / factor), negateReverseDirection, storeTwoDirections); + if (!negateReverseDirection && super.minStorableValue * factor != minStorableValue) + throw new IllegalArgumentException("minStorableValue " + minStorableValue + " is not a multiple of the specified factor " + factor); this.factor = factor; this.defaultIsInfinity = defaultIsInfinity; this.useMaximumAsInfinity = useMaximumAsInfinity; if (useMaximumAsInfinity && defaultIsInfinity) throw new IllegalArgumentException("defaultIsInfinity and useMaximumAsInfinity cannot be both true"); - if (defaultIsInfinity && minValue < 0) - throw new IllegalArgumentException("defaultIsInfinity cannot be true when minValue is negative"); + if (defaultIsInfinity && minStorableValue < 0) + throw new IllegalArgumentException("defaultIsInfinity cannot be true when minStorableValue is negative"); } @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) DecimalEncodedValueImpl(@JsonProperty("name") String name, @JsonProperty("bits") int bits, - @JsonProperty("min_value") int minValue, + @JsonProperty("min_storable_value") int minStorableValue, + @JsonProperty("max_storable_value") int maxStorableValue, @JsonProperty("max_value") int maxValue, - @JsonProperty("max_set_value") int maxSetValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, @JsonProperty("fwd_data_index") int fwdDataIndex, @@ -88,7 +88,7 @@ public DecimalEncodedValueImpl(String name, int bits, double minValue, double fa @JsonProperty("default_is_infinity") boolean defaultIsInfinity, @JsonProperty("use_maximum_as_infinity") boolean useMaximumAsInfinity) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, maxSetValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); + super(name, bits, minStorableValue, maxStorableValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); this.factor = factor; this.defaultIsInfinity = defaultIsInfinity; this.useMaximumAsInfinity = useMaximumAsInfinity; @@ -100,7 +100,7 @@ public void setDecimal(boolean reverse, IntsRef ref, double value) { throw new IllegalStateException("Call init before using EncodedValue " + getName()); if (Double.isInfinite(value)) { if (useMaximumAsInfinity) { - super.setInt(reverse, ref, maxValue); + super.setInt(reverse, ref, maxStorableValue); return; } else if (defaultIsInfinity) { super.setInt(reverse, ref, 0); @@ -112,10 +112,10 @@ public void setDecimal(boolean reverse, IntsRef ref, double value) { throw new IllegalArgumentException("NaN value for " + getName() + " not allowed!"); value /= factor; - if (value > maxValue) - throw new IllegalArgumentException(getName() + " value too large for encoding: " + value + ", maxValue:" + maxValue + ", factor: " + factor); - if (value < minValue) - throw new IllegalArgumentException(getName() + " value too small for encoding " + value + ", minValue:" + minValue + ", factor: " + factor); + if (value > maxStorableValue) + throw new IllegalArgumentException(getName() + " value too large for encoding: " + value + ", maxValue:" + maxStorableValue + ", factor: " + factor); + if (value < minStorableValue) + throw new IllegalArgumentException(getName() + " value too small for encoding " + value + ", minValue:" + minStorableValue + ", factor: " + factor); super.uncheckedSet(reverse, ref, (int) Math.round(value)); } @@ -123,16 +123,16 @@ public void setDecimal(boolean reverse, IntsRef ref, double value) { @Override public double getDecimal(boolean reverse, IntsRef ref) { int value = getInt(reverse, ref); - if (useMaximumAsInfinity && value == maxValue || defaultIsInfinity && value == 0) + if (useMaximumAsInfinity && value == maxStorableValue || defaultIsInfinity && value == 0) return Double.POSITIVE_INFINITY; return value * factor; } @Override public double getNextStorableValue(double value) { - if (!useMaximumAsInfinity && value > getMaxDecimal()) - throw new IllegalArgumentException(getName() + ": There is no next storable value for " + value + ". max:" + getMaxDecimal()); - else if (useMaximumAsInfinity && value > getMaxDecimal()) + if (!useMaximumAsInfinity && value > getMaxStorableDecimal()) + throw new IllegalArgumentException(getName() + ": There is no next storable value for " + value + ". max:" + getMaxStorableDecimal()); + else if (useMaximumAsInfinity && value > getMaxStorableDecimal()) return Double.POSITIVE_INFINITY; else return (factor * (int) Math.ceil(value / factor)); @@ -140,25 +140,25 @@ else if (useMaximumAsInfinity && value > getMaxDecimal()) @Override public double getSmallestNonZeroValue() { - if (minValue != 0 || negateReverseDirection) + if (minStorableValue != 0 || negateReverseDirection) throw new IllegalStateException("getting the smallest non-zero value is not possible if minValue!=0 or negateReverseDirection"); return factor; } @Override - public double getMaxDecimal() { - return maxValue * factor; + public double getMaxStorableDecimal() { + return maxStorableValue * factor; } @Override - public double getMinDecimal() { - return minValue * factor; + public double getMinStorableDecimal() { + return minStorableValue * factor; } @Override - public double getMaxSetValueOrMaxDecimal() { + public double getMaxOrMaxStorableDecimal() { if (useMaximumAsInfinity || defaultIsInfinity) - throw new IllegalStateException("getMaxSetValueOrMaxDecimal() is not implemented for useMaximumAsInfinity or defaultIsInfinity"); - return getMaxSetValueOrMaxInt() * factor; + throw new IllegalStateException("getMaxOrMaxStorableDecimal() is not implemented for useMaximumAsInfinity or defaultIsInfinity"); + return getMaxOrMaxStorableInt() * factor; } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java index c114a2bfffa..9716a59edd0 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/EnumEncodedValue.java @@ -44,9 +44,9 @@ public EnumEncodedValue(String name, Class enumType, boolean storeTwoDirectio @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) EnumEncodedValue(@JsonProperty("name") String name, @JsonProperty("bits") int bits, - @JsonProperty("min_value") int minValue, + @JsonProperty("min_storable_value") int minStorableValue, + @JsonProperty("max_storable_value") int maxStorableValue, @JsonProperty("max_value") int maxValue, - @JsonProperty("max_set_value") int maxSetValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, @JsonProperty("fwd_data_index") int fwdDataIndex, @@ -57,7 +57,7 @@ public EnumEncodedValue(String name, Class enumType, boolean storeTwoDirectio @JsonProperty("bwd_mask") int bwdMask, @JsonProperty("enum_type") Class enumType) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, maxSetValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); + super(name, bits, minStorableValue, maxStorableValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); this.enumType = enumType; arr = enumType.getEnumConstants(); } diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java index 6334e066d74..1157aec1338 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValue.java @@ -24,12 +24,12 @@ public interface IntEncodedValue extends EncodedValue { /** * The maximum int value this EncodedValue accepts for setInt without throwing an exception. */ - int getMaxInt(); + int getMaxStorableInt(); /** * The minimum int value this EncodedValue accepts for setInt without throwing an exception. */ - int getMinInt(); + int getMinStorableInt(); /** * Returns the maximum value set using this encoded value or the physical storage limit if no value has been set @@ -37,7 +37,7 @@ public interface IntEncodedValue extends EncodedValue { * the graph if values are set multiple times for the same edge and they are decreasing. However, the returned value * will always be equal to or larger than the global maximum. */ - int getMaxSetValueOrMaxInt(); + int getMaxOrMaxStorableInt(); /** * @return true if this EncodedValue can store a different value for its reverse direction diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java index 5216cf96745..01ef38024d8 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java @@ -36,9 +36,9 @@ public class IntEncodedValueImpl implements IntEncodedValue { private final boolean storeTwoDirections; final int bits; final boolean negateReverseDirection; - final int minValue; - final int maxValue; - int maxSetValue; + final int minStorableValue; + final int maxStorableValue; + int maxValue; /** * There are multiple int values possible per edge. Here we specify the index into this integer array. @@ -63,32 +63,32 @@ public IntEncodedValueImpl(String name, int bits, boolean storeTwoDirections) { * @param name the key to identify this EncodedValue * @param bits the bits that should be reserved for storing the value. This determines the * maximum value. - * @param minValue the minimum value. Use e.g. 0 if no negative values are needed. + * @param minStorableValue the minimum value. Use e.g. 0 if no negative values are needed. * @param negateReverseDirection true if the reverse direction should be always negative of the forward direction. * This is used to reduce space and store the value only once. If this option is used * you cannot use storeTwoDirections or a minValue different to 0. * @param storeTwoDirections true if forward and backward direction of the edge should get two independent values. */ - public IntEncodedValueImpl(String name, int bits, int minValue, boolean negateReverseDirection, boolean storeTwoDirections) { + public IntEncodedValueImpl(String name, int bits, int minStorableValue, boolean negateReverseDirection, boolean storeTwoDirections) { if (!EncodingManager.isValidEncodedValue(name)) throw new IllegalArgumentException("EncodedValue name wasn't valid: " + name + ". Use lower case letters, underscore and numbers only."); if (bits <= 0) throw new IllegalArgumentException(name + ": bits cannot be zero or negative"); if (bits > 31) throw new IllegalArgumentException(name + ": at the moment the number of reserved bits cannot be more than 31"); - if (negateReverseDirection && (minValue != 0 || storeTwoDirections)) + if (negateReverseDirection && (minStorableValue != 0 || storeTwoDirections)) throw new IllegalArgumentException(name + ": negating value for reverse direction only works for minValue == 0 " + - "and !storeTwoDirections but was minValue=" + minValue + ", storeTwoDirections=" + storeTwoDirections); + "and !storeTwoDirections but was minValue=" + minStorableValue + ", storeTwoDirections=" + storeTwoDirections); this.name = name; this.storeTwoDirections = storeTwoDirections; int max = (1 << bits) - 1; // negateReverseDirection: store the negative value only once, but for that we need the same range as maxValue for negative values - this.minValue = negateReverseDirection ? -max : minValue; - this.maxValue = max + minValue; - if (minValue == Integer.MIN_VALUE) - // we do not allow this because we use this value to represent maxSetValue = untouched, i.e. no value has been set yet + this.minStorableValue = negateReverseDirection ? -max : minStorableValue; + this.maxStorableValue = max + minStorableValue; + if (minStorableValue == Integer.MIN_VALUE) + // we do not allow this because we use this value to represent maxValue = untouched, i.e. no value has been set yet throw new IllegalArgumentException(Integer.MIN_VALUE + " is not allowed for minValue"); - this.maxSetValue = Integer.MIN_VALUE; + this.maxValue = Integer.MIN_VALUE; // negateReverseDirection: we need twice the integer range, i.e. 1 more bit this.bits = negateReverseDirection ? bits + 1 : bits; this.negateReverseDirection = negateReverseDirection; @@ -97,9 +97,9 @@ public IntEncodedValueImpl(String name, int bits, int minValue, boolean negateRe @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) IntEncodedValueImpl(@JsonProperty("name") String name, @JsonProperty("bits") int bits, - @JsonProperty("min_value") int minValue, + @JsonProperty("min_storable_value") int minStorableValue, + @JsonProperty("max_storable_value") int maxStorableValue, @JsonProperty("max_value") int maxValue, - @JsonProperty("max_set_value") int maxSetValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, @JsonProperty("fwd_data_index") int fwdDataIndex, @@ -114,9 +114,9 @@ public IntEncodedValueImpl(String name, int bits, int minValue, boolean negateRe this.storeTwoDirections = storeTwoDirections; this.bits = bits; this.negateReverseDirection = negateReverseDirection; - this.minValue = minValue; + this.minStorableValue = minStorableValue; + this.maxStorableValue = maxStorableValue; this.maxValue = maxValue; - this.maxSetValue = maxSetValue; this.fwdDataIndex = fwdDataIndex; this.bwdDataIndex = bwdDataIndex; this.fwdShift = fwdShift; @@ -157,10 +157,10 @@ public final void setInt(boolean reverse, IntsRef ref, int value) { private void checkValue(int value) { if (!isInitialized()) throw new IllegalStateException("EncodedValue " + getName() + " not initialized"); - if (value > maxValue) - throw new IllegalArgumentException(name + " value too large for encoding: " + value + ", maxValue:" + maxValue); - if (value < minValue) - throw new IllegalArgumentException(name + " value too small for encoding " + value + ", minValue:" + minValue); + if (value > maxStorableValue) + throw new IllegalArgumentException(name + " value too large for encoding: " + value + ", maxValue:" + maxStorableValue); + if (value < minStorableValue) + throw new IllegalArgumentException(name + " value too small for encoding " + value + ", minValue:" + minStorableValue); } final void uncheckedSet(boolean reverse, IntsRef ref, int value) { @@ -172,9 +172,9 @@ final void uncheckedSet(boolean reverse, IntsRef ref, int value) { } else if (reverse && !storeTwoDirections) throw new IllegalArgumentException(getName() + ": value for reverse direction would overwrite forward direction. Enable storeTwoDirections for this EncodedValue or don't use setReverse"); - maxSetValue = Math.max(maxSetValue, value); + maxValue = Math.max(maxValue, value); - value -= minValue; + value -= minStorableValue; if (reverse) { int flags = ref.ints[bwdDataIndex + ref.offset]; // clear value bits @@ -193,28 +193,28 @@ public final int getInt(boolean reverse, IntsRef ref) { // if we do not store both directions ignore reverse == true for convenient reading if (storeTwoDirections && reverse) { flags = ref.ints[bwdDataIndex + ref.offset]; - return minValue + (flags & bwdMask) >>> bwdShift; + return minStorableValue + (flags & bwdMask) >>> bwdShift; } else { flags = ref.ints[fwdDataIndex + ref.offset]; if (negateReverseDirection && reverse) - return -(minValue + (flags & fwdMask) >>> fwdShift); - return minValue + (flags & fwdMask) >>> fwdShift; + return -(minStorableValue + (flags & fwdMask) >>> fwdShift); + return minStorableValue + (flags & fwdMask) >>> fwdShift; } } @Override - public int getMaxInt() { - return maxValue; + public int getMaxStorableInt() { + return maxStorableValue; } @Override - public int getMinInt() { - return minValue; + public int getMinStorableInt() { + return minStorableValue; } @Override - public int getMaxSetValueOrMaxInt() { - return maxSetValue == Integer.MIN_VALUE ? getMaxInt() : maxSetValue; + public int getMaxOrMaxStorableInt() { + return maxValue == Integer.MIN_VALUE ? getMaxStorableInt() : maxValue; } @Override diff --git a/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java index 180bada4491..f82ee30757f 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/SimpleBooleanEncodedValue.java @@ -37,9 +37,9 @@ public SimpleBooleanEncodedValue(String name, boolean storeBothDirections) { SimpleBooleanEncodedValue( @JsonProperty("name") String name, @JsonProperty("bits") int bits, - @JsonProperty("min_value") int minValue, + @JsonProperty("min_storable_value") int minStorableValue, + @JsonProperty("max_storable_value") int maxStorableValue, @JsonProperty("max_value") int maxValue, - @JsonProperty("max_set_value") int maxSetValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, @JsonProperty("fwd_data_index") int fwdDataIndex, @@ -50,7 +50,7 @@ public SimpleBooleanEncodedValue(String name, boolean storeBothDirections) { @JsonProperty("bwd_mask") int bwdMask ) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, maxSetValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); + super(name, bits, minStorableValue, maxStorableValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java b/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java index 29f58535f50..a4c9aa3bfc2 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java +++ b/core/src/main/java/com/graphhopper/routing/ev/StringEncodedValue.java @@ -50,9 +50,9 @@ public StringEncodedValue(String name, int bits, List values, boolean st StringEncodedValue( @JsonProperty("name") String name, @JsonProperty("bits") int bits, - @JsonProperty("min_value") int minValue, + @JsonProperty("min_storable_value") int minStorableValue, + @JsonProperty("max_storable_value") int maxStorableValue, @JsonProperty("max_value") int maxValue, - @JsonProperty("max_set_value") int maxSetValue, @JsonProperty("negate_reverse_direction") boolean negateReverseDirection, @JsonProperty("store_two_directions") boolean storeTwoDirections, @JsonProperty("fwd_data_index") int fwdDataIndex, @@ -65,7 +65,7 @@ public StringEncodedValue(String name, int bits, List values, boolean st @JsonProperty("values") List values, @JsonProperty("index_map") HashMap indexMap) { // we need this constructor for Jackson - super(name, bits, minValue, maxValue, maxSetValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); + super(name, bits, minStorableValue, maxStorableValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); if (values.size() > maxValues) throw new IllegalArgumentException("Number of values is higher than the maximum value count: " + values.size() + " > " + maxValues); diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java b/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java index e6951676ca4..325dd5ba0e1 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java @@ -1,10 +1,5 @@ package com.graphhopper.routing.util.parsers.helpers; -import static com.graphhopper.util.Helper.toLowerCase; - -import java.util.List; -import java.util.regex.Pattern; - import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.MaxSpeed; @@ -12,14 +7,19 @@ import com.graphhopper.util.DistanceCalcEarth; import com.graphhopper.util.Helper; +import java.util.List; +import java.util.regex.Pattern; + +import static com.graphhopper.util.Helper.toLowerCase; + public class OSMValueExtractor { - - private static final Pattern TON_PATTERN = Pattern.compile("tons?"); - private static final Pattern MGW_PATTERN = Pattern.compile("mgw"); + + private static final Pattern TON_PATTERN = Pattern.compile("tons?"); + private static final Pattern MGW_PATTERN = Pattern.compile("mgw"); private static final Pattern WSPACE_PATTERN = Pattern.compile("\\s"); - private static final Pattern METER_PATTERN = Pattern.compile("meters?|mtrs?|mt|m\\."); - private static final Pattern INCH_PATTERN = Pattern.compile("\"|\'\'"); - private static final Pattern FEET_PATTERN = Pattern.compile("\'|feet"); + private static final Pattern METER_PATTERN = Pattern.compile("meters?|mtrs?|mt|m\\."); + private static final Pattern INCH_PATTERN = Pattern.compile("\"|\'\'"); + private static final Pattern FEET_PATTERN = Pattern.compile("\'|feet"); private static final Pattern APPROX_PATTERN = Pattern.compile("~|approx"); private OSMValueExtractor() { @@ -29,13 +29,13 @@ private OSMValueExtractor() { public static void extractTons(IntsRef edgeFlags, ReaderWay way, DecimalEncodedValue valueEncoder, List keys) { final String rawValue = way.getFirstPriorityTag(keys); double value = stringToTons(rawValue); - + if (Double.isNaN(value)) { return; } - - if (value > valueEncoder.getMaxDecimal()) - value = valueEncoder.getMaxDecimal(); + + if (value > valueEncoder.getMaxStorableDecimal()) + value = valueEncoder.getMaxStorableDecimal(); valueEncoder.setDecimal(false, edgeFlags, value); } @@ -69,13 +69,13 @@ public static double stringToTons(String value) { public static void extractMeter(IntsRef edgeFlags, ReaderWay way, DecimalEncodedValue valueEncoder, List keys) { final String rawValue = way.getFirstPriorityTag(keys); double value = stringToMeter(rawValue); - + if (Double.isNaN(value)) { return; } - if (value > valueEncoder.getMaxDecimal()) - value = valueEncoder.getMaxDecimal(); + if (value > valueEncoder.getMaxStorableDecimal()) + value = valueEncoder.getMaxStorableDecimal(); valueEncoder.setDecimal(false, edgeFlags, value); } diff --git a/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java index cc313f6ca1a..c861b5d45f3 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java @@ -47,7 +47,7 @@ public CurvatureWeighting(FlagEncoder flagEncoder, PMap pMap, TurnCostProvider t curvatureEnc = flagEncoder.getDecimalEncodedValue(EncodingManager.getKey(flagEncoder, "curvature")); avSpeedEnc = flagEncoder.getDecimalEncodedValue(EncodingManager.getKey(flagEncoder, "average_speed")); double minBendiness = 1; // see correctErrors - double maxSpeed = avSpeedEnc.getMaxSetValueOrMaxDecimal(); + double maxSpeed = avSpeedEnc.getMaxOrMaxStorableDecimal(); minFactor = minBendiness / Math.log(maxSpeed) / PriorityCode.getValue(BEST.getValue()); } diff --git a/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java index 2a8cee9f718..69f54d0efb5 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java @@ -62,7 +62,7 @@ public FastestWeighting(FlagEncoder encoder, PMap map, TurnCostProvider turnCost super(encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), turnCostProvider); headingPenalty = map.getDouble(Routing.HEADING_PENALTY, Routing.DEFAULT_HEADING_PENALTY); headingPenaltyMillis = Math.round(headingPenalty * 1000); - maxSpeed = speedEnc.getMaxSetValueOrMaxDecimal() / SPEED_CONV; + maxSpeed = speedEnc.getMaxOrMaxStorableDecimal() / SPEED_CONV; if (!encoder.hasEncodedValue(RoadAccess.KEY)) throw new IllegalArgumentException("road_access is not available but expected for FastestWeighting"); diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java index 1e0118eb6e6..7e419eb4002 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java @@ -76,7 +76,7 @@ public static CustomWeighting createWeighting(FlagEncoder baseFlagEncoder, Encod final String pKey = EncodingManager.getKey(baseFlagEncoder.toString(), "priority"); DecimalEncodedValue priorityEnc = lookup.hasEncodedValue(pKey) ? lookup.getDecimalEncodedValue(pKey) : null; - double maxSpeed = avgSpeedEnc.getMaxSetValueOrMaxDecimal(); + double maxSpeed = avgSpeedEnc.getMaxOrMaxStorableDecimal(); CustomWeighting.Parameters parameters = createWeightingParameters(customModel, lookup, avgSpeedEnc, maxSpeed, priorityEnc); return new CustomWeighting(baseFlagEncoder.getAccessEnc(), baseFlagEncoder.getAverageSpeedEnc(), turnCostProvider, parameters); @@ -92,7 +92,7 @@ static CustomWeighting.Parameters createWeightingParameters(CustomModel customMo DecimalEncodedValue avgSpeedEnc, double globalMaxSpeed, DecimalEncodedValue priorityEnc) { - double globalMaxPriority = priorityEnc == null ? 1 : priorityEnc.getMaxDecimal(); + double globalMaxPriority = priorityEnc == null ? 1 : priorityEnc.getMaxStorableDecimal(); // if the same custom model is used with a different base profile we cannot use the cached version String key = customModel + ",speed:" + avgSpeedEnc.getName() + ",global_max_speed:" + globalMaxSpeed + (priorityEnc == null ? "" : "prio:" + priorityEnc.getName() + ",global_max_priority:" + globalMaxPriority); diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitor.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitor.java index 9318c74a1e7..82e8cb0a157 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitor.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/ValueExpressionVisitor.java @@ -167,14 +167,14 @@ static MinMax findMinMax(Set createdObjects, String valueExpression, Enc } static double getMin(EncodedValue enc) { - if (enc instanceof DecimalEncodedValue) return ((DecimalEncodedValue) enc).getMinDecimal(); - else if (enc instanceof IntEncodedValue) return ((IntEncodedValue) enc).getMinInt(); + if (enc instanceof DecimalEncodedValue) return ((DecimalEncodedValue) enc).getMinStorableDecimal(); + else if (enc instanceof IntEncodedValue) return ((IntEncodedValue) enc).getMinStorableInt(); throw new IllegalArgumentException("Cannot use non-number data '" + enc.getName() + "' in value expression"); } static double getMax(EncodedValue enc) { - if (enc instanceof DecimalEncodedValue) return ((DecimalEncodedValue) enc).getMaxDecimal(); - else if (enc instanceof IntEncodedValue) return ((IntEncodedValue) enc).getMaxInt(); + if (enc instanceof DecimalEncodedValue) return ((DecimalEncodedValue) enc).getMaxStorableDecimal(); + else if (enc instanceof IntEncodedValue) return ((IntEncodedValue) enc).getMaxStorableInt(); throw new IllegalArgumentException("Cannot use non-number data '" + enc.getName() + "' in value expression"); } } diff --git a/core/src/main/java/com/graphhopper/util/Constants.java b/core/src/main/java/com/graphhopper/util/Constants.java index 7ebfa321af0..e233e3a9669 100644 --- a/core/src/main/java/com/graphhopper/util/Constants.java +++ b/core/src/main/java/com/graphhopper/util/Constants.java @@ -69,7 +69,7 @@ public class Constants { public static final int VERSION_NODE = 9; public static final int VERSION_EDGE = 21; // this should be increased whenever the format of the serialized EncodingManager is changed - public static final int VERSION_EM = 0; + public static final int VERSION_EM = 1; public static final int VERSION_SHORTCUT = 9; public static final int VERSION_NODE_CH = 0; public static final int VERSION_GEOMETRY = 6; diff --git a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java index 2e0343a2234..340f3adbfe8 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java @@ -60,7 +60,7 @@ public void testNegative() { Exception e = assertThrows(IllegalArgumentException.class, () -> { new DecimalEncodedValueImpl("test", 3, -6, 0.11, false, false, false, true); }); - assertTrue(e.getMessage().contains("minValue -6.0 is not a multiple of the specified factor"), e.getMessage()); + assertTrue(e.getMessage().contains("minStorableValue -6.0 is not a multiple of the specified factor"), e.getMessage()); } @Test @@ -164,17 +164,17 @@ public void testNextStorableValue_maxInfinity() { public void lowestUpperBound_with_negateReverseDirection() { DecimalEncodedValueImpl enc = new DecimalEncodedValueImpl("test", 4, 0, 3, false, true, false, false); enc.init(new EncodedValue.InitializerConfig()); - assertEquals(15 * 3, enc.getMaxSetValueOrMaxDecimal()); + assertEquals(15 * 3, enc.getMaxOrMaxStorableDecimal()); IntsRef ints = new IntsRef(1); enc.setDecimal(false, ints, 3); assertEquals(3, enc.getDecimal(false, ints)); - assertEquals(3, enc.getMaxSetValueOrMaxDecimal()); + assertEquals(3, enc.getMaxOrMaxStorableDecimal()); enc.setDecimal(true, ints, -6); assertEquals(6, enc.getDecimal(false, ints)); - assertEquals(6, enc.getMaxSetValueOrMaxDecimal()); + assertEquals(6, enc.getMaxOrMaxStorableDecimal()); // note that the maximum is never lowered, even when we lower the value for the 'same' edge flags enc.setDecimal(false, ints, 0); assertEquals(0, enc.getDecimal(false, ints)); - assertEquals(6, enc.getMaxSetValueOrMaxDecimal()); + assertEquals(6, enc.getMaxOrMaxStorableDecimal()); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java b/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java index 211f11024b2..d2c2b485ced 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java @@ -73,14 +73,14 @@ void explicitString() { List serialized = evs.stream().map(EncodedValueSerializer::serializeEncodedValue).collect(Collectors.toList()); assertEquals("{\"className\":\"com.graphhopper.routing.ev.IntEncodedValueImpl\",\"name\":\"lanes\",\"bits\":3," + - "\"min_value\":0,\"max_value\":7,\"max_set_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false," + + "\"min_storable_value\":0,\"max_storable_value\":7,\"max_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false," + "\"fwd_data_index\":0,\"bwd_data_index\":0,\"fwd_shift\":0,\"bwd_shift\":-1,\"fwd_mask\":7,\"bwd_mask\":0}", serialized.get(0)); assertEquals("{\"className\":\"com.graphhopper.routing.ev.DecimalEncodedValueImpl\",\"name\":\"max_width\",\"bits\":7," + - "\"min_value\":0,\"max_value\":127,\"max_set_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false," + + "\"min_storable_value\":0,\"max_storable_value\":127,\"max_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false," + "\"fwd_data_index\":0,\"bwd_data_index\":0,\"fwd_shift\":3,\"bwd_shift\":-1,\"fwd_mask\":1016,\"bwd_mask\":0," + "\"factor\":0.1,\"default_is_infinity\":true,\"use_maximum_as_infinity\":false}", serialized.get(1)); assertEquals("{\"className\":\"com.graphhopper.routing.ev.SimpleBooleanEncodedValue\",\"name\":\"get_off_bike\",\"bits\":1," + - "\"min_value\":0,\"max_value\":1,\"max_set_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false,\"fwd_data_index\":0," + + "\"min_storable_value\":0,\"max_storable_value\":1,\"max_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false,\"fwd_data_index\":0," + "\"bwd_data_index\":0,\"fwd_shift\":10,\"bwd_shift\":-1,\"fwd_mask\":1024,\"bwd_mask\":0}", serialized.get(2)); EncodedValue ev0 = EncodedValueSerializer.deserializeEncodedValue(serialized.get(0)); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java index c32fc2ff857..380345e5a28 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java @@ -35,7 +35,7 @@ public void testSimpleTags() { intsRef = new IntsRef(1); readerWay.setTag("maxaxleload", "80"); parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(malEnc.getMaxDecimal(), malEnc.getDecimal(false, intsRef), .01); + assertEquals(malEnc.getMaxStorableDecimal(), malEnc.getDecimal(false, intsRef), .01); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java index 92d2be6a918..759f73aa3e4 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java @@ -36,6 +36,6 @@ public void testSimpleTags() { intsRef = new IntsRef(1); readerWay.setTag("maxweight", "50"); parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(mwEnc.getMaxDecimal(), mwEnc.getDecimal(false, intsRef), .01); + assertEquals(mwEnc.getMaxStorableDecimal(), mwEnc.getDecimal(false, intsRef), .01); } } \ No newline at end of file From 7a59ffbf6b30b742bfb60e2a7b4160e42173d986 Mon Sep 17 00:00:00 2001 From: Andi Date: Thu, 30 Jun 2022 21:34:26 +0200 Subject: [PATCH 078/389] Remove FlagEncoder#getMaxSpeed() (#2619) --- .../util/DefaultFlagEncoderFactory.java | 11 +-- .../graphhopper/routing/util/FlagEncoder.java | 5 - .../routing/util/VehicleEncodedValues.java | 30 ++---- .../routing/DijkstraBidirectionCHTest.java | 9 +- .../com/graphhopper/routing/PathTest.java | 94 +++++++++---------- .../routing/PriorityRoutingTest.java | 17 ++-- .../routing/util/FootTagParserTest.java | 3 +- .../weighting/FastestWeightingTest.java | 2 +- .../custom/CustomModelParserTest.java | 38 ++++---- .../weighting/custom/CustomWeightingTest.java | 6 +- .../storage/index/LocationIndexTreeTest.java | 24 +++-- 11 files changed, 110 insertions(+), 129 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java index c55c424416a..7791fb89688 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java @@ -71,19 +71,18 @@ public FlagEncoder createFlagEncoder(String name, PMap configuration) { @Override public FlagEncoder deserializeFlagEncoder(String serializedFlagEncoder, Function evLookup) { String[] strings = serializedFlagEncoder.split("\\|"); - if (strings.length != 9) - throw new IllegalStateException("Deserialized FlagEncoders should consist of nine pipe-separated strings"); + if (strings.length != 8) + throw new IllegalStateException("Deserialized FlagEncoders should consist of eight pipe-separated strings"); String name = strings[0]; BooleanEncodedValue accessEnc = strings[1].equals("null") ? null : (BooleanEncodedValue) evLookup.apply(strings[1]); DecimalEncodedValue avgSpeedEnc = strings[2].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[2]); DecimalEncodedValue priorityEnc = strings[3].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[3]); DecimalEncodedValue curvatureEnc = strings[4].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[4]); DecimalEncodedValue turnCostEnc = strings[5].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[5]); - double maxPossibleSpeed = Double.parseDouble(strings[6]); - boolean isMotorVehicle = Boolean.parseBoolean(strings[7]); - boolean isHGV = Boolean.parseBoolean(strings[8]); + boolean isMotorVehicle = Boolean.parseBoolean(strings[6]); + boolean isHGV = Boolean.parseBoolean(strings[7]); return new VehicleEncodedValues( - name, accessEnc, avgSpeedEnc, priorityEnc, curvatureEnc, turnCostEnc, maxPossibleSpeed, isMotorVehicle, isHGV + name, accessEnc, avgSpeedEnc, priorityEnc, curvatureEnc, turnCostEnc, isMotorVehicle, isHGV ); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java index 4d1de1f65b2..72359cd4073 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java +++ b/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java @@ -35,11 +35,6 @@ public interface FlagEncoder extends EncodedValueLookup { boolean isHGV(); - /** - * @return the maximum speed in km/h - */ - double getMaxSpeed(); - /** * This method returns the EncodedValue used for the direction-dependent access properties of this encoder. */ diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index b9f90151209..8a0918b1365 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -25,18 +25,12 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static com.graphhopper.routing.util.BikeCommonTagParser.BIKE_MAX_SPEED; -import static com.graphhopper.routing.util.CarTagParser.CAR_MAX_SPEED; import static com.graphhopper.routing.util.EncodingManager.getKey; -import static com.graphhopper.routing.util.FootTagParser.FERRY_SPEED; -import static com.graphhopper.routing.util.MotorcycleTagParser.MOTOR_CYCLE_MAX_SPEED; -import static com.graphhopper.routing.util.RoadsTagParser.ROADS_MAX_SPEED; public class VehicleEncodedValues implements FlagEncoder { private final String name; private final boolean isMotorVehicle; private final boolean isHGV; - private final double maxPossibleSpeed; private final BooleanEncodedValue accessEnc; private final DecimalEncodedValue avgSpeedEnc; private final DecimalEncodedValue priorityEnc; @@ -50,12 +44,11 @@ public static VehicleEncodedValues foot(PMap properties) { double speedFactor = properties.getDouble("speed_factor", 1); boolean speedTwoDirections = properties.getBool("speed_two_directions", false); int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); - double maxSpeed = properties.getDouble("max_speed", FERRY_SPEED); BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), false, false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, false, false); } public static VehicleEncodedValues hike(PMap properties) { @@ -77,12 +70,11 @@ public static VehicleEncodedValues bike(PMap properties) { double speedFactor = properties.getDouble("speed_factor", 2); boolean speedTwoDirections = properties.getBool("speed_two_directions", false); int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); - double maxSpeed = properties.getDouble("max_speed", BIKE_MAX_SPEED); BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), false, false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, false, false); } public static VehicleEncodedValues bike2(PMap properties) { @@ -108,11 +100,10 @@ public static VehicleEncodedValues car(PMap properties) { double speedFactor = properties.getDouble("speed_factor", 5); boolean speedTwoDirections = properties.getBool("speed_two_directions", false); int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); - double maxSpeed = properties.getDouble("max_speed", CAR_MAX_SPEED); BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), true, false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, true, false); } public static VehicleEncodedValues car4wd(PMap properties) { @@ -125,13 +116,12 @@ public static VehicleEncodedValues motorcycle(PMap properties) { double speedFactor = properties.getDouble("speed_factor", 5); boolean speedTwoDirections = properties.getBool("speed_two_directions", true); int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); - double maxSpeed = properties.getDouble("max_speed", MOTOR_CYCLE_MAX_SPEED); BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); DecimalEncodedValue curvatureEnc = new DecimalEncodedValueImpl(getKey(name, "curvature"), 4, 0.1, false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, curvatureEnc, turnCostEnc, speedEnc.getNextStorableValue(maxSpeed), true, false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, curvatureEnc, turnCostEnc, true, false); } public static VehicleEncodedValues roads(PMap properties) { @@ -145,19 +135,18 @@ public static VehicleEncodedValues roads(PMap properties) { DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; boolean isMotorVehicle = properties.getBool("is_motor_vehicle", true); boolean isHGV = properties.getBool("is_hgv", false); - return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, speedEnc.getNextStorableValue(ROADS_MAX_SPEED), isMotorVehicle, isHGV); + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, isMotorVehicle, isHGV); } public VehicleEncodedValues(String name, BooleanEncodedValue accessEnc, DecimalEncodedValue avgSpeedEnc, DecimalEncodedValue priorityEnc, DecimalEncodedValue curvatureEnc, - DecimalEncodedValue turnCostEnc, double maxPossibleSpeed, boolean isMotorVehicle, boolean isHGV) { + DecimalEncodedValue turnCostEnc, boolean isMotorVehicle, boolean isHGV) { this.name = name; this.accessEnc = accessEnc; this.avgSpeedEnc = avgSpeedEnc; this.priorityEnc = priorityEnc; this.curvatureEnc = curvatureEnc; this.turnCostEnc = turnCostEnc; - this.maxPossibleSpeed = maxPossibleSpeed; this.isMotorVehicle = isMotorVehicle; this.isHGV = isHGV; } @@ -187,11 +176,6 @@ public void createTurnCostEncodedValues(List registerNewTurnCostEn registerNewTurnCostEncodedValues.add(turnCostEnc); } - @Override - public double getMaxSpeed() { - return maxPossibleSpeed; - } - @Override public BooleanEncodedValue getAccessEnc() { return accessEnc; @@ -224,7 +208,7 @@ public String toSerializationString() { Stream.of(accessEnc, avgSpeedEnc, priorityEnc, curvatureEnc, turnCostEnc) .map(ev -> ev == null ? "null" : ev.getName()) .collect(Collectors.joining("|")), - String.valueOf(maxPossibleSpeed), String.valueOf(isMotorVehicle), String.valueOf(isHGV)); + String.valueOf(isMotorVehicle), String.valueOf(isHGV)); } @Override diff --git a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java index 5c7fb6c11a5..8add6fd6ecd 100644 --- a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java @@ -20,13 +20,11 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory; import com.graphhopper.routing.ch.PrepareContractionHierarchies; -import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.storage.*; -import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -178,11 +176,8 @@ public void testDirectionDependentSpeedBwdSearch() { private void runTestWithDirectionDependentEdgeSpeed(double speed, double revSpeed, int from, int to, IntArrayList expectedPath, FlagEncoder encoder) { BaseGraph graph = createGHStorage(); - EdgeIteratorState edge = GHUtility.setSpeed(encoder.getMaxSpeed() / 2, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(2)); - DecimalEncodedValue avSpeedEnc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(encoder, "average_speed")); - edge.set(avSpeedEnc, speed, revSpeed); - - GHUtility.setSpeed(encoder.getMaxSpeed() / 2, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(speed, revSpeed, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(2)); + GHUtility.setSpeed(20, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(1)); graph.freeze(); FastestWeighting weighting = new FastestWeighting(encoder); CHConfig chConfig = CHConfig.nodeBased(weighting.getName(), weighting); diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index 1f788bfecf7..9676e38f9c6 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -48,10 +48,14 @@ public class PathTest { private final EncodingManager carManager = EncodingManager.create(encoder); private final BooleanEncodedValue carAccessEnc = encoder.getAccessEnc(); private final DecimalEncodedValue carAvSpeedEnc = encoder.getAverageSpeedEnc(); - private final EncodingManager mixedEncoders = EncodingManager.create(FlagEncoders.createCar(), FlagEncoders.createFoot()); + private final EncodingManager mixedEncodingManager = EncodingManager.create(FlagEncoders.createCar(), FlagEncoders.createFoot()); + private final BooleanEncodedValue mixedCarAccessEnc = mixedEncodingManager.getEncoder("car").getAccessEnc(); + private final DecimalEncodedValue mixedCarSpeedEnc = mixedEncodingManager.getEncoder("car").getAverageSpeedEnc(); + private final BooleanEncodedValue mixedFootAccessEnc = mixedEncodingManager.getEncoder("foot").getAccessEnc(); + private final DecimalEncodedValue mixedFootSpeedEnc = mixedEncodingManager.getEncoder("foot").getAverageSpeedEnc(); private final TranslationMap trMap = TranslationMapTest.SINGLETON; private final Translation tr = trMap.getWithFallBack(Locale.US); - private final RoundaboutGraph roundaboutGraph = new RoundaboutGraph(mixedEncoders); + private final RoundaboutGraph roundaboutGraph = new RoundaboutGraph(); private final Graph pathDetailGraph = generatePathDetailsGraph(); @Test @@ -208,13 +212,13 @@ public void testFindInstruction() { */ @Test public void testCalcInstructionsRoundabout() { - for (FlagEncoder encoder : mixedEncoders.fetchEdgeEncoders()) { + for (FlagEncoder encoder : mixedEncodingManager.fetchEdgeEncoders()) { ShortestWeighting weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 8); assertTrue(p.isFound()); assertEquals("[1, 2, 3, 4, 5, 8]", p.calcNodes().toString()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); // Test instructions List tmpList = getTurnDescriptions(wayList); assertEquals(Arrays.asList("continue onto MainStreet 1 2", @@ -229,7 +233,7 @@ public void testCalcInstructionsRoundabout() { // case of continuing a street through a roundabout p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED). calcPath(1, 7); - wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); tmpList = getTurnDescriptions(wayList); assertEquals(Arrays.asList("continue onto MainStreet 1 2", "At roundabout, take exit 2 onto MainStreet 4 7", @@ -244,12 +248,12 @@ public void testCalcInstructionsRoundabout() { @Test public void testCalcInstructionsRoundaboutBegin() { - FlagEncoder encoder = mixedEncoders.getEncoder("car"); + FlagEncoder encoder = mixedEncodingManager.getEncoder("car"); ShortestWeighting weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(2, 8); assertTrue(p.isFound()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); List tmpList = getTurnDescriptions(wayList); assertEquals(Arrays.asList("At roundabout, take exit 3 onto 5-8", "arrive at destination"), @@ -259,12 +263,12 @@ public void testCalcInstructionsRoundaboutBegin() { @Test public void testCalcInstructionsRoundaboutDirectExit() { roundaboutGraph.inverse3to9(); - FlagEncoder encoder = mixedEncoders.getEncoder("car"); + FlagEncoder encoder = mixedEncodingManager.getEncoder("car"); ShortestWeighting weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(6, 8); assertTrue(p.isFound()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); List tmpList = getTurnDescriptions(wayList); assertEquals(Arrays.asList("continue onto 3-6", "At roundabout, take exit 3 onto 5-8", @@ -451,12 +455,12 @@ public void testCalcDistanceDetails() { @Test public void testCalcInstructionsRoundabout2() { roundaboutGraph.inverse3to6(); - FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 8); assertTrue(p.isFound()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); List tmpList = getTurnDescriptions(wayList); assertEquals(Arrays.asList("continue onto MainStreet 1 2", "At roundabout, take exit 2 onto 5-8", @@ -538,12 +542,12 @@ public void testCalcInstructionsRoundaboutIssue353() { @Test public void testCalcInstructionsRoundaboutClockwise() { roundaboutGraph.setRoundabout(true); - FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 8); assertTrue(p.isFound()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); List tmpList = getTurnDescriptions(wayList); assertEquals(Arrays.asList("continue onto MainStreet 1 2", "At roundabout, take exit 1 onto 5-8", @@ -558,12 +562,12 @@ public void testCalcInstructionsRoundaboutClockwise() { @Test public void testCalcInstructionsIgnoreContinue() { // Follow a couple of straight edges, including a name change - FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(4, 11); assertTrue(p.isFound()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); // Contain only start and finish instruction, no CONTINUE assertEquals(2, wayList.size()); @@ -572,12 +576,12 @@ public void testCalcInstructionsIgnoreContinue() { @Test public void testCalcInstructionsIgnoreTurnIfNoAlternative() { // The street turns left, but there is not turn - FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(10, 12); assertTrue(p.isFound()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); // Contain only start and finish instruction assertEquals(2, wayList.size()); @@ -913,12 +917,12 @@ public void testUTurnRight() { @Test public void testCalcInstructionsForTurn() { // The street turns left, but there is not turn - FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(11, 13); assertTrue(p.isFound()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); // Contain start, turn, and finish instruction assertEquals(3, wayList.size()); @@ -929,12 +933,12 @@ public void testCalcInstructionsForTurn() { @Test public void testCalcInstructionsForSlightTurnWithOtherSlightTurn() { // Test for a fork with two sligh turns. Since there are two sligh turns, show the turn instruction - FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(12, 16); assertTrue(p.isFound()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); // Contain start, turn, and finish instruction assertEquals(3, wayList.size()); @@ -974,12 +978,12 @@ public void testCalcInstructionsForSlightTurnOntoDifferentStreet() { @Test public void testIgnoreInstructionsForSlightTurnWithOtherTurn() { // Test for a fork with one sligh turn and one actual turn. We are going along the slight turn. No turn instruction needed in this case - FlagEncoder mixedCar = mixedEncoders.getEncoder("car"); + FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(16, 19); assertTrue(p.isFound()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncoders, tr); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); // Contain start, and finish instruction assertEquals(2, wayList.size()); @@ -1012,17 +1016,15 @@ private Graph generatePathDetailsGraph() { return graph; } - private static class RoundaboutGraph { + private class RoundaboutGraph { final BaseGraph g; final NodeAccess na; final EdgeIteratorState edge3to6, edge3to9; - final EncodingManager em; boolean clockwise = false; List roundaboutEdges = new LinkedList<>(); - private RoundaboutGraph(EncodingManager em) { - this.em = em; - g = new BaseGraph.Builder(em).create(); + private RoundaboutGraph() { + g = new BaseGraph.Builder(mixedEncodingManager).create(); na = g.getNodeAccess(); // 18 // 8 14 | @@ -1082,40 +1084,36 @@ private RoundaboutGraph(EncodingManager em) { bothDir.add(g.edge(17, 18).setDistance(5)); bothDir.add(g.edge(17, 19).setDistance(5)); - for (FlagEncoder encoder : em.fetchEdgeEncoders()) { - double speed = encoder.getMaxSpeed() / 2; - GHUtility.setSpeed(speed, speed, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), bothDir); - GHUtility.setSpeed(speed, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), oneDir); + for (EdgeIteratorState edge : bothDir) { + GHUtility.setSpeed(70, 70, mixedCarAccessEnc, mixedCarSpeedEnc, edge); + GHUtility.setSpeed(7, 7, mixedFootAccessEnc, mixedFootSpeedEnc, edge); + } + for (EdgeIteratorState edge : oneDir) { + GHUtility.setSpeed(70, 0, mixedCarAccessEnc, mixedCarSpeedEnc, edge); + GHUtility.setSpeed(7, 0, mixedFootAccessEnc, mixedFootSpeedEnc, edge); } - setRoundabout(clockwise); inverse3to9(); } public void setRoundabout(boolean clockwise) { - BooleanEncodedValue mixedRoundabout = em.getBooleanEncodedValue(Roundabout.KEY); - for (FlagEncoder encoder : em.fetchEdgeEncoders()) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - for (EdgeIteratorState edge : roundaboutEdges) { - edge.set(accessEnc, clockwise).setReverse(accessEnc, !clockwise); - edge.set(mixedRoundabout, true); - } + BooleanEncodedValue mixedRoundabout = mixedEncodingManager.getBooleanEncodedValue(Roundabout.KEY); + for (EdgeIteratorState edge : roundaboutEdges) { + edge.set(mixedCarAccessEnc, clockwise).setReverse(mixedCarAccessEnc, !clockwise); + edge.set(mixedFootAccessEnc, clockwise).setReverse(mixedFootAccessEnc, !clockwise); + edge.set(mixedRoundabout, true); } this.clockwise = clockwise; } public void inverse3to9() { - for (FlagEncoder encoder : em.fetchEdgeEncoders()) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - edge3to9.set(accessEnc, !edge3to9.get(accessEnc)).setReverse(accessEnc, false); - } + edge3to9.set(mixedCarAccessEnc, !edge3to9.get(mixedCarAccessEnc)).setReverse(mixedCarAccessEnc, false); + edge3to9.set(mixedFootAccessEnc, !edge3to9.get(mixedFootAccessEnc)).setReverse(mixedFootAccessEnc, false); } public void inverse3to6() { - for (FlagEncoder encoder : em.fetchEdgeEncoders()) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - edge3to6.set(accessEnc, !edge3to6.get(accessEnc)).setReverse(accessEnc, true); - } + edge3to6.set(mixedCarAccessEnc, !edge3to6.get(mixedCarAccessEnc)).setReverse(mixedCarAccessEnc, true); + edge3to6.set(mixedFootAccessEnc, !edge3to6.get(mixedFootAccessEnc)).setReverse(mixedFootAccessEnc, true); } private double getAngle(int n1, int n2, int n3, int n4) { diff --git a/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java b/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java index 0f5ae3dfaac..d98c7e32b96 100644 --- a/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java @@ -55,16 +55,17 @@ void testMaxPriority() { na.setNode(5, 48.2, 11.1); // 0 - 1 - 2 - 3 // \- 4 - 5 -/ + double speed = encoder.getAverageSpeedEnc().getNextStorableValue(30); double dist1 = 0; - dist1 += maxSpeedEdge(em, graph, 0, 1, encoder, 1.0).getDistance(); - dist1 += maxSpeedEdge(em, graph, 1, 2, encoder, 1.0).getDistance(); - dist1 += maxSpeedEdge(em, graph, 2, 3, encoder, 1.0).getDistance(); + dist1 += addEdge(em, graph, 0, 1, encoder, 1.0, speed).getDistance(); + dist1 += addEdge(em, graph, 1, 2, encoder, 1.0, speed).getDistance(); + dist1 += addEdge(em, graph, 2, 3, encoder, 1.0, speed).getDistance(); final double maxPrio = PriorityCode.getFactor(PriorityCode.BEST.getValue()); double dist2 = 0; - dist2 += maxSpeedEdge(em, graph, 0, 4, encoder, maxPrio).getDistance(); - dist2 += maxSpeedEdge(em, graph, 4, 5, encoder, maxPrio).getDistance(); - dist2 += maxSpeedEdge(em, graph, 5, 3, encoder, maxPrio).getDistance(); + dist2 += addEdge(em, graph, 0, 4, encoder, maxPrio, speed).getDistance(); + dist2 += addEdge(em, graph, 4, 5, encoder, maxPrio, speed).getDistance(); + dist2 += addEdge(em, graph, 5, 3, encoder, maxPrio, speed).getDistance(); // the routes 0-1-2-3 and 0-4-5-3 have similar distances (and use max speed everywhere) // ... but the shorter route 0-1-2-3 has smaller priority @@ -101,14 +102,14 @@ void testMaxPriority() { } } - private EdgeIteratorState maxSpeedEdge(EncodingManager em, BaseGraph graph, int p, int q, FlagEncoder encoder, double prio) { + private EdgeIteratorState addEdge(EncodingManager em, BaseGraph graph, int p, int q, FlagEncoder encoder, double prio, double speed) { BooleanEncodedValue accessEnc = encoder.getAccessEnc(); DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); DecimalEncodedValue priorityEnc = em.getDecimalEncodedValue(EncodingManager.getKey(encoder, "priority")); EnumEncodedValue roadClassEnc = em.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); return graph.edge(p, q) .set(accessEnc, true) - .set(speedEnc, encoder.getMaxSpeed()) + .set(speedEnc, speed) .set(priorityEnc, prio) .set(roadClassEnc, RoadClass.MOTORWAY) .setDistance(calcDist(graph, p, q)); diff --git a/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java index 3afa22d6461..38bdcfd8420 100644 --- a/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java @@ -468,6 +468,7 @@ public void maxSpeed() { // ... because of this we have to make sure the max speed is set to a value that cannot be exceeded even when // such conversion occurs. in our case it must be 16 not 15! - assertEquals(16, encoder.getMaxSpeed()); + // note that this test made more sense when we used encoders that defined a max speed. + assertEquals(16, encoder.getAverageSpeedEnc().getNextStorableValue(15)); } } diff --git a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java index da3740f2a84..63472006ccb 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java @@ -45,7 +45,7 @@ public class FastestWeightingTest { @Test public void testMinWeightHasSameUnitAs_getWeight() { - IntsRef flags = GHUtility.setSpeed(encoder.getMaxSpeed(), 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags()); + IntsRef flags = GHUtility.setSpeed(140, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags()); Weighting instance = new FastestWeighting(encoder); assertEquals(instance.getMinWeight(10), instance.calcEdgeWeight(createMockedEdgeIteratorState(10, flags), false), 1e-8); } diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java index b78b575dbc0..3cceb579fd9 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java @@ -51,6 +51,7 @@ class CustomModelParserTest { EnumEncodedValue roadClassEnc; DecimalEncodedValue avgSpeedEnc; StringEncodedValue countryEnc; + double maxSpeed; @BeforeEach void setup() { @@ -61,6 +62,7 @@ void setup() { graph = new BaseGraph.Builder(encodingManager).create(); avgSpeedEnc = encoder.getAverageSpeedEnc(); roadClassEnc = encodingManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); + maxSpeed = 140; } @Test @@ -68,7 +70,7 @@ void setPriorityForRoadClass() { CustomModel customModel = new CustomModel(); customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.5")); CustomWeighting.EdgeToDoubleMapping priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToPriorityMapping(); + avgSpeedEnc, maxSpeed, null).getEdgeToPriorityMapping(); BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); EdgeIteratorState edge1 = graph.edge(0, 1).setDistance(100).set(roadClassEnc, RoadClass.PRIMARY); @@ -94,7 +96,7 @@ void testPriority() { customModel.addToPriority(If("road_environment != FERRY", MULTIPLY, "0.8")); CustomWeighting.EdgeToDoubleMapping priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToPriorityMapping(); + avgSpeedEnc, maxSpeed, null).getEdgeToPriorityMapping(); assertEquals(0.5 * 0.8, priorityMapping.get(primary, false), 0.01); assertEquals(0.7 * 0.8, priorityMapping.get(secondary, false), 0.01); @@ -105,7 +107,7 @@ void testPriority() { customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "1")); customModel.addToPriority(If("road_class == SECONDARY", MULTIPLY, "0.9")); priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToPriorityMapping(); + avgSpeedEnc, maxSpeed, null).getEdgeToPriorityMapping(); assertEquals(1, priorityMapping.get(primary, false), 0.01); assertEquals(0.9, priorityMapping.get(secondary, false), 0.01); } @@ -120,7 +122,7 @@ public void testBrackets() { CustomModel customModel = new CustomModel(); customModel.addToPriority(If("(road_class == PRIMARY || car_access == true) && car_average_speed > 50", MULTIPLY, "0.9")); CustomWeighting.Parameters parameters = CustomModelParser.createWeightingParameters(customModel, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null); + avgSpeedEnc, maxSpeed, null); assertEquals(0.9, parameters.getEdgeToPriorityMapping().get(primary, false), 0.01); assertEquals(1, parameters.getEdgeToPriorityMapping().get(secondary, false), 0.01); } @@ -136,7 +138,7 @@ public void testSpeedFactorAndPriorityAndMaxSpeed() { customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.9")); customModel.addToSpeed(If("road_class == PRIMARY", MULTIPLY, "0.8")); CustomWeighting.Parameters parameters = CustomModelParser.createWeightingParameters(customModel, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null); + avgSpeedEnc, maxSpeed, null); assertEquals(0.9, parameters.getEdgeToPriorityMapping().get(primary, false), 0.01); assertEquals(64, parameters.getEdgeToSpeedMapping().get(primary, false), 0.01); @@ -145,7 +147,7 @@ public void testSpeedFactorAndPriorityAndMaxSpeed() { customModel.addToSpeed(If("road_class != PRIMARY", LIMIT, "50")); CustomWeighting.EdgeToDoubleMapping speedMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToSpeedMapping(); + avgSpeedEnc, maxSpeed, null).getEdgeToSpeedMapping(); assertEquals(64, speedMapping.get(primary, false), 0.01); assertEquals(50, speedMapping.get(secondary, false), 0.01); } @@ -162,7 +164,7 @@ public void testString() { customModel.addToPriority(ElseIf("country == \"blup\"", MULTIPLY, "0.7")); customModel.addToPriority(Else(MULTIPLY, "0.5")); CustomWeighting.EdgeToDoubleMapping priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToPriorityMapping(); + avgSpeedEnc, maxSpeed, null).getEdgeToPriorityMapping(); assertEquals(0.9, priorityMapping.get(deu, false), 0.01); assertEquals(0.7, priorityMapping.get(blup, false), 0.01); } @@ -173,13 +175,13 @@ void testIllegalOrder() { customModel.addToPriority(Else(MULTIPLY, "0.9")); customModel.addToPriority(If("road_environment != FERRY", MULTIPLY, "0.8")); assertThrows(IllegalArgumentException.class, () -> CustomModelParser.createWeightingParameters(customModel, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null)); + avgSpeedEnc, maxSpeed, null)); CustomModel customModel2 = new CustomModel(); customModel2.addToPriority(ElseIf("road_environment != FERRY", MULTIPLY, "0.9")); customModel2.addToPriority(If("road_class != PRIMARY", MULTIPLY, "0.8")); assertThrows(IllegalArgumentException.class, () -> CustomModelParser.createWeightingParameters(customModel2, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null)); + avgSpeedEnc, maxSpeed, null)); } @Test @@ -219,7 +221,7 @@ public void multipleAreas() { // No exception is thrown during createWeightingParameters assertAll(() -> CustomModelParser.createWeightingParameters(customModel, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null)); + avgSpeedEnc, maxSpeed, null)); CustomModel customModel2 = new CustomModel(); customModel2.setAreas(areas); @@ -231,21 +233,21 @@ public void multipleAreas() { assertThrows(IllegalArgumentException.class, () -> CustomModelParser.createWeightingParameters(customModel2, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null)); + avgSpeedEnc, maxSpeed, null)); } @Test public void parseValue() { - DecimalEncodedValue maxSpeed = encodingManager.getDecimalEncodedValue(MaxSpeed.KEY); + DecimalEncodedValue maxSpeedEnc = encodingManager.getDecimalEncodedValue(MaxSpeed.KEY); EdgeIteratorState maxLower = graph.edge(0, 1).setDistance(10). - set(maxSpeed, 60).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); + set(maxSpeedEnc, 60).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); EdgeIteratorState maxSame = graph.edge(1, 2).setDistance(10). - set(maxSpeed, 70).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); + set(maxSpeedEnc, 70).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); CustomModel customModel = new CustomModel(); customModel.addToSpeed(If("true", LIMIT, "max_speed * 1.1")); CustomWeighting.EdgeToDoubleMapping speedMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null).getEdgeToSpeedMapping(); + avgSpeedEnc, maxSpeed, null).getEdgeToSpeedMapping(); assertEquals(70.0, speedMapping.get(maxSame, false), 0.01); assertEquals(66.0, speedMapping.get(maxLower, false), 0.01); } @@ -257,7 +259,7 @@ public void parseValueWithError() { IllegalArgumentException ret = assertThrows(IllegalArgumentException.class, () -> CustomModelParser.createWeightingParameters(customModel1, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null)); + avgSpeedEnc, maxSpeed, null)); assertTrue(ret.getMessage().startsWith("Cannot compile expression: 'unknown' not available"), ret.getMessage()); CustomModel customModel2 = new CustomModel(); @@ -265,7 +267,7 @@ public void parseValueWithError() { customModel2.addToSpeed(Else(MULTIPLY, "-0.5")); ret = assertThrows(IllegalArgumentException.class, () -> CustomModelParser.createWeightingParameters(customModel2, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null)); + avgSpeedEnc, maxSpeed, null)); assertTrue(ret.getMessage().startsWith("Cannot compile expression: speed has to be >=0 but can be negative (-0.5)"), ret.getMessage()); CustomModel customModel3 = new CustomModel(); @@ -273,7 +275,7 @@ public void parseValueWithError() { customModel3.addToSpeed(Else(MULTIPLY, "road_class")); ret = assertThrows(IllegalArgumentException.class, () -> CustomModelParser.createWeightingParameters(customModel3, encodingManager, - avgSpeedEnc, encoder.getMaxSpeed(), null)); + avgSpeedEnc, maxSpeed, null)); assertTrue(ret.getMessage().contains("Binary numeric promotion not possible on types \"double\" and \"java.lang.Enum\""), ret.getMessage()); } diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index b07e51ae824..8ed89caa3c9 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -242,16 +242,16 @@ public void testArea() throws Exception { @Test public void testMaxSpeed() { - assertEquals(140, carFE.getMaxSpeed(), 0.1); + assertEquals(155, avSpeedEnc.getMaxOrMaxStorableDecimal(), 0.1); assertEquals(1000.0 / 72 * 3.6, createWeighting(new CustomModel(). addToSpeed(If("true", LIMIT, "72")).setDistanceInfluence(0)).getMinWeight(1000)); - // ignore too big limit to let custom model compatibility not break when max speed of encoder later decreases + // ignore too big limit to let custom model compatibility not break when max speed of encoded value later decreases assertEquals(1000.0 / 155 * 3.6, createWeighting(new CustomModel(). addToSpeed(If("true", LIMIT, "180")).setDistanceInfluence(0)).getMinWeight(1000)); - // a speed bigger than the allowed stored speed is fine, see discussion in #2335 + // reduce speed only a bit assertEquals(1000.0 / 150 * 3.6, createWeighting(new CustomModel(). addToSpeed(If("road_class == SERVICE", MULTIPLY, "1.5")). addToSpeed(If("true", LIMIT, "150")).setDistanceInfluence(0)).getMinWeight(1000)); diff --git a/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java b/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java index 74343c16343..6d1d0de9675 100644 --- a/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java +++ b/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java @@ -40,7 +40,7 @@ public class LocationIndexTreeTest { protected final EncodingManager encodingManager = EncodingManager.create("car"); - public static void initSimpleGraph(Graph g, EncodingManager em) { + public static void initSimpleGraph(Graph g) { // 6 | 4 // 5 | // | 6 @@ -70,10 +70,6 @@ public static void initSimpleGraph(Graph g, EncodingManager em) { g.edge(3, 5), // make sure 6 is connected g.edge(6, 4)); - for (FlagEncoder encoder : em.fetchEdgeEncoders()) { - double speed = encoder.getMaxSpeed() / 2; - GHUtility.setSpeed(speed, speed, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), list); - } } private LocationIndexTree createIndexNoPrepare(Graph g, int resolution) { @@ -449,8 +445,10 @@ private int findClosestEdge(LocationIndex index, double lat, double lon) { public void testSimpleGraph() { EncodingManager em = EncodingManager.create("car"); BaseGraph g = new BaseGraph.Builder(em).create(); - initSimpleGraph(g, em); - + initSimpleGraph(g); + AllEdgesIterator edge = g.getAllEdges(); + while (edge.next()) + GHUtility.setSpeed(60, 60, em.getEncoder("car").getAccessEnc(), em.getEncoder("car").getAverageSpeedEnc(), edge); LocationIndexTree idx = (LocationIndexTree) createIndexNoPrepare(g, 500000).prepareIndex(); assertEquals(3, findClosestEdge(idx, 5, 2)); assertEquals(3, findClosestEdge(idx, 1.5, 2)); @@ -463,7 +461,10 @@ public void testSimpleGraph() { public void testSimpleGraph2() { EncodingManager em = EncodingManager.create("car"); BaseGraph g = new BaseGraph.Builder(em).create(); - initSimpleGraph(g, em); + initSimpleGraph(g); + AllEdgesIterator edge = g.getAllEdges(); + while (edge.next()) + GHUtility.setSpeed(60, 60, em.getEncoder("car").getAccessEnc(), em.getEncoder("car").getAverageSpeedEnc(), edge); LocationIndexTree idx = (LocationIndexTree) createIndexNoPrepare(g, 500000).prepareIndex(); assertEquals(3, findClosestEdge(idx, 5, 2)); @@ -604,7 +605,12 @@ public BaseGraph createSampleGraph(EncodingManager encodingManager) { public void testDifferentVehicles() { final EncodingManager encodingManager = EncodingManager.create("car,foot"); BaseGraph g = new BaseGraph.Builder(encodingManager).create(); - initSimpleGraph(g, encodingManager); + initSimpleGraph(g); + AllEdgesIterator edge = g.getAllEdges(); + while (edge.next()) { + GHUtility.setSpeed(60, 60, encodingManager.getEncoder("car").getAccessEnc(), encodingManager.getEncoder("car").getAverageSpeedEnc(), edge); + GHUtility.setSpeed(10, 10, encodingManager.getEncoder("foot").getAccessEnc(), encodingManager.getEncoder("foot").getAverageSpeedEnc(), edge); + } LocationIndexTree idx = (LocationIndexTree) createIndexNoPrepare(g, 500000).prepareIndex(); assertEquals(0, findClosestEdge(idx, 1, -1)); From dd24ba4dff936262709669dd1d435f16ccec0908 Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 1 Jul 2022 09:00:11 +0200 Subject: [PATCH 079/389] Remove car/bike_access evs from DefaultEncodedValueFactory, was added only for #2523 --- .../graphhopper/routing/ev/DefaultEncodedValueFactory.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java index c9c53e17595..5cb66e4c713 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java @@ -32,10 +32,6 @@ public EncodedValue create(String string) { if (Roundabout.KEY.equals(name)) { enc = Roundabout.create(); - } else if ("car_access".equals(name)) { - enc = new SimpleBooleanEncodedValue("car_access", true); - } else if ("bike_access".equals(name)) { - enc = new SimpleBooleanEncodedValue("bike_access", true); } else if (GetOffBike.KEY.equals(name)) { enc = GetOffBike.create(); } else if (RoadClass.KEY.equals(name)) { From 83be9d61164c0f947674b2dc7b9095e4c4dfb8d6 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 1 Jul 2022 09:54:11 +0200 Subject: [PATCH 080/389] CustomModelParser: no need for max speed --- .../weighting/custom/CustomModelParser.java | 18 ++++++++---------- .../custom/CustomModelParserTest.java | 6 +++--- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java index 7e419eb4002..2e7ad3efe47 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java @@ -164,7 +164,7 @@ private static Class createClazz(CustomModel customModel, EncodedValueLookup throw new IllegalArgumentException("speed has to be >=0 but can be negative (" + minMaxSpeed.min + ")"); if (minMaxSpeed.max <= 0) throw new IllegalArgumentException("maximum speed has to be >0 but was " + minMaxSpeed.max); - List speedStatements = createGetSpeedStatements(speedVariables, customModel, lookup, minMaxSpeed.max); + List speedStatements = createGetSpeedStatements(speedVariables, customModel, lookup); // Create different class name, which is required only for debugging. // TODO does it improve performance too? I.e. it could be that the JIT is confused if different classes // have the same name and it mixes performance stats. See https://github.com/janino-compiler/janino/issues/137 @@ -188,11 +188,10 @@ private static Class createClazz(CustomModel customModel, EncodedValueLookup * @return the created statements (parsed expressions) */ private static List createGetSpeedStatements(Set speedVariables, - CustomModel customModel, EncodedValueLookup lookup, - double maxSpeed) throws Exception { + CustomModel customModel, EncodedValueLookup lookup) throws Exception { List speedStatements = new ArrayList<>(); speedStatements.addAll(verifyExpressions(new StringBuilder(), "speed entry", speedVariables, - customModel.getSpeed(), lookup, "return Math.min(value, " + maxSpeed + ");\n")); + customModel.getSpeed(), lookup)); String speedMethodStartBlock = "double value = super.getRawSpeed(edge, reverse);\n"; // a bit inefficient to possibly define variables twice, but for now we have two separate methods for (String arg : speedVariables) { @@ -212,7 +211,7 @@ private static List createGetPriorityStatements(Set CustomModel customModel, EncodedValueLookup lookup) throws Exception { List priorityStatements = new ArrayList<>(); priorityStatements.addAll(verifyExpressions(new StringBuilder(), "priority entry, ", - priorityVariables, customModel.getPriority(), lookup, "return value;")); + priorityVariables, customModel.getPriority(), lookup)); String priorityMethodStartBlock = "double value = super.getRawPriority(edge, reverse);\n"; for (String arg : priorityVariables) { priorityMethodStartBlock += getVariableDeclaration(lookup, arg); @@ -364,19 +363,18 @@ private static String createClassTemplate(long counter, * @return the created if-then, else and elseif statements */ private static List verifyExpressions(StringBuilder expressions, String info, Set createObjects, - List list, EncodedValueLookup lookup, - String lastStmt) throws Exception { + List list, EncodedValueLookup lookup) throws Exception { // allow variables, all encoded values, constants NameValidator nameInConditionValidator = name -> lookup.hasEncodedValue(name) || name.toUpperCase(Locale.ROOT).equals(name) || isValidVariableName(name); - parseExpressions(expressions, nameInConditionValidator, lookup, info, createObjects, list, lastStmt); + parseExpressions(expressions, nameInConditionValidator, lookup, info, createObjects, list); return new Parser(new org.codehaus.janino.Scanner(info, new StringReader(expressions.toString()))). parseBlockStatements(); } static void parseExpressions(StringBuilder expressions, NameValidator nameInConditionValidator, EncodedValueLookup lookup, - String exceptionInfo, Set createObjects, List list, String lastStmt) { + String exceptionInfo, Set createObjects, List list) { for (Statement statement : list) { // avoid parsing the RHS value expression again as we just did it to get the maximum values in createClazz @@ -398,7 +396,7 @@ static void parseExpressions(StringBuilder expressions, NameValidator nameInCond throw new IllegalArgumentException("The statement must be either 'if', 'else_if' or 'else'"); } } - expressions.append(lastStmt); + expressions.append("return value;\n"); } /** diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java index 3cceb579fd9..8b6117b7a22 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java @@ -287,21 +287,21 @@ public void parseConditionWithError() { IllegalArgumentException ret = assertThrows(IllegalArgumentException.class, () -> parseExpressions(new StringBuilder(), validVariable, encodingManager, "[HERE]", new HashSet<>(), - Arrays.asList(If("max_weight > 10", MULTIPLY, "0")), "")); + Arrays.asList(If("max_weight > 10", MULTIPLY, "0")))); assertTrue(ret.getMessage().startsWith("[HERE] invalid condition \"max_weight > 10\": 'max_weight' not available"), ret.getMessage()); // invalid variable or constant (NameValidator returns false) ret = assertThrows(IllegalArgumentException.class, () -> parseExpressions(new StringBuilder(), validVariable, encodingManager, "[HERE]", new HashSet<>(), - Arrays.asList(If("country == GERMANY", MULTIPLY, "0")), "")); + Arrays.asList(If("country == GERMANY", MULTIPLY, "0")))); assertTrue(ret.getMessage().startsWith("[HERE] invalid condition \"country == GERMANY\": 'GERMANY' not available"), ret.getMessage()); // not whitelisted method ret = assertThrows(IllegalArgumentException.class, () -> parseExpressions(new StringBuilder(), validVariable, encodingManager, "[HERE]", new HashSet<>(), - Arrays.asList(If("edge.fetchWayGeometry().size() > 2", MULTIPLY, "0")), "")); + Arrays.asList(If("edge.fetchWayGeometry().size() > 2", MULTIPLY, "0")))); assertTrue(ret.getMessage().startsWith("[HERE] invalid condition \"edge.fetchWayGeometry().size() > 2\": size is an illegal method"), ret.getMessage()); } } \ No newline at end of file From 993959d4d6a03aa144d245ee9afbdaf4c3e6e1cb Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 3 Jul 2022 15:24:32 +0200 Subject: [PATCH 081/389] EdgeKVStorage: store name and ref tags separately (#2598) * copied code and tests from byteindex branch * a bit more docu and tests * behaviour change: throw exception if string is too long and so cut string before storing way_name * renamed StringIndex -> EdgeKVStorage * store name and ref tags separately; create separate path detail for ref; use ref as fallback in instruction text * added text to changelog * minor comment changes * review: fix comments * review comments and add getValue method to avoid creating HashMaps * try if speed up was really from the change getKeyValues->edge.getValue * Revert "try if speed up was really from the change getKeyValues->edge.getValue" This reverts commit 58a34d62cb1b84a50c4e49a95abba984851137fd. Co-authored-by: easbar --- CHANGELOG.md | 4 +- .../com/graphhopper/reader/osm/OSMReader.java | 26 ++-- .../routing/InstructionsFromEdges.java | 20 +-- .../routing/InstructionsHelper.java | 5 +- .../querygraph/QueryOverlayBuilder.java | 10 +- .../querygraph/VirtualEdgeIterator.java | 15 +- .../querygraph/VirtualEdgeIteratorState.java | 28 +++- .../com/graphhopper/search/EdgeKVStorage.java | 6 +- .../com/graphhopper/storage/BaseGraph.java | 44 +++--- .../storage/BaseGraphNodesAndEdges.java | 14 +- .../graphhopper/util/EdgeIteratorState.java | 38 ++++- .../java/com/graphhopper/util/GHUtility.java | 12 +- ...tNameDetails.java => KVStringDetails.java} | 26 ++-- .../details/PathDetailsBuilderFactory.java | 8 +- .../java/com/graphhopper/GraphHopperTest.java | 26 ++-- .../com/graphhopper/routing/PathTest.java | 137 +++++++++--------- .../util/NameSimilarityEdgeFilterTest.java | 14 +- .../weighting/FastestWeightingTest.java | 4 +- .../storage/AbstractGraphStorageTester.java | 8 +- .../graphhopper/storage/BaseGraphTest.java | 6 +- .../storage/BaseGraphWithTurnCostsTest.java | 5 +- .../graphhopper/util/InstructionListTest.java | 70 ++++----- .../util/PathSimplificationTest.java | 21 +-- .../example/LocationIndexExample.java | 6 +- .../navigation/NavigateResponseConverter.java | 2 +- .../NavigateResponseConverterTest.java | 2 +- .../gtfs/analysis/PtGraphAsAdjacencyList.java | 13 +- .../com/graphhopper/util/Instruction.java | 14 +- .../java/com/graphhopper/util/Parameters.java | 1 + .../util/RoundaboutInstruction.java | 2 +- .../com/graphhopper/util/ViaInstruction.java | 2 +- .../graphhopper/gpx/GpxConversionsTest.java | 13 +- .../application/MapMatchingTest.java | 4 +- .../resources/ExtendedJsonResponseTest.java | 4 +- .../resources/MvtResourceTest.java | 2 +- .../resources/RouteResourceClientHCTest.java | 6 +- .../resources/SPTResourceTest.java | 2 +- 37 files changed, 364 insertions(+), 256 deletions(-) rename core/src/main/java/com/graphhopper/util/details/{StreetNameDetails.java => KVStringDetails.java} (62%) diff --git a/CHANGELOG.md b/CHANGELOG.md index b981d1b18f6..e7b070615e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ### 6.0 [not yet released] -- StringIndex is now EdgeKVStorage and can store e.g. byte arrays. String values needs to be limited to 255 bytes before storing them. See #2597 +- backward incompatible change as instructions and the street_name path detail do no longer contain the ref #2598 +- StringIndex is now EdgeKVStorage and can store e.g. byte arrays. String values needs to be limited to 255 bytes before + storing them. See #2597 - the Matrix client changed and users have to adapt the usage, see #2587 - replaced car$access with car_access (and same for $average_speed and $priority) - don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index a664df30839..e12353d87bd 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -332,9 +332,14 @@ protected void addEdge(int fromIndex, int toIndex, PointList pointList, ReaderWa if (edgeFlags.isEmpty()) return; - // the storage does not allow too long Strings - String name = Helper.cutStringForKV(way.getTag("way_name", "")); - EdgeIteratorState edge = baseGraph.edge(fromIndex, toIndex).setDistance(distance).setFlags(edgeFlags).setName(name); + Map map = new HashMap<>(2); + // the storage does not accept too long strings -> Helper.cutStringForKV + if (way.hasTag("way_name")) // do not store empty string if missing tag + map.put("name", Helper.cutStringForKV(way.getTag("way_name", ""))); + if (way.hasTag("way_ref")) + map.put("ref", Helper.cutStringForKV(way.getTag("way_ref", ""))); + EdgeIteratorState edge = baseGraph.edge(fromIndex, toIndex).setDistance(distance).setFlags(edgeFlags). + setKeyValues(map); // If the entire way is just the first and last point, do not waste space storing an empty way geometry if (pointList.size() > 2) { @@ -380,23 +385,20 @@ else if (Math.abs(edgeDistance - geometryDistance) > tolerance) protected void preprocessWay(ReaderWay way, WaySegmentParser.CoordinateSupplier coordinateSupplier) { // storing the road name does not yet depend on the flagEncoder so manage it directly if (config.isParseWayNames()) { - // String wayInfo = carFlagEncoder.getWayInfo(way); // http://wiki.openstreetmap.org/wiki/Key:name String name = ""; if (!config.getPreferredLanguage().isEmpty()) name = fixWayName(way.getTag("name:" + config.getPreferredLanguage())); if (name.isEmpty()) name = fixWayName(way.getTag("name")); + + if (!name.isEmpty()) + way.setTag("way_name", name); + // http://wiki.openstreetmap.org/wiki/Key:ref String refName = fixWayName(way.getTag("ref")); - if (!refName.isEmpty()) { - if (name.isEmpty()) - name = refName; - else - name += ", " + refName; - } - - way.setTag("way_name", name); + if (!refName.isEmpty()) + way.setTag("way_ref", refName); } if (!isCalculateWayDistance(way)) diff --git a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java index 84791342770..a87cb9f1f6d 100644 --- a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java +++ b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java @@ -18,7 +18,6 @@ package com.graphhopper.routing; import com.graphhopper.routing.ev.*; -import com.graphhopper.routing.util.FiniteWeightFilter; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.Graph; import com.graphhopper.storage.NodeAccess; @@ -138,12 +137,12 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { assert Double.compare(prevLon, nodeAccess.getLon(baseNode)) == 0; } - String name = edge.getName(); - - if ((prevName == null) && (!isRoundabout)) // very first instruction (if not in Roundabout) + final String name = (String) edge.getValue("name"); + if ((prevInstruction == null) && (!isRoundabout)) // very first instruction (if not in Roundabout) { int sign = Instruction.CONTINUE_ON_STREET; prevInstruction = new Instruction(sign, name, new PointList(10, nodeAccess.is3D())); + prevInstruction.setExtraInfo("ref", edge.getValue("ref")); double startLat = nodeAccess.getLat(baseNode); double startLon = nodeAccess.getLon(baseNode); double heading = AngleCalc.ANGLE_CALC.calcAzimuth(startLat, startLon, latitude, longitude); @@ -159,7 +158,7 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { RoundaboutInstruction roundaboutInstruction = new RoundaboutInstruction(sign, name, new PointList(10, nodeAccess.is3D())); prevInstructionPrevOrientation = prevOrientation; - if (prevName != null) { + if (prevInstruction != null) { // check if there is an exit at the same node the roundabout was entered EdgeIterator edgeIter = outEdgeExplorer.setBaseNode(baseNode); while (edgeIter.next()) { @@ -201,6 +200,7 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { } else if (prevInRoundabout) //previously in roundabout but not anymore { prevInstruction.setName(name); + prevInstruction.setExtraInfo("ref", edge.getValue("ref")); // calc angle between roundabout entrance and exit double orientation = AngleCalc.ANGLE_CALC.calcOrientation(prevLat, prevLon, latitude, longitude); @@ -274,6 +274,7 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { prevInstructionName = prevName; ways.add(prevInstruction); } + prevInstruction.setExtraInfo("ref", edge.getValue("ref")); } // Update the prevName, since we don't always create an instruction on name changes the previous // name can be an old name. This leads to incorrect turn instructions due to name changes @@ -340,10 +341,8 @@ private int getTurn(EdgeIteratorState edge, int baseNode, int prevNode, int adjN // Very certain, this is a turn if (Math.abs(sign) > 1) { - /* - * Don't show an instruction if the user is following a street, even though the street is - * bending. We should only do this, if following the street is the obvious choice. - */ + // Don't show an instruction if the user is following a street, even though the street is + // bending. We should only do this, if following the street is the obvious choice. if (InstructionsHelper.isNameSimilar(name, prevName) && outgoingEdges.outgoingEdgesAreSlowerByFactor(2)) { return Instruction.IGNORE; } @@ -395,7 +394,6 @@ private int getTurn(EdgeIteratorState edge, int baseNode, int prevNode, int adjN } } - GHPoint tmpPoint = InstructionsHelper.getPointForOrientationCalculation(otherContinue, nodeAccess); double otherDelta = InstructionsHelper.calculateOrientationDelta(prevLat, prevLon, tmpPoint.getLat(), tmpPoint.getLon(), prevOrientation); @@ -409,8 +407,6 @@ private int getTurn(EdgeIteratorState edge, int baseNode, int prevNode, int adjN } else { return Instruction.KEEP_RIGHT; } - - } } diff --git a/core/src/main/java/com/graphhopper/routing/InstructionsHelper.java b/core/src/main/java/com/graphhopper/routing/InstructionsHelper.java index 0cb8bf442eb..68186ff175d 100644 --- a/core/src/main/java/com/graphhopper/routing/InstructionsHelper.java +++ b/core/src/main/java/com/graphhopper/routing/InstructionsHelper.java @@ -61,9 +61,8 @@ static int calculateSign(double prevLatitude, double prevLongitude, double latit } static boolean isNameSimilar(String name1, String name2) { - // We don't want two empty names to be similar - // The idea is, if there are only a random tracks, they usually don't have names - if (name1.isEmpty() && name2.isEmpty()) + // We don't want two empty names to be similar (they usually don't have names if they are random tracks) + if (name1 == null || name2 == null || name1.isEmpty() || name2.isEmpty()) return false; return name1.equals(name2); } diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java b/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java index 100900ae52c..54948a849ee 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java @@ -27,10 +27,7 @@ import com.graphhopper.util.shapes.GHPoint; import com.graphhopper.util.shapes.GHPoint3D; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; +import java.util.*; class QueryOverlayBuilder { private final int firstVirtualNodeId; @@ -225,10 +222,11 @@ private void createEdges(int origEdgeKey, int origRevEdgeKey, boolean reverse = closestEdge.get(EdgeIteratorState.REVERSE_STATE); // edges between base and snapped point + Map keyValues = closestEdge.getKeyValues(); VirtualEdgeIteratorState baseEdge = new VirtualEdgeIteratorState(origEdgeKey, GHUtility.createEdgeKey(virtEdgeId, prevNodeId == nodeId, false), - prevNodeId, nodeId, baseDistance, closestEdge.getFlags(), closestEdge.getName(), basePoints, reverse); + prevNodeId, nodeId, baseDistance, closestEdge.getFlags(), keyValues, basePoints, reverse); VirtualEdgeIteratorState baseReverseEdge = new VirtualEdgeIteratorState(origRevEdgeKey, GHUtility.createEdgeKey(virtEdgeId, prevNodeId == nodeId, true), - nodeId, prevNodeId, baseDistance, IntsRef.deepCopyOf(closestEdge.getFlags()), closestEdge.getName(), baseReversePoints, !reverse); + nodeId, prevNodeId, baseDistance, IntsRef.deepCopyOf(closestEdge.getFlags()), keyValues, baseReversePoints, !reverse); baseEdge.setReverseEdge(baseReverseEdge); baseReverseEdge.setReverseEdge(baseEdge); diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java index ac3562c015f..b01f0fd8977 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java @@ -26,6 +26,7 @@ import com.graphhopper.util.PointList; import java.util.List; +import java.util.Map; /** * @author Peter Karich @@ -261,8 +262,18 @@ public String getName() { } @Override - public EdgeIteratorState setName(String name) { - return getCurrentEdge().setName(name); + public Map getKeyValues() { + return getCurrentEdge().getKeyValues(); + } + + @Override + public EdgeIteratorState setKeyValues(Map map) { + return getCurrentEdge().setKeyValues(map); + } + + @Override + public Object getValue(String key) { + return getCurrentEdge().getValue(key); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java index b387bd72f36..002b8b06f98 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java @@ -24,6 +24,8 @@ import com.graphhopper.util.GHUtility; import com.graphhopper.util.PointList; +import java.util.Map; + /** * Creates an edge state decoupled from a graph where nodes, pointList, etc are kept in memory. *

@@ -38,21 +40,21 @@ public class VirtualEdgeIteratorState implements EdgeIteratorState { private final int originalEdgeKey; private double distance; private IntsRef edgeFlags; - private String name; + private Map keyValues; // true if edge should be avoided as start/stop private boolean unfavored; private EdgeIteratorState reverseEdge; private final boolean reverse; public VirtualEdgeIteratorState(int originalEdgeKey, int edgeKey, int baseNode, int adjNode, double distance, - IntsRef edgeFlags, String name, PointList pointList, boolean reverse) { + IntsRef edgeFlags, Map keyValues, PointList pointList, boolean reverse) { this.originalEdgeKey = originalEdgeKey; this.edgeKey = edgeKey; this.baseNode = baseNode; this.adjNode = adjNode; this.distance = distance; this.edgeFlags = edgeFlags; - this.name = name; + this.keyValues = keyValues; this.pointList = pointList; this.reverse = reverse; } @@ -307,15 +309,27 @@ public EdgeIteratorState set(StringEncodedValue property, String fwd, String bwd @Override public String getName() { - return name; + String name = (String) keyValues.get("name"); + // preserve backward compatibility (returns empty string if name tag missing) + return name == null ? "" : name; } @Override - public EdgeIteratorState setName(String name) { - this.name = name; + public EdgeIteratorState setKeyValues(Map map) { + this.keyValues = map; return this; } + @Override + public Map getKeyValues() { + return keyValues; + } + + @Override + public Object getValue(String key) { + return keyValues.get(key); + } + /** * This method sets edge to unfavored status for routing from the start or to the stop location. */ @@ -334,7 +348,7 @@ public EdgeIteratorState detach(boolean reverse) { // update properties of reverse edge // TODO copy pointList (geometry) too reverseEdge.setFlags(getFlags()); - reverseEdge.setName(getName()); + reverseEdge.setKeyValues(getKeyValues()); reverseEdge.setDistance(getDistance()); return reverseEdge; } else { diff --git a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java index 463e40f6270..3c692e9a832 100644 --- a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java +++ b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java @@ -208,7 +208,8 @@ else if (entryMap.size() > 200) boolean hasDynLength = hasDynLength(clazz); if (hasDynLength) { // optimization for empty string or empty byte array - if (clazz.equals(String.class) && ((String) value).isEmpty() || clazz.equals(byte[].class) && ((byte[]) value).length == 0) { + if (clazz.equals(String.class) && ((String) value).isEmpty() + || clazz.equals(byte[].class) && ((byte[]) value).length == 0) { vals.ensureCapacity(currentPointer + 3); vals.setShort(currentPointer, keyIndex.shortValue()); // ensure that also in case of MMap value is set to 0 @@ -249,8 +250,9 @@ else if (entryMap.size() > 200) vals.setBytes(currentPointer, valueBytes, valueBytes.length); currentPointer += valueBytes.length; } - // System.out.println(lastEntryPointer + " " + entryMap); bytePointer = currentPointer; + if (bytePointer < 0) + throw new IllegalStateException("Negative bytePointer in EdgeKVStorage"); return lastEntryPointer; } diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index 077e600c2ca..cf2606b4325 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -27,7 +27,7 @@ import com.graphhopper.util.shapes.BBox; import java.io.Closeable; -import java.util.Collections; +import java.util.Map; import static com.graphhopper.util.Helper.nf; @@ -43,7 +43,6 @@ * loadExisting, (4) usage, (5) flush, (6) close */ public class BaseGraph implements Graph, Closeable { - private final static String EDGEKV_NAME_KEY = "name"; final BaseGraphNodesAndEdges store; final NodeAccess nodeAccess; final EdgeKVStorage edgeKVStorage; @@ -258,7 +257,7 @@ EdgeIteratorState copyProperties(EdgeIteratorState from, EdgeIteratorStateImpl t // copy the rest with higher level API to.setDistance(from.getDistance()). - setName(from.getName()). + setKeyValues(from.getKeyValues()). setWayGeometry(from.fetchWayGeometry(FetchMode.PILLAR_ONLY)); return to; @@ -463,13 +462,6 @@ static int getPointListLength(int pillarNodes, FetchMode mode) { throw new IllegalArgumentException("Mode isn't handled " + mode); } - private void setName(long edgePointer, String name) { - int nameRef = (int) edgeKVStorage.add(Collections.singletonMap(EDGEKV_NAME_KEY, name)); - if (nameRef < 0) - throw new IllegalStateException("Too many names are stored, currently limited to int pointer"); - store.setNameRef(edgePointer, nameRef); - } - private void ensureGeometry(long bytePos, int byteLength) { wayGeometry.ensureCapacity(bytePos + byteLength); } @@ -557,7 +549,6 @@ protected static class EdgeIteratorImpl extends EdgeIteratorStateImpl implements public EdgeIteratorImpl(BaseGraph baseGraph, EdgeFilter filter) { super(baseGraph); - if (filter == null) throw new IllegalArgumentException("Instead null filter use EdgeFilter.ALL_EDGES"); this.filter = filter; @@ -955,17 +946,32 @@ public int getReverseEdgeKey() { } @Override - public String getName() { - int nameRef = store.getNameRef(edgePointer); - String name = (String) baseGraph.edgeKVStorage.get(nameRef, EDGEKV_NAME_KEY); - // preserve backward compatibility (returns null if not explicitly set) - return name == null ? "" : name; + public EdgeIteratorState setKeyValues(Map map) { + long pointer = baseGraph.edgeKVStorage.add(map); + if (pointer > Integer.MAX_VALUE) + throw new IllegalStateException("Too many key value pairs are stored, currently limited to " + Integer.MAX_VALUE + " was " + pointer); + store.setKeyValuesRef(edgePointer, (int) pointer); + return this; } @Override - public EdgeIteratorState setName(String name) { - baseGraph.setName(edgePointer, name); - return this; + public Map getKeyValues() { + int kvEntryRef = store.getKeyValuesRef(edgePointer); + return baseGraph.edgeKVStorage.getAll(kvEntryRef); + } + + @Override + public Object getValue(String key) { + int kvEntryRef = store.getKeyValuesRef(edgePointer); + return baseGraph.edgeKVStorage.get(kvEntryRef, key); + } + + @Override + public String getName() { + int kvEntryRef = store.getKeyValuesRef(edgePointer); + String name = (String) baseGraph.edgeKVStorage.get(kvEntryRef, "name"); + // preserve backward compatibility (returns empty string if name tag missing) + return name == null ? "" : name; } @Override diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraphNodesAndEdges.java b/core/src/main/java/com/graphhopper/storage/BaseGraphNodesAndEdges.java index d6b04c6cdd2..a84bf523bbd 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraphNodesAndEdges.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraphNodesAndEdges.java @@ -48,7 +48,7 @@ class BaseGraphNodesAndEdges { // edges private final DataAccess edges; - private final int E_NODEA, E_NODEB, E_LINKA, E_LINKB, E_FLAGS, E_DIST, E_GEO, E_NAME; + private final int E_NODEA, E_NODEB, E_LINKA, E_LINKB, E_FLAGS, E_DIST, E_GEO, E_KV; private final int intsForFlags; private int edgeEntryBytes; private int edgeCount; @@ -86,8 +86,8 @@ public BaseGraphNodesAndEdges(Directory dir, int intsForFlags, boolean withEleva E_FLAGS = 16; E_DIST = E_FLAGS + intsForFlags * 4; E_GEO = E_DIST + 4; - E_NAME = E_GEO + 4; - edgeEntryBytes = E_NAME + 4; + E_KV = E_GEO + 4; + edgeEntryBytes = E_KV + 4; } public void create(long initSize) { @@ -276,8 +276,8 @@ public void setGeoRef(long edgePointer, int geoRef) { edges.setInt(edgePointer + E_GEO, geoRef); } - public void setNameRef(long edgePointer, int nameRef) { - edges.setInt(edgePointer + E_NAME, nameRef); + public void setKeyValuesRef(long edgePointer, int nameRef) { + edges.setInt(edgePointer + E_KV, nameRef); } public int getNodeA(long edgePointer) { @@ -306,8 +306,8 @@ public int getGeoRef(long edgePointer) { return edges.getInt(edgePointer + E_GEO); } - public int getNameRef(long edgePointer) { - return edges.getInt(edgePointer + E_NAME); + public int getKeyValuesRef(long edgePointer) { + return edges.getInt(edgePointer + E_KV); } public void setEdgeRef(long nodePointer, int edgeRef) { diff --git a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java index 571fa99f632..dec8a2568ba 100644 --- a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java @@ -21,6 +21,8 @@ import com.graphhopper.storage.Graph; import com.graphhopper.storage.IntsRef; +import java.util.Map; + /** * This interface represents an edge and is one possible state of an EdgeIterator. * Example: @@ -180,20 +182,44 @@ public boolean isStoreTwoDirections() { > EdgeIteratorState setReverse(EnumEncodedValue property, T value); > EdgeIteratorState set(EnumEncodedValue property, T fwd, T bwd); - + String get(StringEncodedValue property); - + EdgeIteratorState set(StringEncodedValue property, String value); - + String getReverse(StringEncodedValue property); - + EdgeIteratorState setReverse(StringEncodedValue property, String value); - + EdgeIteratorState set(StringEncodedValue property, String fwd, String bwd); + /** + * Identical to calling getKeyValues().get("name"). I.e. if you need other properties you should prefer to call + * getKeyValues directly instead of getName. Please note that for backward compatibility getName returns an empty + * String instead of null if there was no name set. + * + * @return the stored value for the key "name" in the key-values space of this edge + */ String getName(); - EdgeIteratorState setName(String name); + /** + * This stores the specified key-value pairs in the storage of the current edge. This is more flexible compared to + * the mechanism of flags and EncodedValue and allows to store sparse key value pairs much more efficient. + * But it is slower and more inefficient on retrieval and this setKeyValues method + * should be called only once per edge as it allocates new space everytime this method is called. I.e. for many + * usages like in a custom_model currently the EncodedValue-approach should be preferred. + */ + EdgeIteratorState setKeyValues(Map map); + + Map getKeyValues(); + + /** + * This method returns the value of the specified key. If you need more than one value you should likely better use + * getKeyValues(). + * + * @see #setKeyValues(Map) + */ + Object getValue(String key); /** * Clones this EdgeIteratorState. diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index 8ef7448fdbd..4227185a60c 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -800,7 +800,17 @@ public String getName() { } @Override - public EdgeIteratorState setName(String name) { + public EdgeIteratorState setKeyValues(Map keyValues) { + throw new UnsupportedOperationException("Not supported. Edge is empty."); + } + + @Override + public Map getKeyValues() { + throw new UnsupportedOperationException("Not supported. Edge is empty."); + } + + @Override + public Object getValue(String key) { throw new UnsupportedOperationException("Not supported. Edge is empty."); } diff --git a/core/src/main/java/com/graphhopper/util/details/StreetNameDetails.java b/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java similarity index 62% rename from core/src/main/java/com/graphhopper/util/details/StreetNameDetails.java rename to core/src/main/java/com/graphhopper/util/details/KVStringDetails.java index ca80323f1a3..eb2b50a2e13 100644 --- a/core/src/main/java/com/graphhopper/util/details/StreetNameDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java @@ -19,25 +19,31 @@ import com.graphhopper.util.EdgeIteratorState; -import static com.graphhopper.util.Parameters.Details.STREET_NAME; - /** - * Calculate the speed name segments of a Path + * Return a String value from the key-values * * @author Robin Boldt */ -public class StreetNameDetails extends AbstractPathDetailsBuilder { +public class KVStringDetails extends AbstractPathDetailsBuilder { - private String curStreetName = null; + private String curString = null; + private String key; - public StreetNameDetails() { - super(STREET_NAME); + public KVStringDetails(String name, String key) { + super(name); + this.key = key; } @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { - if (curStreetName == null || !curStreetName.equals(edge.getName())) { - curStreetName = edge.getName(); + if (curString == null) { + // TODO it would be a bit more efficient if we fetch the Map only once per edge when more than one KVStringDetails are requested + curString = (String) edge.getValue(key); + return true; + } + String val = (String) edge.getValue(key); + if (!curString.equals(val)) { + curString = val; return true; } return false; @@ -45,6 +51,6 @@ public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { @Override public Object getCurrentValue() { - return this.curStreetName; + return this.curString; } } diff --git a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java index c3e0849c0a5..5eed6db5692 100644 --- a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java +++ b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java @@ -35,12 +35,14 @@ public class PathDetailsBuilderFactory { public List createPathDetailsBuilders(List requestedPathDetails, EncodedValueLookup evl, Weighting weighting) { List builders = new ArrayList<>(); + if (requestedPathDetails.contains(STREET_NAME)) + builders.add(new KVStringDetails(STREET_NAME, "name")); + if (requestedPathDetails.contains(STREET_REF)) + builders.add(new KVStringDetails(STREET_REF, "ref")); + if (requestedPathDetails.contains(AVERAGE_SPEED)) builders.add(new AverageSpeedDetails(weighting)); - if (requestedPathDetails.contains(STREET_NAME)) - builders.add(new StreetNameDetails()); - if (requestedPathDetails.contains(EDGE_ID)) builders.add(new EdgeIdDetails()); diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 1577484ce7e..01e10c9683e 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -1222,7 +1222,7 @@ public void testKremsCyclewayInstructionsWithWayTypeInfo() { assertEquals("keep left onto Hoher Markt", il.get(4).getTurnDescription(tr)); assertEquals("turn right onto Wegscheid", il.get(6).getTurnDescription(tr)); assertEquals("continue onto Wegscheid", il.get(7).getTurnDescription(tr)); - assertEquals("turn right onto Ringstraße, L73", il.get(8).getTurnDescription(tr)); + assertEquals("turn right onto Ringstraße", il.get(8).getTurnDescription(tr)); assertEquals("keep left onto Eyblparkstraße", il.get(9).getTurnDescription(tr)); assertEquals("keep left onto Austraße", il.get(10).getTurnDescription(tr)); assertEquals("keep left onto Rechte Kremszeile", il.get(11).getTurnDescription(tr)); @@ -2053,8 +2053,8 @@ public void testCurbsides() { GHPoint q = new GHPoint(50.014141, 11.497552); final String itz = "Itzgrund"; final String rotmain = "An den Rotmainauen"; - final String bayreuth = "Bayreuther Straße, KU 18"; - final String kulmbach = "Kulmbacher Straße, KU 18"; + final String bayreuth = "Bayreuther Straße"; + final String kulmbach = "Kulmbacher Straße"; final String adamSeiler = "Adam-Seiler-Straße"; final String friedhof = "Friedhofsweg"; assertCurbsidesPath(h, p, q, asList(CURBSIDE_RIGHT, CURBSIDE_RIGHT), 344, asList(itz, rotmain, rotmain)); @@ -2192,7 +2192,7 @@ public void simplifyWithInstructionsAndPathDetails() { .addPoint(new GHPoint(50.016895, 11.4923)) .addPoint(new GHPoint(50.003464, 11.49157)) .setProfile(profile) - .setPathDetails(Arrays.asList("street_name", "max_speed")); + .setPathDetails(Arrays.asList("street_ref", "max_speed")); req.putHint("elevation", true); GHResponse rsp = hopper.route(req); @@ -2213,14 +2213,14 @@ public void simplifyWithInstructionsAndPathDetails() { assertInstruction(instructions.get(0), "KU 11", "[0, 4[", 4, 4); assertInstruction(instructions.get(1), "B 85", "[4, 16[", 12, 12); // via instructions have length = 0, but the point list must not be empty! - assertInstruction(instructions.get(2), "", "[16, 17[", 0, 1); + assertInstruction(instructions.get(2), null, "[16, 17[", 0, 1); assertInstruction(instructions.get(3), "B 85", "[16, 32[", 16, 16); - assertInstruction(instructions.get(4), "", "[32, 34[", 2, 2); + assertInstruction(instructions.get(4), null, "[32, 34[", 2, 2); assertInstruction(instructions.get(5), "KU 18", "[34, 37[", 3, 3); assertInstruction(instructions.get(6), "St 2189", "[37, 38[", 1, 1); - assertInstruction(instructions.get(7), "", "[38, 40[", 2, 2); + assertInstruction(instructions.get(7), null, "[38, 40[", 2, 2); // finish instructions have length = 0, but the point list must not be empty! - assertInstruction(instructions.get(8), "", "[40, 41[", 0, 1); + assertInstruction(instructions.get(8), null, "[40, 41[", 0, 1); // check max speeds List speeds = path.getPathDetails().get("max_speed"); @@ -2233,17 +2233,17 @@ public void simplifyWithInstructionsAndPathDetails() { assertDetail(speeds.get(6), "null [38, 40]"); // check street_names - List streetNames = path.getPathDetails().get("street_name"); + List streetNames = path.getPathDetails().get("street_ref"); assertDetail(streetNames.get(0), "KU 11 [0, 4]"); assertDetail(streetNames.get(1), "B 85 [4, 32]"); - assertDetail(streetNames.get(2), " [32, 34]"); + assertDetail(streetNames.get(2), "null [32, 34]"); assertDetail(streetNames.get(3), "KU 18 [34, 37]"); assertDetail(streetNames.get(4), "St 2189 [37, 38]"); - assertDetail(streetNames.get(5), " [38, 40]"); + assertDetail(streetNames.get(5), "null [38, 40]"); } - private void assertInstruction(Instruction instruction, String expectedName, String expectedInterval, int expectedLength, int expectedPoints) { - assertEquals(expectedName, instruction.getName()); + private void assertInstruction(Instruction instruction, String expectedRef, String expectedInterval, int expectedLength, int expectedPoints) { + assertEquals(expectedRef, instruction.getExtraInfoJSON().get("ref")); assertEquals(expectedInterval, ((ShallowImmutablePointList) instruction.getPoints()).getIntervalString()); assertEquals(expectedLength, instruction.getLength()); assertEquals(expectedPoints, instruction.getPoints().size()); diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index 9676e38f9c6..1997028799e 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -38,6 +38,7 @@ import static com.graphhopper.storage.AbstractGraphStorageTester.assertPList; import static com.graphhopper.util.Parameters.Details.*; +import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.*; /** @@ -106,7 +107,7 @@ public void testWayList() { assertEquals(path.calcPoints().size() - 1, acc); // force minor change for instructions - edge2.setName("2"); + edge2.setKeyValues(singletonMap("name", "2")); na.setNode(3, 1.0, 1.0); g.edge(1, 3).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 10.0); @@ -173,16 +174,16 @@ public void testFindInstruction() { EdgeIteratorState edge1 = g.edge(0, 1).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge1.setWayGeometry(Helper.createPointList()); - edge1.setName("Street 1"); + edge1.setKeyValues(singletonMap("name", "Street 1")); EdgeIteratorState edge2 = g.edge(1, 2).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge2.setWayGeometry(Helper.createPointList()); - edge2.setName("Street 2"); + edge2.setKeyValues(singletonMap("name", "Street 2")); EdgeIteratorState edge3 = g.edge(2, 3).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge3.setWayGeometry(Helper.createPointList()); - edge3.setName("Street 3"); + edge3.setKeyValues(singletonMap("name", "Street 3")); EdgeIteratorState edge4 = g.edge(3, 4).setDistance(500).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge4.setWayGeometry(Helper.createPointList()); - edge4.setName("Street 4"); + edge4.setKeyValues(singletonMap("name", "Street 4")); g.edge(1, 5).setDistance(10000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); g.edge(2, 5).setDistance(10000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); @@ -501,32 +502,32 @@ public void testCalcInstructionsRoundaboutIssue353() { na.setNode(10, 52.5135, 13.348); na.setNode(11, 52.514, 13.347); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 1).setDistance(5)).setName("MainStreet 2 1"); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 11).setDistance(5)).setName("MainStreet 1 11"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 1).setDistance(5)).setKeyValues(singletonMap("name", "MainStreet 2 1")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 11).setDistance(5)).setKeyValues(singletonMap("name", "MainStreet 1 11")); // roundabout EdgeIteratorState tmpEdge; - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 9).setDistance(2)).setName("3-9"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 9).setDistance(2)).setKeyValues(singletonMap("name", "3-9")); BooleanEncodedValue carManagerRoundabout = carManager.getBooleanEncodedValue(Roundabout.KEY); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(9, 10).setDistance(2)).setName("9-10"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(9, 10).setDistance(2)).setKeyValues(singletonMap("name", "9-10")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(6, 10).setDistance(2)).setName("6-10"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(6, 10).setDistance(2)).setKeyValues(singletonMap("name", "6-10")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(10, 1).setDistance(2)).setName("10-1"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(10, 1).setDistance(2)).setKeyValues(singletonMap("name", "10-1")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 2).setDistance(5)).setName("2-3"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 2).setDistance(5)).setKeyValues(singletonMap("name", "2-3")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 3).setDistance(5)).setName("3-4"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 3).setDistance(5)).setKeyValues(singletonMap("name", "3-4")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(5, 4).setDistance(5)).setName("4-5"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(5, 4).setDistance(5)).setKeyValues(singletonMap("name", "4-5")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 5).setDistance(5)).setName("5-2"); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 5).setDistance(5)).setKeyValues(singletonMap("name", "5-2")); tmpEdge.set(carManagerRoundabout, true); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 7).setDistance(5)).setName("MainStreet 4 7"); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 8).setDistance(5)).setName("5-8"); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 6).setDistance(5)).setName("3-6"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 7).setDistance(5)).setKeyValues(singletonMap("name", "MainStreet 4 7")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 8).setDistance(5)).setKeyValues(singletonMap("name", "5-8")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 6).setDistance(5)).setKeyValues(singletonMap("name", "3-6")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) @@ -605,8 +606,8 @@ public void testCalcInstructionForForkWithSameName() { na.setNode(3, 48.982611, 13.121012); na.setNode(4, 48.982336, 13.121002); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setName("Regener Weg"); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setName("Regener Weg"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "Regener Weg")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setKeyValues(singletonMap("name", "Regener Weg")); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); @@ -638,8 +639,8 @@ public void testCalcInstructionForMotorwayFork() { EnumEncodedValue roadClassEnc = carManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BooleanEncodedValue roadClassLinkEnc = carManager.getBooleanEncodedValue(RoadClassLink.KEY); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setName("A 8").set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setName("A 8").set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "A 8")).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setKeyValues(singletonMap("name", "A 8")).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, true); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); @@ -666,9 +667,9 @@ public void testCalcInstructionsEnterMotorway() { na.setNode(3, 48.630558, 9.459851); na.setNode(4, 48.63054, 9.459406); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setName("A 8"); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setName("A 8"); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 2).setDistance(5)).setName("A 8"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 2).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) @@ -695,9 +696,9 @@ public void testCalcInstructionsMotorwayJunction() { na.setNode(3, 48.706805, 9.162995); na.setNode(4, 48.706705, 9.16329); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setName("A 8"); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("A 8"); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setName("A 8"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -725,9 +726,9 @@ public void testCalcInstructionsOntoOneway() { na.setNode(3, -33.824415, 151.188177); na.setNode(4, -33.824437, 151.187925); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setName("Pacific Highway"); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("Pacific Highway"); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(4, 2).setDistance(5)).setName("Greenwich Road"); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "Pacific Highway")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "Pacific Highway")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(4, 2).setDistance(5)).setKeyValues(singletonMap("name", "Greenwich Road")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -760,9 +761,9 @@ public void testCalcInstructionIssue1047() { EnumEncodedValue roadClassEnc = carManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BooleanEncodedValue roadClassLinkEnc = carManager.getBooleanEncodedValue(RoadClassLink.KEY); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setName("B 156").set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setName("S 108").set(roadClassEnc, RoadClass.SECONDARY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("B 156").set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "B 156")).set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(singletonMap("name", "S 108")).set(roadClassEnc, RoadClass.SECONDARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "B 156")).set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -794,9 +795,9 @@ public void testCalcInstructionContinueLeavingStreet() { na.setNode(3, 48.982611, 13.121012); na.setNode(4, 48.982565, 13.121002); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setName("Regener Weg"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "Regener Weg")); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("Regener Weg"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "Regener Weg")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -824,9 +825,9 @@ public void testCalcInstructionSlightTurn() { na.setNode(3, 48.412034, 15.599411); na.setNode(4, 48.411927, 15.599197); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setName("Stöhrgasse"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "Stöhrgasse")); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setName("Stöhrgasse"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(singletonMap("name", "Stöhrgasse")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -858,13 +859,13 @@ public void testUTurnLeft() { na.setNode(7, 48.402604, 9.994962); GHUtility.setSpeed(60, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), - g.edge(1, 2).setDistance(5).setName("Olgastraße"), - g.edge(2, 3).setDistance(5).setName("Olgastraße"), - g.edge(6, 5).setDistance(5).setName("Olgastraße"), - g.edge(5, 4).setDistance(5).setName("Olgastraße")); + g.edge(1, 2).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße")), + g.edge(2, 3).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße")), + g.edge(6, 5).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße")), + g.edge(5, 4).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße"))); GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), - g.edge(2, 5).setDistance(5).setName("Neithardtstraße"), - g.edge(5, 7).setDistance(5).setName("Neithardtstraße")); + g.edge(2, 5).setDistance(5).setKeyValues(singletonMap("name", "Neithardtstraße")), + g.edge(5, 7).setDistance(5).setKeyValues(singletonMap("name", "Neithardtstraße"))); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -896,13 +897,13 @@ public void testUTurnRight() { na.setNode(7, -33.885692, 151.181445); GHUtility.setSpeed(60, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), - g.edge(1, 2).setDistance(5).setName("Parramatta Road"), - g.edge(2, 3).setDistance(5).setName("Parramatta Road"), - g.edge(4, 5).setDistance(5).setName("Parramatta Road"), - g.edge(5, 6).setDistance(5).setName("Parramatta Road")); + g.edge(1, 2).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road")), + g.edge(2, 3).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road")), + g.edge(4, 5).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road")), + g.edge(5, 6).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road"))); GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), - g.edge(2, 5).setDistance(5).setName("Larkin Street"), - g.edge(5, 7).setDistance(5).setName("Larkin Street")); + g.edge(2, 5).setDistance(5).setKeyValues(singletonMap("name", "Larkin Street")), + g.edge(5, 7).setDistance(5).setKeyValues(singletonMap("name", "Larkin Street"))); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -932,7 +933,7 @@ public void testCalcInstructionsForTurn() { @Test public void testCalcInstructionsForSlightTurnWithOtherSlightTurn() { - // Test for a fork with two sligh turns. Since there are two sligh turns, show the turn instruction + // Test for a fork with two slight turns. Since there are two slight turns, show the turn instruction FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) @@ -961,9 +962,9 @@ public void testCalcInstructionsForSlightTurnOntoDifferentStreet() { na.setNode(3, 48.764149, 8.678926); na.setNode(4, 48.764085, 8.679183); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 3).setDistance(5)).setName("Talstraße, K 4313"); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setName("Calmbacher Straße, K 4312"); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(3, 4).setDistance(5)).setName("Calmbacher Straße, K 4312"); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 3).setDistance(5)).setKeyValues(singletonMap("name", "Talstraße, K 4313")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "Calmbacher Straße, K 4312")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(3, 4).setDistance(5)).setKeyValues(singletonMap("name", "Calmbacher Straße, K 4312")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -1008,11 +1009,11 @@ private Graph generatePathDetailsGraph() { na.setNode(5, 52.516, 13.3452); na.setNode(6, 52.516, 13.344); - GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setName("1-2"); - GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 5).setDistance(5)).setName("4-5"); - GHUtility.setSpeed(90, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setName("2-3"); - GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 4).setDistance(10)).setName("3-4"); - GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 6).setDistance(0.01)).setName("3-4"); + GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "1-2")); + GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 5).setDistance(5)).setKeyValues(singletonMap("name", "4-5")); + GHUtility.setSpeed(90, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "2-3")); + GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 4).setDistance(10)).setKeyValues(singletonMap("name", "3-4")); + GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 6).setDistance(0.01)).setKeyValues(singletonMap("name", "3-4")); return graph; } @@ -1058,20 +1059,20 @@ private RoundaboutGraph() { na.setNode(19, 52.515, 13.368); // roundabout - roundaboutEdges.add(g.edge(3, 2).setDistance(5).setName("2-3")); - roundaboutEdges.add(g.edge(4, 3).setDistance(5).setName("3-4")); - roundaboutEdges.add(g.edge(5, 4).setDistance(5).setName("4-5")); - roundaboutEdges.add(g.edge(2, 5).setDistance(5).setName("5-2")); + roundaboutEdges.add(g.edge(3, 2).setDistance(5).setKeyValues(singletonMap("name", "2-3"))); + roundaboutEdges.add(g.edge(4, 3).setDistance(5).setKeyValues(singletonMap("name", "3-4"))); + roundaboutEdges.add(g.edge(5, 4).setDistance(5).setKeyValues(singletonMap("name", "4-5"))); + roundaboutEdges.add(g.edge(2, 5).setDistance(5).setKeyValues(singletonMap("name", "5-2"))); List bothDir = new ArrayList<>(); List oneDir = new ArrayList<>(roundaboutEdges); - bothDir.add(g.edge(1, 2).setDistance(5).setName("MainStreet 1 2")); - bothDir.add(g.edge(4, 7).setDistance(5).setName("MainStreet 4 7")); - bothDir.add(g.edge(5, 8).setDistance(5).setName("5-8")); + bothDir.add(g.edge(1, 2).setDistance(5).setKeyValues(singletonMap("name", "MainStreet 1 2"))); + bothDir.add(g.edge(4, 7).setDistance(5).setKeyValues(singletonMap("name", "MainStreet 4 7"))); + bothDir.add(g.edge(5, 8).setDistance(5).setKeyValues(singletonMap("name", "5-8"))); - bothDir.add(edge3to6 = g.edge(3, 6).setDistance(5).setName("3-6")); - oneDir.add(edge3to9 = g.edge(3, 9).setDistance(5).setName("3-9")); + bothDir.add(edge3to6 = g.edge(3, 6).setDistance(5).setKeyValues(singletonMap("name", "3-6"))); + oneDir.add(edge3to9 = g.edge(3, 9).setDistance(5).setKeyValues(singletonMap("name", "3-9"))); bothDir.add(g.edge(7, 10).setDistance(5)); bothDir.add(g.edge(10, 11).setDistance(5)); diff --git a/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java index 41ddc7ed379..dcf1dac2e47 100644 --- a/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java @@ -23,6 +23,7 @@ import com.graphhopper.util.shapes.GHPoint; import org.junit.jupiter.api.Test; +import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.*; /** @@ -98,11 +99,11 @@ public void testDistanceFiltering() { na.setNode(nodeID200, point200mAway.lat, point200mAway.lon); // Check that it matches a street 50m away - EdgeIteratorState edge1 = g.edge(nodeId50, farAwayId).setName("Wentworth Street"); + EdgeIteratorState edge1 = g.edge(nodeId50, farAwayId).setKeyValues(singletonMap("name", "Wentworth Street")); assertTrue(createNameSimilarityEdgeFilter("Wentworth Street").accept(edge1)); // Check that it doesn't match streets 200m away - EdgeIteratorState edge2 = g.edge(nodeID200, farAwayId).setName("Wentworth Street"); + EdgeIteratorState edge2 = g.edge(nodeID200, farAwayId).setKeyValues(singletonMap("name", "Wentworth Street")); assertFalse(createNameSimilarityEdgeFilter("Wentworth Street").accept(edge2)); } @@ -302,14 +303,17 @@ public void curvedWayGeometry_issue2319() { pointList.add(43.842711, -79.264588); graph.getNodeAccess().setNode(0, 43.844521, -79.263976); graph.getNodeAccess().setNode(1, 43.842775, -79.264649); - EdgeIteratorState doubtfire = graph.edge(0, 1).setWayGeometry(pointList).set(encoder.getAccessEnc(), true, true).set(encoder.getAverageSpeedEnc(), 60, 60).setName("Doubtfire Crescent"); - EdgeIteratorState golden = graph.edge(0, 1).set(encoder.getAccessEnc(), true, true).set(encoder.getAverageSpeedEnc(), 60, 60).setName("Golden Avenue"); + EdgeIteratorState doubtfire = graph.edge(0, 1).setWayGeometry(pointList).set(encoder.getAccessEnc(), true, true). + set(encoder.getAverageSpeedEnc(), 60, 60).setKeyValues(singletonMap("name", "Doubtfire Crescent")); + EdgeIteratorState golden = graph.edge(0, 1).set(encoder.getAccessEnc(), true, true).set(encoder.getAverageSpeedEnc(), 60, 60). + setKeyValues(singletonMap("name", "Golden Avenue")); graph.getNodeAccess().setNode(2, 43.841501560244744, -79.26366394602502); graph.getNodeAccess().setNode(3, 43.842247922172724, -79.2605663670726); PointList pointList2 = new PointList(1, false); pointList2.add(43.84191413615452, -79.261912128223); - EdgeIteratorState denison = graph.edge(2, 3).setWayGeometry(pointList2).set(encoder.getAccessEnc(), true, true).set(encoder.getAverageSpeedEnc(), 60, 60).setName("Denison Street"); + EdgeIteratorState denison = graph.edge(2, 3).setWayGeometry(pointList2).set(encoder.getAccessEnc(), true, true). + set(encoder.getAverageSpeedEnc(), 60, 60).setKeyValues(singletonMap("name", "Denison Street")); double qlat = 43.842122; double qLon = -79.262162; diff --git a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java index 63472006ccb..7d6b1dd024f 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java @@ -30,6 +30,8 @@ import com.graphhopper.util.Parameters.Routing; import org.junit.jupiter.api.Test; +import java.util.Collections; + import static com.graphhopper.util.GHUtility.createMockedEdgeIteratorState; import static com.graphhopper.util.GHUtility.getEdge; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -55,7 +57,7 @@ public void testWeightWrongHeading() { Weighting instance = new FastestWeighting(encoder, new PMap().putObject(Parameters.Routing.HEADING_PENALTY, 100)); VirtualEdgeIteratorState virtEdge = new VirtualEdgeIteratorState(0, GHUtility.createEdgeKey(1, false, false), 1, 2, 10, - GHUtility.setSpeed(10, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags()), "test", Helper.createPointList(51, 0, 51, 1), false); + GHUtility.setSpeed(10, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags()), Collections.singletonMap("name", "test"), Helper.createPointList(51, 0, 51, 1), false); double time = instance.calcEdgeWeight(virtEdge, false); virtEdge.setUnfavored(true); diff --git a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java index 83cfd305a9a..e476f8da013 100644 --- a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java +++ b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java @@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test; import java.io.File; +import java.util.Collections; import static com.graphhopper.routing.util.EncodingManager.getKey; import static org.junit.jupiter.api.Assertions.*; @@ -258,7 +259,8 @@ public void testUpdateUnidirectional() { @Test public void testCopyProperties() { graph = createGHStorage(); - EdgeIteratorState edge = graph.edge(1, 3).setDistance(10).set(carAccessEnc, true, false).setName("testing").setWayGeometry(Helper.createPointList(1, 2)); + EdgeIteratorState edge = graph.edge(1, 3).setDistance(10).set(carAccessEnc, true, false). + setKeyValues(Collections.singletonMap("name", "testing")).setWayGeometry(Helper.createPointList(1, 2)); EdgeIteratorState newEdge = graph.edge(1, 3).setDistance(10).set(carAccessEnc, true, false); newEdge.copyPropertiesFrom(edge); @@ -646,10 +648,10 @@ public void testGetAllEdges() { public void testEdgeKVStorage() { graph = createGHStorage(); EdgeIteratorState iter1 = graph.edge(0, 1).setDistance(10).set(carAccessEnc, true, true); - iter1.setName("named street1"); + iter1.setKeyValues(Collections.singletonMap("name", "named street1")); EdgeIteratorState iter2 = graph.edge(0, 1).setDistance(10).set(carAccessEnc, true, true); - iter2.setName("named street2"); + iter2.setKeyValues(Collections.singletonMap("name", "named street2")); assertEquals(graph.getEdgeIteratorState(iter1.getEdge(), iter1.getAdjNode()).getName(), "named street1"); assertEquals(graph.getEdgeIteratorState(iter2.getEdge(), iter2.getAdjNode()).getName(), "named street2"); diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java index 939c9d07449..8bbdd257292 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java @@ -23,6 +23,8 @@ import com.graphhopper.util.shapes.BBox; import org.junit.jupiter.api.Test; +import java.util.Collections; + import static com.graphhopper.util.EdgeIteratorState.REVERSE_STATE; import static com.graphhopper.util.FetchMode.*; import static org.junit.jupiter.api.Assertions.*; @@ -64,8 +66,8 @@ public void testSave_and_fileFormat() { graph.edge(9, 11).setDistance(200).set(carAccessEnc, true, true); graph.edge(1, 2).setDistance(120).set(carAccessEnc, true, false); - iter1.setName("named street1"); - iter2.setName("named street2"); + iter1.setKeyValues(Collections.singletonMap("name", "named street1")); + iter2.setKeyValues(Collections.singletonMap("name", "named street2")); checkGraph(graph); graph.flush(); diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java index e73beea37bd..b2e7d27cb2c 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java @@ -26,6 +26,7 @@ import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; +import java.util.Collections; import java.util.Random; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -72,8 +73,8 @@ public void testSave_and_fileFormat() { setTurnCost(iter2.getEdge(), 0, iter1.getEdge(), 666); setTurnCost(iter1.getEdge(), 1, iter2.getEdge(), 815); - iter1.setName("named street1"); - iter2.setName("named street2"); + iter1.setKeyValues(Collections.singletonMap("name", "named street1")); + iter2.setKeyValues(Collections.singletonMap("name", "named street2")); checkGraph(graph); graph.flush(); diff --git a/core/src/test/java/com/graphhopper/util/InstructionListTest.java b/core/src/test/java/com/graphhopper/util/InstructionListTest.java index f5f5fbf7d46..03978d9db52 100644 --- a/core/src/test/java/com/graphhopper/util/InstructionListTest.java +++ b/core/src/test/java/com/graphhopper/util/InstructionListTest.java @@ -46,6 +46,7 @@ import java.util.List; import java.util.Locale; +import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.*; /** @@ -100,30 +101,30 @@ Graph createTestGraph() { na.setNode(6, 1.0, 1.0); na.setNode(7, 1.0, 1.1); na.setNode(8, 1.0, 1.2); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setName("0-1"); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setName("1-2"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(singletonMap("name", "0-1")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(singletonMap("name", "1-2")); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(11000)); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setName("1-4"); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setName("5-2"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setKeyValues(singletonMap("name", "1-4")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setKeyValues(singletonMap("name", "5-2")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setName("3-6"); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setName("4-7"); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setName("5-8"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setKeyValues(singletonMap("name", "3-6")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setKeyValues(singletonMap("name", "4-7")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setKeyValues(singletonMap("name", "5-8")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setName("6-7"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setKeyValues(singletonMap("name", "6-7")); EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(10000)); PointList list = new PointList(); list.add(1.0, 1.15); list.add(1.0, 1.16); iter.setWayGeometry(list); - iter.setName("7-8"); + iter.setKeyValues(singletonMap("name", "7-8")); // missing edge name GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(10000)); EdgeIteratorState iter2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 9).setDistance(20000)); list.clear(); list.add(1.0, 1.3); - iter2.setName("8-9"); + iter2.setKeyValues(singletonMap("name", "8-9")); iter2.setWayGeometry(list); return g; } @@ -192,11 +193,11 @@ public void testWayList2() { na.setNode(3, 10.0, 10.08); na.setNode(4, 10.1, 10.10); na.setNode(5, 10.2, 10.13); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setName("3-4"); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setName("4-5"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setKeyValues(singletonMap("name", "3-4")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setKeyValues(singletonMap("name", "4-5")); EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(100)); - iter.setName("2-4"); + iter.setKeyValues(singletonMap("name", "2-4")); PointList list = new PointList(); list.add(10.20, 10.05); iter.setWayGeometry(list); @@ -231,11 +232,11 @@ public void testNoInstructionIfSameStreet() { na.setNode(3, 10.0, 10.05); na.setNode(4, 10.1, 10.10); na.setNode(5, 10.2, 10.15); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setName("street"); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setName("4-5"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setKeyValues(singletonMap("name", "street")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setKeyValues(singletonMap("name", "4-5")); EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(100)); - iter.setName("street"); + iter.setKeyValues(singletonMap("name", "street")); PointList list = new PointList(); list.add(10.20, 10.05); iter.setWayGeometry(list); @@ -330,9 +331,9 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp3() { GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20)); GHUtility.setSpeed(4, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20)); - g.edge(1, 2).set(rcEV, RoadClass.RESIDENTIAL).setName("pfarr"); - g.edge(2, 3).set(rcEV, RoadClass.RESIDENTIAL).setName("pfarr"); - g.edge(2, 4).set(rcEV, RoadClass.PEDESTRIAN).setName("markt"); + g.edge(1, 2).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(singletonMap("name", "pfarr")); + g.edge(2, 3).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(singletonMap("name", "pfarr")); + g.edge(2, 4).set(rcEV, RoadClass.PEDESTRIAN).setKeyValues(singletonMap("name", "markt")); FastestWeighting weighting = new FastestWeighting(bike); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 3); @@ -364,13 +365,12 @@ public void testInstructionIfTurn() { na.setNode(3, 48.412614, 15.604872); na.setNode(4, 48.412148, 15.605543); - GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(1, 2).setDistance(20)); - GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20)); - GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20)); - - g.edge(1, 2).set(rcEV, RoadClass.RESIDENTIAL).setName("land"); - g.edge(2, 3).set(rcEV, RoadClass.SECONDARY).setName("ring"); - g.edge(2, 4).set(rcEV, RoadClass.SECONDARY).setName("ring"); + GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(1, 2).setDistance(20)) + .set(rcEV, RoadClass.RESIDENTIAL); + GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20)) + .set(rcEV, RoadClass.SECONDARY); + GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20)) + .set(rcEV, RoadClass.SECONDARY); FastestWeighting weighting = new FastestWeighting(bike); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 4); @@ -404,11 +404,11 @@ public void testInstructionIfSlightTurnForCustomProfile() { na.setNode(4, 43.729476, 7.417633); DecimalEncodedValue priorityEnc = tmpEM.getDecimalEncodedValue(EncodingManager.getKey(foot.toString(), "priority")); // default is priority=0 so set it to 1 - GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(1, 2).setDistance(20).setName("myroad").set(priorityEnc, 1)); - GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20).setName("myroad").set(priorityEnc, 1)); + GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(1, 2).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1)); + GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1)); PointList pointList = new PointList(); pointList.add(43.729627, 7.41749); - GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20).setName("myroad").set(priorityEnc, 1).setWayGeometry(pointList)); + GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1).setWayGeometry(pointList)); Weighting weighting = CustomModelParser.createWeighting(foot, tmpEM, DefaultTurnCostProvider.NO_TURN_COST_PROVIDER, new CustomModel().setDistanceInfluence(0)); Path p = new Dijkstra(g, weighting, tMode).calcPath(4, 3); @@ -494,12 +494,12 @@ public void testFind() { na.setNode(6, 15.1, 10.1); na.setNode(7, 15.1, 9.8); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(10000)).setName("1-2"); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10000)).setName("2-3"); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000)).setName("2-6"); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(10000)).setName("3-4").setWayGeometry(waypoint); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000)).setName("3-7"); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000)).setName("4-5"); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(10000)).setKeyValues(singletonMap("name", "1-2")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10000)).setKeyValues(singletonMap("name", "2-3")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000)).setKeyValues(singletonMap("name", "2-6")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(10000)).setKeyValues(singletonMap("name", "3-4")).setWayGeometry(waypoint); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000)).setKeyValues(singletonMap("name", "3-7")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000)).setKeyValues(singletonMap("name", "4-5")); FastestWeighting weighting = new FastestWeighting(carEncoder); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 5); diff --git a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java index cff4cb26800..15635cd3a27 100644 --- a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java +++ b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java @@ -38,6 +38,7 @@ import java.util.*; import static com.graphhopper.util.Parameters.Details.AVERAGE_SPEED; +import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -76,24 +77,24 @@ public void testScenario() { BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setName("0-1"); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setName("1-2"); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(singletonMap("name", "0-1")); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(singletonMap("name", "1-2")); GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(11000)); - GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setName("1-4"); - GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setName("5-2"); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setKeyValues(singletonMap("name", "1-4")); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setKeyValues(singletonMap("name", "5-2")); - GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setName("3-6"); - GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setName("4-7"); - GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setName("5-8"); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setKeyValues(singletonMap("name", "3-6")); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setKeyValues(singletonMap("name", "4-7")); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setKeyValues(singletonMap("name", "5-8")); - GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setName("6-7"); + GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setKeyValues(singletonMap("name", "6-7")); EdgeIteratorState tmpEdge = GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(10000)); PointList list = new PointList(); list.add(1.0, 1.15); list.add(1.0, 1.16); tmpEdge.setWayGeometry(list); - tmpEdge.setName("7-8"); + tmpEdge.setKeyValues(singletonMap("name", "7-8")); // missing edge name GHUtility.setSpeed(45, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(10000)); @@ -103,7 +104,7 @@ public void testScenario() { list.add(1.0, 1.3001); list.add(1.0, 1.3002); list.add(1.0, 1.3003); - tmpEdge.setName("8-9"); + tmpEdge.setKeyValues(singletonMap("name", "8-9")); tmpEdge.setWayGeometry(list); // Path is: [0 0-1, 3 1-4, 6 4-7, 9 7-8, 11 8-9, 10 9-10] diff --git a/example/src/main/java/com/graphhopper/example/LocationIndexExample.java b/example/src/main/java/com/graphhopper/example/LocationIndexExample.java index e7a2d9f1a6c..dbf599a3665 100644 --- a/example/src/main/java/com/graphhopper/example/LocationIndexExample.java +++ b/example/src/main/java/com/graphhopper/example/LocationIndexExample.java @@ -11,6 +11,8 @@ import com.graphhopper.storage.index.Snap; import com.graphhopper.util.EdgeIteratorState; +import java.util.Collections; + public class LocationIndexExample { public static void main(String[] args) { String relDir = args.length == 1 ? args[0] : ""; @@ -36,7 +38,7 @@ public static void graphhopperLocationIndex(String relDir) { public static void lowLevelLocationIndex() { // If you don't use the GraphHopper class you have to use the low level API: BaseGraph graph = new BaseGraph.Builder(EncodingManager.create(FlagEncoders.createCar())).create(); - graph.edge(0, 1).setName("test edge"); + graph.edge(0, 1).setKeyValues(Collections.singletonMap("name", "test edge")); graph.getNodeAccess().setNode(0, 12, 42); graph.getNodeAccess().setNode(1, 12.01, 42.01); @@ -47,6 +49,6 @@ public static void lowLevelLocationIndex() { index.prepareIndex(); Snap snap = index.findClosest(12, 42, EdgeFilter.ALL_EDGES); EdgeIteratorState edge = snap.getClosestEdge(); - assert edge.getName().equals("test edge"); + assert edge.getKeyValues().get("name").equals("test edge"); } } diff --git a/navigation/src/main/java/com/graphhopper/navigation/NavigateResponseConverter.java b/navigation/src/main/java/com/graphhopper/navigation/NavigateResponseConverter.java index ad0c6d7e911..e749bbe4690 100644 --- a/navigation/src/main/java/com/graphhopper/navigation/NavigateResponseConverter.java +++ b/navigation/src/main/java/com/graphhopper/navigation/NavigateResponseConverter.java @@ -278,7 +278,7 @@ private static void putBannerInstructions(InstructionList instructions, double d private static void putSingleBannerInstruction(Instruction instruction, Locale locale, TranslationMap translationMap, ObjectNode singleBannerInstruction) { String bannerInstructionName = instruction.getName(); - if (bannerInstructionName == null || bannerInstructionName.isEmpty()) { + if (bannerInstructionName.isEmpty()) { // Fix for final instruction and for instructions without name bannerInstructionName = instruction.getTurnDescription(translationMap.getWithFallBack(locale)); diff --git a/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java b/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java index f60ca76ee10..08f8f8cf79a 100644 --- a/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java +++ b/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java @@ -227,7 +227,6 @@ public void voiceInstructionTranslationTest() { steps = json.get("routes").get(0).get("legs").get(0).get("steps"); voiceInstruction = steps.get(14).get("voiceInstructions").get(0); assertEquals("In 2 Kilometern rechts halten", voiceInstruction.get("announcement").asText()); - } @Test @@ -245,6 +244,7 @@ public void roundaboutDegreesTest() { JsonNode primary = bannerInstructions.get(0).get("primary"); assertEquals("roundabout", primary.get("type").asText()); + assertEquals("At roundabout, take exit 2 onto CG-3", primary.get("text").asText()); assertEquals("right", primary.get("modifier").asText()); assertEquals(222, primary.get("degrees").asDouble(), 1); diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java index 705703e65e4..190ad2aacdc 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java @@ -10,6 +10,7 @@ import com.graphhopper.util.shapes.BBox; import java.util.Iterator; +import java.util.Map; class PtGraphAsAdjacencyList implements Graph { private final PtGraph ptGraph; @@ -302,7 +303,17 @@ public String getName() { } @Override - public EdgeIteratorState setName(String name) { + public EdgeIteratorState setKeyValues(Map map) { + throw new RuntimeException(); + } + + @Override + public Map getKeyValues() { + throw new RuntimeException(); + } + + @Override + public Object getValue(String key) { throw new RuntimeException(); } diff --git a/web-api/src/main/java/com/graphhopper/util/Instruction.java b/web-api/src/main/java/com/graphhopper/util/Instruction.java index 27e78f4ef2a..7bc11d849eb 100644 --- a/web-api/src/main/java/com/graphhopper/util/Instruction.java +++ b/web-api/src/main/java/com/graphhopper/util/Instruction.java @@ -45,7 +45,7 @@ public class Instruction { protected PointList points; protected boolean rawName; protected int sign; - protected String name; + protected String name = ""; protected double distance; protected long time; protected Map extraInfo = new HashMap<>(3); @@ -56,7 +56,7 @@ public class Instruction { */ public Instruction(int sign, String name, PointList pl) { this.sign = sign; - this.name = name; + if (name != null) this.name = name; this.points = pl; } @@ -84,7 +84,11 @@ public String getName() { } public void setName(String name) { - this.name = name; + if (name != null) this.name = name; + } + + String getStreetName() { + return getName().isEmpty() && extraInfo.get("ref") instanceof String ? (String) extraInfo.get("ref") : getName(); } public Map getExtraInfoJSON() { @@ -161,7 +165,7 @@ public String getTurnDescription(Translation tr) { return getName(); String str; - String streetName = getName(); + String streetName = getStreetName(); int indi = getSign(); if (indi == Instruction.CONTINUE_ON_STREET) { str = Helper.isEmpty(streetName) ? tr.tr("continue") : tr.tr("continue_onto", streetName); @@ -211,7 +215,7 @@ public String getTurnDescription(Translation tr) { if (dir == null) str = tr.tr("unknown", indi); else - str = Helper.isEmpty(streetName) ? dir : tr.tr("turn_onto", dir, streetName); + str = streetName.isEmpty() ? dir : tr.tr("turn_onto", dir, streetName); } return str; } diff --git a/web-api/src/main/java/com/graphhopper/util/Parameters.java b/web-api/src/main/java/com/graphhopper/util/Parameters.java index 9c563e6117f..fa4d9a35b1b 100644 --- a/web-api/src/main/java/com/graphhopper/util/Parameters.java +++ b/web-api/src/main/java/com/graphhopper/util/Parameters.java @@ -199,6 +199,7 @@ public static final class Details { public static final String AVERAGE_SPEED = "average_speed"; public static final String STREET_NAME = "street_name"; + public static final String STREET_REF = "street_ref"; public static final String EDGE_ID = "edge_id"; public static final String EDGE_KEY = "edge_key"; public static final String TIME = "time"; diff --git a/web-api/src/main/java/com/graphhopper/util/RoundaboutInstruction.java b/web-api/src/main/java/com/graphhopper/util/RoundaboutInstruction.java index 493836d7ba8..e2991174d75 100644 --- a/web-api/src/main/java/com/graphhopper/util/RoundaboutInstruction.java +++ b/web-api/src/main/java/com/graphhopper/util/RoundaboutInstruction.java @@ -114,7 +114,7 @@ public String getTurnDescription(Translation tr) { return getName(); String str; - String streetName = getName(); + String streetName = getStreetName(); int indi = getSign(); if (indi == Instruction.USE_ROUNDABOUT) { if (!exited) { diff --git a/web-api/src/main/java/com/graphhopper/util/ViaInstruction.java b/web-api/src/main/java/com/graphhopper/util/ViaInstruction.java index d521876703b..d6adc440aee 100644 --- a/web-api/src/main/java/com/graphhopper/util/ViaInstruction.java +++ b/web-api/src/main/java/com/graphhopper/util/ViaInstruction.java @@ -55,6 +55,6 @@ public String getTurnDescription(Translation tr) { if (rawName) return getName(); - return tr.tr("stopover", viaPosition); + return tr.tr("stopover", getViaCount()); } } diff --git a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java index 9053834d1f2..7649e4651b5 100644 --- a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java +++ b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java @@ -46,6 +46,7 @@ import java.util.List; import java.util.Locale; +import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.*; public class GpxConversionsTest { @@ -80,12 +81,12 @@ public void testInstructionsWithTimeAndPlace() { BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); - GHUtility.setSpeed(63, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(7000).setName("1-2")); - GHUtility.setSpeed(72, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(8000).setName("2-3")); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000).setName("2-6")); - GHUtility.setSpeed(81, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(9000).setName("3-4")); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000).setName("3-7")); - GHUtility.setSpeed(90, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000).setName("4-5")); + GHUtility.setSpeed(63, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(7000).setKeyValues(singletonMap("name", "1-2"))); + GHUtility.setSpeed(72, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(8000).setKeyValues(singletonMap("name", "2-3"))); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000).setKeyValues(singletonMap("name", "2-6"))); + GHUtility.setSpeed(81, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(9000).setKeyValues(singletonMap("name", "3-4"))); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000).setKeyValues(singletonMap("name", "3-7"))); + GHUtility.setSpeed(90, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000).setKeyValues(singletonMap("name", "4-5"))); ShortestWeighting weighting = new ShortestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); diff --git a/web/src/test/java/com/graphhopper/application/MapMatchingTest.java b/web/src/test/java/com/graphhopper/application/MapMatchingTest.java index 2733bbfcbeb..5d3a0644cee 100644 --- a/web/src/test/java/com/graphhopper/application/MapMatchingTest.java +++ b/web/src/test/java/com/graphhopper/application/MapMatchingTest.java @@ -266,8 +266,8 @@ public void testLoop2(PMap hints) throws IOException { mapMatching.setMeasurementErrorSigma(50); Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/tour-with-loop.gpx"), Gpx.class); MatchResult mr = mapMatching.match(GpxConversions.getEntries(gpx.trk.get(0))); - assertEquals(Arrays.asList("Jahnallee, B 87, B 181", "Funkenburgstraße", - "Gustav-Adolf-Straße", "Tschaikowskistraße", "Jahnallee, B 87, B 181", + assertEquals(Arrays.asList("Jahnallee", "Funkenburgstraße", + "Gustav-Adolf-Straße", "Tschaikowskistraße", "Jahnallee", "Lessingstraße"), fetchStreets(mr.getEdgeMatches())); } diff --git a/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java b/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java index 4c1ec1d6072..7771ba85e7c 100644 --- a/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java @@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -86,7 +87,8 @@ private EdgeIteratorState getEdgeIterator() { PointList pointList = new PointList(); pointList.add(-3.4445, -38.9990); pointList.add(-3.5550, -38.7990); - return new VirtualEdgeIteratorState(0, 0, 0, 1, 10, new IntsRef(1), "test of iterator", pointList, false); + return new VirtualEdgeIteratorState(0, 0, 0, 1, 10, new IntsRef(1), + Collections.singletonMap("name", "test of iterator"), pointList, false); } } diff --git a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java index 93758f25a2a..f4df3193516 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java @@ -100,7 +100,7 @@ public void testWithDetailsInResponse() throws IOException { assertEquals(21, layer.getGeometries().size()); Geometry geometry = layer.getGeometries().stream(). - filter(g -> attributes(g).get("name").equals("Avinguda de Tarragona, CG-1")) + filter(g -> attributes(g).get("name").equals("Avinguda de Tarragona")) .findFirst().get(); assertEquals("road", attributes(geometry).get("road_environment")); assertEquals(50.0, attributes(geometry).get("max_speed")); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java index e95e7eb230c..1118ef29bbe 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java @@ -293,9 +293,9 @@ public void doNotReadFinishInstruction(TestParam p) { assertEquals("", finishInstructionName); } - void isBetween(double from, double to, double expected) { - assertTrue(expected >= from, "expected value " + expected + " was smaller than limit " + from); - assertTrue(expected <= to, "expected value " + expected + " was bigger than limit " + to); + void isBetween(double from, double to, double value) { + assertTrue(value >= from, "value " + value + " was smaller than expected limit " + from); + assertTrue(value <= to, "value " + value + " was bigger than expected limit " + to); } @ParameterizedTest diff --git a/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java index 11d279d3651..18e82924848 100644 --- a/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java @@ -113,7 +113,7 @@ public void requestDetails() { assertEquals(20, Double.parseDouble(row[2]), .1); row = lines[249].split(","); - assertEquals("Carretera d'Engolasters CS-200", row[0]); + assertEquals("Carretera d'Engolasters", row[0]); assertEquals("secondary", row[1]); assertTrue(Double.isInfinite(Double.parseDouble(row[2]))); } From 702b8f13f08bf52084d3ba1949435ca2e00fdc8e Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 4 Jul 2022 17:25:40 +0200 Subject: [PATCH 082/389] update i18n --- .../resources/com/graphhopper/util/ar.txt | 1 + .../resources/com/graphhopper/util/ast.txt | 1 + .../resources/com/graphhopper/util/bg.txt | 1 + .../resources/com/graphhopper/util/bn_BN.txt | 1 + .../resources/com/graphhopper/util/ca.txt | 1 + .../resources/com/graphhopper/util/cs_CZ.txt | 1 + .../resources/com/graphhopper/util/da_DK.txt | 1 + .../resources/com/graphhopper/util/de_DE.txt | 5 ++- .../resources/com/graphhopper/util/el.txt | 39 ++++++++++--------- .../resources/com/graphhopper/util/en_US.txt | 1 + .../resources/com/graphhopper/util/eo.txt | 1 + .../resources/com/graphhopper/util/es.txt | 1 + .../resources/com/graphhopper/util/fa.txt | 1 + .../resources/com/graphhopper/util/fi.txt | 1 + .../resources/com/graphhopper/util/fil.txt | 1 + .../resources/com/graphhopper/util/fr_CH.txt | 1 + .../resources/com/graphhopper/util/fr_FR.txt | 1 + .../resources/com/graphhopper/util/gl.txt | 1 + .../resources/com/graphhopper/util/he.txt | 1 + .../resources/com/graphhopper/util/hr_HR.txt | 1 + .../resources/com/graphhopper/util/hsb.txt | 1 + .../resources/com/graphhopper/util/hu_HU.txt | 1 + .../resources/com/graphhopper/util/in_ID.txt | 1 + .../resources/com/graphhopper/util/it.txt | 1 + .../resources/com/graphhopper/util/ja.txt | 1 + .../resources/com/graphhopper/util/ko.txt | 13 ++++--- .../resources/com/graphhopper/util/lt_LT.txt | 1 + .../resources/com/graphhopper/util/ne.txt | 1 + .../resources/com/graphhopper/util/nl.txt | 1 + .../resources/com/graphhopper/util/pl_PL.txt | 1 + .../resources/com/graphhopper/util/pt_BR.txt | 1 + .../resources/com/graphhopper/util/pt_PT.txt | 1 + .../resources/com/graphhopper/util/ro.txt | 1 + .../resources/com/graphhopper/util/ru.txt | 1 + .../resources/com/graphhopper/util/sk.txt | 1 + .../resources/com/graphhopper/util/sl_SI.txt | 1 + .../resources/com/graphhopper/util/sr_RS.txt | 1 + .../resources/com/graphhopper/util/sv_SE.txt | 1 + .../resources/com/graphhopper/util/tr.txt | 1 + .../resources/com/graphhopper/util/uk.txt | 1 + .../resources/com/graphhopper/util/vi_VN.txt | 1 + .../resources/com/graphhopper/util/zh_CN.txt | 1 + .../resources/com/graphhopper/util/zh_HK.txt | 1 + .../resources/com/graphhopper/util/zh_TW.txt | 1 + 44 files changed, 71 insertions(+), 27 deletions(-) diff --git a/core/src/main/resources/com/graphhopper/util/ar.txt b/core/src/main/resources/com/graphhopper/util/ar.txt index 9c6e4740904..832198046f6 100644 --- a/core/src/main/resources/com/graphhopper/util/ar.txt +++ b/core/src/main/resources/com/graphhopper/util/ar.txt @@ -13,6 +13,7 @@ turn_slight_right=إستدر لليمين قليلا turn_sharp_left=اتجه قليلاً لليسار turn_sharp_right=اتجه قليلاً لليمين u_turn=الدوران للإتجاه المعاكس +toward_destination= unknown=علامة غير معرفة '%1$s' via=من خلال hour_abbr=ساعة diff --git a/core/src/main/resources/com/graphhopper/util/ast.txt b/core/src/main/resources/com/graphhopper/util/ast.txt index 212085a831e..760da8f4f73 100644 --- a/core/src/main/resources/com/graphhopper/util/ast.txt +++ b/core/src/main/resources/com/graphhopper/util/ast.txt @@ -13,6 +13,7 @@ turn_slight_right=xira llixeramente a la drecha turn_sharp_left=xira fuerte a la izquierda turn_sharp_right=xira fuerte a la drecha u_turn=da vuelta atrás +toward_destination= unknown=signu indicador desconocíu '%1$s' via=pasando per hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/bg.txt b/core/src/main/resources/com/graphhopper/util/bg.txt index e63c3b7561f..ce530055c36 100644 --- a/core/src/main/resources/com/graphhopper/util/bg.txt +++ b/core/src/main/resources/com/graphhopper/util/bg.txt @@ -13,6 +13,7 @@ turn_slight_right=завий леко надясно turn_sharp_left=завий рязко наляво turn_sharp_right=завий рязко надясно u_turn= +toward_destination= unknown= via=през hour_abbr=ч diff --git a/core/src/main/resources/com/graphhopper/util/bn_BN.txt b/core/src/main/resources/com/graphhopper/util/bn_BN.txt index d914c370757..bd9e1be684e 100644 --- a/core/src/main/resources/com/graphhopper/util/bn_BN.txt +++ b/core/src/main/resources/com/graphhopper/util/bn_BN.txt @@ -13,6 +13,7 @@ turn_slight_right=ektu dane jan turn_sharp_left=bame jan turn_sharp_right=dane jan u_turn=u turn nin +toward_destination= unknown= via= hour_abbr= diff --git a/core/src/main/resources/com/graphhopper/util/ca.txt b/core/src/main/resources/com/graphhopper/util/ca.txt index 413e0f031ef..ce859a90167 100644 --- a/core/src/main/resources/com/graphhopper/util/ca.txt +++ b/core/src/main/resources/com/graphhopper/util/ca.txt @@ -13,6 +13,7 @@ turn_slight_right=gira lleugerament a la dreta turn_sharp_left=gira just a l'esquerra turn_sharp_right=gira just a la dreta u_turn=fes la volta +toward_destination= unknown=instrucció desconeguda «%1$s» via=passant per hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/cs_CZ.txt b/core/src/main/resources/com/graphhopper/util/cs_CZ.txt index 98ece1c2df1..d996b198382 100644 --- a/core/src/main/resources/com/graphhopper/util/cs_CZ.txt +++ b/core/src/main/resources/com/graphhopper/util/cs_CZ.txt @@ -13,6 +13,7 @@ turn_slight_right=odbočte mírně vpravo turn_sharp_left=odbočte ostře vlevo turn_sharp_right=odbočte ostře vpravo u_turn=otočte se +toward_destination= unknown=neznámý pokyn „%1$s“ via=přes hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/da_DK.txt b/core/src/main/resources/com/graphhopper/util/da_DK.txt index dd281c67d0c..89d50190080 100644 --- a/core/src/main/resources/com/graphhopper/util/da_DK.txt +++ b/core/src/main/resources/com/graphhopper/util/da_DK.txt @@ -13,6 +13,7 @@ turn_slight_right=drej lidt til højre turn_sharp_left=drej skarpt til venstre turn_sharp_right=drej skarpt til højre u_turn=foretag en U-vending +toward_destination= unknown=ukendt instruktionsskilt '%1$s' via=via hour_abbr=t diff --git a/core/src/main/resources/com/graphhopper/util/de_DE.txt b/core/src/main/resources/com/graphhopper/util/de_DE.txt index 0935c4b42ce..23e5dcb03a6 100644 --- a/core/src/main/resources/com/graphhopper/util/de_DE.txt +++ b/core/src/main/resources/com/graphhopper/util/de_DE.txt @@ -13,6 +13,7 @@ turn_slight_right=leicht rechts abbiegen turn_sharp_left=scharf links abbiegen turn_sharp_right=scharf rechts abbiegen u_turn=wenden +toward_destination=%1$s und Richtung %2$s fahren unknown=unbekanntes Richtungszeichen '%1$s' via=über hour_abbr=h @@ -94,5 +95,5 @@ navigate.in_mi_singular=In 1 Meile navigate.in_mi=In %1$s Meilen navigate.in_ft=In %1$s Fuß navigate.for_mi=für %1$s Meilen -navigate.warning= -navigate.accept_risks_after_warning= +navigate.warning=Achtung: diese Applikation ist experimentell! Benutzung auf eigene Gefahr! +navigate.accept_risks_after_warning=I verstehe und akzeptiere das Risiko diff --git a/core/src/main/resources/com/graphhopper/util/el.txt b/core/src/main/resources/com/graphhopper/util/el.txt index ece15bde5c9..8ead1ab5fa3 100644 --- a/core/src/main/resources/com/graphhopper/util/el.txt +++ b/core/src/main/resources/com/graphhopper/util/el.txt @@ -13,6 +13,7 @@ turn_slight_right=στρίψτε λοξά δεξιά turn_sharp_left=στρίψτε κλειστά αριστερά turn_sharp_right=στρίψτε κλειστά δεξιά u_turn=κάνετε αναστροφή +toward_destination= unknown=άγνωστη οδηγία '%1$s' via=μέσω hour_abbr=h @@ -36,9 +37,9 @@ roundabout_exit_onto=Στον κυκλικό κόμβο βγείτε στην έ total_ascend=%1$s συνολική ανάβαση total_descend=%1$s συνολική κατάβαση way_contains_ford=υπάρχει πέρασμα στο δρόμο -way_contains_ferry= -way_contains_private= -way_contains_toll= +way_contains_ferry=χρησιμοποιήστε το ferry +way_contains_private=ιδιωτικός δρόμος +way_contains_toll=δρόμος με διόδια pt_start_trip=μπείτε στο %1$s pt_end_trip=αφήστε το %1$s pt_transfer_to=αλλάξτε στο %1$s @@ -59,11 +60,11 @@ web.server_status=Κατάσταση web.zoom_in=Μεγέθυνση web.zoom_out=Σμίκρυνση web.drag_to_reorder=Σύρετε για αναδιάταξη -web.route_timed_out= -web.route_request_failed= -web.current_location= -web.searching_location= -web.searching_location_failed= +web.route_timed_out=Ο υπολογισμός διαδρομής απέτυχε λόγω εξάντλησης χρόνου +web.route_request_failed=Ο υπολογισμός διαδρομής απέτυχε +web.current_location=Τωρινή τοποθεσία +web.searching_location=Αναζήτηση τοποθεσίας +web.searching_location_failed=Η αναζήτηση τοποθεσίας απέτυχε web.via_hint=Μέσω web.from_hint=Αφετηρία web.gpx_export_button=Εξαγωγή GPX @@ -85,14 +86,14 @@ web.bus=Λεωφορείο web.truck=Φορτηγό web.staticlink=στατική διεύθυνση web.motorcycle=Μοτοσυκλέτα -navigate.in_km_singular= -navigate.in_km= -navigate.in_m= -navigate.for_km= -navigate.then= -navigate.in_mi_singular= -navigate.in_mi= -navigate.in_ft= -navigate.for_mi= -navigate.warning= -navigate.accept_risks_after_warning= +navigate.in_km_singular=Σε 1 χιλιόμετρο +navigate.in_km=Σε %1$s χιλιόμετρα +navigate.in_m=Σε %1$s μέτρα +navigate.for_km=Για %1$s χιλιόμετρα +navigate.then=τότε +navigate.in_mi_singular=Σε 1 μίλη +navigate.in_mi=Σε %1$s μίλια +navigate.in_ft=Σε %1$s πόδια +navigate.for_mi=για %1$s μίλια +navigate.warning=ΠΡΟΣΟΧΗ: Αυτή η εφαρμογή είναι πειραματική! Χρησιμοποιήστε την με δική σας ευθύνη! +navigate.accept_risks_after_warning=Καταλαβαίνω και συμφωνώ diff --git a/core/src/main/resources/com/graphhopper/util/en_US.txt b/core/src/main/resources/com/graphhopper/util/en_US.txt index e3b04f1d36a..b7ff0e335a6 100644 --- a/core/src/main/resources/com/graphhopper/util/en_US.txt +++ b/core/src/main/resources/com/graphhopper/util/en_US.txt @@ -13,6 +13,7 @@ turn_slight_right=turn slight right turn_sharp_left=turn sharp left turn_sharp_right=turn sharp right u_turn=make a U-turn +toward_destination=%1$s and drive toward %2$s unknown=unknown instruction sign '%1$s' via=via hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/eo.txt b/core/src/main/resources/com/graphhopper/util/eo.txt index 7acaf08c4da..704ffcf1a76 100644 --- a/core/src/main/resources/com/graphhopper/util/eo.txt +++ b/core/src/main/resources/com/graphhopper/util/eo.txt @@ -13,6 +13,7 @@ turn_slight_right=turniĝetu dekstren turn_sharp_left=turniĝegu maldekstren turn_sharp_right=turniĝegu dekstren u_turn=turniĝu malantaŭen +toward_destination= unknown=nekonata instrukcio “%1$s” via=tra hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/es.txt b/core/src/main/resources/com/graphhopper/util/es.txt index 4f8cc792553..b93fa203a05 100644 --- a/core/src/main/resources/com/graphhopper/util/es.txt +++ b/core/src/main/resources/com/graphhopper/util/es.txt @@ -13,6 +13,7 @@ turn_slight_right=gira leve a la derecha turn_sharp_left=gira fuerte a la izquierda turn_sharp_right=gira fuerte a la derecha u_turn=da la vuelta +toward_destination= unknown=señal de instrucción «%1$s» desconocida via=pasando por hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/fa.txt b/core/src/main/resources/com/graphhopper/util/fa.txt index 41dddce3431..b83f2bd98ac 100644 --- a/core/src/main/resources/com/graphhopper/util/fa.txt +++ b/core/src/main/resources/com/graphhopper/util/fa.txt @@ -13,6 +13,7 @@ turn_slight_right=کمی به راست بپیچید turn_sharp_left=در پیچ تند به چپ بپیچید turn_sharp_right=در پیچ تند به راست بپیچید u_turn=دور بزنید +toward_destination= unknown=علامت راهنمایی ناشناخته: '%1$s' via=با گذر از hour_abbr=ساعت diff --git a/core/src/main/resources/com/graphhopper/util/fi.txt b/core/src/main/resources/com/graphhopper/util/fi.txt index e93121a1b80..dfb77bb6452 100644 --- a/core/src/main/resources/com/graphhopper/util/fi.txt +++ b/core/src/main/resources/com/graphhopper/util/fi.txt @@ -13,6 +13,7 @@ turn_slight_right=käänny loivasti oikealle turn_sharp_left=käänny jyrkästi vasemmalle turn_sharp_right=käänny jyrkästi oikealle u_turn=tee U-käännös +toward_destination= unknown=tuntematon ohje '%1$s' via=kautta hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/fil.txt b/core/src/main/resources/com/graphhopper/util/fil.txt index 9692aa6d946..b6344f44421 100644 --- a/core/src/main/resources/com/graphhopper/util/fil.txt +++ b/core/src/main/resources/com/graphhopper/util/fil.txt @@ -13,6 +13,7 @@ turn_slight_right=pagliko bahagyang kanan turn_sharp_left=pagliko matalim kaliwa turn_sharp_right=pagliko matalim karapatan u_turn= +toward_destination= unknown= via=sa pamamagitan ng hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/fr_CH.txt b/core/src/main/resources/com/graphhopper/util/fr_CH.txt index f68d973a0a4..5247e76dbbc 100644 --- a/core/src/main/resources/com/graphhopper/util/fr_CH.txt +++ b/core/src/main/resources/com/graphhopper/util/fr_CH.txt @@ -13,6 +13,7 @@ turn_slight_right=tournez légèrement à droite turn_sharp_left=tournez fort à gauche turn_sharp_right=tournez fort à droite u_turn=faites demi-tour +toward_destination= unknown=indication inconnue '%1$s' via=via hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/fr_FR.txt b/core/src/main/resources/com/graphhopper/util/fr_FR.txt index 04c39d54dd5..f2dae12a8d8 100644 --- a/core/src/main/resources/com/graphhopper/util/fr_FR.txt +++ b/core/src/main/resources/com/graphhopper/util/fr_FR.txt @@ -13,6 +13,7 @@ turn_slight_right=tournez légèrement à droite turn_sharp_left=tournez fort à gauche turn_sharp_right=tournez fort à droite u_turn=faites demi-tour +toward_destination= unknown=indication inconnue '%1$s' via=via hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/gl.txt b/core/src/main/resources/com/graphhopper/util/gl.txt index 0b308b69b73..73c63c59583 100644 --- a/core/src/main/resources/com/graphhopper/util/gl.txt +++ b/core/src/main/resources/com/graphhopper/util/gl.txt @@ -13,6 +13,7 @@ turn_slight_right=vire á dereita turn_sharp_left=vire por xusto á esquerda turn_sharp_right=vire por xusto á dereita u_turn= +toward_destination= unknown= via=vía hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/he.txt b/core/src/main/resources/com/graphhopper/util/he.txt index 791e63c5d61..1fb3263fd87 100644 --- a/core/src/main/resources/com/graphhopper/util/he.txt +++ b/core/src/main/resources/com/graphhopper/util/he.txt @@ -13,6 +13,7 @@ turn_slight_right=מעט ימינה turn_sharp_left=שמאלה בחדות turn_sharp_right=ימינה בחדות u_turn=לבצע פניית פרסה +toward_destination= unknown=שלט הנחייה לא מוכר '%1$s' via=דרך hour_abbr=שע׳ diff --git a/core/src/main/resources/com/graphhopper/util/hr_HR.txt b/core/src/main/resources/com/graphhopper/util/hr_HR.txt index 33115c494cc..d1c40107422 100644 --- a/core/src/main/resources/com/graphhopper/util/hr_HR.txt +++ b/core/src/main/resources/com/graphhopper/util/hr_HR.txt @@ -13,6 +13,7 @@ turn_slight_right=skrenite blago desno turn_sharp_left=skrenite oštro lijevo turn_sharp_right=skrenite oštro desno u_turn= +toward_destination= unknown= via=preko hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/hsb.txt b/core/src/main/resources/com/graphhopper/util/hsb.txt index 14657c985a1..ec21e45427e 100644 --- a/core/src/main/resources/com/graphhopper/util/hsb.txt +++ b/core/src/main/resources/com/graphhopper/util/hsb.txt @@ -13,6 +13,7 @@ turn_slight_right=zlochka naprawo wotbočić turn_sharp_left=wótrje nalěwo wotbočić turn_sharp_right=wótrje naprawo wotbočić u_turn= +toward_destination= unknown= via=via hour_abbr=hodź. diff --git a/core/src/main/resources/com/graphhopper/util/hu_HU.txt b/core/src/main/resources/com/graphhopper/util/hu_HU.txt index 0f03b8c4edf..511587c31b1 100644 --- a/core/src/main/resources/com/graphhopper/util/hu_HU.txt +++ b/core/src/main/resources/com/graphhopper/util/hu_HU.txt @@ -13,6 +13,7 @@ turn_slight_right=forduljon enyhén jobbra turn_sharp_left=forduljon élesen balra turn_sharp_right=forduljon élesen jobbra u_turn=forduljon meg +toward_destination= unknown=ismeretlen jelzőtábla: %1$s via=ezen át: hour_abbr=óra diff --git a/core/src/main/resources/com/graphhopper/util/in_ID.txt b/core/src/main/resources/com/graphhopper/util/in_ID.txt index f936924cacf..670ca889eda 100644 --- a/core/src/main/resources/com/graphhopper/util/in_ID.txt +++ b/core/src/main/resources/com/graphhopper/util/in_ID.txt @@ -13,6 +13,7 @@ turn_slight_right=belok kanan sedikit turn_sharp_left=belok kiri tajam turn_sharp_right=belok kanan tajam u_turn=putar balik +toward_destination= unknown=petunjuk baru %1$s via=melalui hour_abbr=jam diff --git a/core/src/main/resources/com/graphhopper/util/it.txt b/core/src/main/resources/com/graphhopper/util/it.txt index 6805e183261..ada708620f8 100644 --- a/core/src/main/resources/com/graphhopper/util/it.txt +++ b/core/src/main/resources/com/graphhopper/util/it.txt @@ -13,6 +13,7 @@ turn_slight_right=gira leggermente a destra turn_sharp_left=gira nettamente a sinistra turn_sharp_right=gira nettamente a destra u_turn=fai una inversione a U +toward_destination= unknown=sconosciuto %1$s via=via hour_abbr=hh diff --git a/core/src/main/resources/com/graphhopper/util/ja.txt b/core/src/main/resources/com/graphhopper/util/ja.txt index 9c38de4c2c5..f9c35e1afe1 100644 --- a/core/src/main/resources/com/graphhopper/util/ja.txt +++ b/core/src/main/resources/com/graphhopper/util/ja.txt @@ -13,6 +13,7 @@ turn_slight_right=右に曲がる turn_sharp_left=左に曲がる turn_sharp_right=右に曲がる u_turn= +toward_destination= unknown= via=経由 hour_abbr=時間 diff --git a/core/src/main/resources/com/graphhopper/util/ko.txt b/core/src/main/resources/com/graphhopper/util/ko.txt index 9d018f63df1..52017df8824 100644 --- a/core/src/main/resources/com/graphhopper/util/ko.txt +++ b/core/src/main/resources/com/graphhopper/util/ko.txt @@ -6,13 +6,14 @@ finish=도착 keep_left=좌측 유지 keep_right=우측 유지 turn_onto=%2$s로 %1$s -turn_left=TranslationMap +turn_left=좌회전 turn_right=우회전 turn_slight_left=왼쪽 방향 turn_slight_right=오른쪽 방향 turn_sharp_left=왼쪽 방향 turn_sharp_right=오른쪽 방향 u_turn=유턴 +toward_destination= unknown=알 수 없는 안내 '%1$s' via=경유 hour_abbr=시간 @@ -59,11 +60,11 @@ web.server_status=상태 web.zoom_in=확대 web.zoom_out=축소 web.drag_to_reorder=드래그하여 재정렬 -web.route_timed_out= -web.route_request_failed= -web.current_location= -web.searching_location= -web.searching_location_failed= +web.route_timed_out=경로 탐색 시간 초과 +web.route_request_failed=경로 탐색 요청 실패 +web.current_location=현재 위치 +web.searching_location=위치 탐색 +web.searching_location_failed=위티 탐색 실패 web.via_hint=경유 web.from_hint=출발 web.gpx_export_button=GPX 내보내기 diff --git a/core/src/main/resources/com/graphhopper/util/lt_LT.txt b/core/src/main/resources/com/graphhopper/util/lt_LT.txt index a9d221afd28..a9615e75e8c 100644 --- a/core/src/main/resources/com/graphhopper/util/lt_LT.txt +++ b/core/src/main/resources/com/graphhopper/util/lt_LT.txt @@ -13,6 +13,7 @@ turn_slight_right=laikykite dešiniau turn_sharp_left=staigiai sukite kairėn turn_sharp_right=staigiai sukite dešinėn u_turn=apsisukite +toward_destination= unknown=nežinomos instrukcijos žymėjimas '%1$s' via=per hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/ne.txt b/core/src/main/resources/com/graphhopper/util/ne.txt index 4716d331ab3..2c34f64eab7 100644 --- a/core/src/main/resources/com/graphhopper/util/ne.txt +++ b/core/src/main/resources/com/graphhopper/util/ne.txt @@ -13,6 +13,7 @@ turn_slight_right=थोरै दाया मोड्नुहोस turn_sharp_left=धेरै बाया मोड्नुहोस turn_sharp_right=धेरै दाया मोड्नुहोस u_turn= +toward_destination= unknown= via=बाट hour_abbr=घण्टा diff --git a/core/src/main/resources/com/graphhopper/util/nl.txt b/core/src/main/resources/com/graphhopper/util/nl.txt index 5ff275d39c6..ce7c242855b 100644 --- a/core/src/main/resources/com/graphhopper/util/nl.txt +++ b/core/src/main/resources/com/graphhopper/util/nl.txt @@ -13,6 +13,7 @@ turn_slight_right=houd rechts aan turn_sharp_left=ga linksaf turn_sharp_right=ga rechtsaf u_turn=keer om +toward_destination= unknown=onbekende richtingaanwijzer '%1$s' via=via hour_abbr=u diff --git a/core/src/main/resources/com/graphhopper/util/pl_PL.txt b/core/src/main/resources/com/graphhopper/util/pl_PL.txt index 28889957253..e8ea6553416 100644 --- a/core/src/main/resources/com/graphhopper/util/pl_PL.txt +++ b/core/src/main/resources/com/graphhopper/util/pl_PL.txt @@ -13,6 +13,7 @@ turn_slight_right=skręć delikatnie w prawo turn_sharp_left=skręć ostro w lewo turn_sharp_right=skręć ostro w prawo u_turn=zawróć +toward_destination= unknown=nieznana instrukcja '%1$s' via=przez hour_abbr=g diff --git a/core/src/main/resources/com/graphhopper/util/pt_BR.txt b/core/src/main/resources/com/graphhopper/util/pt_BR.txt index 757bff6d1f3..b873fdac350 100644 --- a/core/src/main/resources/com/graphhopper/util/pt_BR.txt +++ b/core/src/main/resources/com/graphhopper/util/pt_BR.txt @@ -13,6 +13,7 @@ turn_slight_right=curva suave à direita turn_sharp_left=curva acentuada à esquerda turn_sharp_right=curva acentuada à direita u_turn=faça um retorno +toward_destination= unknown=sinalização desconhecida '%1$s' via=via hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/pt_PT.txt b/core/src/main/resources/com/graphhopper/util/pt_PT.txt index b4440b3e94a..4b5dace2c9e 100644 --- a/core/src/main/resources/com/graphhopper/util/pt_PT.txt +++ b/core/src/main/resources/com/graphhopper/util/pt_PT.txt @@ -13,6 +13,7 @@ turn_slight_right=vire à curva ligeira à direita turn_sharp_left=vire à curva apertada à esquerda turn_sharp_right=vire à curva apertada à direita u_turn= +toward_destination= unknown= via=por hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/ro.txt b/core/src/main/resources/com/graphhopper/util/ro.txt index 4cb3693622f..bb7f3c60214 100644 --- a/core/src/main/resources/com/graphhopper/util/ro.txt +++ b/core/src/main/resources/com/graphhopper/util/ro.txt @@ -13,6 +13,7 @@ turn_slight_right=schimbați direcția la ușor la dreapta turn_sharp_left=schimbați direcția la brusc la stânga turn_sharp_right=schimbați direcția la brusc la dreapta u_turn= +toward_destination= unknown= via=prin hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/ru.txt b/core/src/main/resources/com/graphhopper/util/ru.txt index d774030906f..f1a34d0a674 100644 --- a/core/src/main/resources/com/graphhopper/util/ru.txt +++ b/core/src/main/resources/com/graphhopper/util/ru.txt @@ -13,6 +13,7 @@ turn_slight_right=Плавно поверните направо turn_sharp_left=Резко поверните налево turn_sharp_right=Резко поверните направо u_turn=Развернитесь +toward_destination= unknown=Неизвестная инструкция '%1$s' via=через hour_abbr=ч diff --git a/core/src/main/resources/com/graphhopper/util/sk.txt b/core/src/main/resources/com/graphhopper/util/sk.txt index 0e8621a6ec3..cc1e8ac0d33 100644 --- a/core/src/main/resources/com/graphhopper/util/sk.txt +++ b/core/src/main/resources/com/graphhopper/util/sk.txt @@ -13,6 +13,7 @@ turn_slight_right=odbočte mierne doprava turn_sharp_left=odbočte ostro doľava turn_sharp_right=odbočte ostro doprava u_turn=otočte sa o 180° +toward_destination= unknown= via=cez hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/sl_SI.txt b/core/src/main/resources/com/graphhopper/util/sl_SI.txt index 0d34bfe4e55..f9af219469d 100644 --- a/core/src/main/resources/com/graphhopper/util/sl_SI.txt +++ b/core/src/main/resources/com/graphhopper/util/sl_SI.txt @@ -13,6 +13,7 @@ turn_slight_right=zavijte rahlo desno turn_sharp_left=zavijte ostro levo turn_sharp_right=zavijte ostro desno u_turn=zavijte za 180° +toward_destination= unknown=neznano navodilo '%1$s' via=preko hour_abbr=ur diff --git a/core/src/main/resources/com/graphhopper/util/sr_RS.txt b/core/src/main/resources/com/graphhopper/util/sr_RS.txt index a74bd0d36e1..0e82deb1cbc 100644 --- a/core/src/main/resources/com/graphhopper/util/sr_RS.txt +++ b/core/src/main/resources/com/graphhopper/util/sr_RS.txt @@ -13,6 +13,7 @@ turn_slight_right=skrenite blago desno turn_sharp_left=skrenite oštro levo turn_sharp_right=skrenite oštro desno u_turn= +toward_destination= unknown= via=preko hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/sv_SE.txt b/core/src/main/resources/com/graphhopper/util/sv_SE.txt index b89a8c482c8..ea0b7d14708 100644 --- a/core/src/main/resources/com/graphhopper/util/sv_SE.txt +++ b/core/src/main/resources/com/graphhopper/util/sv_SE.txt @@ -13,6 +13,7 @@ turn_slight_right=sväng svagt höger turn_sharp_left=sväng kraftigt vänster turn_sharp_right=sväng kraftigt höger u_turn=gör en u-sväng +toward_destination= unknown= via=via hour_abbr= tim diff --git a/core/src/main/resources/com/graphhopper/util/tr.txt b/core/src/main/resources/com/graphhopper/util/tr.txt index 4e1cb95d426..39202d875e8 100644 --- a/core/src/main/resources/com/graphhopper/util/tr.txt +++ b/core/src/main/resources/com/graphhopper/util/tr.txt @@ -13,6 +13,7 @@ turn_slight_right=sağa hafif dön turn_sharp_left=sola keskin dön turn_sharp_right=sağa keskin dön u_turn=u dönüşü yap +toward_destination= unknown=bilinmeyen yön işareti '%1$s' via=yoluyla hour_abbr=s diff --git a/core/src/main/resources/com/graphhopper/util/uk.txt b/core/src/main/resources/com/graphhopper/util/uk.txt index 71839323467..617c06c8575 100644 --- a/core/src/main/resources/com/graphhopper/util/uk.txt +++ b/core/src/main/resources/com/graphhopper/util/uk.txt @@ -13,6 +13,7 @@ turn_slight_right=Поверніть трохи правіше turn_sharp_left=Різко поверніть ліворуч turn_sharp_right=Різко поверніть праворуч u_turn=Розверніться +toward_destination= unknown=Невідома інструкція %1$s via=через hour_abbr= год diff --git a/core/src/main/resources/com/graphhopper/util/vi_VN.txt b/core/src/main/resources/com/graphhopper/util/vi_VN.txt index 137c6d9be1c..2f2dee32658 100644 --- a/core/src/main/resources/com/graphhopper/util/vi_VN.txt +++ b/core/src/main/resources/com/graphhopper/util/vi_VN.txt @@ -13,6 +13,7 @@ turn_slight_right=rẽ nhẹ sang phải turn_sharp_left=rẽ trái ngay lập tức turn_sharp_right=rẽ phải ngay lập tức u_turn=quay đầu xe +toward_destination= unknown=không xác định %1$s via=qua hour_abbr=giờ diff --git a/core/src/main/resources/com/graphhopper/util/zh_CN.txt b/core/src/main/resources/com/graphhopper/util/zh_CN.txt index ca2913a88a2..aecda848ad4 100644 --- a/core/src/main/resources/com/graphhopper/util/zh_CN.txt +++ b/core/src/main/resources/com/graphhopper/util/zh_CN.txt @@ -13,6 +13,7 @@ turn_slight_right=偏右转 turn_sharp_left=左急转 turn_sharp_right=右急转 u_turn=掉头 +toward_destination= unknown=未知指示标志 '%1$s' via=途经 hour_abbr=小时 diff --git a/core/src/main/resources/com/graphhopper/util/zh_HK.txt b/core/src/main/resources/com/graphhopper/util/zh_HK.txt index 6a545966dc9..120dd187c00 100644 --- a/core/src/main/resources/com/graphhopper/util/zh_HK.txt +++ b/core/src/main/resources/com/graphhopper/util/zh_HK.txt @@ -13,6 +13,7 @@ turn_slight_right=右轉 turn_sharp_left=左急轉 turn_sharp_right=右急轉 u_turn= +toward_destination= unknown= via=途經 hour_abbr=小時 diff --git a/core/src/main/resources/com/graphhopper/util/zh_TW.txt b/core/src/main/resources/com/graphhopper/util/zh_TW.txt index d629c04b66a..87bd675922f 100644 --- a/core/src/main/resources/com/graphhopper/util/zh_TW.txt +++ b/core/src/main/resources/com/graphhopper/util/zh_TW.txt @@ -13,6 +13,7 @@ turn_slight_right=微靠右轉 turn_sharp_left=左急轉 turn_sharp_right=右急轉 u_turn=迴轉 +toward_destination= unknown=未知指示標誌 '%1$s' via=途經 hour_abbr=小時 From a37f2fb474520aac161a0b3ebb8389c3af0a41ee Mon Sep 17 00:00:00 2001 From: Andi Date: Mon, 4 Jul 2022 20:40:35 +0200 Subject: [PATCH 083/389] Remove FlagEncoder (#2611) --- CHANGELOG.md | 2 + benchmark/benchmark.sh | 15 +- .../java/com/graphhopper/GraphHopper.java | 40 ++--- .../routing/DefaultWeightingFactory.java | 66 +++++-- .../graphhopper/routing/ProfileResolver.java | 13 +- .../graphhopper/routing/ev/VehicleAccess.java | 32 ++++ .../routing/ev/VehiclePriority.java | 32 ++++ .../graphhopper/routing/ev/VehicleSpeed.java | 32 ++++ .../routing/util/Bike2WeightTagParser.java | 7 +- .../routing/util/BikeTagParser.java | 7 +- .../routing/util/Car4WDTagParser.java | 5 +- .../routing/util/CarTagParser.java | 7 +- .../util/DefaultFlagEncoderFactory.java | 88 --------- .../DefaultVehicleEncodedValuesFactory.java | 65 +++++++ .../util/DefaultVehicleTagParserFactory.java | 2 +- .../routing/util/EncodingManager.java | 99 +++-------- .../graphhopper/routing/util/FlagEncoder.java | 61 ------- .../routing/util/FlagEncoders.java | 85 --------- .../routing/util/FootTagParser.java | 7 +- .../routing/util/HikeTagParser.java | 7 +- .../routing/util/MotorcycleTagParser.java | 6 +- .../routing/util/MountainBikeTagParser.java | 7 +- .../routing/util/RacingBikeTagParser.java | 7 +- .../routing/util/RoadsTagParser.java | 10 +- .../routing/util/VehicleEncodedValues.java | 133 +++----------- ....java => VehicleEncodedValuesFactory.java} | 8 +- .../routing/util/WheelchairTagParser.java | 7 +- .../routing/weighting/CurvatureWeighting.java | 26 +-- .../routing/weighting/FastestWeighting.java | 41 ++--- .../routing/weighting/PriorityWeighting.java | 14 +- .../weighting/ShortFastestWeighting.java | 21 +-- .../weighting/custom/CustomModelParser.java | 16 +- .../weighting/custom/CustomWeighting.java | 4 +- .../java/com/graphhopper/util/GHUtility.java | 19 +- .../graphhopper/GraphHopperProfileTest.java | 4 +- .../java/com/graphhopper/GraphHopperTest.java | 9 +- .../algorithm/ShortestPathTreeTest.java | 27 ++- .../dem/BridgeElevationInterpolatorTest.java | 4 +- .../dem/EdgeElevationInterpolatorTest.java | 15 +- .../dem/TunnelElevationInterpolatorTest.java | 2 +- .../reader/osm/GraphHopperOSMTest.java | 3 - .../graphhopper/reader/osm/OSMReaderTest.java | 47 ++--- .../routing/AStarBidirectionTest.java | 13 +- .../routing/AlternativeRouteCHTest.java | 15 +- .../routing/AlternativeRouteEdgeCHTest.java | 28 ++- .../routing/AlternativeRouteTest.java | 34 ++-- .../routing/CHQueryWithTurnCostsTest.java | 22 +-- .../DefaultBidirPathExtractorTest.java | 22 +-- .../routing/DijkstraBidirectionCHTest.java | 73 +++++--- .../routing/DijkstraOneToManyTest.java | 31 ++-- .../DirectedBidirectionalDijkstraTest.java | 25 ++- .../routing/DirectedRoutingTest.java | 34 ++-- .../DirectionResolverOnQueryGraphTest.java | 21 ++- .../routing/DirectionResolverTest.java | 21 ++- .../EdgeBasedRoutingAlgorithmTest.java | 30 +--- .../routing/HeadingResolverTest.java | 27 +-- .../routing/HeadingRoutingTest.java | 74 ++++---- .../com/graphhopper/routing/PathTest.java | 127 +++++++------ .../routing/PriorityRoutingTest.java | 43 ++--- .../routing/ProfileResolverTest.java | 8 + .../routing/QueryRoutingCHGraphTest.java | 39 ++-- .../routing/RandomCHRoutingTest.java | 50 +++--- .../routing/RandomizedRoutingTest.java | 42 +++-- .../routing/RoundTripRoutingTest.java | 20 ++- .../routing/RoutingAlgorithmTest.java | 121 ++++++------- .../routing/RoutingCHGraphImplTest.java | 106 ++++++----- ...fficChangeWithNodeOrderingReusingTest.java | 22 ++- .../routing/ch/CHProfileSelectorTest.java | 17 +- .../routing/ch/CHTurnCostTest.java | 28 ++- .../ch/EdgeBasedNodeContractorTest.java | 20 +-- .../ch/NodeBasedNodeContractorTest.java | 27 +-- .../ch/PrepareContractionHierarchiesTest.java | 120 +++++++------ .../routing/ev/DecimalEncodedValueTest.java | 36 +--- .../routing/lm/LMApproximatorTest.java | 22 +-- .../graphhopper/routing/lm/LMIssueTest.java | 19 +- .../routing/lm/LMPreparationHandlerTest.java | 15 +- .../routing/lm/LMProfileSelectorTest.java | 17 +- .../routing/lm/LandmarkStorageTest.java | 34 ++-- .../routing/lm/PrepareLandmarksTest.java | 34 ++-- .../routing/querygraph/QueryGraphTest.java | 53 +++--- .../PrepareRoutingSubnetworksTest.java | 167 ++++++++---------- .../util/AbstractBikeTagParserTester.java | 8 +- .../routing/util/AccessFilterTest.java | 13 +- .../routing/util/Car4WDTagParserTest.java | 4 +- .../routing/util/CarTagParserTest.java | 72 ++++---- .../routing/util/EncodingManagerTest.java | 27 +-- .../routing/util/FootTagParserTest.java | 31 ++-- .../routing/util/HeadingEdgeFilterTest.java | 14 +- .../routing/util/MotorcycleTagParserTest.java | 27 +-- .../util/NameSimilarityEdgeFilterTest.java | 26 +-- .../routing/util/RacingBikeTagParserTest.java | 39 ++-- .../routing/util/TagParsingTest.java | 95 ++++++---- .../routing/util/WheelchairTagParserTest.java | 35 ++-- .../parsers/OSMTurnRelationParserTest.java | 30 ++-- .../weighting/BlockAreaWeightingTest.java | 27 +-- .../weighting/FastestWeightingTest.java | 113 ++++++------ .../weighting/ShortFastestWeightingTest.java | 30 ++-- .../custom/CustomModelParserTest.java | 35 ++-- .../weighting/custom/CustomWeightingTest.java | 34 ++-- .../storage/AbstractGraphStorageTester.java | 84 +++++---- .../graphhopper/storage/BaseGraphTest.java | 10 +- .../storage/BaseGraphWithTurnCostsTest.java | 21 ++- .../storage/GraphEdgeIdFinderTest.java | 20 ++- .../storage/ShortcutUnpackerTest.java | 30 ++-- .../storage/TurnCostStorageTest.java | 44 ++--- .../storage/index/LocationIndexTreeTest.java | 111 ++++++------ .../com/graphhopper/util/GHUtilityTest.java | 19 +- .../graphhopper/util/InstructionListTest.java | 83 +++++---- .../util/PathSimplificationTest.java | 11 +- .../graphhopper/example/IsochroneExample.java | 8 +- .../example/LocationIndexExample.java | 4 +- .../example/LowLevelAPIExample.java | 33 ++-- .../graphhopper/example/RoutingExampleTC.java | 5 +- .../java/com/graphhopper/gtfs/GtfsReader.java | 8 +- .../gtfs/PtRouterFreeWalkImpl.java | 17 +- .../com/graphhopper/gtfs/PtRouterImpl.java | 12 +- .../com/graphhopper/tools/Measurement.java | 28 ++- .../java/com/graphhopper/ui/MiniGraphUI.java | 12 +- .../graphhopper/resources/InfoResource.java | 8 +- .../resources/PtIsochroneResource.java | 8 +- .../graphhopper/gpx/GpxConversionsTest.java | 14 +- .../resources/RouteResourceTest.java | 2 +- 122 files changed, 1913 insertions(+), 2098 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/ev/VehicleAccess.java create mode 100644 core/src/main/java/com/graphhopper/routing/ev/VehiclePriority.java create mode 100644 core/src/main/java/com/graphhopper/routing/ev/VehicleSpeed.java delete mode 100644 core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java delete mode 100644 core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java delete mode 100644 core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java rename core/src/main/java/com/graphhopper/routing/util/{FlagEncoderFactory.java => VehicleEncodedValuesFactory.java} (80%) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7b070615e5..1e3a5ff216d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ ### 6.0 [not yet released] +- removed the FlagEncoder interface. for example encoder.getAccessEnc() is now encodingManager.getBooleanEncodedValue( + VehicleAccess.key("car")), #2611 - backward incompatible change as instructions and the street_name path detail do no longer contain the ref #2598 - StringIndex is now EdgeKVStorage and can store e.g. byte arrays. String values needs to be limited to 255 bytes before storing them. See #2597 diff --git a/benchmark/benchmark.sh b/benchmark/benchmark.sh index 05904f5952d..2ceabed5a71 100755 --- a/benchmark/benchmark.sh +++ b/benchmark/benchmark.sh @@ -53,7 +53,8 @@ measurement.weighting=fastest \ measurement.ch.node=true \ measurement.ch.edge=true \ measurement.lm=false \ -"graph.flag_encoders=car|turn_costs=true" \ +measurement.vehicle=car \ +measurement.turn_costs=true \ graph.location=${TMP_DIR}measurement-small-gh \ prepare.min_network_size=10000 \ measurement.json=true \ @@ -80,7 +81,8 @@ measurement.ch.edge=false \ measurement.lm=true \ "measurement.lm.active_counts=[4,8,12]" \ measurement.lm.edge_based=true \ -"graph.flag_encoders=car|turn_costs=true" \ +measurement.vehicle=car \ +measurement.turn_costs=true \ graph.location=${TMP_DIR}measurement-big-gh \ prepare.min_network_size=10000 \ measurement.json=true \ @@ -110,7 +112,8 @@ measurement.ch.edge=false \ measurement.lm=true \ "measurement.lm.active_counts=[8]" \ measurement.lm.edge_based=false \ -"graph.flag_encoders=car|turn_costs=true" \ +measurement.vehicle=car \ +measurement.turn_costs=true \ graph.location=${TMP_DIR}measurement-big-little-custom-gh \ prepare.min_network_size=10000 \ measurement.json=true \ @@ -140,7 +143,8 @@ measurement.ch.edge=false \ measurement.lm=true \ "measurement.lm.active_counts=[8]" \ measurement.lm.edge_based=false \ -"graph.flag_encoders=car|turn_costs=true" \ +measurement.vehicle=car \ +measurement.turn_costs=true \ graph.location=${TMP_DIR}measurement-big-very-custom-gh \ prepare.min_network_size=10000 \ measurement.json=true \ @@ -167,7 +171,8 @@ measurement.ch.edge=false \ measurement.lm=true \ "measurement.lm.active_counts=[4,8,12]" \ measurement.lm.edge_based=false \ -"graph.flag_encoders=foot" \ +measurement.vehicle=foot \ +measurement.turn_costs=false \ graph.location=${TMP_DIR}measurement-big-outdoor-gh \ prepare.min_network_size=10000 \ measurement.json=true \ diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 0094932ae0e..5159f766cce 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -66,7 +66,6 @@ import java.text.DateFormat; import java.util.*; import java.util.stream.Collectors; -import java.util.stream.Stream; import static com.graphhopper.util.GHUtility.readCountries; import static com.graphhopper.util.Helper.*; @@ -121,7 +120,7 @@ public class GraphHopper { // for data reader private String osmFile; private ElevationProvider eleProvider = ElevationProvider.NOOP; - private FlagEncoderFactory flagEncoderFactory = new DefaultFlagEncoderFactory(); + private VehicleEncodedValuesFactory vehicleEncodedValuesFactory = new DefaultVehicleEncodedValuesFactory(); private VehicleTagParserFactory vehicleTagParserFactory = new DefaultVehicleTagParserFactory(); private EncodedValueFactory encodedValueFactory = new DefaultEncodedValueFactory(); private TagParserFactory tagParserFactory = new DefaultTagParserFactory(); @@ -390,8 +389,8 @@ public TranslationMap getTranslationMap() { return trMap; } - public GraphHopper setFlagEncoderFactory(FlagEncoderFactory factory) { - this.flagEncoderFactory = factory; + public GraphHopper setVehicleEncodedValuesFactory(VehicleEncodedValuesFactory factory) { + this.vehicleEncodedValuesFactory = factory; return this; } @@ -580,7 +579,7 @@ private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String en .collect(Collectors.toList()); EncodingManager.Builder emBuilder = new EncodingManager.Builder(); - flagEncodersMap.forEach((name, encoderStr) -> emBuilder.add(flagEncoderFactory.createFlagEncoder(name, new PMap(encoderStr)))); + flagEncodersMap.forEach((name, encoderStr) -> emBuilder.add(vehicleEncodedValuesFactory.createVehicleEncodedValues(name, new PMap(encoderStr)))); profiles.forEach(profile -> emBuilder.add(Subnetwork.create(profile.getName()))); encodedValueStrings.forEach(s -> emBuilder.add(encodedValueFactory.create(s))); encodingManager = emBuilder.build(); @@ -831,7 +830,6 @@ protected void writeEncodingManagerToProperties() { properties.put("graph.em.edge_config", encodingManager.toEdgeConfigAsString()); properties.put("graph.em.turn_cost_config", encodingManager.toTurnCostConfigAsString()); properties.put("graph.encoded_values", encodingManager.toEncodedValuesAsString()); - properties.put("graph.flag_encoders", encodingManager.toFlagEncodersAsString()); } private List readCustomAreas() { @@ -956,23 +954,9 @@ private void loadEncodingManagerFromProperties(StorableProperties properties) { throw new IllegalStateException("Duplicate encoded value name: " + encodedValue.getName() + " in: graph.encoded_values=" + encodedValueStr); }); - String flagEncodersStr = properties.get("graph.flag_encoders"); - LinkedHashMap flagEncoders = Stream.of(flagEncodersStr.split(",")) - .map(str -> flagEncoderFactory.deserializeFlagEncoder(str, name -> { - EncodedValue ev = encodedValues.get(name); - if (ev == null) - throw new IllegalStateException("FlagEncoder " + str + " uses unknown encoded value: " + name); - return ev; - })) - .collect(Collectors.toMap(FlagEncoder::getName, f -> (VehicleEncodedValues) f, - (f1, f2) -> { - throw new IllegalStateException("Duplicate flag encoder: " + f1.getName() + " in: " + flagEncodersStr); - }, - LinkedHashMap::new)); - EncodedValue.InitializerConfig edgeConfig = EncodedValueSerializer.deserializeInitializerConfig(properties.get("graph.em.edge_config")); EncodedValue.InitializerConfig turnCostConfig = EncodedValueSerializer.deserializeInitializerConfig(properties.get("graph.em.turn_cost_config")); - encodingManager = new EncodingManager(encodedValues, flagEncoders, edgeConfig, turnCostConfig); + encodingManager = new EncodingManager(encodedValues, edgeConfig, turnCostConfig); } private ArrayNode deserializeEncodedValueList(String encodedValueStr) { @@ -992,11 +976,15 @@ private void checkProfilesConsistency() { throw new IllegalArgumentException("There has to be at least one profile"); EncodingManager encodingManager = getEncodingManager(); for (Profile profile : profilesByName.values()) { - if (!encodingManager.hasEncoder(profile.getVehicle())) { - throw new IllegalArgumentException("Unknown vehicle '" + profile.getVehicle() + "' in profile: " + profile + ". Make sure all vehicles used in 'profiles' exist in 'graph.flag_encoders'"); - } - FlagEncoder encoder = encodingManager.getEncoder(profile.getVehicle()); - if (profile.isTurnCosts() && !encoder.supportsTurnCosts()) { + String accessEncName = VehicleAccess.key(profile.getVehicle()); + String speedEncName = VehicleSpeed.key(profile.getVehicle()); + if (!encodingManager.hasEncodedValue(accessEncName) || !encodingManager.hasEncodedValue(speedEncName)) + throw new IllegalArgumentException("Unknown vehicle '" + profile.getVehicle() + "' in profile: " + profile + ". " + + "Encoded values " + accessEncName + " and " + speedEncName + " are required"); + DecimalEncodedValue turnCostEnc = encodingManager.hasEncodedValue(TurnCost.key(profile.getVehicle())) + ? encodingManager.getDecimalEncodedValue(TurnCost.key(profile.getVehicle())) + : null; + if (profile.isTurnCosts() && turnCostEnc == null) { throw new IllegalArgumentException("The profile '" + profile.getName() + "' was configured with " + "'turn_costs=true', but the corresponding vehicle '" + profile.getVehicle() + "' does not support turn costs." + "\nYou need to add `|turn_costs=true` to the vehicle in `graph.flag_encoders`"); diff --git a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java index 9d1dbe6c1a7..b7f3d51ad2e 100644 --- a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java +++ b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java @@ -19,23 +19,30 @@ package com.graphhopper.routing; import com.graphhopper.config.Profile; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.*; import com.graphhopper.routing.weighting.custom.CustomModelParser; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.routing.weighting.custom.CustomWeighting; -import com.graphhopper.routing.weighting.custom.FindMinMax; import com.graphhopper.storage.BaseGraph; import com.graphhopper.util.CustomModel; import com.graphhopper.util.PMap; import com.graphhopper.util.Parameters; +import java.util.Arrays; +import java.util.List; + +import static com.graphhopper.routing.util.VehicleEncodedValuesFactory.*; +import static com.graphhopper.routing.weighting.FastestWeighting.DESTINATION_FACTOR; +import static com.graphhopper.routing.weighting.FastestWeighting.PRIVATE_FACTOR; import static com.graphhopper.routing.weighting.TurnCostProvider.NO_TURN_COST_PROVIDER; import static com.graphhopper.routing.weighting.Weighting.INFINITE_U_TURN_COSTS; import static com.graphhopper.util.Helper.toLowerCase; public class DefaultWeightingFactory implements WeightingFactory { + private static final List OUTDOOR_VEHICLES = Arrays.asList(BIKE, BIKE2, RACINGBIKE, MOUNTAINBIKE, FOOT, HIKE, WHEELCHAIR); + private final BaseGraph graph; private final EncodingManager encodingManager; @@ -55,13 +62,20 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis hints.putAll(profile.getHints()); hints.putAll(requestHints); - FlagEncoder encoder = encodingManager.getEncoder(profile.getVehicle()); + final String vehicle = profile.getVehicle(); + if (isOutdoorVehicle(vehicle)) { + hints.putObject(PRIVATE_FACTOR, hints.getDouble(PRIVATE_FACTOR, 1.2)); + } else { + hints.putObject(DESTINATION_FACTOR, hints.getDouble(DESTINATION_FACTOR, 10)); + hints.putObject(PRIVATE_FACTOR, hints.getDouble(PRIVATE_FACTOR, 10)); + } TurnCostProvider turnCostProvider; if (profile.isTurnCosts() && !disableTurnCosts) { - if (!encoder.supportsTurnCosts()) - throw new IllegalArgumentException("Encoder " + encoder + " does not support turn costs"); + DecimalEncodedValue turnCostEnc = encodingManager.getDecimalEncodedValue(TurnCost.key(vehicle)); + if (turnCostEnc == null) + throw new IllegalArgumentException("Vehicle " + vehicle + " does not support turn costs"); int uTurnCosts = hints.getInt(Parameters.Routing.U_TURN_COSTS, INFINITE_U_TURN_COSTS); - turnCostProvider = new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage(), uTurnCosts); + turnCostProvider = new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage(), uTurnCosts); } else { turnCostProvider = NO_TURN_COST_PROVIDER; } @@ -71,6 +85,11 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis throw new IllegalArgumentException("You have to specify a weighting"); Weighting weighting = null; + BooleanEncodedValue accessEnc = encodingManager.getBooleanEncodedValue(VehicleAccess.key(vehicle)); + DecimalEncodedValue speedEnc = encodingManager.getDecimalEncodedValue(VehicleSpeed.key(vehicle)); + DecimalEncodedValue priorityEnc = encodingManager.hasEncodedValue(VehiclePriority.key(vehicle)) + ? encodingManager.getDecimalEncodedValue(VehiclePriority.key(vehicle)) + : null; if (CustomWeighting.NAME.equalsIgnoreCase(weightingStr)) { if (!(profile instanceof CustomProfile)) throw new IllegalArgumentException("custom weighting requires a CustomProfile but was profile=" + profile.getName()); @@ -78,20 +97,33 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis CustomProfile customProfile = (CustomProfile) profile; queryCustomModel = CustomModel.merge(customProfile.getCustomModel(), queryCustomModel); - weighting = CustomModelParser.createWeighting(encoder, encodingManager, turnCostProvider, queryCustomModel); + weighting = CustomModelParser.createWeighting(accessEnc, speedEnc, + priorityEnc, encodingManager, turnCostProvider, queryCustomModel); } else if ("shortest".equalsIgnoreCase(weightingStr)) { - weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), turnCostProvider); + weighting = new ShortestWeighting(accessEnc, speedEnc, turnCostProvider); } else if ("fastest".equalsIgnoreCase(weightingStr)) { - if (encoder.getPriorityEnc() != null) - weighting = new PriorityWeighting(encoder, hints, turnCostProvider); + if (!encodingManager.hasEncodedValue(RoadAccess.KEY)) + throw new IllegalArgumentException("fastest weighting requires road_access"); + EnumEncodedValue roadAccessEnc = encodingManager.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class); + if (priorityEnc != null) + weighting = new PriorityWeighting(accessEnc, speedEnc, priorityEnc, roadAccessEnc, hints, turnCostProvider); else - weighting = new FastestWeighting(encoder, hints, turnCostProvider); + weighting = new FastestWeighting(accessEnc, speedEnc, roadAccessEnc, hints, turnCostProvider); } else if ("curvature".equalsIgnoreCase(weightingStr)) { - if (encoder.getCurvatureEnc() != null) - weighting = new CurvatureWeighting(encoder, hints, turnCostProvider); - + DecimalEncodedValue curvatureEnc = encodingManager.hasEncodedValue(EncodingManager.getKey(vehicle, "curvature")) + ? encodingManager.getDecimalEncodedValue(EncodingManager.getKey(vehicle, "curvature")) + : null; + if (curvatureEnc == null || priorityEnc == null) + throw new IllegalArgumentException("curvature weighting requires curvature and priority, but not found for " + vehicle); + if (!encodingManager.hasEncodedValue(RoadAccess.KEY)) + throw new IllegalArgumentException("curvature weighting requires road_access"); + EnumEncodedValue roadAccessEnc = encodingManager.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class); + weighting = new CurvatureWeighting(accessEnc, speedEnc, priorityEnc, curvatureEnc, roadAccessEnc, hints, turnCostProvider); } else if ("short_fastest".equalsIgnoreCase(weightingStr)) { - weighting = new ShortFastestWeighting(encoder, hints, turnCostProvider); + if (!encodingManager.hasEncodedValue(RoadAccess.KEY)) + throw new IllegalArgumentException("curvature weighting requires road_access"); + EnumEncodedValue roadAccessEnc = encodingManager.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class); + weighting = new ShortFastestWeighting(accessEnc, speedEnc, roadAccessEnc, hints, turnCostProvider); } if (weighting == null) @@ -99,4 +131,8 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis return weighting; } + + public boolean isOutdoorVehicle(String name) { + return OUTDOOR_VEHICLES.contains(name); + } } \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/routing/ProfileResolver.java b/core/src/main/java/com/graphhopper/routing/ProfileResolver.java index 3785eef7e00..5083b06052b 100644 --- a/core/src/main/java/com/graphhopper/routing/ProfileResolver.java +++ b/core/src/main/java/com/graphhopper/routing/ProfileResolver.java @@ -79,11 +79,14 @@ public Profile resolveProfile(PMap hints) { boolean disableLM = hints.getBool(Parameters.Landmark.DISABLE, false); String vehicle = hints.getString("vehicle", "").toLowerCase(); - if (!vehicle.isEmpty() && !encodingManager.hasEncoder(vehicle)) - throw new IllegalArgumentException("Vehicle not supported: `" + vehicle + "`. Supported are: `" + encodingManager.toString() + - "`\nYou should consider using the `profile` parameter instead of specifying a vehicle." + - "\nAvailable profiles: " + getProfileNames() + - "\nTo learn more about profiles, see: docs/core/profiles.md"); + if (!vehicle.isEmpty()) { + List availableVehicles = encodingManager.getVehicles(); + if (!availableVehicles.contains(vehicle)) + throw new IllegalArgumentException("Vehicle not supported: `" + vehicle + "`. Supported are: `" + availableVehicles + + "`\nYou should consider using the `profile` parameter instead of specifying a vehicle." + + "\nAvailable profiles: " + getProfileNames() + + "\nTo learn more about profiles, see: docs/core/profiles.md"); + } // we select the profile based on the given request hints and the available profiles if (!chProfiles.isEmpty() && !disableCH) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/VehicleAccess.java b/core/src/main/java/com/graphhopper/routing/ev/VehicleAccess.java new file mode 100644 index 00000000000..a7f76d9cbab --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/VehicleAccess.java @@ -0,0 +1,32 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.ev; + +import com.graphhopper.routing.util.EncodingManager; + +public class VehicleAccess { + + public static String key(String name) { + return EncodingManager.getKey(name, "access"); + } + + public static BooleanEncodedValue create(String name) { + return new SimpleBooleanEncodedValue(key(name), true); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/ev/VehiclePriority.java b/core/src/main/java/com/graphhopper/routing/ev/VehiclePriority.java new file mode 100644 index 00000000000..c727997f6f3 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/VehiclePriority.java @@ -0,0 +1,32 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.ev; + +import com.graphhopper.routing.util.EncodingManager; + +public class VehiclePriority { + + public static String key(String name) { + return EncodingManager.getKey(name, "priority"); + } + + public static DecimalEncodedValue create(String name, int speedBits, double speedFactor, boolean storeTwoDirections) { + return new DecimalEncodedValueImpl(key(name), speedBits, speedFactor, storeTwoDirections); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/ev/VehicleSpeed.java b/core/src/main/java/com/graphhopper/routing/ev/VehicleSpeed.java new file mode 100644 index 00000000000..a95f09c8754 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/VehicleSpeed.java @@ -0,0 +1,32 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.ev; + +import com.graphhopper.routing.util.EncodingManager; + +public class VehicleSpeed { + + public static String key(String name) { + return EncodingManager.getKey(name, "average_speed"); + } + + public static DecimalEncodedValue create(String name, int speedBits, double speedFactor, boolean storeTwoDirections) { + return new DecimalEncodedValueImpl(key(name), speedBits, speedFactor, storeTwoDirections); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java b/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java index 3fd0b4311d7..6bc34b1f49e 100644 --- a/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java @@ -25,7 +25,6 @@ import com.graphhopper.util.PMap; import com.graphhopper.util.PointList; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.util.Helper.keepIn; /** @@ -37,9 +36,9 @@ public class Bike2WeightTagParser extends BikeTagParser { public Bike2WeightTagParser(EncodedValueLookup lookup, PMap properties) { this( - lookup.getBooleanEncodedValue(getKey(properties.getString("name", "bike2"), "access")), - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "bike2"), "average_speed")), - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "bike2"), "priority")), + lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "bike2"))), + lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "bike2"))), + lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "bike2"))), lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), lookup.getBooleanEncodedValue(Roundabout.KEY), lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class), diff --git a/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java index 082b1a3bef3..accd01b3c85 100644 --- a/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java @@ -21,7 +21,6 @@ import com.graphhopper.util.PMap; import static com.graphhopper.routing.ev.Smoothness.*; -import static com.graphhopper.routing.util.EncodingManager.getKey; /** * Specifies the settings for cycletouring/trekking @@ -33,9 +32,9 @@ public class BikeTagParser extends BikeCommonTagParser { public BikeTagParser(EncodedValueLookup lookup, PMap properties) { this( - lookup.getBooleanEncodedValue(getKey(properties.getString("name", "bike"), "access")), - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "bike"), "average_speed")), - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "bike"), "priority")), + lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "bike"))), + lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "bike"))), + lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "bike"))), lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class), properties.getString("name", "bike"), diff --git a/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java b/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java index fcf81b82915..79ed0dd4b19 100644 --- a/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java @@ -20,7 +20,6 @@ import com.graphhopper.routing.ev.*; import com.graphhopper.util.PMap; -import static com.graphhopper.routing.util.EncodingManager.getKey; /** * Defines bit layout for cars with four wheel drive @@ -31,8 +30,8 @@ public class Car4WDTagParser extends CarTagParser { public Car4WDTagParser(EncodedValueLookup lookup, PMap properties) { this( - lookup.getBooleanEncodedValue(getKey(properties.getString("name", "car4wd"), "access")), - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "car4wd"), "average_speed")), + lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "car4wd"))), + lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "car4wd"))), lookup.hasEncodedValue(TurnCost.key(properties.getString("name", "car4wd"))) ? lookup.getDecimalEncodedValue(TurnCost.key(properties.getString("name", "car4wd"))) : null, lookup.getBooleanEncodedValue(Roundabout.KEY), new PMap(properties).putObject("name", "car4wd"), diff --git a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java index 4f3ea5654cf..77babb47be6 100644 --- a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java @@ -28,7 +28,6 @@ import java.util.Map; import java.util.Set; -import static com.graphhopper.routing.util.EncodingManager.getKey; /** * Defines bit layout for cars. (speed, access, ferries, ...) @@ -52,13 +51,13 @@ public class CarTagParser extends VehicleTagParser { public CarTagParser(EncodedValueLookup lookup, PMap properties) { this( - lookup.getBooleanEncodedValue(getKey(properties.getString("name", "car"), "access")), - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "car"), "average_speed")), + lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "car"))), + lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "car"))), lookup.hasEncodedValue(TurnCost.key(properties.getString("name", "car"))) ? lookup.getDecimalEncodedValue(TurnCost.key(properties.getString("name", "car"))) : null, lookup.getBooleanEncodedValue(Roundabout.KEY), properties, TransportationMode.CAR, - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "car"), "average_speed")).getNextStorableValue(CAR_MAX_SPEED) + lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "car"))).getNextStorableValue(CAR_MAX_SPEED) ); } diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java deleted file mode 100644 index 7791fb89688..00000000000 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultFlagEncoderFactory.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.routing.util; - -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.util.PMap; - -import java.util.function.Function; - -/** - * This class creates FlagEncoders that are already included in the GraphHopper distribution. - * - * @author Peter Karich - */ -public class DefaultFlagEncoderFactory implements FlagEncoderFactory { - @Override - public FlagEncoder createFlagEncoder(String name, PMap configuration) { - if (name.equals(ROADS)) - return FlagEncoders.createRoads(configuration); - - if (name.equals(CAR)) - return FlagEncoders.createCar(configuration); - - if (name.equals(CAR4WD)) - return FlagEncoders.createCar4wd(configuration); - - if (name.equals(BIKE)) - return FlagEncoders.createBike(configuration); - - if (name.equals(BIKE2)) - return FlagEncoders.createBike2(configuration); - - if (name.equals(RACINGBIKE)) - return FlagEncoders.createRacingBike(configuration); - - if (name.equals(MOUNTAINBIKE)) - return FlagEncoders.createMountainBike(configuration); - - if (name.equals(FOOT)) - return FlagEncoders.createFoot(configuration); - - if (name.equals(HIKE)) - return FlagEncoders.createHike(configuration); - - if (name.equals(MOTORCYCLE)) - return FlagEncoders.createMotorcycle(configuration); - - if (name.equals(WHEELCHAIR)) - return FlagEncoders.createWheelchair(configuration); - - throw new IllegalArgumentException("entry in encoder list not supported: " + name); - } - - @Override - public FlagEncoder deserializeFlagEncoder(String serializedFlagEncoder, Function evLookup) { - String[] strings = serializedFlagEncoder.split("\\|"); - if (strings.length != 8) - throw new IllegalStateException("Deserialized FlagEncoders should consist of eight pipe-separated strings"); - String name = strings[0]; - BooleanEncodedValue accessEnc = strings[1].equals("null") ? null : (BooleanEncodedValue) evLookup.apply(strings[1]); - DecimalEncodedValue avgSpeedEnc = strings[2].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[2]); - DecimalEncodedValue priorityEnc = strings[3].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[3]); - DecimalEncodedValue curvatureEnc = strings[4].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[4]); - DecimalEncodedValue turnCostEnc = strings[5].equals("null") ? null : (DecimalEncodedValue) evLookup.apply(strings[5]); - boolean isMotorVehicle = Boolean.parseBoolean(strings[6]); - boolean isHGV = Boolean.parseBoolean(strings[7]); - return new VehicleEncodedValues( - name, accessEnc, avgSpeedEnc, priorityEnc, curvatureEnc, turnCostEnc, isMotorVehicle, isHGV - ); - } -} diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java new file mode 100644 index 00000000000..394d38fb64c --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java @@ -0,0 +1,65 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.util; + +import com.graphhopper.util.PMap; + +/** + * This class creates vehicle encoded values that are already included in the GraphHopper distribution. + * + * @author Peter Karich + */ +public class DefaultVehicleEncodedValuesFactory implements VehicleEncodedValuesFactory { + @Override + public VehicleEncodedValues createVehicleEncodedValues(String name, PMap configuration) { + if (name.equals(ROADS)) + return VehicleEncodedValues.roads(); + + if (name.equals(CAR)) + return VehicleEncodedValues.car(configuration); + + if (name.equals(CAR4WD)) + return VehicleEncodedValues.car4wd(configuration); + + if (name.equals(BIKE)) + return VehicleEncodedValues.bike(configuration); + + if (name.equals(BIKE2)) + return VehicleEncodedValues.bike2(configuration); + + if (name.equals(RACINGBIKE)) + return VehicleEncodedValues.racingbike(configuration); + + if (name.equals(MOUNTAINBIKE)) + return VehicleEncodedValues.mountainbike(configuration); + + if (name.equals(FOOT)) + return VehicleEncodedValues.foot(configuration); + + if (name.equals(HIKE)) + return VehicleEncodedValues.hike(configuration); + + if (name.equals(MOTORCYCLE)) + return VehicleEncodedValues.motorcycle(configuration); + + if (name.equals(WHEELCHAIR)) + return VehicleEncodedValues.wheelchair(configuration); + + throw new IllegalArgumentException("entry in vehicle list not supported: " + name); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java index 07a2da84ced..4a395fbd09c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java @@ -21,7 +21,7 @@ import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.util.PMap; -import static com.graphhopper.routing.util.FlagEncoderFactory.*; +import static com.graphhopper.routing.util.VehicleEncodedValuesFactory.*; public class DefaultVehicleTagParserFactory implements VehicleTagParserFactory { public VehicleTagParser createParser(EncodedValueLookup lookup, String name, PMap configuration) { diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java index 99aea6e686b..d958780ba18 100644 --- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java +++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java @@ -40,42 +40,26 @@ */ public class EncodingManager implements EncodedValueLookup { private final LinkedHashMap encodedValueMap; - private final LinkedHashMap flagEncoders; private final EncodedValue.InitializerConfig edgeConfig; private final EncodedValue.InitializerConfig turnCostConfig; /** * Instantiate manager with the given list of encoders. The manager knows several default - * encoders using DefaultFlagEncoderFactory. + * encoders using DefaultVehicleEncodedValuesFactory. */ public static EncodingManager create(String flagEncodersStr) { - return create(new DefaultFlagEncoderFactory(), flagEncodersStr); + return create(new DefaultVehicleEncodedValuesFactory(), flagEncodersStr); } - public static EncodingManager create(FlagEncoderFactory factory, String flagEncodersStr) { + public static EncodingManager create(VehicleEncodedValuesFactory factory, String flagEncodersStr) { return createBuilder(Arrays.stream(flagEncodersStr.split(",")).filter(s -> !s.trim().isEmpty()). map(s -> parseEncoderString(factory, s)).collect(Collectors.toList())).build(); } - /** - * Instantiate manager with the given list of encoders. - */ - public static EncodingManager create(FlagEncoder... flagEncoders) { - return create(Arrays.asList(flagEncoders)); - } - - /** - * Instantiate manager with the given list of encoders. - */ - public static EncodingManager create(List flagEncoders) { - return createBuilder(flagEncoders).build(); - } - - private static EncodingManager.Builder createBuilder(List flagEncoders) { + private static EncodingManager.Builder createBuilder(List vehicleEncodedValues) { Builder builder = new Builder(); - for (FlagEncoder flagEncoder : flagEncoders) { - builder.add(flagEncoder); - } + for (VehicleEncodedValues v : vehicleEncodedValues) + builder.add(v); return builder; } @@ -86,27 +70,21 @@ public static Builder start() { return new Builder(); } - public EncodingManager(LinkedHashMap encodedValueMap, LinkedHashMap flagEncoders, EncodedValue.InitializerConfig edgeConfig, EncodedValue.InitializerConfig turnCostConfig) { - this.flagEncoders = flagEncoders; + public EncodingManager(LinkedHashMap encodedValueMap, EncodedValue.InitializerConfig edgeConfig, EncodedValue.InitializerConfig turnCostConfig) { this.encodedValueMap = encodedValueMap; this.turnCostConfig = turnCostConfig; this.edgeConfig = edgeConfig; - flagEncoders.values().forEach(f -> f.setEncodedValueLookup(this)); } private EncodingManager() { - this(new LinkedHashMap<>(), new LinkedHashMap<>(), new EncodedValue.InitializerConfig(), new EncodedValue.InitializerConfig()); + this(new LinkedHashMap<>(), new EncodedValue.InitializerConfig(), new EncodedValue.InitializerConfig()); } public static class Builder { private EncodingManager em = new EncodingManager(); - public Builder add(FlagEncoder encoder) { + public Builder add(VehicleEncodedValues v) { checkNotBuiltAlready(); - if (em.hasEncoder(encoder.getName())) - throw new IllegalArgumentException("FlagEncoder already exists: " + encoder.getName()); - VehicleEncodedValues v = (VehicleEncodedValues) encoder; - v.setEncodedValueLookup(em); List list = new ArrayList<>(); v.createEncodedValues(list); list.forEach(this::add); @@ -114,8 +92,6 @@ public Builder add(FlagEncoder encoder) { list = new ArrayList<>(); v.createTurnCostEncodedValues(list); list.forEach(this::addTurnCostEncodedValue); - - em.flagEncoders.put(v.getName(), v); return this; } @@ -168,15 +144,15 @@ private void addDefaultEncodedValues() { if (!em.hasEncodedValue(RoadAccess.KEY)) add(new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class)); - for (VehicleEncodedValues encoder : em.flagEncoders.values()) { - if (encoder.getName().contains("bike") || encoder.getName().contains("mtb")) { + for (String vehicle : em.getVehicles()) { + if (vehicle.contains("bike") || vehicle.contains("mtb")) { if (!em.hasEncodedValue(BikeNetwork.KEY)) add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)); if (!em.hasEncodedValue(GetOffBike.KEY)) add(GetOffBike.create()); if (!em.hasEncodedValue(Smoothness.KEY)) add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)); - } else if (encoder.getName().contains("foot") || encoder.getName().contains("hike") || encoder.getName().contains("wheelchair")) { + } else if (vehicle.contains("foot") || vehicle.contains("hike") || vehicle.contains("wheelchair")) { if (!em.hasEncodedValue(FootNetwork.KEY)) add(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)); } @@ -184,13 +160,13 @@ private void addDefaultEncodedValues() { } } - static FlagEncoder parseEncoderString(FlagEncoderFactory factory, String encoderString) { + static VehicleEncodedValues parseEncoderString(VehicleEncodedValuesFactory factory, String encoderString) { if (!encoderString.equals(toLowerCase(encoderString))) - throw new IllegalArgumentException("An upper case name for the FlagEncoder is not allowed: " + encoderString); + throw new IllegalArgumentException("An upper case name for the vehicle is not allowed: " + encoderString); encoderString = encoderString.trim(); if (encoderString.isEmpty()) - throw new IllegalArgumentException("FlagEncoder cannot be empty. " + encoderString); + throw new IllegalArgumentException("vehicle cannot be empty. " + encoderString); String entryVal = ""; if (encoderString.contains("|")) { @@ -198,7 +174,7 @@ static FlagEncoder parseEncoderString(FlagEncoderFactory factory, String encoder encoderString = encoderString.split("\\|")[0]; } PMap configuration = new PMap(entryVal); - return factory.createFlagEncoder(encoderString, configuration); + return factory.createVehicleEncodedValues(encoderString, configuration); } public int getIntsForFlags() { @@ -209,23 +185,13 @@ public boolean hasEncodedValue(String key) { return encodedValueMap.get(key) != null; } - public boolean hasEncoder(String encoder) { - return flagEncoders.containsKey(encoder); - } - - public FlagEncoder getEncoder(String name) { - return getEncoder(name, true); - } - - private FlagEncoder getEncoder(String name, boolean throwExc) { - VehicleEncodedValues flagEncoder = flagEncoders.get(name); - if (flagEncoder == null && throwExc) - throw new IllegalArgumentException("FlagEncoder " + name + " not found. Existing: " + flagEncoders.keySet()); - return flagEncoder; - } - - public String toFlagEncodersAsString() { - return flagEncoders.values().stream().map(VehicleEncodedValues::toSerializationString).collect(Collectors.joining(",")); + public List getVehicles() { + // the supported vehicles are all those prefixes for which there is an access and speed EV + return getEncodedValues().stream() + .filter(ev -> ev.getName().endsWith("_access")) + .map(ev -> ev.getName().replaceAll("_access", "")) + .filter(v -> hasEncodedValue(VehicleSpeed.key(v))) + .collect(Collectors.toList()); } public String toEncodedValuesAsString() { @@ -247,7 +213,7 @@ public String toTurnCostConfigAsString() { @Override public String toString() { - return flagEncoders.values().stream().map(Object::toString).collect(Collectors.joining(",")); + return String.join(",", getVehicles()); } // TODO hide IntsRef even more in a later version: https://gist.github.com/karussell/f4c2b2b1191be978d7ee9ec8dd2cd48f @@ -260,15 +226,8 @@ public IntsRef createRelationFlags() { return new IntsRef(2); } - public List fetchEdgeEncoders() { - return new ArrayList<>(flagEncoders.values()); - } - public boolean needsTurnCostsSupport() { - for (FlagEncoder encoder : flagEncoders.values()) - if (encoder.supportsTurnCosts()) - return true; - return false; + return turnCostConfig.getRequiredBits() > 0; } @Override @@ -311,14 +270,6 @@ public T getEncodedValue(String key, Class encodedVa return (T) ev; } - /** - * All EncodedValue names that are created from a FlagEncoder should use this method to mark them as - * "none-shared" across the other FlagEncoders. - */ - public static String getKey(FlagEncoder encoder, String str) { - return getKey(encoder.toString(), str); - } - public static String getKey(String prefix, String str) { return prefix + "_" + str; } diff --git a/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java deleted file mode 100644 index 72359cd4073..00000000000 --- a/core/src/main/java/com/graphhopper/routing/util/FlagEncoder.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.routing.util; - -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; - -/** - * This class provides methods to define how a value (like speed or direction) converts to a flag - * (currently an integer value), which is stored in an edge. - * - * @author Peter Karich - */ -public interface FlagEncoder extends EncodedValueLookup { - - String getName(); - - boolean isMotorVehicle(); - - boolean isHGV(); - - /** - * This method returns the EncodedValue used for the direction-dependent access properties of this encoder. - */ - BooleanEncodedValue getAccessEnc(); - - /** - * This method returns the EncodedValue used for the average speed of this encoder. - */ - DecimalEncodedValue getAverageSpeedEnc(); - - DecimalEncodedValue getPriorityEnc(); - - DecimalEncodedValue getCurvatureEnc(); - - DecimalEncodedValue getTurnCostEnc(); - - boolean supportsTurnCosts(); - - - /** - * @return true if already registered in an EncodingManager - */ - boolean isRegistered(); -} diff --git a/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java b/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java deleted file mode 100644 index 4437e9f1056..00000000000 --- a/core/src/main/java/com/graphhopper/routing/util/FlagEncoders.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.graphhopper.routing.util; - -import com.graphhopper.util.PMap; - -public class FlagEncoders { - public static FlagEncoder createFoot() { - return createFoot(new PMap()); - } - - public static FlagEncoder createFoot(PMap properties) { - return VehicleEncodedValues.foot(properties); - } - - public static FlagEncoder createHike() { - return createHike(new PMap()); - } - - public static FlagEncoder createHike(PMap properties) { - return VehicleEncodedValues.hike(properties); - } - - public static FlagEncoder createWheelchair() { - return createWheelchair(new PMap()); - } - - public static FlagEncoder createWheelchair(PMap properties) { - return VehicleEncodedValues.wheelchair(properties); - } - - public static FlagEncoder createCar() { - return createCar(new PMap()); - } - - public static FlagEncoder createCar(PMap properties) { - return VehicleEncodedValues.car(properties); - } - - public static FlagEncoder createMotorcycle() { - return createMotorcycle(new PMap()); - } - - public static FlagEncoder createMotorcycle(PMap properties) { - return VehicleEncodedValues.motorcycle(properties); - } - - public static FlagEncoder createCar4wd(PMap properties) { - return VehicleEncodedValues.car4wd(properties); - } - - public static FlagEncoder createRacingBike() { - return createRacingBike(new PMap()); - } - - public static FlagEncoder createRacingBike(PMap properties) { - return VehicleEncodedValues.racingbike(properties); - } - - public static FlagEncoder createBike() { - return createBike(new PMap()); - } - - public static FlagEncoder createBike(PMap properties) { - return VehicleEncodedValues.bike(properties); - } - - public static FlagEncoder createBike2() { - return createBike2(new PMap()); - } - - public static FlagEncoder createBike2(PMap properties) { - return VehicleEncodedValues.bike2(properties); - } - - public static FlagEncoder createMountainBike() { - return createMountainBike(new PMap()); - } - - public static FlagEncoder createMountainBike(PMap properties) { - return VehicleEncodedValues.mountainbike(properties); - } - - public static FlagEncoder createRoads(PMap properties) { - return VehicleEncodedValues.roads(properties); - } -} diff --git a/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java b/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java index 5aee1625660..d3fb6218be3 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/FootTagParser.java @@ -25,7 +25,6 @@ import java.util.*; import static com.graphhopper.routing.ev.RouteNetwork.*; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.PriorityCode.*; /** @@ -55,9 +54,9 @@ public class FootTagParser extends VehicleTagParser { public FootTagParser(EncodedValueLookup lookup, PMap properties) { this( - lookup.getBooleanEncodedValue(getKey(properties.getString("name", "foot"), "access")), - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "foot"), "average_speed")), - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "foot"), "priority")), + lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "foot"))), + lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "foot"))), + lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "foot"))), lookup.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class), "foot" ); diff --git a/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java index 75c0ff9817b..87eb5285fd1 100644 --- a/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java @@ -25,7 +25,6 @@ import java.util.TreeMap; import static com.graphhopper.routing.ev.RouteNetwork.*; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.PriorityCode.*; /** @@ -37,9 +36,9 @@ public class HikeTagParser extends FootTagParser { public HikeTagParser(EncodedValueLookup lookup, PMap properties) { this( - lookup.getBooleanEncodedValue(getKey(properties.getString("name", "hike"), "access")), - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "hike"), "average_speed")), - lookup.getDecimalEncodedValue(getKey(properties.getString("name", "hike"), "priority")), + lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "hike"))), + lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "hike"))), + lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "hike"))), lookup.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class), properties.getString("name", "hike") ); diff --git a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java index a154da15b30..9c3e872883f 100644 --- a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java @@ -46,11 +46,11 @@ public class MotorcycleTagParser extends CarTagParser { public MotorcycleTagParser(EncodedValueLookup lookup, PMap properties) { this( - lookup.getBooleanEncodedValue(getKey("motorcycle", "access")), - lookup.getDecimalEncodedValue(getKey("motorcycle", "average_speed")), + lookup.getBooleanEncodedValue(VehicleAccess.key("motorcycle")), + lookup.getDecimalEncodedValue(VehicleSpeed.key("motorcycle")), lookup.hasEncodedValue(TurnCost.key("motorcycle")) ? lookup.getDecimalEncodedValue(TurnCost.key("motorcycle")) : null, lookup.getBooleanEncodedValue(Roundabout.KEY), - lookup.getDecimalEncodedValue(getKey("motorcycle", "priority")), + lookup.getDecimalEncodedValue(VehiclePriority.key("motorcycle")), lookup.getDecimalEncodedValue(getKey("motorcycle", "curvature")), new PMap(properties).putObject("name", "motorcycle"), TransportationMode.MOTORCYCLE diff --git a/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java index b02fc0e1f65..467d64a658d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java @@ -24,7 +24,6 @@ import java.util.TreeMap; import static com.graphhopper.routing.ev.RouteNetwork.*; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.PriorityCode.*; /** @@ -38,9 +37,9 @@ public class MountainBikeTagParser extends BikeCommonTagParser { public MountainBikeTagParser(EncodedValueLookup lookup, PMap properties) { this( - lookup.getBooleanEncodedValue(getKey("mtb", "access")), - lookup.getDecimalEncodedValue(getKey("mtb", "average_speed")), - lookup.getDecimalEncodedValue(getKey("mtb", "priority")), + lookup.getBooleanEncodedValue(VehicleAccess.key("mtb")), + lookup.getDecimalEncodedValue(VehicleSpeed.key("mtb")), + lookup.getDecimalEncodedValue(VehiclePriority.key("mtb")), lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class), lookup.getBooleanEncodedValue(Roundabout.KEY), diff --git a/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java index c94a578f260..374650b0182 100644 --- a/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java @@ -24,7 +24,6 @@ import java.util.TreeMap; import static com.graphhopper.routing.ev.RouteNetwork.*; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.PriorityCode.*; /** @@ -37,9 +36,9 @@ public class RacingBikeTagParser extends BikeCommonTagParser { public RacingBikeTagParser(EncodedValueLookup lookup, PMap properties) { this( - lookup.getBooleanEncodedValue(getKey("racingbike", "access")), - lookup.getDecimalEncodedValue(getKey("racingbike", "average_speed")), - lookup.getDecimalEncodedValue(getKey("racingbike", "priority")), + lookup.getBooleanEncodedValue(VehicleAccess.key("racingbike")), + lookup.getDecimalEncodedValue(VehicleSpeed.key("racingbike")), + lookup.getDecimalEncodedValue(VehiclePriority.key("racingbike")), lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class), lookup.getBooleanEncodedValue(Roundabout.KEY), diff --git a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java index f556c0264ba..94db9124c11 100644 --- a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java @@ -1,21 +1,17 @@ package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; -import static com.graphhopper.routing.util.EncodingManager.getKey; public class RoadsTagParser extends VehicleTagParser { public static final double ROADS_MAX_SPEED = 254; public RoadsTagParser(EncodedValueLookup lookup) { this( - lookup.getBooleanEncodedValue(getKey("roads", "access")), - lookup.getDecimalEncodedValue(getKey("roads", "average_speed")), + lookup.getBooleanEncodedValue(VehicleAccess.key("roads")), + lookup.getDecimalEncodedValue(VehicleSpeed.key("roads")), lookup.getDecimalEncodedValue(TurnCost.key("roads")) ); } diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index 8a0918b1365..f7e83945bb4 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -22,21 +22,16 @@ import com.graphhopper.util.PMap; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; import static com.graphhopper.routing.util.EncodingManager.getKey; -public class VehicleEncodedValues implements FlagEncoder { +public class VehicleEncodedValues { private final String name; - private final boolean isMotorVehicle; - private final boolean isHGV; private final BooleanEncodedValue accessEnc; private final DecimalEncodedValue avgSpeedEnc; private final DecimalEncodedValue priorityEnc; private final DecimalEncodedValue curvatureEnc; private final DecimalEncodedValue turnCostEnc; - private EncodedValueLookup encodedValueLookup; public static VehicleEncodedValues foot(PMap properties) { String name = properties.getString("name", "foot"); @@ -44,11 +39,11 @@ public static VehicleEncodedValues foot(PMap properties) { double speedFactor = properties.getDouble("speed_factor", 1); boolean speedTwoDirections = properties.getBool("speed_two_directions", false); int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); - BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); - DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); - DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); + BooleanEncodedValue accessEnc = VehicleAccess.create(name); + DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); + DecimalEncodedValue priorityEnc = VehiclePriority.create(name, 4, PriorityCode.getFactor(1), false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, false, false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc); } public static VehicleEncodedValues hike(PMap properties) { @@ -57,7 +52,7 @@ public static VehicleEncodedValues hike(PMap properties) { public static VehicleEncodedValues wheelchair(PMap properties) { if (properties.has("speed_two_directions")) - throw new IllegalArgumentException("bike2 always uses two directions"); + throw new IllegalArgumentException("wheelchair always uses two directions"); return foot(new PMap(properties) .putObject("name", properties.getString("name", "wheelchair")) .putObject("speed_two_directions", true) @@ -70,11 +65,11 @@ public static VehicleEncodedValues bike(PMap properties) { double speedFactor = properties.getDouble("speed_factor", 2); boolean speedTwoDirections = properties.getBool("speed_two_directions", false); int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); - BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); - DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); - DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); + BooleanEncodedValue accessEnc = VehicleAccess.create(name); + DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); + DecimalEncodedValue priorityEnc = VehiclePriority.create(name, 4, PriorityCode.getFactor(1), false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc, false, false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc); } public static VehicleEncodedValues bike2(PMap properties) { @@ -100,10 +95,10 @@ public static VehicleEncodedValues car(PMap properties) { double speedFactor = properties.getDouble("speed_factor", 5); boolean speedTwoDirections = properties.getBool("speed_two_directions", false); int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); - BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); - DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); + BooleanEncodedValue accessEnc = VehicleAccess.create(name); + DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, true, false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc); } public static VehicleEncodedValues car4wd(PMap properties) { @@ -116,48 +111,35 @@ public static VehicleEncodedValues motorcycle(PMap properties) { double speedFactor = properties.getDouble("speed_factor", 5); boolean speedTwoDirections = properties.getBool("speed_two_directions", true); int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", false) ? 1 : 0); - BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); - DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); - DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl(getKey(name, "priority"), 4, PriorityCode.getFactor(1), false); + BooleanEncodedValue accessEnc = VehicleAccess.create(name); + DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); + DecimalEncodedValue priorityEnc = VehiclePriority.create(name, 4, PriorityCode.getFactor(1), false); DecimalEncodedValue curvatureEnc = new DecimalEncodedValueImpl(getKey(name, "curvature"), 4, 0.1, false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, curvatureEnc, turnCostEnc, true, false); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, curvatureEnc, turnCostEnc); } - public static VehicleEncodedValues roads(PMap properties) { + public static VehicleEncodedValues roads() { String name = "roads"; int speedBits = 7; double speedFactor = 2; boolean speedTwoDirections = true; int maxTurnCosts = 3; - BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue(getKey(name, "access"), true); - DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl(getKey(name, "average_speed"), speedBits, speedFactor, speedTwoDirections); + BooleanEncodedValue accessEnc = VehicleAccess.create(name); + DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - boolean isMotorVehicle = properties.getBool("is_motor_vehicle", true); - boolean isHGV = properties.getBool("is_hgv", false); - return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc, isMotorVehicle, isHGV); + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc); } public VehicleEncodedValues(String name, BooleanEncodedValue accessEnc, DecimalEncodedValue avgSpeedEnc, DecimalEncodedValue priorityEnc, DecimalEncodedValue curvatureEnc, - DecimalEncodedValue turnCostEnc, boolean isMotorVehicle, boolean isHGV) { + DecimalEncodedValue turnCostEnc) { this.name = name; this.accessEnc = accessEnc; this.avgSpeedEnc = avgSpeedEnc; this.priorityEnc = priorityEnc; this.curvatureEnc = curvatureEnc; this.turnCostEnc = turnCostEnc; - this.isMotorVehicle = isMotorVehicle; - this.isHGV = isHGV; - } - - public void setEncodedValueLookup(EncodedValueLookup encodedValueLookup) { - this.encodedValueLookup = encodedValueLookup; - } - - @Override - public boolean isRegistered() { - return encodedValueLookup != null; } public void createEncodedValues(List registerNewEncodedValue) { @@ -176,97 +158,26 @@ public void createTurnCostEncodedValues(List registerNewTurnCostEn registerNewTurnCostEncodedValues.add(turnCostEnc); } - @Override public BooleanEncodedValue getAccessEnc() { return accessEnc; } - @Override public DecimalEncodedValue getAverageSpeedEnc() { return avgSpeedEnc; } - @Override public DecimalEncodedValue getPriorityEnc() { return priorityEnc; } - @Override public DecimalEncodedValue getCurvatureEnc() { return curvatureEnc; } - @Override public DecimalEncodedValue getTurnCostEnc() { return turnCostEnc; } - public String toSerializationString() { - return - String.join("|", - name, - Stream.of(accessEnc, avgSpeedEnc, priorityEnc, curvatureEnc, turnCostEnc) - .map(ev -> ev == null ? "null" : ev.getName()) - .collect(Collectors.joining("|")), - String.valueOf(isMotorVehicle), String.valueOf(isHGV)); - } - - @Override - public List getEncodedValues() { - return encodedValueLookup.getEncodedValues(); - } - - @Override - public T getEncodedValue(String key, Class encodedValueType) { - return encodedValueLookup.getEncodedValue(key, encodedValueType); - } - - @Override - public BooleanEncodedValue getBooleanEncodedValue(String key) { - return encodedValueLookup.getBooleanEncodedValue(key); - } - - @Override - public IntEncodedValue getIntEncodedValue(String key) { - return encodedValueLookup.getIntEncodedValue(key); - } - - @Override - public DecimalEncodedValue getDecimalEncodedValue(String key) { - return encodedValueLookup.getDecimalEncodedValue(key); - } - - @Override - public > EnumEncodedValue getEnumEncodedValue(String key, Class enumType) { - return encodedValueLookup.getEnumEncodedValue(key, enumType); - } - - @Override - public StringEncodedValue getStringEncodedValue(String key) { - return encodedValueLookup.getStringEncodedValue(key); - } - - @Override - public boolean isMotorVehicle() { - return isMotorVehicle; - } - - @Override - public boolean isHGV() { - return isHGV; - } - - @Override - public boolean supportsTurnCosts() { - return turnCostEnc != null; - } - - @Override - public boolean hasEncodedValue(String key) { - return encodedValueLookup.hasEncodedValue(key); - } - - @Override public String getName() { return name; } diff --git a/core/src/main/java/com/graphhopper/routing/util/FlagEncoderFactory.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java similarity index 80% rename from core/src/main/java/com/graphhopper/routing/util/FlagEncoderFactory.java rename to core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java index 6131a6b1405..57402acfba4 100644 --- a/core/src/main/java/com/graphhopper/routing/util/FlagEncoderFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java @@ -17,15 +17,12 @@ */ package com.graphhopper.routing.util; -import com.graphhopper.routing.ev.EncodedValue; import com.graphhopper.util.PMap; -import java.util.function.Function; - /** * @author Peter Karich */ -public interface FlagEncoderFactory { +public interface VehicleEncodedValuesFactory { String ROADS = "roads"; String CAR = "car"; String CAR4WD = "car4wd"; @@ -38,7 +35,6 @@ public interface FlagEncoderFactory { String MOTORCYCLE = "motorcycle"; String WHEELCHAIR = "wheelchair"; - FlagEncoder createFlagEncoder(String name, PMap configuration); + VehicleEncodedValues createVehicleEncodedValues(String name, PMap configuration); - FlagEncoder deserializeFlagEncoder(String serializedFlagEncoder, Function evLookup); } diff --git a/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java b/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java index 1cc04a9b63d..808f6565b73 100644 --- a/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java @@ -29,7 +29,6 @@ import java.util.Set; import java.util.TreeMap; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.PriorityCode.AVOID; import static com.graphhopper.routing.util.PriorityCode.VERY_NICE; @@ -45,9 +44,9 @@ public class WheelchairTagParser extends FootTagParser { public WheelchairTagParser(EncodedValueLookup lookup, PMap properties) { this( - lookup.getBooleanEncodedValue(getKey("wheelchair", "access")), - lookup.getDecimalEncodedValue(getKey("wheelchair", "average_speed")), - lookup.getDecimalEncodedValue(getKey("wheelchair", "priority")), + lookup.getBooleanEncodedValue(VehicleAccess.key("wheelchair")), + lookup.getDecimalEncodedValue(VehicleSpeed.key("wheelchair")), + lookup.getDecimalEncodedValue(VehiclePriority.key("wheelchair")), lookup.getEnumEncodedValue(FootNetwork.KEY, RouteNetwork.class) ); blockPrivate(properties.getBool("block_private", true)); diff --git a/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java index c861b5d45f3..fdeaf63d7ad 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java @@ -17,37 +17,29 @@ */ package com.graphhopper.routing.weighting; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.RoadAccess; import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.PMap; import static com.graphhopper.routing.util.PriorityCode.BEST; -import static com.graphhopper.routing.weighting.TurnCostProvider.NO_TURN_COST_PROVIDER; /** * This Class uses bendiness parameter to prefer curvy routes. */ public class CurvatureWeighting extends PriorityWeighting { private final double minFactor; - private final DecimalEncodedValue priorityEnc; private final DecimalEncodedValue curvatureEnc; - private final DecimalEncodedValue avSpeedEnc; - public CurvatureWeighting(FlagEncoder flagEncoder, PMap pMap) { - this(flagEncoder, pMap, NO_TURN_COST_PROVIDER); - } - - public CurvatureWeighting(FlagEncoder flagEncoder, PMap pMap, TurnCostProvider turnCostProvider) { - super(flagEncoder, pMap, turnCostProvider); - - priorityEnc = flagEncoder.getDecimalEncodedValue(EncodingManager.getKey(flagEncoder, "priority")); - curvatureEnc = flagEncoder.getDecimalEncodedValue(EncodingManager.getKey(flagEncoder, "curvature")); - avSpeedEnc = flagEncoder.getDecimalEncodedValue(EncodingManager.getKey(flagEncoder, "average_speed")); + public CurvatureWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, + DecimalEncodedValue curvatureEnc, EnumEncodedValue roadAccessEnc, PMap pMap, TurnCostProvider turnCostProvider) { + super(accessEnc, speedEnc, priorityEnc, roadAccessEnc, pMap, turnCostProvider); + this.curvatureEnc = curvatureEnc; double minBendiness = 1; // see correctErrors - double maxSpeed = avSpeedEnc.getMaxOrMaxStorableDecimal(); + double maxSpeed = speedEnc.getMaxOrMaxStorableDecimal(); minFactor = minBendiness / Math.log(maxSpeed) / PriorityCode.getValue(BEST.getValue()); } @@ -69,7 +61,7 @@ public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { } protected double getRoadSpeed(EdgeIteratorState edge, boolean reverse) { - return reverse ? edge.getReverse(avSpeedEnc) : edge.get(avSpeedEnc); + return reverse ? edge.getReverse(speedEnc) : edge.get(speedEnc); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java index 69f54d0efb5..970e17a48d1 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java @@ -17,9 +17,10 @@ */ package com.graphhopper.routing.weighting; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.RoadAccess; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.PMap; import com.graphhopper.util.Parameters.Routing; @@ -34,6 +35,8 @@ * @author Peter Karich */ public class FastestWeighting extends AbstractWeighting { + public static String DESTINATION_FACTOR = "road_access_destination_factor"; + public static String PRIVATE_FACTOR = "road_access_private_factor"; /** * Converting to seconds is not necessary but makes adding other penalties easier (e.g. turn * costs or traffic light costs etc) @@ -46,33 +49,31 @@ public class FastestWeighting extends AbstractWeighting { // this factor puts a penalty on roads with a "destination"-only or private access, see #733 and #1936 private final double destinationPenalty, privatePenalty; - public FastestWeighting(FlagEncoder encoder) { - this(encoder, new PMap(0)); + public FastestWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { + this(accessEnc, speedEnc, NO_TURN_COST_PROVIDER); } - public FastestWeighting(FlagEncoder encoder, TurnCostProvider turnCostProvider) { - this(encoder, new PMap(0), turnCostProvider); + public FastestWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, TurnCostProvider turnCostProvider) { + this(accessEnc, speedEnc, null, new PMap(0), turnCostProvider); } - public FastestWeighting(FlagEncoder encoder, PMap map) { - this(encoder, map, NO_TURN_COST_PROVIDER); - } - - public FastestWeighting(FlagEncoder encoder, PMap map, TurnCostProvider turnCostProvider) { - super(encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), turnCostProvider); + public FastestWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, EnumEncodedValue roadAccessEnc, PMap map, TurnCostProvider turnCostProvider) { + super(accessEnc, speedEnc, turnCostProvider); headingPenalty = map.getDouble(Routing.HEADING_PENALTY, Routing.DEFAULT_HEADING_PENALTY); headingPenaltyMillis = Math.round(headingPenalty * 1000); maxSpeed = speedEnc.getMaxOrMaxStorableDecimal() / SPEED_CONV; - if (!encoder.hasEncodedValue(RoadAccess.KEY)) - throw new IllegalArgumentException("road_access is not available but expected for FastestWeighting"); - - // ensure that we do not need to change getMinWeight, i.e. road_access_factor >= 1 - double defaultDestinationFactor = encoder.isMotorVehicle() ? 10 : 1; - destinationPenalty = checkBounds("road_access_destination_factor", map.getDouble("road_access_destination_factor", defaultDestinationFactor), 1, 10); - double defaultPrivateFactor = encoder.isMotorVehicle() ? 10 : 1.2; - privatePenalty = checkBounds("road_access_private_factor", map.getDouble("road_access_private_factor", defaultPrivateFactor), 1, 10); - roadAccessEnc = destinationPenalty > 1 || privatePenalty > 1 ? encoder.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class) : null; + destinationPenalty = map.getDouble(DESTINATION_FACTOR, 1); + privatePenalty = map.getDouble(PRIVATE_FACTOR, 1); + // ensure that we do not need to change getMinWeight, i.e. both factors need to be >= 1 + checkBounds(DESTINATION_FACTOR, destinationPenalty, 1, 10); + checkBounds(PRIVATE_FACTOR, privatePenalty, 1, 10); + if (destinationPenalty > 1 || privatePenalty > 1) { + if (roadAccessEnc == null) + throw new IllegalArgumentException("road_access must not be null when destination or private penalties are > 1"); + this.roadAccessEnc = roadAccessEnc; + } else + this.roadAccessEnc = null; } @Override diff --git a/core/src/main/java/com/graphhopper/routing/weighting/PriorityWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/PriorityWeighting.java index 6e3c5094505..43f33a43d16 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/PriorityWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/PriorityWeighting.java @@ -17,9 +17,10 @@ */ package com.graphhopper.routing.weighting; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.RoadAccess; import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.PMap; @@ -35,11 +36,12 @@ public class PriorityWeighting extends FastestWeighting { private final double minFactor; private final double maxPrio; - private final DecimalEncodedValue priorityEnc; + protected final DecimalEncodedValue priorityEnc; - public PriorityWeighting(FlagEncoder encoder, PMap pMap, TurnCostProvider turnCostProvider) { - super(encoder, pMap, turnCostProvider); - priorityEnc = encoder.getDecimalEncodedValue(EncodingManager.getKey(encoder, "priority")); + public PriorityWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, + EnumEncodedValue roadAccessEnc, PMap pMap, TurnCostProvider turnCostProvider) { + super(accessEnc, speedEnc, roadAccessEnc, pMap, turnCostProvider); + this.priorityEnc = priorityEnc; minFactor = 1 / PriorityCode.getValue(BEST.getValue()); maxPrio = PriorityCode.getFactor(BEST.getValue()); } diff --git a/core/src/main/java/com/graphhopper/routing/weighting/ShortFastestWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/ShortFastestWeighting.java index cc6ec82b949..90bdf80be12 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/ShortFastestWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/ShortFastestWeighting.java @@ -17,12 +17,13 @@ */ package com.graphhopper.routing.weighting; -import com.graphhopper.routing.util.FlagEncoder; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.RoadAccess; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.PMap; -import static com.graphhopper.routing.weighting.TurnCostProvider.NO_TURN_COST_PROVIDER; - /** * Calculates the fastest route with distance influence controlled by a new parameter. *

@@ -36,8 +37,8 @@ public class ShortFastestWeighting extends FastestWeighting { private final double distanceFactor; private final double timeFactor; - public ShortFastestWeighting(FlagEncoder encoder, PMap map, TurnCostProvider turnCostProvider) { - super(encoder, map, turnCostProvider); + public ShortFastestWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, EnumEncodedValue roadAccessEnc, PMap map, TurnCostProvider turnCostProvider) { + super(accessEnc, speedEnc, roadAccessEnc, map, turnCostProvider); timeFactor = checkBounds(TIME_FACTOR, map.getDouble(TIME_FACTOR, 1), 0, 10); // default value derived from the cost for time e.g. 25€/hour and for distance 0.5€/km @@ -47,16 +48,6 @@ public ShortFastestWeighting(FlagEncoder encoder, PMap map, TurnCostProvider tur throw new IllegalArgumentException("[" + NAME + "] one of distance_factor or time_factor has to be non-zero"); } - public ShortFastestWeighting(FlagEncoder encoder, double distanceFactor) { - this(encoder, distanceFactor, NO_TURN_COST_PROVIDER); - } - - public ShortFastestWeighting(FlagEncoder encoder, double distanceFactor, TurnCostProvider turnCostProvider) { - super(encoder, new PMap(), turnCostProvider); - this.distanceFactor = checkBounds(DISTANCE_FACTOR, distanceFactor, 0, 10); - this.timeFactor = 1; - } - @Override public double getMinWeight(double distance) { return super.getMinWeight(distance) * timeFactor + distance * distanceFactor; diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java index 2e7ad3efe47..c69181bc7fe 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java @@ -21,7 +21,6 @@ import com.graphhopper.json.Statement; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.TurnCostProvider; import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; @@ -68,18 +67,13 @@ private CustomModelParser() { // utility class } - public static CustomWeighting createWeighting(FlagEncoder baseFlagEncoder, EncodedValueLookup lookup, - TurnCostProvider turnCostProvider, CustomModel customModel) { + public static CustomWeighting createWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, + EncodedValueLookup lookup, TurnCostProvider turnCostProvider, CustomModel customModel) { if (customModel == null) throw new IllegalStateException("CustomModel cannot be null"); - DecimalEncodedValue avgSpeedEnc = lookup.getDecimalEncodedValue(EncodingManager.getKey(baseFlagEncoder.toString(), "average_speed")); - final String pKey = EncodingManager.getKey(baseFlagEncoder.toString(), "priority"); - DecimalEncodedValue priorityEnc = lookup.hasEncodedValue(pKey) ? lookup.getDecimalEncodedValue(pKey) : null; - - double maxSpeed = avgSpeedEnc.getMaxOrMaxStorableDecimal(); - CustomWeighting.Parameters parameters = createWeightingParameters(customModel, lookup, - avgSpeedEnc, maxSpeed, priorityEnc); - return new CustomWeighting(baseFlagEncoder.getAccessEnc(), baseFlagEncoder.getAverageSpeedEnc(), turnCostProvider, parameters); + double maxSpeed = speedEnc.getMaxOrMaxStorableDecimal(); + CustomWeighting.Parameters parameters = createWeightingParameters(customModel, lookup, speedEnc, maxSpeed, priorityEnc); + return new CustomWeighting(accessEnc, speedEnc, turnCostProvider, parameters); } /** diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java index a945061d5b6..c7759f7c6e5 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java @@ -77,7 +77,6 @@ public final class CustomWeighting extends AbstractWeighting { * costs or traffic light costs etc) */ private final static double SPEED_CONV = 3.6; - private final BooleanEncodedValue baseVehicleAccessEnc; private final double maxSpeed; private final double maxPriority; private final double distanceInfluence; @@ -89,7 +88,6 @@ public CustomWeighting(BooleanEncodedValue baseAccessEnc, DecimalEncodedValue ba super(baseAccessEnc, baseSpeedEnc, turnCostProvider); this.edgeToSpeedMapping = parameters.getEdgeToSpeedMapping(); this.edgeToPriorityMapping = parameters.getEdgeToPriorityMapping(); - this.baseVehicleAccessEnc = baseAccessEnc; this.headingPenaltySeconds = parameters.getHeadingPenaltySeconds(); this.maxSpeed = parameters.getMaxSpeed() / SPEED_CONV; this.maxPriority = parameters.getMaxPriority(); @@ -124,7 +122,7 @@ public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { reverse = false; // TODO see #1835 - if (reverse ? !edgeState.getReverse(baseVehicleAccessEnc) : !edgeState.get(baseVehicleAccessEnc)) + if (reverse ? !edgeState.getReverse(accessEnc) : !edgeState.get(accessEnc)) return Double.POSITIVE_INFINITY; double speed = edgeToSpeedMapping.get(edgeState, reverse); diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index 4227185a60c..6d11467edb3 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -24,7 +24,10 @@ import com.graphhopper.coll.GHBitSet; import com.graphhopper.coll.GHBitSetImpl; import com.graphhopper.routing.ev.*; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.AccessFilter; +import com.graphhopper.routing.util.AllEdgesIterator; +import com.graphhopper.routing.util.CustomArea; +import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.*; import com.graphhopper.storage.index.LocationIndex; @@ -149,19 +152,11 @@ public static List getEdgeIds(EdgeIterator iter) { return list; } - public static void printGraphForUnitTest(Graph g, FlagEncoder encoder) { - printGraphForUnitTest(g, encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); - } - public static void printGraphForUnitTest(Graph g, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { printGraphForUnitTest(g, accessEnc, speedEnc, new BBox( Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)); } - public static void printGraphForUnitTest(Graph g, FlagEncoder encoder, BBox bBox) { - printGraphForUnitTest(g, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), bBox); - } - public static void printGraphForUnitTest(Graph g, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, BBox bBox) { System.out.println("WARNING: printGraphForUnitTest does not pay attention to custom edge speeds at the moment"); NodeAccess na = g.getNodeAccess(); @@ -267,12 +262,6 @@ public static double getDistance(int from, int to, NodeAccess nodeAccess) { return DistancePlaneProjection.DIST_PLANE.calcDist(fromLat, fromLon, toLat, toLon); } - public static void addRandomTurnCosts(Graph graph, long seed, EncodingManager em, FlagEncoder encoder, int maxTurnCost, TurnCostStorage turnCostStorage) { - DecimalEncodedValue turnCostEnc = em.getDecimalEncodedValue(TurnCost.key(encoder.toString())); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - addRandomTurnCosts(graph, seed, accessEnc, turnCostEnc, maxTurnCost, turnCostStorage); - } - public static void addRandomTurnCosts(Graph graph, long seed, BooleanEncodedValue accessEnc, DecimalEncodedValue turnCostEnc, int maxTurnCost, TurnCostStorage turnCostStorage) { Random random = new Random(seed); double pNodeHasTurnCosts = 0.3; diff --git a/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java b/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java index 71d95c9f3d4..6fcd9fb7a62 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperProfileTest.java @@ -63,14 +63,14 @@ public void vehicleDoesNotExist_error() { final GraphHopper hopper = new GraphHopper(); hopper.setGraphHopperLocation(GH_LOCATION).setStoreOnFlush(false). setProfiles(new Profile("profile").setVehicle("your_car")); - assertIllegalArgument(hopper::importOrLoad, "entry in encoder list not supported: your_car"); + assertIllegalArgument(hopper::importOrLoad, "entry in vehicle list not supported: your_car"); } @Test public void vehicleDoesNotExist_error2() { final GraphHopper hopper = new GraphHopper().setGraphHopperLocation(GH_LOCATION).setStoreOnFlush(false). setProfiles(new Profile("profile").setVehicle("your_car")); - assertIllegalArgument(hopper::importOrLoad, "entry in encoder list not supported: your_car"); + assertIllegalArgument(hopper::importOrLoad, "entry in vehicle list not supported: your_car"); } @Test diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 01e10c9683e..00d1b5134e0 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -1337,18 +1337,17 @@ public void testMultipleVehiclesWithCH() { new CHProfile(profile2) ); hopper.importOrLoad(); - String str = hopper.getEncodingManager().toString(); GHResponse rsp = hopper.route(new GHRequest(43.73005, 7.415707, 43.741522, 7.42826) .setProfile("profile2")); ResponsePath res = rsp.getBest(); - assertFalse(rsp.hasErrors(), "car routing for " + str + " should not have errors:" + rsp.getErrors()); + assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); assertEquals(207, res.getTime() / 1000f, 1); assertEquals(2837, res.getDistance(), 1); rsp = hopper.route(new GHRequest(43.73005, 7.415707, 43.741522, 7.42826) .setProfile("profile1")); res = rsp.getBest(); - assertFalse(rsp.hasErrors(), "bike routing for " + str + " should not have errors:" + rsp.getErrors()); + assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); assertEquals(511, res.getTime() / 1000f, 1); assertEquals(2481, res.getDistance(), 1); @@ -2546,7 +2545,7 @@ public void testLoadGraph_implicitEncodedValues_issue1862() { int nodes = hopper.getBaseGraph().getNodes(); hopper.close(); - // load without configured FlagEncoders + // load without configured graph.flag_encoders hopper = new GraphHopper(); hopper.setProfiles(Arrays.asList( new Profile("p_car").setVehicle("car").setWeighting("fastest"), @@ -2558,7 +2557,7 @@ public void testLoadGraph_implicitEncodedValues_issue1862() { assertEquals(nodes, hopper.getBaseGraph().getNodes()); hopper.close(); - // load via explicitly configured FlagEncoders + // load via explicitly configured graph.flag_encoders hopper = new GraphHopper(); hopper.setFlagEncodersString("car,bike"); hopper.setProfiles(Arrays.asList( diff --git a/core/src/test/java/com/graphhopper/isochrone/algorithm/ShortestPathTreeTest.java b/core/src/test/java/com/graphhopper/isochrone/algorithm/ShortestPathTreeTest.java index 29fc51753c3..dc1939bdf31 100644 --- a/core/src/test/java/com/graphhopper/isochrone/algorithm/ShortestPathTreeTest.java +++ b/core/src/test/java/com/graphhopper/isochrone/algorithm/ShortestPathTreeTest.java @@ -2,16 +2,16 @@ import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.AllEdgesIterator; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.TurnCostProvider; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -60,10 +60,9 @@ public long calcTurnMillis(int inEdge, int viaNode, int outEdge) { }; - private final EncodingManager encodingManager = EncodingManager.create("car"); - private final FlagEncoder carEncoder = encodingManager.getEncoder("car"); - private final BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - private final DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + private final EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); private BaseGraph graph; @@ -120,7 +119,7 @@ public void tearDown() { @Test public void testSPTAndIsochrone25Seconds() { List result = new ArrayList<>(); - ShortestPathTree instance = new ShortestPathTree(graph, new FastestWeighting(carEncoder, new PMap()), false, TraversalMode.NODE_BASED); + ShortestPathTree instance = new ShortestPathTree(graph, new FastestWeighting(accessEnc, speedEnc), false, TraversalMode.NODE_BASED); instance.setTimeLimit(25_000); instance.search(0, result::add); assertEquals(3, result.size()); @@ -136,7 +135,7 @@ public void testSPTAndIsochrone25Seconds() { @Test public void testSPT26Seconds() { List result = new ArrayList<>(); - ShortestPathTree instance = new ShortestPathTree(graph, new FastestWeighting(carEncoder, new PMap()), false, TraversalMode.NODE_BASED); + ShortestPathTree instance = new ShortestPathTree(graph, new FastestWeighting(accessEnc, speedEnc), false, TraversalMode.NODE_BASED); instance.setTimeLimit(26_000); instance.search(0, result::add); assertEquals(4, result.size()); @@ -151,7 +150,7 @@ public void testSPT26Seconds() { @Test public void testNoTimeLimit() { List result = new ArrayList<>(); - ShortestPathTree instance = new ShortestPathTree(graph, new FastestWeighting(carEncoder, new PMap()), false, TraversalMode.NODE_BASED); + ShortestPathTree instance = new ShortestPathTree(graph, new FastestWeighting(accessEnc, speedEnc), false, TraversalMode.NODE_BASED); instance.setTimeLimit(Double.MAX_VALUE); instance.search(0, result::add); assertEquals(9, result.size()); @@ -171,7 +170,7 @@ public void testNoTimeLimit() { @Test public void testEdgeBasedWithFreeUTurns() { List result = new ArrayList<>(); - ShortestPathTree instance = new ShortestPathTree(graph, new FastestWeighting(carEncoder, new PMap()), false, TraversalMode.EDGE_BASED); + ShortestPathTree instance = new ShortestPathTree(graph, new FastestWeighting(accessEnc, speedEnc), false, TraversalMode.EDGE_BASED); instance.setTimeLimit(Double.MAX_VALUE); instance.search(0, result::add); // The origin, and every end of every directed edge, are traversed. @@ -203,7 +202,7 @@ public void testEdgeBasedWithFreeUTurns() { @Test public void testEdgeBasedWithForbiddenUTurns() { - FastestWeighting fastestWeighting = new FastestWeighting(carEncoder, new PMap(), FORBIDDEN_UTURNS); + FastestWeighting fastestWeighting = new FastestWeighting(accessEnc, speedEnc, FORBIDDEN_UTURNS); List result = new ArrayList<>(); ShortestPathTree instance = new ShortestPathTree(graph, fastestWeighting, false, TraversalMode.EDGE_BASED); instance.setTimeLimit(Double.MAX_VALUE); @@ -237,7 +236,7 @@ public void testEdgeBasedWithForbiddenUTurns() { @Test public void testEdgeBasedWithFinitePositiveUTurnCost() { TimeBasedUTurnCost turnCost = new TimeBasedUTurnCost(80000); - FastestWeighting fastestWeighting = new FastestWeighting(carEncoder, new PMap(), turnCost); + FastestWeighting fastestWeighting = new FastestWeighting(accessEnc, speedEnc, turnCost); List result = new ArrayList<>(); ShortestPathTree instance = new ShortestPathTree(graph, fastestWeighting, false, TraversalMode.EDGE_BASED); instance.setTimeLimit(Double.MAX_VALUE); @@ -272,7 +271,7 @@ public void testEdgeBasedWithFinitePositiveUTurnCost() { @Test public void testEdgeBasedWithSmallerUTurnCost() { TimeBasedUTurnCost turnCost = new TimeBasedUTurnCost(20000); - FastestWeighting fastestWeighting = new FastestWeighting(carEncoder, new PMap(), turnCost); + FastestWeighting fastestWeighting = new FastestWeighting(accessEnc, speedEnc, turnCost); List result = new ArrayList<>(); ShortestPathTree instance = new ShortestPathTree(graph, fastestWeighting, false, TraversalMode.EDGE_BASED); instance.setTimeLimit(Double.MAX_VALUE); @@ -307,7 +306,7 @@ public void testEdgeBasedWithSmallerUTurnCost() { @Test public void testSearchByDistance() { List result = new ArrayList<>(); - ShortestPathTree instance = new ShortestPathTree(graph, new FastestWeighting(carEncoder, new PMap()), false, TraversalMode.NODE_BASED); + ShortestPathTree instance = new ShortestPathTree(graph, new FastestWeighting(accessEnc, speedEnc), false, TraversalMode.NODE_BASED); instance.setDistanceLimit(110.0); instance.search(5, result::add); assertEquals(6, result.size()); diff --git a/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java b/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java index 10259d5231b..ef21e3d019c 100644 --- a/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java +++ b/core/src/test/java/com/graphhopper/reader/dem/BridgeElevationInterpolatorTest.java @@ -19,7 +19,6 @@ import com.graphhopper.coll.GHIntHashSet; import com.graphhopper.routing.ev.RoadEnvironment; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.NodeAccess; import com.graphhopper.util.*; @@ -71,9 +70,8 @@ public void interpolatesElevationOfPillarNodes() { na.setNode(8, 30, 10, 10); na.setNode(9, 40, 10, 0); - FlagEncoder encoder = encodingManager.getEncoder("car"); EdgeIteratorState edge01, edge12, edge23, edge34, edge56, edge67, edge78, edge89, edge17, edge27, edge37; - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, edge01 = graph.edge(0, 1).setDistance(10), edge12 = graph.edge(1, 2).setDistance(10), edge23 = graph.edge(2, 3).setDistance(10), diff --git a/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationInterpolatorTest.java b/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationInterpolatorTest.java index 044b34f3838..f2010d99e49 100644 --- a/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationInterpolatorTest.java +++ b/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationInterpolatorTest.java @@ -19,13 +19,8 @@ import com.graphhopper.coll.GHBitSetImpl; import com.graphhopper.coll.GHIntHashSet; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.RoadEnvironment; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.EdgeIteratorState; @@ -43,7 +38,6 @@ public abstract class EdgeElevationInterpolatorTest { protected BaseGraph graph; protected EnumEncodedValue roadEnvEnc; - protected FlagEncoder encoder; protected BooleanEncodedValue accessEnc; protected DecimalEncodedValue speedEnc; protected EncodingManager encodingManager; @@ -52,10 +46,9 @@ public abstract class EdgeElevationInterpolatorTest { @SuppressWarnings("resource") @BeforeEach public void setUp() { - encoder = FlagEncoders.createCar(); - encodingManager = EncodingManager.create(encoder); - accessEnc = encoder.getAccessEnc(); - speedEnc = encoder.getAverageSpeedEnc(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); graph = new BaseGraph.Builder(encodingManager).set3D(true).create(); roadEnvEnc = encodingManager.getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class); edgeElevationInterpolator = createEdgeElevationInterpolator(); diff --git a/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java b/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java index 22d75773cfc..55f470ec729 100644 --- a/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java +++ b/core/src/test/java/com/graphhopper/reader/dem/TunnelElevationInterpolatorTest.java @@ -253,7 +253,7 @@ public void interpolatesElevationOfTunnelWithFourOuterNodes() { na.setNode(9, 40, 10, 0); EdgeIteratorState edge01, edge12, edge23, edge34, edge56, edge67, edge78, edge89, edge27; - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, edge01 = graph.edge(0, 1).setDistance(10), edge12 = graph.edge(1, 2).setDistance(10), edge23 = graph.edge(2, 3).setDistance(10), diff --git a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java index 903084643ea..65d8c430015 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java @@ -26,7 +26,6 @@ import com.graphhopper.routing.ev.EncodedValue; import com.graphhopper.routing.lm.LandmarkStorage; import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.storage.*; import com.graphhopper.storage.index.LocationIndexTree; @@ -515,7 +514,6 @@ public void testNothingHappensWhenFlagEncodersAreChangedForLoad() { setGraphHopperLocation(ghLoc); instance.load(); assertEquals(5, instance.getBaseGraph().getNodes()); - assertEquals("foot,car", instance.getEncodingManager().fetchEdgeEncoders().stream().map(FlagEncoder::getName).collect(Collectors.joining(","))); assertEquals("foot_access,foot_average_speed,foot_priority,car_access,car_average_speed,foot_subnetwork,car_subnetwork,roundabout,road_class,road_class_link,road_environment,max_speed,road_access,foot_network", instance.getEncodingManager().getEncodedValues().stream().map(EncodedValue::getName).collect(Collectors.joining(","))); } @@ -554,7 +552,6 @@ public void testFailsForWrongEVConfig() { setOSMFile(testOsm3); instance.load(); assertEquals(5, instance.getBaseGraph().getNodes()); - assertEquals("foot,car", instance.getEncodingManager().fetchEdgeEncoders().stream().map(FlagEncoder::getName).collect(Collectors.joining(","))); assertEquals("foot_access,foot_average_speed,foot_priority,car_access,car_average_speed,foot_subnetwork,car_subnetwork,roundabout,road_class,road_class_link,road_environment,max_speed,road_access,foot_network", instance.getEncodingManager().getEncodedValues().stream().map(EncodedValue::getName).collect(Collectors.joining(","))); } diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 0c4081b39f0..670a7145fcc 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -46,7 +46,6 @@ import java.io.IOException; import java.util.Collections; import java.util.List; -import java.util.function.Function; import static com.graphhopper.util.GHUtility.readCountries; import static org.junit.jupiter.api.Assertions.*; @@ -64,9 +63,9 @@ public class OSMReaderTest { private final String file7 = "test-osm7.xml"; private final String fileBarriers = "test-barriers.xml"; private final String dir = "./target/tmp/test-db"; - private FlagEncoder carEncoder; private BooleanEncodedValue carAccessEnc; - private FlagEncoder footEncoder; + private DecimalEncodedValue carSpeedEnc; + private BooleanEncodedValue footAccessEnc; private EdgeExplorer carOutExplorer; private EdgeExplorer carAllExplorer; @@ -218,13 +217,13 @@ public void cleanUp() { int n80 = AbstractGraphStorageTester.getIdOf(graph, 54.1); EdgeIterator iter = carOutExplorer.setBaseNode(n80); iter.next(); - assertEquals(5, iter.get(carEncoder.getAverageSpeedEnc()), 1e-1); + assertEquals(5, iter.get(carSpeedEnc), 1e-1); // duration 01:10 is given => more precise speed calculation! // ~111km (from 54.0,10.1 to 55.0,10.2) in duration=70 minutes => 95km/h => / 1.4 => 71km/h iter = carOutExplorer.setBaseNode(n40); iter.next(); - assertEquals(70, iter.get(carEncoder.getAverageSpeedEnc()), 1e-1); + assertEquals(70, iter.get(carSpeedEnc), 1e-1); } @Test @@ -239,7 +238,7 @@ public void cleanUp() { int n60 = AbstractGraphStorageTester.getIdOf(graph, 56.0); EdgeIterator iter = carOutExplorer.setBaseNode(n60); iter.next(); - assertEquals(35, iter.get(carEncoder.getAverageSpeedEnc()), 1e-1); + assertEquals(35, iter.get(carSpeedEnc), 1e-1); } @Test @@ -309,7 +308,7 @@ public void testFoot() { assertEquals(GHUtility.asSet(n10, n30, n40), GHUtility.getNeighbors(carAllExplorer.setBaseNode(n20))); assertEquals(GHUtility.asSet(n30, n40), GHUtility.getNeighbors(carOutExplorer.setBaseNode(n20))); - EdgeExplorer footOutExplorer = graph.createEdgeExplorer(AccessFilter.outEdges(footEncoder.getAccessEnc())); + EdgeExplorer footOutExplorer = graph.createEdgeExplorer(AccessFilter.outEdges(footAccessEnc)); assertEquals(GHUtility.asSet(n20, n50), GHUtility.getNeighbors(footOutExplorer.setBaseNode(n10))); assertEquals(GHUtility.asSet(n20, n50), GHUtility.getNeighbors(footOutExplorer.setBaseNode(n30))); assertEquals(GHUtility.asSet(n10, n30), GHUtility.getNeighbors(footOutExplorer.setBaseNode(n20))); @@ -414,12 +413,12 @@ public void testFords() { Graph graph = hopper.getBaseGraph(); // our way is split into five edges, because there are two ford nodes assertEquals(5, graph.getEdges()); - FlagEncoder encoder = hopper.getEncodingManager().fetchEdgeEncoders().get(0); + BooleanEncodedValue accessEnc = hopper.getEncodingManager().getBooleanEncodedValue(VehicleAccess.key("car")); int blocked = 0; int notBlocked = 0; AllEdgesIterator edge = graph.getAllEdges(); while (edge.next()) { - if (!edge.get(encoder.getAccessEnc())) + if (!edge.get(accessEnc)) blocked++; else notBlocked++; @@ -667,26 +666,18 @@ public void testReadEleFromDataProvider() { @Test public void testTurnFlagCombination() { GraphHopper hopper = new GraphHopper(); - hopper.setFlagEncoderFactory(new FlagEncoderFactory() { - @Override - public FlagEncoder createFlagEncoder(String name, PMap config) { - if (name.equals("truck")) { - return FlagEncoders.createCar(new PMap(config).putObject("name", "truck")); - } else { - return new DefaultFlagEncoderFactory().createFlagEncoder(name, config); - } - } - - @Override - public FlagEncoder deserializeFlagEncoder(String serializedFlagEncoder, Function evLookup) { - return null; + hopper.setVehicleEncodedValuesFactory((name, config) -> { + if (name.equals("truck")) { + return VehicleEncodedValues.car(new PMap(config).putObject("name", "truck")); + } else { + return new DefaultVehicleEncodedValuesFactory().createVehicleEncodedValues(name, config); } }); hopper.setVehicleTagParserFactory((lookup, name, config) -> { if (name.equals("truck")) { return new CarTagParser( - lookup.getBooleanEncodedValue(EncodingManager.getKey("truck", "access")), - lookup.getDecimalEncodedValue(EncodingManager.getKey("truck", "average_speed")), + lookup.getBooleanEncodedValue(VehicleAccess.key("truck")), + lookup.getDecimalEncodedValue(VehicleSpeed.key("truck")), lookup.hasEncodedValue(TurnCost.key("truck")) ? lookup.getDecimalEncodedValue(TurnCost.key("truck")) : null, lookup.getBooleanEncodedValue(Roundabout.KEY), config, @@ -965,7 +956,7 @@ public void testCurvedWayAlongBorder() throws IOException { // see https://discuss.graphhopper.com/t/country-of-way-is-wrong-on-road-near-border-with-curvature/6908/2 EnumEncodedValue countryEnc = new EnumEncodedValue<>(Country.KEY, Country.class); EncodingManager em = EncodingManager.start() - .add(FlagEncoders.createCar()) + .add(VehicleEncodedValues.car(new PMap())) .add(countryEnc) .build(); CarTagParser carParser = new CarTagParser(em, new PMap()); @@ -1017,11 +1008,11 @@ protected void importOSM() { BaseGraph baseGraph = new BaseGraph.Builder(getEncodingManager()).set3D(hasElevation()).withTurnCosts(getEncodingManager().needsTurnCostsSupport()).build(); setBaseGraph(baseGraph); super.importOSM(); - carEncoder = getEncodingManager().getEncoder("car"); - footEncoder = getEncodingManager().getEncoder("foot"); - carAccessEnc = carEncoder.getAccessEnc(); + carAccessEnc = getEncodingManager().getBooleanEncodedValue(VehicleAccess.key("car")); + carSpeedEnc = getEncodingManager().getDecimalEncodedValue(VehicleSpeed.key("car")); carOutExplorer = getBaseGraph().createEdgeExplorer(AccessFilter.outEdges(carAccessEnc)); carAllExplorer = getBaseGraph().createEdgeExplorer(AccessFilter.allEdges(carAccessEnc)); + footAccessEnc = getEncodingManager().getBooleanEncodedValue(VehicleAccess.key("foot")); } @Override diff --git a/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java b/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java index a65ccbe324d..33b260e7c85 100644 --- a/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java +++ b/core/src/test/java/com/graphhopper/routing/AStarBidirectionTest.java @@ -21,9 +21,9 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.routing.weighting.WeightApproximator; @@ -37,8 +37,6 @@ class AStarBidirectionTest { @Test void infeasibleApproximator_noException() { - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); // An infeasible approximator means that the weight of the entries polled from the priority queue does not // increase monotonically. Here we deliberately choose the approximations and edge distances such that the fwd // search first explores the 0-1-2-3-4 branch, then polls node 10 which causes an update for node 2, but the @@ -47,12 +45,13 @@ void infeasibleApproximator_noException() { // This means the resulting path contains the invalid search tree branch 2(old)-3-4 and is not the shortest path, // because the SPTEntry for node 3 still points to the outdated/deleted entry for node 2. // We do not expect an exception, though, because for an infeasible approximator we cannot expect optimal paths. + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); + BaseGraph graph = new BaseGraph.Builder(em).create(); // 0-1----2-3-4----5-6-7-8-9 // \ / // 10 - BaseGraph graph = new BaseGraph.Builder(em).create(); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); // the distance 1-2 is longer than 1-10-2 // we deliberately use 2-1 as storage direction, even though the edge points from 1 to 2, because this way diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteCHTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteCHTest.java index d9082ed71e0..daf70797c94 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteCHTest.java @@ -19,9 +19,11 @@ import com.graphhopper.routing.ch.NodeOrderingProvider; import com.graphhopper.routing.ch.PrepareContractionHierarchies; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.CHConfig; @@ -36,8 +38,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class AlternativeRouteCHTest { - private final FlagEncoder carFE = FlagEncoders.createCar(); - private final EncodingManager em = EncodingManager.create(carFE); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + private final EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); public BaseGraph createTestGraph(EncodingManager tmpEM) { final BaseGraph graph = new BaseGraph.Builder(tmpEM).create(); @@ -56,7 +59,7 @@ public BaseGraph createTestGraph(EncodingManager tmpEM) { // has to be locally-shortest to be considered. // So we get all three alternatives. - GHUtility.setSpeed(60, 60, carFE.getAccessEnc(), carFE.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(5, 6).setDistance(10000), graph.edge(6, 3).setDistance(10000), graph.edge(3, 4).setDistance(10000), @@ -81,7 +84,7 @@ private RoutingCHGraph prepareCH(BaseGraph graph) { // meet on all four possible paths from 5 to 10 // 5 ---> 11 will be reachable via shortcuts, as 11 is on shortest path 5 --> 12 final int[] nodeOrdering = new int[]{0, 10, 12, 4, 3, 2, 5, 1, 6, 7, 8, 9, 11}; - CHConfig chConfig = CHConfig.nodeBased("p", new FastestWeighting(carFE)); + CHConfig chConfig = CHConfig.nodeBased("p", new FastestWeighting(accessEnc, speedEnc)); PrepareContractionHierarchies contractionHierarchies = PrepareContractionHierarchies.fromGraph(graph, chConfig); contractionHierarchies.useFixedNodeOrdering(NodeOrderingProvider.fromArray(nodeOrdering)); PrepareContractionHierarchies.Result res = contractionHierarchies.doWork(); diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java index 0bf2c254a6f..47b9eab6cfa 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteEdgeCHTest.java @@ -19,12 +19,8 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ch.PrepareContractionHierarchies; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.TurnCostProvider; @@ -41,8 +37,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class AlternativeRouteEdgeCHTest { - private final FlagEncoder carFE = FlagEncoders.createCar(new PMap().putObject("turn_costs", true)); - private final EncodingManager em = EncodingManager.create(carFE); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + private final DecimalEncodedValue turnCostEnc = TurnCost.create("car", 1); + private final EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); public BaseGraph createTestGraph(EncodingManager tmpEM) { final BaseGraph graph = new BaseGraph.Builder(tmpEM).withTurnCosts(true).create(); @@ -61,9 +59,6 @@ public BaseGraph createTestGraph(EncodingManager tmpEM) { // has to be locally-shortest to be considered. // So we get all three alternatives. - FlagEncoder encoder = carFE; - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6).setDistance(10000)); EdgeIteratorState e6_3 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(6, 3).setDistance(10000)); EdgeIteratorState e3_4 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10000)); @@ -83,17 +78,16 @@ public BaseGraph createTestGraph(EncodingManager tmpEM) { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(12, 10).setDistance(10000)); TurnCostStorage turnCostStorage = graph.getTurnCostStorage(); - DecimalEncodedValue carTurnCost = em.getDecimalEncodedValue(TurnCost.key(carFE.toString())); - turnCostStorage.set(carTurnCost, e3_4.getEdge(), 4, e4_11.getEdge(), Double.POSITIVE_INFINITY); - turnCostStorage.set(carTurnCost, e6_3.getEdge(), 3, e3_4.getEdge(), Double.POSITIVE_INFINITY); + turnCostStorage.set(turnCostEnc, e3_4.getEdge(), 4, e4_11.getEdge(), Double.POSITIVE_INFINITY); + turnCostStorage.set(turnCostEnc, e6_3.getEdge(), 3, e3_4.getEdge(), Double.POSITIVE_INFINITY); graph.freeze(); return graph; } private RoutingCHGraph prepareCH(BaseGraph graph) { - TurnCostProvider turnCostProvider = new DefaultTurnCostProvider(carFE.getTurnCostEnc(), graph.getTurnCostStorage()); - CHConfig chConfig = CHConfig.edgeBased("profile", new FastestWeighting(carFE, turnCostProvider)); + TurnCostProvider turnCostProvider = new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage()); + CHConfig chConfig = CHConfig.edgeBased("profile", new FastestWeighting(accessEnc, speedEnc, turnCostProvider)); PrepareContractionHierarchies contractionHierarchies = PrepareContractionHierarchies.fromGraph(graph, chConfig); PrepareContractionHierarchies.Result res = contractionHierarchies.doWork(); return RoutingCHGraphImpl.fromGraph(graph, res.getCHStorage(), res.getCHConfig()); @@ -102,8 +96,8 @@ private RoutingCHGraph prepareCH(BaseGraph graph) { @Test public void testAssumptions() { BaseGraph g = createTestGraph(em); - TurnCostProvider turnCostProvider = new DefaultTurnCostProvider(carFE.getTurnCostEnc(), g.getTurnCostStorage()); - CHConfig chConfig = CHConfig.edgeBased("profile", new FastestWeighting(carFE, turnCostProvider)); + TurnCostProvider turnCostProvider = new DefaultTurnCostProvider(turnCostEnc, g.getTurnCostStorage()); + CHConfig chConfig = CHConfig.edgeBased("profile", new FastestWeighting(accessEnc, speedEnc, turnCostProvider)); CHStorage chStorage = CHStorage.fromGraph(g, chConfig); RoutingCHGraph chGraph = RoutingCHGraphImpl.fromGraph(g, chStorage, chConfig); DijkstraBidirectionEdgeCHNoSOD router = new DijkstraBidirectionEdgeCHNoSOD(chGraph); diff --git a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java index 7e9f8ab0c66..7aa702b0420 100644 --- a/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java +++ b/core/src/test/java/com/graphhopper/routing/AlternativeRouteTest.java @@ -18,9 +18,8 @@ package com.graphhopper.routing; import com.carrotsearch.hppc.IntArrayList; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; @@ -48,17 +47,22 @@ private static final class Fixture { final Weighting weighting; final TraversalMode traversalMode; final BaseGraph graph; - final FlagEncoder carFE; + final BooleanEncodedValue accessEnc; + final DecimalEncodedValue speedEnc; + final DecimalEncodedValue turnCostEnc; public Fixture(TraversalMode tMode) { this.traversalMode = tMode; - carFE = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(carFE); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + turnCostEnc = TurnCost.create("car", 1); + + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).add(turnCostEnc).build(); graph = new BaseGraph.Builder(em).withTurnCosts(true).create(); TurnCostProvider turnCostProvider = tMode.isEdgeBased() - ? new DefaultTurnCostProvider(carFE.getTurnCostEnc(), graph.getTurnCostStorage()) + ? new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage()) : TurnCostProvider.NO_TURN_COST_PROVIDER; - weighting = new FastestWeighting(carFE, turnCostProvider); + weighting = new FastestWeighting(accessEnc, speedEnc, turnCostProvider); } @Override @@ -77,7 +81,7 @@ public Stream provideArguments(ExtensionContext context) th } } - public static void initTestGraph(Graph graph, FlagEncoder encoder) { + public static void initTestGraph(Graph graph, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { /* 9 _/\ 1 2-3-4-10 @@ -85,7 +89,7 @@ public static void initTestGraph(Graph graph, FlagEncoder encoder) { 5--6-7---8 */ - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(1, 9).setDistance(1), graph.edge(9, 2).setDistance(1), graph.edge(2, 3).setDistance(1), @@ -114,7 +118,7 @@ public static void initTestGraph(Graph graph, FlagEncoder encoder) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testCalcAlternatives(Fixture f) { - initTestGraph(f.graph, f.carFE); + initTestGraph(f.graph, f.accessEnc, f.speedEnc); PMap hints = new PMap(). putObject("alternative_route.max_share_factor", 0.5). putObject("alternative_route.max_weight_factor", 2). @@ -145,7 +149,7 @@ public void testCalcAlternatives(Fixture f) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testCalcAlternatives2(Fixture f) { - initTestGraph(f.graph, f.carFE); + initTestGraph(f.graph, f.accessEnc, f.speedEnc); PMap hints = new PMap().putObject("alternative_route.max_paths", 3). putObject("alternative_route.max_share_factor", 0.7). putObject("alternative_route.min_plateau_factor", 0.15). @@ -179,14 +183,14 @@ private void checkAlternatives(List alternativ @ParameterizedTest @ArgumentsSource(FixtureProvider.class) - public void testDisconnectedAreas(Fixture p) { - initTestGraph(p.graph, p.carFE); + public void testDisconnectedAreas(Fixture f) { + initTestGraph(f.graph, f.accessEnc, f.speedEnc); // one single disconnected node - updateDistancesFor(p.graph, 20, 0.00, -0.01); + updateDistancesFor(f.graph, 20, 0.00, -0.01); PMap hints = new PMap().putObject("alternative_route.max_exploration_factor", 1); - AlternativeRoute altDijkstra = new AlternativeRoute(p.graph, p.weighting, p.traversalMode, hints); + AlternativeRoute altDijkstra = new AlternativeRoute(f.graph, f.weighting, f.traversalMode, hints); Path path = altDijkstra.calcPath(1, 20); assertFalse(path.isFound()); diff --git a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java index 497a9eb8a83..769c00b088b 100644 --- a/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/routing/CHQueryWithTurnCostsTest.java @@ -20,19 +20,13 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ch.PrepareEncoder; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.storage.*; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -56,10 +50,9 @@ public class CHQueryWithTurnCostsTest { private static class Fixture { private final int maxCost = 10; - private final FlagEncoder encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxCost).putObject("speed_two_directions", true)); - private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - private final DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); - private final EncodingManager encodingManager = EncodingManager.create(encoder); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, true); + private final DecimalEncodedValue turnCostEnc = TurnCost.create("car", maxCost); private final BaseGraph graph; private final CHConfig chConfig; private final String algoString; @@ -68,8 +61,9 @@ private static class Fixture { public Fixture(String algoString) { this.algoString = algoString; - graph = new BaseGraph.Builder(encodingManager).create(); - chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()))); + EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); + graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); + chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage()))); } @Override @@ -103,7 +97,7 @@ private void setTurnCost(int from, int via, int to, double cost) { } private void setTurnCost(EdgeIteratorState edge1, EdgeIteratorState edge2, int viaNode, double costs) { - graph.getTurnCostStorage().set(((EncodedValueLookup) encodingManager).getDecimalEncodedValue(TurnCost.key(encoder.toString())), edge1.getEdge(), viaNode, edge2.getEdge(), costs); + graph.getTurnCostStorage().set(turnCostEnc, edge1.getEdge(), viaNode, edge2.getEdge(), costs); } private void setRestriction(int from, int via, int to) { diff --git a/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java b/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java index 8d7cebad2df..df84341d82a 100644 --- a/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/DefaultBidirPathExtractorTest.java @@ -18,19 +18,14 @@ package com.graphhopper.routing; import com.carrotsearch.hppc.IntArrayList; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.storage.TurnCostStorage; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -40,13 +35,13 @@ * @author easbar */ public class DefaultBidirPathExtractorTest { - private final FlagEncoder carEncoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", 10)); - private final BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - private final DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); - private final EncodingManager encodingManager = EncodingManager.create(carEncoder); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + private final DecimalEncodedValue turnCostEnc = TurnCost.create("car", 10); + private final EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); BaseGraph createGraph() { - return new BaseGraph.Builder(encodingManager).create(); + return new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); } @Test @@ -55,7 +50,7 @@ public void testExtract() { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); SPTEntry fwdEntry = new SPTEntry(0, 2, 0, new SPTEntry(1, 10)); SPTEntry bwdEntry = new SPTEntry(2, 0); - Path p = DefaultBidirPathExtractor.extractPath(graph, new FastestWeighting(carEncoder), fwdEntry, bwdEntry, 0); + Path p = DefaultBidirPathExtractor.extractPath(graph, new FastestWeighting(accessEnc, speedEnc), fwdEntry, bwdEntry, 0); assertEquals(IntArrayList.from(1, 2), p.calcNodes()); assertEquals(10, p.getDistance(), 1e-4); } @@ -69,13 +64,12 @@ public void testExtract2() { // add some turn costs at node 2 where fwd&bwd searches meet. these costs have to be included in the // weight and the time of the path TurnCostStorage turnCostStorage = graph.getTurnCostStorage(); - DecimalEncodedValue turnCostEnc = encodingManager.getDecimalEncodedValue(TurnCost.key(carEncoder.toString())); turnCostStorage.set(turnCostEnc, 0, 2, 1, 5); SPTEntry fwdEntry = new SPTEntry(0, 2, 0.6, new SPTEntry(1, 0)); SPTEntry bwdEntry = new SPTEntry(1, 2, 1.2, new SPTEntry(3, 0)); - Path p = DefaultBidirPathExtractor.extractPath(graph, new FastestWeighting(carEncoder, new DefaultTurnCostProvider(carEncoder.getTurnCostEnc(), turnCostStorage)), fwdEntry, bwdEntry, 0); + Path p = DefaultBidirPathExtractor.extractPath(graph, new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage)), fwdEntry, bwdEntry, 0); p.setWeight(5 + 1.8); assertEquals(IntArrayList.from(1, 2, 3), p.calcNodes()); diff --git a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java index 8add6fd6ecd..aa59b8e0c7f 100644 --- a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java @@ -20,8 +20,11 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory; import com.graphhopper.routing.ch.PrepareContractionHierarchies; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.storage.*; @@ -43,24 +46,34 @@ public class DijkstraBidirectionCHTest { private final EncodingManager encodingManager; - private final FlagEncoder carEncoder; - private final FlagEncoder bike2Encoder; - private final FlagEncoder motorCycleEncoder; + private final BooleanEncodedValue carAccessEnc; + private final DecimalEncodedValue carSpeedEnc; + private final BooleanEncodedValue bike2AccessEnc; + private final DecimalEncodedValue bike2SpeedEnc; + private final BooleanEncodedValue motorcycleAccessEnc; + private final DecimalEncodedValue motorcycleSpeedEnc; public DijkstraBidirectionCHTest() { - encodingManager = EncodingManager.create("car,foot,bike2,motorcycle"); - carEncoder = encodingManager.getEncoder("car"); - bike2Encoder = encodingManager.getEncoder("bike2"); - motorCycleEncoder = encodingManager.getEncoder("motorcycle"); + carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + bike2AccessEnc = new SimpleBooleanEncodedValue("bike2_access", true); + bike2SpeedEnc = new DecimalEncodedValueImpl("bike2_speed", 4, 2, true); + motorcycleAccessEnc = new SimpleBooleanEncodedValue("motorcycle_access", true); + motorcycleSpeedEnc = new DecimalEncodedValueImpl("motorcycle_speed", 5, 5, true); + encodingManager = EncodingManager.start() + .add(carAccessEnc).add(carSpeedEnc) + .add(bike2AccessEnc).add(bike2SpeedEnc) + .add(motorcycleAccessEnc).add(motorcycleSpeedEnc) + .build(); } @Test public void testBaseGraph() { BaseGraph graph = createGHStorage(); - RoutingAlgorithmTest.initDirectedAndDiffSpeed(graph, carEncoder); + RoutingAlgorithmTest.initDirectedAndDiffSpeed(graph, carAccessEnc, carSpeedEnc); // do CH preparation for car - ShortestWeighting weighting = new ShortestWeighting(carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carSpeedEnc); prepareCH(graph, CHConfig.nodeBased(weighting.getName(), weighting)); // use base graph for solving normal Dijkstra @@ -72,15 +85,17 @@ public void testBaseGraph() { @Test public void testBaseGraphMultipleVehicles() { - EncodingManager em = EncodingManager.create("foot,car"); - FlagEncoder footEncoder = em.getEncoder("foot"); - FlagEncoder carEncoder = em.getEncoder("car"); - FastestWeighting footWeighting = new FastestWeighting(footEncoder); - FastestWeighting carWeighting = new FastestWeighting(carEncoder); + SimpleBooleanEncodedValue footAccessEnc = new SimpleBooleanEncodedValue("foot_access", true); + DecimalEncodedValueImpl footSpeedEnc = new DecimalEncodedValueImpl("foot_speed", 4, 1, false); + SimpleBooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + DecimalEncodedValueImpl carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(footAccessEnc).add(footSpeedEnc).add(carAccessEnc).add(carSpeedEnc).build(); + FastestWeighting footWeighting = new FastestWeighting(footAccessEnc, footSpeedEnc); + FastestWeighting carWeighting = new FastestWeighting(carAccessEnc, carSpeedEnc); CHConfig carConfig = CHConfig.nodeBased("p_car", carWeighting); BaseGraph g = new BaseGraph.Builder(em).create(); - RoutingAlgorithmTest.initFootVsCar(carEncoder, footEncoder, g); + RoutingAlgorithmTest.initFootVsCar(carAccessEnc, carSpeedEnc, footAccessEnc, footSpeedEnc, g); // do CH preparation for car RoutingCHGraph chGraph = prepareCH(g, carConfig); @@ -114,7 +129,7 @@ public void testBaseGraphMultipleVehicles() { @Test public void testStallingNodesReducesNumberOfVisitedNodes() { BaseGraph graph = createGHStorage(); - GHUtility.setSpeed(60, 0, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 0, carAccessEnc, carSpeedEnc, graph.edge(8, 9).setDistance(100), graph.edge(8, 3).setDistance(2), graph.edge(8, 5).setDistance(1), @@ -124,13 +139,13 @@ public void testStallingNodesReducesNumberOfVisitedNodes() { graph.edge(1, 8).setDistance(1), graph.edge(2, 3).setDistance(3)); for (int i = 3; i < 7; ++i) { - GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(i, i + 1).setDistance(1)); + GHUtility.setSpeed(60, true, false, carAccessEnc, carSpeedEnc, graph.edge(i, i + 1).setDistance(1)); } - GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(9, 0).setDistance(1)); - GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(3, 9).setDistance(200)); + GHUtility.setSpeed(60, true, false, carAccessEnc, carSpeedEnc, graph.edge(9, 0).setDistance(1)); + GHUtility.setSpeed(60, true, false, carAccessEnc, carSpeedEnc, graph.edge(3, 9).setDistance(200)); graph.freeze(); - ShortestWeighting weighting = new ShortestWeighting(carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carSpeedEnc); CHConfig chConfig = CHConfig.nodeBased(weighting.getName(), weighting); CHStorage store = CHStorage.fromGraph(graph, chConfig); @@ -160,8 +175,8 @@ public void testStallingNodesReducesNumberOfVisitedNodes() { // \--<---| @Test public void testDirectionDependentSpeedFwdSearch() { - runTestWithDirectionDependentEdgeSpeed(10, 20, 0, 2, IntArrayList.from(0, 1, 2), motorCycleEncoder); - runTestWithDirectionDependentEdgeSpeed(10, 20, 0, 2, IntArrayList.from(0, 1, 2), bike2Encoder); + runTestWithDirectionDependentEdgeSpeed(10, 20, 0, 2, IntArrayList.from(0, 1, 2), motorcycleAccessEnc, motorcycleSpeedEnc); + runTestWithDirectionDependentEdgeSpeed(10, 20, 0, 2, IntArrayList.from(0, 1, 2), bike2AccessEnc, bike2SpeedEnc); } // s(0)--fast->1--t(2) @@ -170,16 +185,16 @@ public void testDirectionDependentSpeedFwdSearch() { // \--<---| @Test public void testDirectionDependentSpeedBwdSearch() { - runTestWithDirectionDependentEdgeSpeed(20, 10, 2, 0, IntArrayList.from(2, 1, 0), motorCycleEncoder); - runTestWithDirectionDependentEdgeSpeed(20, 10, 2, 0, IntArrayList.from(2, 1, 0), bike2Encoder); + runTestWithDirectionDependentEdgeSpeed(20, 10, 2, 0, IntArrayList.from(2, 1, 0), motorcycleAccessEnc, motorcycleSpeedEnc); + runTestWithDirectionDependentEdgeSpeed(20, 10, 2, 0, IntArrayList.from(2, 1, 0), bike2AccessEnc, bike2SpeedEnc); } - private void runTestWithDirectionDependentEdgeSpeed(double speed, double revSpeed, int from, int to, IntArrayList expectedPath, FlagEncoder encoder) { + private void runTestWithDirectionDependentEdgeSpeed(double speed, double revSpeed, int from, int to, IntArrayList expectedPath, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { BaseGraph graph = createGHStorage(); - GHUtility.setSpeed(speed, revSpeed, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(2)); - GHUtility.setSpeed(20, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(1)); + GHUtility.setSpeed(speed, revSpeed, accessEnc, speedEnc, graph.edge(0, 1).setDistance(2)); + GHUtility.setSpeed(20, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); graph.freeze(); - FastestWeighting weighting = new FastestWeighting(encoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased(weighting.getName(), weighting); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); new CHStorageBuilder(chStore).setIdentityLevels(); diff --git a/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java b/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java index 204045bc984..fe3d0339b70 100644 --- a/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java +++ b/core/src/test/java/com/graphhopper/routing/DijkstraOneToManyTest.java @@ -18,8 +18,11 @@ package com.graphhopper.routing; import com.carrotsearch.hppc.IntArrayList; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -40,17 +43,19 @@ */ public class DijkstraOneToManyTest { + private final BooleanEncodedValue accessEnc; + private final DecimalEncodedValue speedEnc; private final EncodingManager encodingManager; - private final FlagEncoder encoder; - private Weighting defaultWeighting; + private final Weighting defaultWeighting; public DijkstraOneToManyTest() { - encodingManager = EncodingManager.create("car"); - encoder = encodingManager.getEncoder("car"); - defaultWeighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); + defaultWeighting = new ShortestWeighting(accessEnc, speedEnc); } - private static void initGraphWeightLimit(Graph graph, FlagEncoder encoder) { + private static void initGraphWeightLimit(Graph graph, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { // 0----1 // / | // 7-- | @@ -59,7 +64,7 @@ private static void initGraphWeightLimit(Graph graph, FlagEncoder encoder) { // | | | // 4---3---2 - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1), graph.edge(1, 2).setDistance(1), graph.edge(3, 2).setDistance(1), @@ -87,7 +92,7 @@ public void testIssue182() { @Test public void testIssue239_and362() { BaseGraph graph = createGHStorage(); - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1), graph.edge(1, 2).setDistance(1), graph.edge(2, 0).setDistance(1), @@ -106,7 +111,7 @@ public void testIssue239_and362() { @Test public void testUseCache() { BaseGraph graph = createGHStorage(); - initTestStorage(graph, encoder); + initTestStorage(graph, accessEnc, speedEnc); RoutingAlgorithm algo = createAlgo(graph); Path p = algo.calcPath(0, 4); assertEquals(IntArrayList.from(0, 4), p.calcNodes()); @@ -125,7 +130,7 @@ private void initGraph(Graph graph) { // | / // 7-10---- // \-8 - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1), graph.edge(1, 2).setDistance(1), graph.edge(2, 3).setDistance(1), @@ -139,7 +144,7 @@ private void initGraph(Graph graph) { @Test public void testWeightLimit_issue380() { BaseGraph graph = createGHStorage(); - initGraphWeightLimit(graph, encoder); + initGraphWeightLimit(graph, accessEnc, speedEnc); DijkstraOneToMany algo = createAlgo(graph); algo.setWeightLimit(3); @@ -156,7 +161,7 @@ public void testWeightLimit_issue380() { @Test public void testUseCacheZeroPath_issue707() { BaseGraph graph = createGHStorage(); - initTestStorage(graph, encoder); + initTestStorage(graph, accessEnc, speedEnc); RoutingAlgorithm algo = createAlgo(graph); Path p = algo.calcPath(0, 0); diff --git a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java index 20385628f9d..6e1cbb7995f 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectedBidirectionalDijkstraTest.java @@ -2,10 +2,11 @@ import com.carrotsearch.hppc.IntArrayList; import com.carrotsearch.hppc.IntHashSet; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.QueryGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.AvoidEdgesWeighting; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; @@ -18,7 +19,6 @@ import com.graphhopper.storage.index.Snap; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; @@ -41,28 +41,25 @@ public class DirectedBidirectionalDijkstraTest { private TurnCostStorage turnCostStorage; private int maxTurnCosts; private BaseGraph graph; - private FlagEncoder encoder; private BooleanEncodedValue accessEnc; private DecimalEncodedValue speedEnc; - private EncodingManager encodingManager; private Weighting weighting; private DecimalEncodedValue turnCostEnc; @BeforeEach public void setup() { maxTurnCosts = 10; - encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxTurnCosts)); - encodingManager = EncodingManager.create(encoder); - accessEnc = encoder.getAccessEnc(); - speedEnc = encoder.getAverageSpeedEnc(); - turnCostEnc = encoder.getTurnCostEnc(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + turnCostEnc = TurnCost.create("car", maxTurnCosts); + EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); turnCostStorage = graph.getTurnCostStorage(); weighting = createWeighting(Weighting.INFINITE_U_TURN_COSTS); } private Weighting createWeighting(int uTurnCosts) { - return new FastestWeighting(encoder, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, uTurnCosts)); + return new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, uTurnCosts)); } @Test @@ -238,7 +235,7 @@ public void directedRouting() { // | / \ | // 8 = 7 6 = 5 EdgeIteratorState rightNorth, rightSouth, leftSouth, leftNorth; - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1), graph.edge(1, 2).setDistance(1), graph.edge(2, 3).setDistance(1), @@ -396,7 +393,7 @@ private void compare_with_dijkstra(Weighting w) { int numNodes = 100; GHUtility.buildRandomGraph(graph, rnd, numNodes, 2.2, true, true, accessEnc, speedEnc, null, 0.7, 0.8, 0.8); - GHUtility.addRandomTurnCosts(graph, seed, encodingManager, encoder, maxTurnCosts, turnCostStorage); + GHUtility.addRandomTurnCosts(graph, seed, accessEnc, turnCostEnc, maxTurnCosts, turnCostStorage); long numStrictViolations = 0; for (int i = 0; i < numQueries; i++) { diff --git a/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java b/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java index 72636589930..5c13e177ff3 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectedRoutingTest.java @@ -20,9 +20,7 @@ import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory; import com.graphhopper.routing.ch.PrepareContractionHierarchies; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.lm.LMConfig; import com.graphhopper.routing.lm.LMRoutingAlgorithmFactory; import com.graphhopper.routing.lm.LandmarkStorage; @@ -30,7 +28,9 @@ import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.querygraph.QueryRoutingCHGraph; import com.graphhopper.routing.subnetwork.PrepareRoutingSubnetworks; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -85,7 +85,9 @@ private static class Fixture { private final boolean prepareLM; private final Directory dir; private final BaseGraph graph; - private final FlagEncoder encoder; + private final BooleanEncodedValue accessEnc; + private final DecimalEncodedValue speedEnc; + private final DecimalEncodedValue turnCostEnc; private final TurnCostStorage turnCostStorage; private final int maxTurnCosts; private Weighting weighting; @@ -104,8 +106,10 @@ public Fixture(Algo algo, int uTurnCosts, boolean prepareCH, boolean prepareLM) // todo: this test only works with speedTwoDirections=false (as long as loops are enabled), otherwise it will // fail sometimes for edge-based algorithms, #1631, but maybe we can should disable different fwd/bwd speeds // only for loops instead? - encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxTurnCosts)); - encodingManager = EncodingManager.start().add(encoder).add(Subnetwork.create("c2")).build(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + turnCostEnc = TurnCost.create("car", maxTurnCosts); + encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).add(Subnetwork.create("c2")).build(); graph = new BaseGraph.Builder(encodingManager).setDir(dir).withTurnCosts(true).create(); turnCostStorage = graph.getTurnCostStorage(); } @@ -117,7 +121,7 @@ public String toString() { private void preProcessGraph() { graph.freeze(); - weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), turnCostStorage, uTurnCosts)); + weighting = new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, turnCostStorage, uTurnCosts)); if (!prepareCH && !prepareLM) { return; } @@ -129,7 +133,7 @@ private void preProcessGraph() { } if (prepareLM) { // important: for LM preparation we need to use a weighting without turn costs #1960 - LMConfig lmConfig = new LMConfig("c2", new FastestWeighting(encoder)); + LMConfig lmConfig = new LMConfig("c2", new FastestWeighting(accessEnc, speedEnc)); // we need the subnetwork EV for LM PrepareRoutingSubnetworks preparation = new PrepareRoutingSubnetworks(graph, Arrays.asList(new PrepareRoutingSubnetworks.PrepareJob(encodingManager.getBooleanEncodedValue(Subnetwork.key("c2")), lmConfig.getWeighting()))); @@ -214,8 +218,8 @@ public void randomGraph(Fixture f) { final int numQueries = 50; Random rnd = new Random(seed); GHUtility.buildRandomGraph(f.graph, rnd, 100, 2.2, true, true, - f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), null, 0.7, 0.8, 0.8); - GHUtility.addRandomTurnCosts(f.graph, seed, f.encodingManager, f.encoder, f.maxTurnCosts, f.turnCostStorage); + f.accessEnc, f.speedEnc, null, 0.7, 0.8, 0.8); + GHUtility.addRandomTurnCosts(f.graph, seed, f.accessEnc, f.turnCostEnc, f.maxTurnCosts, f.turnCostStorage); // GHUtility.printGraphForUnitTest(f.graph, f.encoder); f.preProcessGraph(); List strictViolations = new ArrayList<>(); @@ -256,8 +260,8 @@ public void randomGraph_withQueryGraph(Fixture f) { double pOffset = 0; Random rnd = new Random(seed); GHUtility.buildRandomGraph(f.graph, rnd, 50, 2.2, true, true, - f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), null, 0.7, 0.8, pOffset); - GHUtility.addRandomTurnCosts(f.graph, seed, f.encodingManager, f.encoder, f.maxTurnCosts, f.turnCostStorage); + f.accessEnc, f.speedEnc, null, 0.7, 0.8, pOffset); + GHUtility.addRandomTurnCosts(f.graph, seed, f.accessEnc, f.turnCostEnc, f.maxTurnCosts, f.turnCostStorage); // GHUtility.printGraphForUnitTest(graph, encoder); f.preProcessGraph(); LocationIndexTree index = new LocationIndexTree(f.graph, f.dir); @@ -309,8 +313,8 @@ public void issue_2581() { // 3-0=1-2=7-5 // | // 4 - BooleanEncodedValue accessEnc = f.encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = f.encoder.getAverageSpeedEnc(); + BooleanEncodedValue accessEnc = f.accessEnc; + DecimalEncodedValue speedEnc = f.speedEnc; GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(0, 1).setDistance(300.186000)); // edgeId=0 GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(0, 4).setDistance(751.113000)); // edgeId=1 GHUtility.setSpeed(60, 60, accessEnc, speedEnc, f.graph.edge(7, 2).setDistance(113.102000)); // edgeId=2 diff --git a/core/src/test/java/com/graphhopper/routing/DirectionResolverOnQueryGraphTest.java b/core/src/test/java/com/graphhopper/routing/DirectionResolverOnQueryGraphTest.java index 6e1f9fbbe57..7d35788bc2f 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectionResolverOnQueryGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectionResolverOnQueryGraphTest.java @@ -19,8 +19,13 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.querygraph.QueryGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.AccessFilter; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.NodeAccess; import com.graphhopper.storage.RAMDirectory; @@ -48,14 +53,17 @@ public class DirectionResolverOnQueryGraphTest { private QueryGraph queryGraph; private NodeAccess na; - private FlagEncoder encoder; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; private BaseGraph graph; private LocationIndexTree locationIndex; @BeforeEach public void setup() { - encoder = FlagEncoders.createCar(); - graph = new BaseGraph.Builder(EncodingManager.create(encoder)).create(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); + graph = new BaseGraph.Builder(em).create(); na = graph.getNodeAccess(); } @@ -294,7 +302,7 @@ private void addNode(int nodeId, double lat, double lon) { } private EdgeIteratorState addEdge(int from, int to, boolean bothDirections) { - return GHUtility.setSpeed(60, true, bothDirections, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(from, to).setDistance(1)); + return GHUtility.setSpeed(60, true, bothDirections, accessEnc, speedEnc, graph.edge(from, to).setDistance(1)); } private void init() { @@ -349,7 +357,7 @@ private DirectionResolverResult restrictedDirection(ExpectedResult restriction) } private int findEdge(int from, int to) { - EdgeExplorer explorer = queryGraph.createEdgeExplorer(AccessFilter.outEdges(encoder.getAccessEnc())); + EdgeExplorer explorer = queryGraph.createEdgeExplorer(AccessFilter.outEdges(accessEnc)); EdgeIterator iter = explorer.setBaseNode(from); while (iter.next()) { if (iter.getAdjNode() == to) { @@ -360,7 +368,6 @@ private int findEdge(int from, int to) { } private boolean isAccessible(EdgeIteratorState edge, boolean reverse) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); return reverse ? edge.getReverse(accessEnc) : edge.get(accessEnc); } diff --git a/core/src/test/java/com/graphhopper/routing/DirectionResolverTest.java b/core/src/test/java/com/graphhopper/routing/DirectionResolverTest.java index 84152715c70..9149e5cf5d7 100644 --- a/core/src/test/java/com/graphhopper/routing/DirectionResolverTest.java +++ b/core/src/test/java/com/graphhopper/routing/DirectionResolverTest.java @@ -18,11 +18,12 @@ package com.graphhopper.routing; import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.AccessFilter; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.NodeAccess; import com.graphhopper.util.EdgeExplorer; @@ -43,14 +44,17 @@ * @see DirectionResolverOnQueryGraphTest for tests that include direction resolving for virtual nodes and edges */ public class DirectionResolverTest { - private FlagEncoder encoder; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; private BaseGraph graph; private NodeAccess na; @BeforeEach public void setup() { - encoder = FlagEncoders.createCar(); - graph = new BaseGraph.Builder(EncodingManager.create(encoder)).create(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); + graph = new BaseGraph.Builder(em).create(); na = graph.getNodeAccess(); } @@ -70,7 +74,7 @@ public void isolated_nodes_blocked_edge() { addNode(0, 0, 0); addNode(1, 0.1, 0.1); // with edges without access flags (blocked edges) - graph.edge(0, 1).set(encoder.getAccessEnc(), false, false); + graph.edge(0, 1).set(accessEnc, false, false); checkResult(0, impossible()); checkResult(1, impossible()); @@ -382,11 +386,10 @@ private void addNode(int nodeId, double lat, double lon) { } private EdgeIteratorState addEdge(int from, int to, boolean bothDirections) { - return GHUtility.setSpeed(60, true, bothDirections, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(from, to).setDistance(1)); + return GHUtility.setSpeed(60, true, bothDirections, accessEnc, speedEnc, graph.edge(from, to).setDistance(1)); } private boolean isAccessible(EdgeIteratorState edge, boolean reverse) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); return reverse ? edge.getReverse(accessEnc) : edge.get(accessEnc); } @@ -400,7 +403,7 @@ private void checkResult(int node, double lat, double lon, DirectionResolverResu } private int edge(int from, int to) { - EdgeExplorer explorer = graph.createEdgeExplorer(AccessFilter.outEdges(encoder.getAccessEnc())); + EdgeExplorer explorer = graph.createEdgeExplorer(AccessFilter.outEdges(accessEnc)); EdgeIterator iter = explorer.setBaseNode(from); while (iter.next()) { if (iter.getAdjNode() == to) { diff --git a/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java b/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java index 99cc4769034..0675629765c 100644 --- a/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java +++ b/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java @@ -19,12 +19,8 @@ import com.carrotsearch.hppc.IntArrayList; import com.carrotsearch.hppc.cursors.IntCursor; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; @@ -34,7 +30,6 @@ import com.graphhopper.storage.TurnCostStorage; import com.graphhopper.util.GHUtility; import com.graphhopper.util.Helper; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -58,7 +53,6 @@ */ public class EdgeBasedRoutingAlgorithmTest { private static final Logger LOGGER = LoggerFactory.getLogger(EdgeBasedRoutingAlgorithmTest.class); - private FlagEncoder carEncoder; private BooleanEncodedValue accessEnc; private DecimalEncodedValue speedEnc; private DecimalEncodedValue turnCostEnc; @@ -98,12 +92,10 @@ private void initGraph(Graph graph) { } private EncodingManager createEncodingManager(boolean restrictedOnly) { - carEncoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", restrictedOnly ? 1 : 3)); - EncodingManager em = EncodingManager.create(carEncoder); - accessEnc = carEncoder.getAccessEnc(); - speedEnc = carEncoder.getAverageSpeedEnc(); - turnCostEnc = getTurnCostEnc(carEncoder); - return em; + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + turnCostEnc = TurnCost.create("car", restrictedOnly ? 1 : 3); + return EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); } public Path calcPath(Graph g, int from, int to, String algoStr) { @@ -118,15 +110,11 @@ public RoutingAlgorithm createAlgo(Graph g, Weighting weighting, String algoStr, } private BaseGraph createStorage(EncodingManager em) { - BaseGraph graph = new BaseGraph.Builder(em).create(); + BaseGraph graph = new BaseGraph.Builder(em).withTurnCosts(true).create(); tcs = graph.getTurnCostStorage(); return graph; } - private DecimalEncodedValue getTurnCostEnc(FlagEncoder encoder) { - return encoder.getDecimalEncodedValue(TurnCost.key(encoder.toString())); - } - private void initTurnRestrictions(BaseGraph g) { // only forward from 2-3 to 3-4 => limit 2,3->3,6 and 2,3->3,1 setTurnRestriction(g, 2, 3, 6); @@ -157,7 +145,7 @@ private Weighting createWeighting() { } private Weighting createWeighting(int uTurnCosts) { - return new FastestWeighting(carEncoder, new DefaultTurnCostProvider(turnCostEnc, tcs, uTurnCosts)); + return new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, tcs, uTurnCosts)); } @ParameterizedTest @@ -170,7 +158,7 @@ public void testRandomGraph(String algoStr) { BaseGraph g = createStorage(em); GHUtility.buildRandomGraph(g, rnd, 50, 2.2, true, true, accessEnc, speedEnc, null, 0.8, 0.8, 0.8); - GHUtility.addRandomTurnCosts(g, seed, em, carEncoder, 3, tcs); + GHUtility.addRandomTurnCosts(g, seed, accessEnc, turnCostEnc, 3, tcs); g.freeze(); int numPathsNotFound = 0; // todo: reduce redundancy with RandomCHRoutingTest @@ -418,7 +406,7 @@ public void testTurnCostsBug_991(String algoStr) { setTurnCost(g, 2, 5, 6, 3); setTurnCost(g, 1, 6, 7, 4); - FastestWeighting weighting = new FastestWeighting(carEncoder, new DefaultTurnCostProvider(turnCostEnc, tcs) { + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, tcs) { @Override public double calcTurnWeight(int edgeFrom, int nodeVia, int edgeTo) { if (edgeFrom >= 0) diff --git a/core/src/test/java/com/graphhopper/routing/HeadingResolverTest.java b/core/src/test/java/com/graphhopper/routing/HeadingResolverTest.java index 72debe7f8df..8689b05e2a6 100644 --- a/core/src/test/java/com/graphhopper/routing/HeadingResolverTest.java +++ b/core/src/test/java/com/graphhopper/routing/HeadingResolverTest.java @@ -21,10 +21,10 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.NodeAccess; import com.graphhopper.storage.index.Snap; @@ -45,8 +45,9 @@ public void straightEdges() { // 7 -- 8 --- 3 // /|\ // 6 5 4 - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); NodeAccess na = graph.getNodeAccess(); na.setNode(0, 49.5073, 1.5545); @@ -59,8 +60,6 @@ public void straightEdges() { na.setNode(7, 48.8611, 1.2194); na.setNode(8, 48.8538, 2.3950); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 0).setDistance(10)); // edge 0 GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 1).setDistance(10)); // edge 1 GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(8, 2).setDistance(10)); // edge 2 @@ -89,16 +88,17 @@ public void curvyEdge() { // 1 -| // |- 0 -| // |- 2 - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); NodeAccess na = graph.getNodeAccess(); na.setNode(1, 0.01, 0.00); na.setNode(0, 0.00, 0.00); na.setNode(2, -0.01, 0.00); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(10)). + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)). setWayGeometry(Helper.createPointList(0.00, 0.01, 0.01, 0.01)); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 2).setDistance(10)). + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2).setDistance(10)). setWayGeometry(Helper.createPointList(0.00, -0.01, -0.01, -0.01)); HeadingResolver resolver = new HeadingResolver(graph); resolver.setTolerance(120); @@ -112,14 +112,15 @@ public void curvyEdge() { public void withQueryGraph() { // 2 // 0 -x- 1 - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); NodeAccess na = graph.getNodeAccess(); na.setNode(0, 48.8611, 1.2194); na.setNode(1, 48.8538, 2.3950); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(10)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); Snap snap = createSnap(edge, 48.859, 2.00, 0); QueryGraph queryGraph = QueryGraph.create(graph, snap); HeadingResolver resolver = new HeadingResolver(queryGraph); diff --git a/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java b/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java index 17c5f899a8a..53036f2bf65 100644 --- a/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java @@ -22,12 +22,8 @@ import com.graphhopper.GHResponse; import com.graphhopper.ResponsePath; import com.graphhopper.config.Profile; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.storage.NodeAccess; @@ -58,9 +54,10 @@ class HeadingRoutingTest { @Test public void headingTest1() { // Test enforce start direction - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager encodingManager = new EncodingManager.Builder().add(carEncoder).add(Subnetwork.create("profile")).build(); - BaseGraph graph = createSquareGraph(encodingManager); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(Subnetwork.create("profile")).build(); + BaseGraph graph = createSquareGraph(encodingManager, accessEnc, speedEnc); Router router = createRouter(graph, encodingManager); // Start in middle of edge 4-5 @@ -81,9 +78,10 @@ public void headingTest1() { @Test public void headingTest2() { // Test enforce south start direction and east end direction - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager encodingManager = new EncodingManager.Builder().add(carEncoder).add(Subnetwork.create("profile")).build(); - BaseGraph graph = createSquareGraph(encodingManager); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(Subnetwork.create("profile")).build(); + BaseGraph graph = createSquareGraph(encodingManager, accessEnc, speedEnc); Router router = createRouter(graph, encodingManager); // Start in middle of edge 4-5 @@ -108,9 +106,10 @@ public void headingTest2() { @Test public void headingTest3() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager encodingManager = new EncodingManager.Builder().add(carEncoder).add(Subnetwork.create("profile")).build(); - BaseGraph graph = createSquareGraph(encodingManager); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(Subnetwork.create("profile")).build(); + BaseGraph graph = createSquareGraph(encodingManager, accessEnc, speedEnc); Router router = createRouter(graph, encodingManager); // Start in middle of edge 4-5 @@ -133,9 +132,10 @@ public void headingTest3() { @Test public void headingTest4() { // Test straight via routing - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager encodingManager = new EncodingManager.Builder().add(carEncoder).add(Subnetwork.create("profile")).build(); - BaseGraph graph = createSquareGraph(encodingManager); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(Subnetwork.create("profile")).build(); + BaseGraph graph = createSquareGraph(encodingManager, accessEnc, speedEnc); Router router = createRouter(graph, encodingManager); // Start in middle of edge 4-5 @@ -158,9 +158,10 @@ public void headingTest4() { @Test public void headingTest5() { // Test independence of previous enforcement for subsequent paths - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager encodingManager = new EncodingManager.Builder().add(carEncoder).add(Subnetwork.create("profile")).build(); - BaseGraph graph = createSquareGraph(encodingManager); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(Subnetwork.create("profile")).build(); + BaseGraph graph = createSquareGraph(encodingManager, accessEnc, speedEnc); Router router = createRouter(graph, encodingManager); // Start in middle of edge 4-5 @@ -182,9 +183,10 @@ public void headingTest5() { @Test public void testHeadingWithSnapFilter() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager encodingManager = new EncodingManager.Builder().add(carEncoder).add(Subnetwork.create("profile")).build(); - BaseGraph graph = createSquareGraphWithTunnel(encodingManager); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(Subnetwork.create("profile")).build(); + BaseGraph graph = createSquareGraphWithTunnel(encodingManager, accessEnc, speedEnc); Router router = createRouter(graph, encodingManager); // Start at 8 (slightly north to make it independent on some edge ordering and always use 8-3 or 3-8 as fallback) GHPoint start = new GHPoint(0.0011, 0.001); @@ -244,9 +246,10 @@ public void testHeadingWithSnapFilter() { @Test public void testHeadingWithSnapFilter2() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager encodingManager = new EncodingManager.Builder().add(carEncoder).add(Subnetwork.create("profile")).build(); - BaseGraph graph = createSquareGraphWithTunnel(encodingManager); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(Subnetwork.create("profile")).build(); + BaseGraph graph = createSquareGraphWithTunnel(encodingManager, accessEnc, speedEnc); Router router = createRouter(graph, encodingManager); // Start at 8 (slightly east to snap to edge 1->5 per default) GHPoint start = new GHPoint(0.001, 0.0011); @@ -277,9 +280,10 @@ public void testHeadingWithSnapFilter2() { @Test public void headingTest6() { // Test if snaps at tower nodes are ignored - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager encodingManager = new EncodingManager.Builder().add(carEncoder).add(Subnetwork.create("profile")).build(); - BaseGraph graph = createSquareGraph(encodingManager); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(Subnetwork.create("profile")).build(); + BaseGraph graph = createSquareGraph(encodingManager, accessEnc, speedEnc); Router router = createRouter(graph, encodingManager); // QueryPoints directly on TowerNodes @@ -306,10 +310,8 @@ private Router createRouter(BaseGraph graph, EncodingManager encodingManager) { new DefaultWeightingFactory(graph.getBaseGraph(), encodingManager), Collections.emptyMap(), Collections.emptyMap()); } - private BaseGraph createSquareGraph(EncodingManager encodingManager) { + private BaseGraph createSquareGraph(EncodingManager encodingManager, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { BaseGraph g = new BaseGraph.Builder(encodingManager).create(); - FlagEncoder carEncoder = encodingManager.getEncoder("car"); - // 2---3---4 // | | | // 1---8---5 @@ -326,8 +328,6 @@ private BaseGraph createSquareGraph(EncodingManager encodingManager) { na.setNode(7, 0.000, 0.001); na.setNode(8, 0.001, 0.001); - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(100)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(100)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(100)); @@ -345,10 +345,8 @@ private BaseGraph createSquareGraph(EncodingManager encodingManager) { return g; } - private BaseGraph createSquareGraphWithTunnel(EncodingManager encodingManager) { + private BaseGraph createSquareGraphWithTunnel(EncodingManager encodingManager, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { BaseGraph g = new BaseGraph.Builder(encodingManager).create(); - FlagEncoder carEncoder = encodingManager.getEncoder("car"); - // 2----3---4 // | | | // 1->- 8 >-5 (edge 1->5 is not connected to 8) @@ -365,8 +363,6 @@ private BaseGraph createSquareGraphWithTunnel(EncodingManager encodingManager) { na.setNode(7, 0.000, 0.001); na.setNode(8, 0.001, 0.001); - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(100)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(100)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(100)); diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index 1997028799e..e6b0af10645 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -19,8 +19,6 @@ import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.ShortestWeighting; @@ -45,15 +43,14 @@ * @author Peter Karich */ public class PathTest { - private final FlagEncoder encoder = FlagEncoders.createCar(); - private final EncodingManager carManager = EncodingManager.create(encoder); - private final BooleanEncodedValue carAccessEnc = encoder.getAccessEnc(); - private final DecimalEncodedValue carAvSpeedEnc = encoder.getAverageSpeedEnc(); - private final EncodingManager mixedEncodingManager = EncodingManager.create(FlagEncoders.createCar(), FlagEncoders.createFoot()); - private final BooleanEncodedValue mixedCarAccessEnc = mixedEncodingManager.getEncoder("car").getAccessEnc(); - private final DecimalEncodedValue mixedCarSpeedEnc = mixedEncodingManager.getEncoder("car").getAverageSpeedEnc(); - private final BooleanEncodedValue mixedFootAccessEnc = mixedEncodingManager.getEncoder("foot").getAccessEnc(); - private final DecimalEncodedValue mixedFootSpeedEnc = mixedEncodingManager.getEncoder("foot").getAverageSpeedEnc(); + private final BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue carAvSpeedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + private final EncodingManager carManager = EncodingManager.start().add(carAccessEnc).add(carAvSpeedEnc).build(); + private final BooleanEncodedValue mixedCarAccessEnc = new SimpleBooleanEncodedValue("mixed_car_access", true); + private final DecimalEncodedValue mixedCarSpeedEnc = new DecimalEncodedValueImpl("mixed_car_speed", 5, 5, false); + private final BooleanEncodedValue mixedFootAccessEnc = new SimpleBooleanEncodedValue("mixed_foot_access", true); + private final DecimalEncodedValue mixedFootSpeedEnc = new DecimalEncodedValueImpl("mixed_foot_speed", 4, 1, false); + private final EncodingManager mixedEncodingManager = EncodingManager.start().add(mixedCarAccessEnc).add(mixedCarSpeedEnc).add(mixedFootAccessEnc).add(mixedFootSpeedEnc).build(); private final TranslationMap trMap = TranslationMapTest.SINGLETON; private final Translation tr = trMap.getWithFallBack(Locale.US); private final RoundaboutGraph roundaboutGraph = new RoundaboutGraph(); @@ -83,7 +80,7 @@ public void testWayList() { edge2.setWayGeometry(Helper.createPointList(11, 1, 10, 1)); SPTEntry e1 = new SPTEntry(edge2.getEdge(), 2, 1, new SPTEntry(edge1.getEdge(), 1, 1, new SPTEntry(0, 1))); - FastestWeighting weighting = new FastestWeighting(encoder); + FastestWeighting weighting = new FastestWeighting(carAccessEnc, carAvSpeedEnc); Path path = extractPath(g, weighting, e1); // 0-1-2 assertPList(Helper.createPointList(0, 0.1, 8, 1, 9, 1, 1, 0.1, 10, 1, 11, 1, 2, 0.1), path.calcPoints()); @@ -196,7 +193,7 @@ public void testFindInstruction() { new SPTEntry(edge1.getEdge(), 1, 1, new SPTEntry(0, 1) )))); - FastestWeighting weighting = new FastestWeighting(encoder); + FastestWeighting weighting = new FastestWeighting(carAccessEnc, carAvSpeedEnc); Path path = extractPath(g, weighting, e1); InstructionList il = InstructionsFromEdges.calcInstructions(path, path.graph, weighting, carManager, tr); @@ -212,45 +209,47 @@ public void testFindInstruction() { * Test roundabout instructions for different profiles */ @Test - public void testCalcInstructionsRoundabout() { - for (FlagEncoder encoder : mixedEncodingManager.fetchEdgeEncoders()) { - ShortestWeighting weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); - Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) - .calcPath(1, 8); - assertTrue(p.isFound()); - assertEquals("[1, 2, 3, 4, 5, 8]", p.calcNodes().toString()); - InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); - // Test instructions - List tmpList = getTurnDescriptions(wayList); - assertEquals(Arrays.asList("continue onto MainStreet 1 2", - "At roundabout, take exit 3 onto 5-8", - "arrive at destination"), - tmpList); - // Test Radian - double delta = roundaboutGraph.getAngle(1, 2, 5, 8); - RoundaboutInstruction instr = (RoundaboutInstruction) wayList.get(1); - assertEquals(delta, instr.getTurnAngle(), 0.01); - - // case of continuing a street through a roundabout - p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED). - calcPath(1, 7); - wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); - tmpList = getTurnDescriptions(wayList); - assertEquals(Arrays.asList("continue onto MainStreet 1 2", - "At roundabout, take exit 2 onto MainStreet 4 7", - "arrive at destination"), - tmpList); - // Test Radian - delta = roundaboutGraph.getAngle(1, 2, 4, 7); - instr = (RoundaboutInstruction) wayList.get(1); - assertEquals(delta, instr.getTurnAngle(), 0.01); - } + void testCalcInstructionsRoundabout() { + calcInstructionsRoundabout(mixedCarAccessEnc, mixedCarSpeedEnc); + calcInstructionsRoundabout(mixedFootAccessEnc, mixedFootSpeedEnc); + } + + public void calcInstructionsRoundabout(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { + ShortestWeighting weighting = new ShortestWeighting(accessEnc, speedEnc); + Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) + .calcPath(1, 8); + assertTrue(p.isFound()); + assertEquals("[1, 2, 3, 4, 5, 8]", p.calcNodes().toString()); + InstructionList wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); + // Test instructions + List tmpList = getTurnDescriptions(wayList); + assertEquals(Arrays.asList("continue onto MainStreet 1 2", + "At roundabout, take exit 3 onto 5-8", + "arrive at destination"), + tmpList); + // Test Radian + double delta = roundaboutGraph.getAngle(1, 2, 5, 8); + RoundaboutInstruction instr = (RoundaboutInstruction) wayList.get(1); + assertEquals(delta, instr.getTurnAngle(), 0.01); + + // case of continuing a street through a roundabout + p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED). + calcPath(1, 7); + wayList = InstructionsFromEdges.calcInstructions(p, p.graph, weighting, mixedEncodingManager, tr); + tmpList = getTurnDescriptions(wayList); + assertEquals(Arrays.asList("continue onto MainStreet 1 2", + "At roundabout, take exit 2 onto MainStreet 4 7", + "arrive at destination"), + tmpList); + // Test Radian + delta = roundaboutGraph.getAngle(1, 2, 4, 7); + instr = (RoundaboutInstruction) wayList.get(1); + assertEquals(delta, instr.getTurnAngle(), 0.01); } @Test public void testCalcInstructionsRoundaboutBegin() { - FlagEncoder encoder = mixedEncodingManager.getEncoder("car"); - ShortestWeighting weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(mixedCarAccessEnc, mixedCarSpeedEnc); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(2, 8); assertTrue(p.isFound()); @@ -264,8 +263,7 @@ public void testCalcInstructionsRoundaboutBegin() { @Test public void testCalcInstructionsRoundaboutDirectExit() { roundaboutGraph.inverse3to9(); - FlagEncoder encoder = mixedEncodingManager.getEncoder("car"); - ShortestWeighting weighting = new ShortestWeighting(encoder.getAccessEnc(), encoder.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(mixedCarAccessEnc, mixedCarSpeedEnc); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(6, 8); assertTrue(p.isFound()); @@ -456,8 +454,7 @@ public void testCalcDistanceDetails() { @Test public void testCalcInstructionsRoundabout2() { roundaboutGraph.inverse3to6(); - FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); - ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(mixedCarAccessEnc, mixedCarSpeedEnc); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 8); assertTrue(p.isFound()); @@ -543,8 +540,7 @@ public void testCalcInstructionsRoundaboutIssue353() { @Test public void testCalcInstructionsRoundaboutClockwise() { roundaboutGraph.setRoundabout(true); - FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); - ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(mixedCarAccessEnc, mixedCarSpeedEnc); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(1, 8); assertTrue(p.isFound()); @@ -563,8 +559,7 @@ public void testCalcInstructionsRoundaboutClockwise() { @Test public void testCalcInstructionsIgnoreContinue() { // Follow a couple of straight edges, including a name change - FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); - ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(mixedCarAccessEnc, mixedCarSpeedEnc); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(4, 11); assertTrue(p.isFound()); @@ -577,8 +572,7 @@ public void testCalcInstructionsIgnoreContinue() { @Test public void testCalcInstructionsIgnoreTurnIfNoAlternative() { // The street turns left, but there is not turn - FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); - ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(mixedCarAccessEnc, mixedCarSpeedEnc); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(10, 12); assertTrue(p.isFound()); @@ -858,12 +852,12 @@ public void testUTurnLeft() { na.setNode(6, 48.402422, 9.996067); na.setNode(7, 48.402604, 9.994962); - GHUtility.setSpeed(60, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 0, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße")), g.edge(2, 3).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße")), g.edge(6, 5).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße")), g.edge(5, 4).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße"))); - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, carAccessEnc, carAvSpeedEnc, g.edge(2, 5).setDistance(5).setKeyValues(singletonMap("name", "Neithardtstraße")), g.edge(5, 7).setDistance(5).setKeyValues(singletonMap("name", "Neithardtstraße"))); @@ -896,12 +890,12 @@ public void testUTurnRight() { na.setNode(6, -33.885692, 151.181445); na.setNode(7, -33.885692, 151.181445); - GHUtility.setSpeed(60, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 0, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road")), g.edge(2, 3).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road")), g.edge(4, 5).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road")), g.edge(5, 6).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road"))); - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, carAccessEnc, carAvSpeedEnc, g.edge(2, 5).setDistance(5).setKeyValues(singletonMap("name", "Larkin Street")), g.edge(5, 7).setDistance(5).setKeyValues(singletonMap("name", "Larkin Street"))); @@ -918,8 +912,7 @@ public void testUTurnRight() { @Test public void testCalcInstructionsForTurn() { // The street turns left, but there is not turn - FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); - ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(mixedCarAccessEnc, mixedCarSpeedEnc); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(11, 13); assertTrue(p.isFound()); @@ -934,8 +927,7 @@ public void testCalcInstructionsForTurn() { @Test public void testCalcInstructionsForSlightTurnWithOtherSlightTurn() { // Test for a fork with two slight turns. Since there are two slight turns, show the turn instruction - FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); - ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(mixedCarAccessEnc, mixedCarSpeedEnc); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(12, 16); assertTrue(p.isFound()); @@ -979,8 +971,7 @@ public void testCalcInstructionsForSlightTurnOntoDifferentStreet() { @Test public void testIgnoreInstructionsForSlightTurnWithOtherTurn() { // Test for a fork with one sligh turn and one actual turn. We are going along the slight turn. No turn instruction needed in this case - FlagEncoder mixedCar = mixedEncodingManager.getEncoder("car"); - ShortestWeighting weighting = new ShortestWeighting(mixedCar.getAccessEnc(), mixedCar.getAverageSpeedEnc()); + ShortestWeighting weighting = new ShortestWeighting(mixedCarAccessEnc, mixedCarSpeedEnc); Path p = new Dijkstra(roundaboutGraph.g, weighting, TraversalMode.NODE_BASED) .calcPath(16, 19); assertTrue(p.isFound()); diff --git a/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java b/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java index d98c7e32b96..15c1bb9873e 100644 --- a/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/PriorityRoutingTest.java @@ -20,11 +20,10 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.json.Statement; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.RoadClass; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.PriorityCode; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.PriorityWeighting; import com.graphhopper.routing.weighting.TurnCostProvider; import com.graphhopper.routing.weighting.custom.CustomModelParser; @@ -43,8 +42,10 @@ public class PriorityRoutingTest { @Test void testMaxPriority() { - FlagEncoder encoder = FlagEncoders.createBike(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", false); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 4, 2, false); + DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl("priority", 4, PriorityCode.getFactor(1), false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).add(priorityEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); NodeAccess na = graph.getNodeAccess(); na.setNode(0, 48.0, 11.0); @@ -55,17 +56,17 @@ void testMaxPriority() { na.setNode(5, 48.2, 11.1); // 0 - 1 - 2 - 3 // \- 4 - 5 -/ - double speed = encoder.getAverageSpeedEnc().getNextStorableValue(30); + double speed = speedEnc.getNextStorableValue(30); double dist1 = 0; - dist1 += addEdge(em, graph, 0, 1, encoder, 1.0, speed).getDistance(); - dist1 += addEdge(em, graph, 1, 2, encoder, 1.0, speed).getDistance(); - dist1 += addEdge(em, graph, 2, 3, encoder, 1.0, speed).getDistance(); + dist1 += addEdge(em, graph, 0, 1, 1.0, accessEnc, speedEnc, priorityEnc, speed).getDistance(); + dist1 += addEdge(em, graph, 1, 2, 1.0, accessEnc, speedEnc, priorityEnc, speed).getDistance(); + dist1 += addEdge(em, graph, 2, 3, 1.0, accessEnc, speedEnc, priorityEnc, speed).getDistance(); final double maxPrio = PriorityCode.getFactor(PriorityCode.BEST.getValue()); double dist2 = 0; - dist2 += addEdge(em, graph, 0, 4, encoder, maxPrio, speed).getDistance(); - dist2 += addEdge(em, graph, 4, 5, encoder, maxPrio, speed).getDistance(); - dist2 += addEdge(em, graph, 5, 3, encoder, maxPrio, speed).getDistance(); + dist2 += addEdge(em, graph, 0, 4, maxPrio, accessEnc, speedEnc, priorityEnc, speed).getDistance(); + dist2 += addEdge(em, graph, 4, 5, maxPrio, accessEnc, speedEnc, priorityEnc, speed).getDistance(); + dist2 += addEdge(em, graph, 5, 3, maxPrio, accessEnc, speedEnc, priorityEnc, speed).getDistance(); // the routes 0-1-2-3 and 0-4-5-3 have similar distances (and use max speed everywhere) // ... but the shorter route 0-1-2-3 has smaller priority @@ -74,7 +75,7 @@ void testMaxPriority() { // A* and Dijkstra should yield the same path (the max priority must be taken into account by weighting.getMinWeight) { - PriorityWeighting weighting = new PriorityWeighting(encoder, new PMap(), TurnCostProvider.NO_TURN_COST_PROVIDER); + PriorityWeighting weighting = new PriorityWeighting(accessEnc, speedEnc, priorityEnc, null, new PMap(), TurnCostProvider.NO_TURN_COST_PROVIDER); Path pathDijkstra = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED).calcPath(0, 3); Path pathAStar = new AStar(graph, weighting, TraversalMode.NODE_BASED).calcPath(0, 3); assertEquals(pathDijkstra.calcNodes(), pathAStar.calcNodes()); @@ -83,7 +84,9 @@ void testMaxPriority() { { CustomModel customModel = new CustomModel(); - CustomWeighting weighting = CustomModelParser.createWeighting(encoder, em, TurnCostProvider.NO_TURN_COST_PROVIDER, customModel); + CustomWeighting weighting = CustomModelParser.createWeighting(accessEnc, + speedEnc, priorityEnc, em, + TurnCostProvider.NO_TURN_COST_PROVIDER, customModel); Path pathDijkstra = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED).calcPath(0, 3); Path pathAStar = new AStar(graph, weighting, TraversalMode.NODE_BASED).calcPath(0, 3); assertEquals(pathDijkstra.calcNodes(), pathAStar.calcNodes()); @@ -94,7 +97,8 @@ void testMaxPriority() { CustomModel customModel = new CustomModel(); // now we even increase the priority in the custom model, which also needs to be accounted for in weighting.getMinWeight customModel.addToPriority(Statement.If("road_class == MOTORWAY", Statement.Op.MULTIPLY, "3")); - CustomWeighting weighting = CustomModelParser.createWeighting(encoder, em, TurnCostProvider.NO_TURN_COST_PROVIDER, customModel); + CustomWeighting weighting = CustomModelParser.createWeighting(accessEnc, speedEnc, + priorityEnc, em, TurnCostProvider.NO_TURN_COST_PROVIDER, customModel); Path pathDijkstra = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED).calcPath(0, 3); Path pathAStar = new AStar(graph, weighting, TraversalMode.NODE_BASED).calcPath(0, 3); assertEquals(pathDijkstra.calcNodes(), pathAStar.calcNodes()); @@ -102,10 +106,7 @@ void testMaxPriority() { } } - private EdgeIteratorState addEdge(EncodingManager em, BaseGraph graph, int p, int q, FlagEncoder encoder, double prio, double speed) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); - DecimalEncodedValue priorityEnc = em.getDecimalEncodedValue(EncodingManager.getKey(encoder, "priority")); + private EdgeIteratorState addEdge(EncodingManager em, BaseGraph graph, int p, int q, double prio, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, double speed) { EnumEncodedValue roadClassEnc = em.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); return graph.edge(p, q) .set(accessEnc, true) diff --git a/core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java b/core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java index 0ede45cc403..3d859d5d4e5 100644 --- a/core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java +++ b/core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java @@ -30,6 +30,7 @@ import java.util.Arrays; import java.util.Collections; +import java.util.List; import static org.junit.jupiter.api.Assertions.*; @@ -92,6 +93,8 @@ public void missingProfiles() { // if we set the weighting as well it works assertEquals("fast_bike", profileResolver.resolveProfile(new PMap().putObject("vehicle", "bike").putObject("weighting", "fastest")).getName()); assertEquals("short_bike", profileResolver.resolveProfile(new PMap().putObject("vehicle", "bike").putObject("weighting", "shortest")).getName()); + + assertUnsupportedVehicle(profileResolver, "unknown", Arrays.asList("car", "bike")); } @Test @@ -165,4 +168,9 @@ private void assertProfileNotFound(ProfileResolver profileResolver, PMap hints) } } + private void assertUnsupportedVehicle(ProfileResolver profileResolver, String vehicle, List supported) { + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> profileResolver.resolveProfile(new PMap().putObject("vehicle", vehicle))); + assertTrue(e.getMessage().contains("Vehicle not supported: `" + vehicle + "`. Supported are: `" + supported + "`"), e.getMessage()); + } + } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java b/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java index caf2aa32d64..a556844f224 100644 --- a/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/QueryRoutingCHGraphTest.java @@ -19,13 +19,10 @@ package com.graphhopper.routing; import com.graphhopper.routing.ch.PrepareEncoder; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.querygraph.QueryRoutingCHGraph; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.storage.*; @@ -33,7 +30,6 @@ import com.graphhopper.util.DistancePlaneProjection; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -44,7 +40,9 @@ import static org.junit.jupiter.api.Assertions.*; class QueryRoutingCHGraphTest { - private FlagEncoder encoder; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; + private DecimalEncodedValue turnCostEnc; private EncodingManager encodingManager; private FastestWeighting weighting; private BaseGraph graph; @@ -52,18 +50,20 @@ class QueryRoutingCHGraphTest { @BeforeEach public void setup() { - encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", 5).putObject("speed_two_directions", true)); - encodingManager = EncodingManager.create(encoder); - graph = new BaseGraph.Builder(encodingManager).create(); - weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage())); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, true); + turnCostEnc = TurnCost.create("car", 5); + encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); + graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); + weighting = new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage())); na = graph.getNodeAccess(); } @Test public void basic() { // 0-1-2 - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); graph.freeze(); assertEquals(2, graph.getEdges()); @@ -100,8 +100,8 @@ public void basic() { public void withShortcuts() { // 0-1-2 // \-/ - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(10)); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); graph.freeze(); assertEquals(2, graph.getEdges()); @@ -266,7 +266,7 @@ public void withVirtualEdgesAndShortcuts() { @Test public void getBaseGraph() { - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); graph.freeze(); CHConfig chConfig = CHConfig.edgeBased("x", weighting); @@ -370,7 +370,7 @@ public void getWeight() { na.setNode(2, 50.00, 10.20); EdgeIteratorState edge = addEdge(graph, 0, 1) // use different speeds for the two directions - .set(encoder.getAverageSpeedEnc(), 90, 30); + .set(speedEnc, 90, 30); addEdge(graph, 1, 2); graph.freeze(); @@ -471,8 +471,8 @@ public void getWeight_withAccess() { // we set the access flags, but do use direction dependent speeds to make sure we are testing whether or not the // access flags are respected and the weight calculation does not simply rely on the speed, see this forum issue // https://discuss.graphhopper.com/t/speed-and-access-when-setbothdirections-true-false/5695 - edge.set(encoder.getAccessEnc(), true, false); - edge.set(encoder.getAverageSpeedEnc(), 60, 60); + edge.set(accessEnc, true, false); + edge.set(speedEnc, 60, 60); graph.freeze(); CHConfig chConfig = CHConfig.edgeBased("x", weighting); @@ -550,7 +550,6 @@ public void getTurnCost() { na.setNode(2, 50.00, 10.20); EdgeIteratorState edge1 = addEdge(graph, 0, 1); EdgeIteratorState edge2 = addEdge(graph, 1, 2); - DecimalEncodedValue turnCostEnc = encodingManager.getDecimalEncodedValue(TurnCost.key(encoder.toString())); graph.getTurnCostStorage().set(turnCostEnc, 0, 1, 1, 5); graph.freeze(); @@ -695,7 +694,7 @@ private void assertEnd(RoutingCHEdgeIterator outIter) { private EdgeIteratorState addEdge(Graph graph, int from, int to) { NodeAccess na = graph.getNodeAccess(); double dist = DistancePlaneProjection.DIST_PLANE.calcDist(na.getLat(from), na.getLon(from), na.getLat(to), na.getLon(to)); - return GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(from, to).setDistance(dist)); + return GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(from, to).setDistance(dist)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java b/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java index 840347c8947..e1f361e0536 100644 --- a/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/RandomCHRoutingTest.java @@ -2,10 +2,12 @@ import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory; import com.graphhopper.routing.ch.PrepareContractionHierarchies; -import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.querygraph.QueryRoutingCHGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -43,28 +45,29 @@ private static final class Fixture { private final TraversalMode traversalMode; private final int maxTurnCosts; private final int uTurnCosts; - private final Directory dir; - private final FlagEncoder encoder; - private final EncodingManager encodingManager; + private final BooleanEncodedValue accessEnc; + private final DecimalEncodedValue speedEnc; + private final DecimalEncodedValue turnCostEnc; private Weighting weighting; - private BaseGraph graph; + private final BaseGraph graph; private CHConfig chConfig; Fixture(TraversalMode traversalMode, int uTurnCosts) { this.traversalMode = traversalMode; this.maxTurnCosts = 10; this.uTurnCosts = uTurnCosts; - dir = new RAMDirectory(); - encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxTurnCosts)); - encodingManager = EncodingManager.create(encoder); - graph = new BaseGraph.Builder(encodingManager).create(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + turnCostEnc = TurnCost.create("car", maxTurnCosts); + EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); + graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); } void freeze() { graph.freeze(); chConfig = traversalMode.isEdgeBased() - ? CHConfig.edgeBased("p", new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage(), uTurnCosts))) - : CHConfig.nodeBased("p", new FastestWeighting(encoder)); + ? CHConfig.edgeBased("p", new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage(), uTurnCosts))) + : CHConfig.nodeBased("p", new FastestWeighting(accessEnc, speedEnc)); weighting = chConfig.getWeighting(); } @@ -103,9 +106,9 @@ public void random(Fixture f) { // the same as taking the direct edge! double pOffset = 0; GHUtility.buildRandomGraph(f.graph, rnd, numNodes, 2.5, true, true, - f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), null, 0.7, 0.9, pOffset); + f.accessEnc, f.speedEnc, null, 0.7, 0.9, pOffset); if (f.traversalMode.isEdgeBased()) { - GHUtility.addRandomTurnCosts(f.graph, seed, f.encodingManager, f.encoder, f.maxTurnCosts, f.graph.getTurnCostStorage()); + GHUtility.addRandomTurnCosts(f.graph, seed, f.accessEnc, f.turnCostEnc, f.maxTurnCosts, f.graph.getTurnCostStorage()); } runRandomTest(f, rnd, 20); } @@ -115,7 +118,7 @@ public void random(Fixture f) { public void issue1574_1(Fixture f) { assumeFalse(f.traversalMode.isEdgeBased()); Random rnd = new Random(9348906923700L); - buildRandomGraphLegacy(f.graph, f.encoder, rnd, 50, 2.5, false, true, 0.9); + buildRandomGraphLegacy(f.graph, f.accessEnc, f.speedEnc, rnd, 50, 2.5, false, true, 0.9); runRandomTest(f, rnd, 20); } @@ -124,7 +127,7 @@ public void issue1574_1(Fixture f) { public void issue1574_2(Fixture f) { assumeFalse(f.traversalMode.isEdgeBased()); Random rnd = new Random(10093639220394L); - buildRandomGraphLegacy(f.graph, f.encoder, rnd, 50, 2.5, false, true, 0.9); + buildRandomGraphLegacy(f.graph, f.accessEnc, f.speedEnc, rnd, 50, 2.5, false, true, 0.9); runRandomTest(f, rnd, 20); } @@ -133,7 +136,7 @@ public void issue1574_2(Fixture f) { public void issue1582(Fixture f) { assumeFalse(f.traversalMode.isEdgeBased()); Random rnd = new Random(4111485945982L); - buildRandomGraphLegacy(f.graph, f.encoder, rnd, 10, 2.5, false, true, 0.9); + buildRandomGraphLegacy(f.graph, f.accessEnc, f.speedEnc, rnd, 10, 2.5, false, true, 0.9); runRandomTest(f, rnd, 100); } @@ -142,7 +145,7 @@ public void issue1582(Fixture f) { public void issue1583(Fixture f) { assumeFalse(f.traversalMode.isEdgeBased()); Random rnd = new Random(10785899964423L); - buildRandomGraphLegacy(f.graph, f.encoder, rnd, 50, 2.5, true, true, 0.9); + buildRandomGraphLegacy(f.graph, f.accessEnc, f.speedEnc, rnd, 50, 2.5, true, true, 0.9); runRandomTest(f, rnd, 20); } @@ -153,13 +156,13 @@ public void issue1593(Fixture f) { long seed = 60643479675316L; Random rnd = new Random(seed); GHUtility.buildRandomGraph(f.graph, rnd, 50, 2.5, true, true, - f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), null, 0.7, 0.9, 0.0); - GHUtility.addRandomTurnCosts(f.graph, seed, f.encodingManager, f.encoder, f.maxTurnCosts, f.graph.getTurnCostStorage()); + f.accessEnc, f.speedEnc, null, 0.7, 0.9, 0.0); + GHUtility.addRandomTurnCosts(f.graph, seed, f.accessEnc, f.turnCostEnc, f.maxTurnCosts, f.graph.getTurnCostStorage()); runRandomTest(f, rnd, 20); } private void runRandomTest(Fixture f, Random rnd, int numVirtualNodes) { - LocationIndexTree locationIndex = new LocationIndexTree(f.graph, f.dir); + LocationIndexTree locationIndex = new LocationIndexTree(f.graph, f.graph.getDirectory()); locationIndex.prepareIndex(); f.freeze(); @@ -225,7 +228,7 @@ private void runRandomTest(Fixture f, Random rnd, int numVirtualNodes) { * More or less does the same as {@link GHUtility#buildRandomGraph}, but since some special seeds * are used in a few tests above this code is kept here. Do not use it for new tests. */ - private void buildRandomGraphLegacy(Graph graph, FlagEncoder encoder, Random random, int numNodes, double meanDegree, boolean allowLoops, boolean allowZeroDistance, double pBothDir) { + private void buildRandomGraphLegacy(Graph graph, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, Random random, int numNodes, double meanDegree, boolean allowLoops, boolean allowZeroDistance, double pBothDir) { for (int i = 0; i < numNodes; ++i) { double lat = 49.4 + (random.nextDouble() * 0.0001); double lon = 9.7 + (random.nextDouble() * 0.0001); @@ -251,10 +254,9 @@ private void buildRandomGraphLegacy(Graph graph, FlagEncoder encoder, Random ran maxDist = Math.max(maxDist, distance); // using bidirectional edges will increase mean degree of graph above given value boolean bothDirections = random.nextDouble() < pBothDir; - EdgeIteratorState edge = GHUtility.setSpeed(60, true, bothDirections, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(from, to).setDistance(distance)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, bothDirections, accessEnc, speedEnc, graph.edge(from, to).setDistance(distance)); double fwdSpeed = 10 + random.nextDouble() * 120; double bwdSpeed = 10 + random.nextDouble() * 120; - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); edge.set(speedEnc, fwdSpeed); if (speedEnc.isStoreTwoDirections()) edge.setReverse(speedEnc, bwdSpeed); diff --git a/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java b/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java index 11c506c25ef..f032779f377 100644 --- a/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/RandomizedRoutingTest.java @@ -22,11 +22,13 @@ import com.carrotsearch.hppc.IntIndexedContainer; import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory; import com.graphhopper.routing.ch.PrepareContractionHierarchies; -import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.lm.*; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.querygraph.QueryRoutingCHGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -94,9 +96,10 @@ private static class Fixture { private final boolean prepareCH; private final boolean prepareLM; private final TraversalMode traversalMode; - private final Directory dir; private final BaseGraph graph; - private final FlagEncoder encoder; + private final BooleanEncodedValue accessEnc; + private final DecimalEncodedValue speedEnc; + private final DecimalEncodedValue turnCostEnc; private final TurnCostStorage turnCostStorage; private final int maxTurnCosts; private Weighting weighting; @@ -110,14 +113,15 @@ private static class Fixture { this.prepareLM = prepareLM; this.traversalMode = traversalMode; maxTurnCosts = 10; - dir = new RAMDirectory(); // todo: this test only works with speedTwoDirections=false (as long as loops are enabled), otherwise it will // fail sometimes for edge-based algorithms, #1631, but maybe we can should disable different fwd/bwd speeds // only for loops instead? - encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxTurnCosts)); - encodingManager = new EncodingManager.Builder().add(encoder).add(Subnetwork.create("car")).build(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + turnCostEnc = TurnCost.create("car", maxTurnCosts); + encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).add(Subnetwork.create("car")).build(); graph = new BaseGraph.Builder(encodingManager) - .setDir(dir) + .withTurnCosts(true) .create(); turnCostStorage = graph.getTurnCostStorage(); } @@ -130,8 +134,8 @@ public String toString() { private void preProcessGraph() { graph.freeze(); weighting = traversalMode.isEdgeBased() - ? new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage())) - : new FastestWeighting(encoder); + ? new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage())) + : new FastestWeighting(accessEnc, speedEnc); if (prepareCH) { CHConfig chConfig = traversalMode.isEdgeBased() ? CHConfig.edgeBased("p", weighting) : CHConfig.nodeBased("p", weighting); PrepareContractionHierarchies pch = PrepareContractionHierarchies.fromGraph(graph, chConfig); @@ -140,8 +144,8 @@ private void preProcessGraph() { } if (prepareLM) { // important: for LM preparation we need to use a weighting without turn costs #1960 - LMConfig lmConfig = new LMConfig("car", new FastestWeighting(encoder)); - PrepareLandmarks prepare = new PrepareLandmarks(dir, graph, encodingManager, lmConfig, 16); + LMConfig lmConfig = new LMConfig("car", new FastestWeighting(accessEnc, speedEnc)); + PrepareLandmarks prepare = new PrepareLandmarks(graph.getDirectory(), graph, encodingManager, lmConfig, 16); prepare.setMaximumWeight(10000); prepare.doWork(); lm = prepare.getLandmarkStorage(); @@ -298,9 +302,9 @@ public void randomGraph(Supplier fixtureSupplier) { final int numQueries = 50; Random rnd = new Random(seed); GHUtility.buildRandomGraph(f.graph, rnd, 100, 2.2, true, true, - f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), null, 0.7, 0.8, 0.8); - GHUtility.addRandomTurnCosts(f.graph, seed, f.encodingManager, f.encoder, f.maxTurnCosts, f.turnCostStorage); -// GHUtility.printGraphForUnitTest(f.graph, f.encoder); + f.accessEnc, f.speedEnc, null, 0.7, 0.8, 0.8); + GHUtility.addRandomTurnCosts(f.graph, seed, f.accessEnc, f.turnCostEnc, f.maxTurnCosts, f.turnCostStorage); +// GHUtility.printGraphForUnitTest(f.graph, f.accessEnc, f.speedEnc); f.preProcessGraph(); List strictViolations = new ArrayList<>(); for (int i = 0; i < numQueries; i++) { @@ -336,11 +340,11 @@ public void randomGraph_withQueryGraph(Supplier fixtureSupplier) { double pOffset = 0; Random rnd = new Random(seed); GHUtility.buildRandomGraph(f.graph, rnd, 50, 2.2, true, true, - f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), null, 0.7, 0.8, pOffset); - GHUtility.addRandomTurnCosts(f.graph, seed, f.encodingManager, f.encoder, f.maxTurnCosts, f.turnCostStorage); -// GHUtility.printGraphForUnitTest(f.graph, f.encoder); + f.accessEnc, f.speedEnc, null, 0.7, 0.8, pOffset); + GHUtility.addRandomTurnCosts(f.graph, seed, f.accessEnc, f.turnCostEnc, f.maxTurnCosts, f.turnCostStorage); +// GHUtility.printGraphForUnitTest(f.graph, f.accessEnc, f.speedEnc); f.preProcessGraph(); - LocationIndexTree index = new LocationIndexTree(f.graph, f.dir); + LocationIndexTree index = new LocationIndexTree(f.graph, f.graph.getDirectory()); index.prepareIndex(); List strictViolations = new ArrayList<>(); for (int i = 0; i < numQueries; i++) { diff --git a/core/src/test/java/com/graphhopper/routing/RoundTripRoutingTest.java b/core/src/test/java/com/graphhopper/routing/RoundTripRoutingTest.java index 3089c6e1c34..f0b41076a6c 100644 --- a/core/src/test/java/com/graphhopper/routing/RoundTripRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoundTripRoutingTest.java @@ -18,8 +18,15 @@ package com.graphhopper.routing; import com.carrotsearch.hppc.IntArrayList; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.querygraph.QueryGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.FiniteWeightFilter; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.BaseGraph; @@ -46,9 +53,10 @@ * @author Peter Karich */ public class RoundTripRoutingTest { - private final FlagEncoder carFE = FlagEncoders.createCar(); - private final EncodingManager em = EncodingManager.create(carFE); - private final Weighting fastestWeighting = new FastestWeighting(carFE); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + private final EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); + private final Weighting fastestWeighting = new FastestWeighting(accessEnc, speedEnc); // TODO private final TraversalMode tMode = TraversalMode.EDGE_BASED; private final TraversalMode tMode = TraversalMode.NODE_BASED; private final GHPoint ghPoint1 = new GHPoint(0, 0); @@ -122,7 +130,7 @@ public void testCalcRoundTrip() { private BaseGraph createTestGraph() { BaseGraph graph = new BaseGraph.Builder(em).withTurnCosts(true).create(); - AlternativeRouteTest.initTestGraph(graph, carFE); + AlternativeRouteTest.initTestGraph(graph, accessEnc, speedEnc); return graph; } @@ -135,7 +143,7 @@ private BaseGraph createSquareGraph() { // |-1 0 1 BaseGraph graph = new BaseGraph.Builder(em).create(); for (int i = 0; i < 8; ++i) { - GHUtility.setSpeed(60, true, true, carFE.getAccessEnc(), carFE.getAverageSpeedEnc(), graph.edge(i, (i + 1) % 8).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(i, (i + 1) % 8).setDistance(1)); } updateDistancesFor(graph, 0, 1, -1); updateDistancesFor(graph, 1, 1, 0); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java index 9cb1bcfe23f..aeafcf8bf19 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java @@ -23,11 +23,12 @@ import com.graphhopper.routing.ch.PrepareContractionHierarchies; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.querygraph.QueryRoutingCHGraph; import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.ShortestWeighting; @@ -87,11 +88,12 @@ public class RoutingAlgorithmTest { private static class Fixture { private final EncodingManager encodingManager; - private final FlagEncoder carEncoder; - private final FlagEncoder footEncoder; - private final FlagEncoder bike2Encoder; private final BooleanEncodedValue carAccessEnc; + private final BooleanEncodedValue footAccessEnc; + private final BooleanEncodedValue bike2AccessEnc; private final DecimalEncodedValue carSpeedEnc; + private final DecimalEncodedValue footSpeedEnc; + private final DecimalEncodedValue bike2SpeedEnc; private final PathCalculator pathCalculator; private final TraversalMode traversalMode; private final Weighting defaultWeighting; @@ -100,13 +102,16 @@ private static class Fixture { public Fixture(PathCalculator pathCalculator, TraversalMode traversalMode) { this.pathCalculator = pathCalculator; this.traversalMode = traversalMode; - // vehicles used in this test - encodingManager = EncodingManager.create("car,foot,bike2"); - carEncoder = encodingManager.getEncoder("car"); - footEncoder = encodingManager.getEncoder("foot"); - bike2Encoder = encodingManager.getEncoder("bike2"); - carAccessEnc = carEncoder.getAccessEnc(); - carSpeedEnc = carEncoder.getAverageSpeedEnc(); + carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + footAccessEnc = new SimpleBooleanEncodedValue("foot_access", true); + bike2AccessEnc = new SimpleBooleanEncodedValue("bike2_access", true); + carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + footSpeedEnc = new DecimalEncodedValueImpl("foot_speed", 4, 1, false); + bike2SpeedEnc = new DecimalEncodedValueImpl("bike2_speed", 4, 2, true); + encodingManager = EncodingManager.start() + .add(carAccessEnc).add(carSpeedEnc) + .add(footAccessEnc).add(footSpeedEnc) + .add(bike2AccessEnc).add(bike2SpeedEnc).build(); // most tests use the default weighting, but this can be chosen for each test separately defaultWeighting = new ShortestWeighting(carAccessEnc, carSpeedEnc); // most tests do not limit the number of visited nodes, but this can be chosen for each test separately @@ -230,7 +235,7 @@ public Stream provideArguments(ExtensionContext context) th @ArgumentsSource(FixtureProvider.class) public void testCalcShortestPath(Fixture f) { BaseGraph graph = f.createGHStorage(); - initTestStorage(graph, f.carEncoder); + initTestStorage(graph, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(graph, 0, 7); assertEquals(nodes(0, 4, 5, 7), p.calcNodes(), p.toString()); assertEquals(62.1, p.getDistance(), .1, p.toString()); @@ -283,9 +288,9 @@ public void testBidirectionalLinear(Fixture f) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testCalcFastestPath(Fixture f) { - FastestWeighting fastestWeighting = new FastestWeighting(f.carEncoder); + FastestWeighting fastestWeighting = new FastestWeighting(f.carAccessEnc, f.carSpeedEnc); BaseGraph graph = f.createGHStorage(false); - initDirectedAndDiffSpeed(graph, f.carEncoder); + initDirectedAndDiffSpeed(graph, f.carAccessEnc, f.carSpeedEnc); Path p1 = f.calcPath(graph, f.defaultWeighting, 0, 3); assertEquals(nodes(0, 1, 5, 2, 3), p1.calcNodes()); @@ -303,9 +308,7 @@ public void testCalcFastestPath(Fixture f) { // 4-5-- | // |/ \--7 // 6----/ - static void initDirectedAndDiffSpeed(Graph graph, FlagEncoder enc) { - BooleanEncodedValue accessEnc = enc.getAccessEnc(); - DecimalEncodedValue speedEnc = enc.getAverageSpeedEnc(); + static void initDirectedAndDiffSpeed(Graph graph, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { GHUtility.setSpeed(10, true, false, accessEnc, speedEnc, graph.edge(0, 1)); GHUtility.setSpeed(100, true, false, accessEnc, speedEnc, graph.edge(0, 4)); @@ -343,21 +346,17 @@ static void initDirectedAndDiffSpeed(Graph graph, FlagEncoder enc) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testCalcFootPath(Fixture f) { - ShortestWeighting shortestWeighting = new ShortestWeighting(f.footEncoder.getAccessEnc(), f.footEncoder.getAverageSpeedEnc()); + ShortestWeighting shortestWeighting = new ShortestWeighting(f.footAccessEnc, f.footSpeedEnc); BaseGraph graph = f.createGHStorage(false); - initFootVsCar(f.carEncoder, f.footEncoder, graph); + initFootVsCar(f.carAccessEnc, f.carSpeedEnc, f.footAccessEnc, f.footSpeedEnc, graph); Path p1 = f.calcPath(graph, shortestWeighting, 0, 7); assertEquals(17000, p1.getDistance(), 1e-6, p1.toString()); assertEquals(12240 * 1000, p1.getTime(), p1.toString()); assertEquals(nodes(0, 4, 5, 7), p1.calcNodes()); } - static void initFootVsCar(FlagEncoder carEncoder, FlagEncoder footEncoder, Graph graph) { - BooleanEncodedValue footAccessEnc = footEncoder.getAccessEnc(); - DecimalEncodedValue footSpeedEnc = footEncoder.getAverageSpeedEnc(); - BooleanEncodedValue carAccessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue carSpeedEnc = carEncoder.getAverageSpeedEnc(); - + static void initFootVsCar(BooleanEncodedValue carAccessEnc, DecimalEncodedValue carSpeedEnc, + BooleanEncodedValue footAccessEnc, DecimalEncodedValue footSpeedEnc, Graph graph) { EdgeIteratorState edge = graph.edge(0, 1).setDistance(7000); GHUtility.setSpeed(5, true, true, footAccessEnc, footSpeedEnc, edge); GHUtility.setSpeed(10, true, false, carAccessEnc, carSpeedEnc, edge); @@ -395,9 +394,7 @@ static void initFootVsCar(FlagEncoder carEncoder, FlagEncoder footEncoder, Graph } // see test-graph.svg ! - static void initTestStorage(Graph graph, FlagEncoder encoder) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + static void initTestStorage(Graph graph, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(7)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 4).setDistance(6)); @@ -468,7 +465,7 @@ public void testNoPathFound(Fixture f) { @ArgumentsSource(FixtureProvider.class) public void testWikipediaShortestPath(Fixture f) { BaseGraph graph = f.createGHStorage(); - initWikipediaTestGraph(graph, f.carEncoder); + initWikipediaTestGraph(graph, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(graph, 0, 4); assertEquals(nodes(0, 2, 5, 4), p.calcNodes(), p.toString()); assertEquals(20, p.getDistance(), 1e-4, p.toString()); @@ -478,16 +475,14 @@ public void testWikipediaShortestPath(Fixture f) { @ArgumentsSource(FixtureProvider.class) public void testCalcIf1EdgeAway(Fixture f) { BaseGraph graph = f.createGHStorage(); - initTestStorage(graph, f.carEncoder); + initTestStorage(graph, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(graph, 1, 2); assertEquals(nodes(1, 2), p.calcNodes()); assertEquals(35.1, p.getDistance(), .1, p.toString()); } // see wikipedia-graph.svg ! - private void initWikipediaTestGraph(Graph graph, FlagEncoder encoder) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + private void initWikipediaTestGraph(Graph graph, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(7)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2).setDistance(9)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 5).setDistance(14)); @@ -503,7 +498,7 @@ private void initWikipediaTestGraph(Graph graph, FlagEncoder encoder) { @ArgumentsSource(FixtureProvider.class) public void testBidirectional(Fixture f) { BaseGraph graph = f.createGHStorage(); - initBiGraph(graph, f.carEncoder); + initBiGraph(graph, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(graph, 0, 4); assertEquals(nodes(0, 7, 6, 8, 3, 4), p.calcNodes(), p.toString()); @@ -520,10 +515,8 @@ public void testBidirectional(Fixture f) { // | 8 | // \ / | // 7-6----5 - public static void initBiGraph(Graph graph, FlagEncoder encoder) { + public static void initBiGraph(Graph graph, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { // distance will be overwritten in second step as we need to calculate it from lat,lon - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); @@ -582,7 +575,7 @@ public void testCreateAlgoTwice(Fixture f) { @ArgumentsSource(FixtureProvider.class) public void testMaxVisitedNodes(Fixture f) { BaseGraph graph = f.createGHStorage(); - initBiGraph(graph, f.carEncoder); + initBiGraph(graph, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(graph, 0, 4); assertTrue(p.isFound()); @@ -595,21 +588,19 @@ public void testMaxVisitedNodes(Fixture f) { @ArgumentsSource(FixtureProvider.class) public void testBidirectional2(Fixture f) { BaseGraph graph = f.createGHStorage(); - initBidirGraphManualDistances(graph, f.carEncoder); + initBidirGraphManualDistances(graph, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(graph, 0, 4); assertEquals(40, p.getDistance(), 1e-4, p.toString()); assertEquals(5, p.calcNodes().size(), p.toString()); assertEquals(nodes(0, 7, 6, 5, 4), p.calcNodes()); } - private void initBidirGraphManualDistances(BaseGraph graph, FlagEncoder encoder) { + private void initBidirGraphManualDistances(BaseGraph graph, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { // 0-1-2-3-4 // | / | // | 8 | // \ / / // 7-6-5-/ - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); @@ -627,7 +618,7 @@ private void initBidirGraphManualDistances(BaseGraph graph, FlagEncoder encoder) public void testRekeyBugOfIntBinHeap(Fixture f) { // using Dijkstra + IntBinHeap then rekey loops endlessly BaseGraph matrixGraph = f.createGHStorage(); - initMatrixALikeGraph(matrixGraph, f.carEncoder); + initMatrixALikeGraph(matrixGraph, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(matrixGraph, 36, 91); assertEquals(12, p.calcNodes().size()); @@ -642,7 +633,7 @@ public void testRekeyBugOfIntBinHeap(Fixture f) { testCorrectWeight(f, matrixGraph); } - private static void initMatrixALikeGraph(BaseGraph tmpGraph, FlagEncoder encoder) { + private static void initMatrixALikeGraph(BaseGraph tmpGraph, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { int WIDTH = 10; int HEIGHT = 15; int[][] matrix = new int[WIDTH][HEIGHT]; @@ -664,7 +655,7 @@ private static void initMatrixALikeGraph(BaseGraph tmpGraph, FlagEncoder encoder if (print) System.out.print(" " + (int) dist + "\t "); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), tmpGraph.edge(matrix[w][h], matrix[w][h - 1]).setDistance(dist)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, tmpGraph.edge(matrix[w][h], matrix[w][h - 1]).setDistance(dist)); } } if (print) { @@ -682,7 +673,7 @@ private static void initMatrixALikeGraph(BaseGraph tmpGraph, FlagEncoder encoder float dist = 5 + Math.abs(rand.nextInt(5)); if (print) System.out.print("-- " + (int) dist + "\t-- "); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), tmpGraph.edge(matrix[w][h], matrix[w - 1][h]).setDistance(dist)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, tmpGraph.edge(matrix[w][h], matrix[w - 1][h]).setDistance(dist)); } if (print) System.out.print("(" + matrix[w][h] + ")\t"); @@ -794,7 +785,7 @@ public void testWithCoordinates(Fixture f) { @ArgumentsSource(FixtureProvider.class) public void testCalcIfEmptyWay(Fixture f) { BaseGraph graph = f.createGHStorage(); - initTestStorage(graph, f.carEncoder); + initTestStorage(graph, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(graph, 0, 0); assertPathFromEqualsTo(p, 0); } @@ -803,7 +794,7 @@ public void testCalcIfEmptyWay(Fixture f) { @ArgumentsSource(FixtureProvider.class) public void testViaEdges_FromEqualsTo(Fixture f) { BaseGraph graph = f.createGHStorage(); - initTestStorage(graph, f.carEncoder); + initTestStorage(graph, f.carAccessEnc, f.carSpeedEnc); // identical tower nodes Path p = f.calcPath(graph, new GHPoint(0.001, 0.000), new GHPoint(0.001, 0.000)); assertPathFromEqualsTo(p, 0); @@ -822,7 +813,7 @@ public void testViaEdges_FromEqualsTo(Fixture f) { @ArgumentsSource(FixtureProvider.class) public void testViaEdges_BiGraph(Fixture f) { BaseGraph graph = f.createGHStorage(); - initBiGraph(graph, f.carEncoder); + initBiGraph(graph, f.carAccessEnc, f.carSpeedEnc); // 0-7 to 4-3 Path p = f.calcPath(graph, new GHPoint(0.0009, 0), new GHPoint(0.001, 0.001105)); @@ -839,7 +830,7 @@ public void testViaEdges_BiGraph(Fixture f) { @ArgumentsSource(FixtureProvider.class) public void testViaEdges_WithCoordinates(Fixture f) { BaseGraph graph = f.createGHStorage(); - initTestStorage(graph, f.carEncoder); + initTestStorage(graph, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(graph, f.defaultWeighting, 0, 1, 2, 3); assertEquals(nodes(8, 1, 2, 9), p.calcNodes()); assertEquals(56.7, p.getDistance(), .1, p.toString()); @@ -883,9 +874,9 @@ public void testViaEdges_SpecialCases(Fixture f) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testQueryGraphAndFastest(Fixture f) { - Weighting weighting = new FastestWeighting(f.carEncoder); + Weighting weighting = new FastestWeighting(f.carAccessEnc, f.carSpeedEnc); BaseGraph graph = f.createGHStorage(false); - initDirectedAndDiffSpeed(graph, f.carEncoder); + initDirectedAndDiffSpeed(graph, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(graph, weighting, new GHPoint(0.002, 0.0005), new GHPoint(0.0017, 0.0031)); assertEquals(nodes(8, 1, 5, 3, 9), p.calcNodes()); assertEquals(602.98, p.getDistance(), 1e-1); @@ -894,11 +885,11 @@ public void testQueryGraphAndFastest(Fixture f) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testTwoWeightsPerEdge(Fixture f) { - FastestWeighting fastestWeighting = new FastestWeighting(f.bike2Encoder); + FastestWeighting fastestWeighting = new FastestWeighting(f.bike2AccessEnc, f.bike2SpeedEnc); BaseGraph graph = f.createGHStorage(true); - initEleGraph(graph, f.bike2Encoder, 18); + initEleGraph(graph, 18, f.bike2AccessEnc, f.bike2SpeedEnc); // force the other path - GHUtility.setSpeed(10, false, true, f.bike2Encoder.getAccessEnc(), f.bike2Encoder.getAverageSpeedEnc(), GHUtility.getEdge(graph, 0, 3)); + GHUtility.setSpeed(10, false, true, f.bike2AccessEnc, f.bike2SpeedEnc, GHUtility.getEdge(graph, 0, 3)); // for two weights per edge it happened that Path (and also the Weighting) read the wrong side // of the speed and read 0 => infinity weight => overflow of millis => negative millis! @@ -933,7 +924,7 @@ public void test0SpeedButUnblocked_Issue242(Fixture f) { public void testTwoWeightsPerEdge2(Fixture f) { // other direction should be different! Weighting fakeWeighting = new Weighting() { - private final Weighting tmpW = new FastestWeighting(f.carEncoder); + private final Weighting tmpW = new FastestWeighting(f.carAccessEnc, f.carSpeedEnc); @Override public double getMinWeight(double distance) { @@ -997,12 +988,12 @@ public String toString() { }; BaseGraph graph = f.createGHStorage(true); - initEleGraph(graph, f.carEncoder, 60); + initEleGraph(graph, 60, f.carAccessEnc, f.carSpeedEnc); Path p = f.calcPath(graph, 0, 10); assertEquals(nodes(0, 4, 6, 10), p.calcNodes()); graph = f.createGHStorage(true); - initEleGraph(graph, f.carEncoder, 60); + initEleGraph(graph, 60, f.carAccessEnc, f.carSpeedEnc); p = f.calcPath(graph, fakeWeighting, 3, 0, 10, 9); assertEquals(nodes(12, 0, 1, 2, 11, 7, 10, 13), p.calcNodes()); assertEquals(37009621, p.getTime()); @@ -1014,7 +1005,7 @@ public String toString() { @ArgumentsSource(FixtureProvider.class) public void testRandomGraph(Fixture f) { // todo: use speed both directions - FastestWeighting fastestWeighting = new FastestWeighting(f.carEncoder); + FastestWeighting fastestWeighting = new FastestWeighting(f.carAccessEnc, f.carSpeedEnc); BaseGraph graph = f.createGHStorage(false); final long seed = System.nanoTime(); LOGGER.info("testRandomGraph - using seed: " + seed); @@ -1037,11 +1028,11 @@ public void testRandomGraph(Fixture f) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testMultipleVehicles_issue548(Fixture f) { - FastestWeighting footWeighting = new FastestWeighting(f.footEncoder); - FastestWeighting carWeighting = new FastestWeighting(f.carEncoder); + FastestWeighting footWeighting = new FastestWeighting(f.footAccessEnc, f.footSpeedEnc); + FastestWeighting carWeighting = new FastestWeighting(f.carAccessEnc, f.carSpeedEnc); BaseGraph graph = f.createGHStorage(false); - initFootVsCar(f.carEncoder, f.footEncoder, graph); + initFootVsCar(f.carAccessEnc, f.carSpeedEnc, f.footAccessEnc, f.footSpeedEnc, graph); // normal path would be 0-4-6-7 for car: Path carPath1 = f.calcPath(graph, carWeighting, 0, 7); @@ -1055,7 +1046,7 @@ public void testMultipleVehicles_issue548(Fixture f) { // ... but now we block 4-6 for car. note that we have to recreate the storage to create a new directory so // we can create new CHs :( graph = f.createGHStorage(false); - initFootVsCar(f.carEncoder, f.footEncoder, graph); + initFootVsCar(f.carAccessEnc, f.carSpeedEnc, f.footAccessEnc, f.footSpeedEnc, graph); GHUtility.setSpeed(20, false, false, f.carAccessEnc, f.carSpeedEnc, GHUtility.getEdge(graph, 4, 6)); f.resetCH(); @@ -1076,9 +1067,7 @@ public void testMultipleVehicles_issue548(Fixture f) { // 5-6-7 // | |\| // 8-9-10 - private void initEleGraph(Graph graph, FlagEncoder encoder, double s) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + private void initEleGraph(Graph graph, double s, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(10)); GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(0, 4).setDistance(12)); GHUtility.setSpeed(s, true, true, accessEnc, speedEnc, graph.edge(0, 3).setDistance(5)); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java b/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java index 7713ce75ff1..0d07bb0a463 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingCHGraphImplTest.java @@ -21,10 +21,10 @@ import com.graphhopper.routing.ch.PrepareEncoder; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.AccessFilter; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.storage.*; import com.graphhopper.util.EdgeExplorer; @@ -38,14 +38,15 @@ public class RoutingCHGraphImplTest { @Test public void testBaseAndCHEdges() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(carEncoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); graph.edge(1, 0); graph.edge(8, 9); graph.freeze(); - CHConfig chConfig = CHConfig.nodeBased("p", new FastestWeighting(carEncoder)); + CHConfig chConfig = CHConfig.nodeBased("p", new FastestWeighting(accessEnc, speedEnc)); CHStorage store = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(store); chBuilder.setIdentityLevels(); @@ -76,14 +77,15 @@ void testShortcutConnection() { // 4 ------ 1 > 0 // ^ \ // 3 2 - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); - EdgeExplorer baseCarOutExplorer = graph.createEdgeExplorer(AccessFilter.outEdges(encoder.getAccessEnc())); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(4, 1).setDistance(30)); + EdgeExplorer baseCarOutExplorer = graph.createEdgeExplorer(AccessFilter.outEdges(accessEnc)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 1).setDistance(30)); graph.freeze(); - CHConfig chConfig = CHConfig.nodeBased("ch", new FastestWeighting(encoder)); + CHConfig chConfig = CHConfig.nodeBased("ch", new FastestWeighting(accessEnc, speedEnc)); CHStorage store = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(store); chBuilder.setIdentityLevels(); @@ -113,14 +115,15 @@ void testShortcutConnection() { @Test public void testGetWeight() { - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); EdgeIteratorState edge1 = graph.edge(0, 1); EdgeIteratorState edge2 = graph.edge(1, 2); graph.freeze(); - CHConfig chConfig = CHConfig.nodeBased("ch", new FastestWeighting(encoder)); + CHConfig chConfig = CHConfig.nodeBased("ch", new FastestWeighting(accessEnc, speedEnc)); CHStorage store = CHStorage.fromGraph(graph, chConfig); RoutingCHGraph g = RoutingCHGraphImpl.fromGraph(graph, store, chConfig); assertFalse(g.getEdgeIteratorState(edge1.getEdge(), Integer.MIN_VALUE).isShortcut()); @@ -140,13 +143,14 @@ public void testGetWeight() { @Test public void testGetWeightIfAdvancedEncoder() { - FlagEncoder customEncoder = FlagEncoders.createBike2(); - EncodingManager em = EncodingManager.create(customEncoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 4, 2, true); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph ghStorage = new BaseGraph.Builder(em).create(); ghStorage.edge(0, 3); ghStorage.freeze(); - FastestWeighting weighting = new FastestWeighting(customEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased("p1", weighting); CHStorage chStore = CHStorage.fromGraph(ghStorage, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); @@ -167,16 +171,15 @@ public void testGetWeightIfAdvancedEncoder() { @Test public void testWeightExact() { - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); graph.freeze(); - CHConfig chConfig = CHConfig.nodeBased("ch", new FastestWeighting(encoder)); + CHConfig chConfig = CHConfig.nodeBased("ch", new FastestWeighting(accessEnc, speedEnc)); CHStorage store = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(store); chBuilder.setIdentityLevels(); @@ -193,17 +196,16 @@ public void testWeightExact() { @Test public void testSimpleShortcutCreationAndTraversal() { - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(10)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); graph.freeze(); - FastestWeighting weighting = new FastestWeighting(encoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased("p1", weighting); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); @@ -219,16 +221,15 @@ public void testSimpleShortcutCreationAndTraversal() { @Test public void testAddShortcutSkippedEdgesWriteRead() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(carEncoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(10)); final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); graph.freeze(); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased("p1", weighting); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); @@ -242,16 +243,15 @@ public void testAddShortcutSkippedEdgesWriteRead() { @Test public void testSkippedEdges() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(carEncoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); final EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(10)); final EdgeIteratorState edge2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10)); graph.freeze(); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased("p1", weighting); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); @@ -263,17 +263,16 @@ public void testSkippedEdges() { @Test public void testAddShortcut_edgeBased_throwsIfNotConfiguredForEdgeBased() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(carEncoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); graph.freeze(); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased("p1", weighting); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); @@ -283,16 +282,15 @@ public void testAddShortcut_edgeBased_throwsIfNotConfiguredForEdgeBased() { @Test public void testAddShortcut_edgeBased() { // 0 -> 1 -> 2 - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(carEncoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).set3D(true).create(); - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(3)); graph.freeze(); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.edgeBased("p1", weighting); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); @@ -305,11 +303,12 @@ public void testAddShortcut_edgeBased() { @Test public void outOfBounds() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(carEncoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).set3D(true).create(); graph.freeze(); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased("p1", weighting); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); RoutingCHGraph lg = RoutingCHGraphImpl.fromGraph(graph, chStore, chConfig); @@ -318,16 +317,15 @@ public void outOfBounds() { @Test public void testGetEdgeIterator() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(carEncoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).set3D(true).create(); - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); graph.freeze(); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.edgeBased("p1", weighting); CHStorage store = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(store); diff --git a/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java b/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java index d0ea3eaf111..1a66c9db238 100644 --- a/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java +++ b/core/src/test/java/com/graphhopper/routing/TrafficChangeWithNodeOrderingReusingTest.java @@ -4,7 +4,14 @@ import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory; import com.graphhopper.routing.ch.PrepareContractionHierarchies; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.VehicleAccess; +import com.graphhopper.routing.ev.VehicleSpeed; +import com.graphhopper.routing.util.CarTagParser; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.OSMParsers; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.AbstractWeighting; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.TurnCostProvider; @@ -51,14 +58,15 @@ private static class Fixture { public Fixture(int maxDeviationPercentage) { this.maxDeviationPercentage = maxDeviationPercentage; - FlagEncoder encoder = FlagEncoders.createCar(); - em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); CarTagParser carParser = new CarTagParser(em, new PMap()); carParser.init(new DateRangeParser()); osmParsers = new OSMParsers() .addVehicleTagParser(carParser); - baseCHConfig = CHConfig.nodeBased("base", new FastestWeighting(encoder)); - trafficCHConfig = CHConfig.nodeBased("traffic", new RandomDeviationWeighting(baseCHConfig.getWeighting(), encoder, maxDeviationPercentage)); + baseCHConfig = CHConfig.nodeBased("base", new FastestWeighting(accessEnc, speedEnc)); + trafficCHConfig = CHConfig.nodeBased("traffic", new RandomDeviationWeighting(baseCHConfig.getWeighting(), accessEnc, speedEnc, maxDeviationPercentage)); graph = new BaseGraph.Builder(em).create(); } @@ -193,8 +201,8 @@ private static class RandomDeviationWeighting extends AbstractWeighting { private final Weighting baseWeighting; private final double maxDeviationPercentage; - public RandomDeviationWeighting(Weighting baseWeighting, FlagEncoder encoder, double maxDeviationPercentage) { - super(encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), TurnCostProvider.NO_TURN_COST_PROVIDER); + public RandomDeviationWeighting(Weighting baseWeighting, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, double maxDeviationPercentage) { + super(accessEnc, speedEnc, TurnCostProvider.NO_TURN_COST_PROVIDER); this.baseWeighting = baseWeighting; this.maxDeviationPercentage = maxDeviationPercentage; } diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java index e32d2d269ef..9191ed0555f 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java @@ -22,9 +22,11 @@ import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; import com.graphhopper.routing.ProfileResolver; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.VehicleAccess; +import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.util.PMap; import com.graphhopper.util.Parameters; import org.junit.jupiter.api.BeforeEach; @@ -55,9 +57,14 @@ public class CHProfileSelectorTest { @BeforeEach public void setup() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - FlagEncoder bikeEncoder = FlagEncoders.createBike(); - encodingManager = EncodingManager.create(carEncoder, bikeEncoder); + BooleanEncodedValue carAccessEnc = VehicleAccess.create("car"); + DecimalEncodedValue carSpeedEnc = VehicleSpeed.create("car", 5, 5, false); + BooleanEncodedValue bikeAccessEnc = VehicleAccess.create("bike"); + DecimalEncodedValue bikeSpeedEnc = VehicleSpeed.create("bike", 4, 2, false); + encodingManager = EncodingManager.start() + .add(carAccessEnc).add(carSpeedEnc) + .add(bikeAccessEnc).add(bikeSpeedEnc) + .build(); fastCar = new Profile("fast_car").setWeighting("fastest").setVehicle("car").setTurnCosts(false); fastCarEdge = new Profile("fast_car_edge").setWeighting("fastest").setVehicle("car").setTurnCosts(true); fastCarEdge10 = new Profile("fast_car_edge10").setWeighting("fastest").setVehicle("car").setTurnCosts(true).putHint(Parameters.Routing.U_TURN_COSTS, 10); diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java index a0975512b0a..edd12db6bd7 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java @@ -22,13 +22,13 @@ import com.graphhopper.routing.DijkstraBidirectionEdgeCHNoSOD; import com.graphhopper.routing.Path; import com.graphhopper.routing.RoutingAlgorithm; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.querygraph.QueryRoutingCHGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.AccessFilter; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -68,7 +68,6 @@ public class CHTurnCostTest { private static final Logger LOGGER = LoggerFactory.getLogger(CHTurnCostTest.class); private int maxCost; - private FlagEncoder encoder; private BooleanEncodedValue accessEnc; private DecimalEncodedValue speedEnc; private DecimalEncodedValue turnCostEnc; @@ -83,12 +82,11 @@ public class CHTurnCostTest { @BeforeEach public void init() { maxCost = 10; - encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxCost)); - accessEnc = encoder.getAccessEnc(); - speedEnc = encoder.getAverageSpeedEnc(); - turnCostEnc = encoder.getTurnCostEnc(); - encodingManager = EncodingManager.create(encoder); - graph = new BaseGraph.Builder(encodingManager).build(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + turnCostEnc = TurnCost.create("car", maxCost); + encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); + graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).build(); turnCostStorage = graph.getTurnCostStorage(); chConfigs = createCHConfigs(); // the default CH profile with infinite u-turn costs, can be reset in tests that should run with finite u-turn @@ -1209,7 +1207,7 @@ private void compareWithDijkstraOnRandomGraph(long seed) { // for larger graphs preparation takes much longer the higher the degree is! GHUtility.buildRandomGraph(graph, rnd, 20, 3.0, true, true, accessEnc, speedEnc, null, 0.7, 0.9, 0.8); - GHUtility.addRandomTurnCosts(graph, seed, encodingManager, encoder, maxCost, turnCostStorage); + GHUtility.addRandomTurnCosts(graph, seed, accessEnc, turnCostEnc, maxCost, turnCostStorage); graph.freeze(); checkStrict = false; IntArrayList contractionOrder = getRandomIntegerSequence(graph.getNodes(), rnd); @@ -1237,7 +1235,7 @@ public void testFindPath_heuristic_compareWithDijkstra_finiteUTurnCost() { private void compareWithDijkstraOnRandomGraph_heuristic(long seed) { GHUtility.buildRandomGraph(graph, new Random(seed), 20, 3.0, true, true, accessEnc, speedEnc, null, 0.7, 0.9, 0.8); - GHUtility.addRandomTurnCosts(graph, seed, encodingManager, encoder, maxCost, turnCostStorage); + GHUtility.addRandomTurnCosts(graph, seed, accessEnc, turnCostEnc, maxCost, turnCostStorage); graph.freeze(); checkStrict = false; automaticCompareCHWithDijkstra(100); @@ -1351,7 +1349,7 @@ private void compareCHQueryWithDijkstra(int from, int to) { } if (algosDisagree) { System.out.println("Graph that produced error:"); - GHUtility.printGraphForUnitTest(graph, encoder); + GHUtility.printGraphForUnitTest(graph, accessEnc, speedEnc); fail("Dijkstra and CH did not find equal shortest paths for route from " + from + " to " + to + "\n" + " dijkstra: weight: " + dijkstraPath.getWeight() + ", distance: " + dijkstraPath.getDistance() + ", time: " + dijkstraPath.getTime() + ", nodes: " + dijkstraPath.calcNodes() + "\n" + diff --git a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java index 15f2baac8b9..4e723b6bf95 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/EdgeBasedNodeContractorTest.java @@ -18,12 +18,8 @@ package com.graphhopper.routing.ch; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -49,7 +45,6 @@ */ public class EdgeBasedNodeContractorTest { private final int maxCost = 10; - private FlagEncoder encoder; private BooleanEncodedValue accessEnc; private DecimalEncodedValue speedEnc; private DecimalEncodedValue turnCostEnc; @@ -66,12 +61,11 @@ public void setup() { } private void initialize() { - encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", maxCost)); - EncodingManager encodingManager = EncodingManager.create(encoder); - accessEnc = encoder.getAccessEnc(); - speedEnc = encoder.getAverageSpeedEnc(); - turnCostEnc = encoder.getTurnCostEnc(); - graph = new BaseGraph.Builder(encodingManager).create(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + turnCostEnc = TurnCost.create("car", maxCost); + EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); + graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); chConfigs = Arrays.asList( CHConfig.edgeBased("p1", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage()))), CHConfig.edgeBased("p2", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage(), 60))), @@ -1483,7 +1477,7 @@ private void setTurnCost(int from, int via, int to, double cost) { private void setTurnCost(EdgeIteratorState inEdge, EdgeIteratorState outEdge, int viaNode, double cost) { double cost1 = cost >= maxCost ? Double.POSITIVE_INFINITY : cost; - graph.getTurnCostStorage().set(encoder.getDecimalEncodedValue(TurnCost.key("car")), inEdge.getEdge(), viaNode, outEdge.getEdge(), cost1); + graph.getTurnCostStorage().set(turnCostEnc, inEdge.getEdge(), viaNode, outEdge.getEdge(), cost1); } private EdgeIteratorState getEdge(int from, int to) { diff --git a/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java index 58ff8b62df1..fa5bf1b4bf3 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/NodeBasedNodeContractorTest.java @@ -22,7 +22,11 @@ import com.graphhopper.routing.Path; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; +import com.graphhopper.routing.util.AllEdgesIterator; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -42,10 +46,9 @@ import static org.junit.jupiter.api.Assertions.*; public class NodeBasedNodeContractorTest { - private final FlagEncoder encoder = FlagEncoders.createCar(); - private final EncodingManager encodingManager = EncodingManager.create(encoder); - private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - private final DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + private final EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); private final Weighting weighting = new ShortestWeighting(accessEnc, speedEnc); private final BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); private final CHConfig chConfig = CHConfig.nodeBased("profile", weighting); @@ -266,8 +269,9 @@ public void testNodeContraction_shortcutDistanceRounding() { */ @Test public void testNodeContraction_shortcutWeightRounding() { - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager encodingManager = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); // 0 ------------> 4 // \ / @@ -280,7 +284,7 @@ public void testNodeContraction_shortcutWeightRounding() { GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 3).setDistance(distances[3])); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 4).setDistance(distances[4])); graph.freeze(); - Weighting weighting = new FastestWeighting(encoder); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased("p1", weighting); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); setMaxLevelOnAllNodes(chStore); @@ -305,8 +309,9 @@ public void testNodeContraction_shortcutWeightRounding() { public void testNodeContraction_preventUnnecessaryShortcutWithLoop() { // there should not be shortcuts where one of the skipped edges is a loop at the node to be contracted, // see also #1583 - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager encodingManager = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); // 0 - 1 - 2 - 3 // o o @@ -317,7 +322,7 @@ public void testNodeContraction_preventUnnecessaryShortcutWithLoop() { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 3).setDistance(1)); graph.freeze(); - Weighting weighting = new FastestWeighting(encoder); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased("p1", weighting); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); setMaxLevelOnAllNodes(chStore); diff --git a/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java b/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java index 997af933d0d..782be23861e 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/PrepareContractionHierarchiesTest.java @@ -22,8 +22,7 @@ import com.graphhopper.routing.Dijkstra; import com.graphhopper.routing.Path; import com.graphhopper.routing.RoutingAlgorithm; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.*; import com.graphhopper.routing.weighting.FastestWeighting; @@ -44,9 +43,10 @@ * @author Peter Karich */ public class PrepareContractionHierarchiesTest { - private final FlagEncoder carEncoder = FlagEncoders.createCar(new PMap().putObject("speed_two_directions", true)); - private final EncodingManager encodingManager = EncodingManager.create(carEncoder); - private final Weighting weighting = new ShortestWeighting(carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc()); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, true); + private final EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); + private final Weighting weighting = new ShortestWeighting(accessEnc, speedEnc); private final CHConfig chConfig = CHConfig.nodeBased("c", weighting); private BaseGraph g; @@ -54,9 +54,7 @@ public class PrepareContractionHierarchiesTest { // | ^ \ // | | | // 17-16-...-11<-/ - private static void initDirected2(Graph g, FlagEncoder encoder) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + private static void initDirected2(Graph g, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(1)); @@ -79,9 +77,7 @@ private static void initDirected2(Graph g, FlagEncoder encoder) { } // prepare-routing.svg - private static void initShortcutsGraph(Graph g, FlagEncoder encoder) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + private static void initShortcutsGraph(Graph g, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 2).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); @@ -106,15 +102,13 @@ private static void initShortcutsGraph(Graph g, FlagEncoder encoder) { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(14, 16).setDistance(1)); } - private static void initExampleGraph(Graph g, FlagEncoder encoder) { + private static void initExampleGraph(Graph g, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { //5-1-----2 // \ __/| // 0 | // / | // 4-----3 // - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 2).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 4).setDistance(3)); @@ -142,7 +136,7 @@ public void testReturnsCorrectWeighting() { @Test public void testAddShortcuts() { - initExampleGraph(g, carEncoder); + initExampleGraph(g, accessEnc, speedEnc); PrepareContractionHierarchies prepare = createPrepareContractionHierarchies(g); useNodeOrdering(prepare, new int[]{5, 3, 4, 0, 1, 2}); PrepareContractionHierarchies.Result res = prepare.doWork(); @@ -151,7 +145,7 @@ public void testAddShortcuts() { @Test public void testMoreComplexGraph() { - initShortcutsGraph(g, carEncoder); + initShortcutsGraph(g, accessEnc, speedEnc); PrepareContractionHierarchies prepare = createPrepareContractionHierarchies(g); useNodeOrdering(prepare, new int[]{0, 5, 6, 7, 8, 10, 11, 13, 15, 1, 3, 9, 14, 16, 12, 4, 2}); PrepareContractionHierarchies.Result res = prepare.doWork(); @@ -160,8 +154,6 @@ public void testMoreComplexGraph() { @Test public void testDirectedGraph() { - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(5, 4).setDistance(3)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(4, 5).setDistance(10)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(2, 4).setDistance(1)); @@ -183,7 +175,7 @@ public void testDirectedGraph() { @Test public void testDirectedGraph2() { - initDirected2(g, carEncoder); + initDirected2(g, accessEnc, speedEnc); int oldCount = g.getEdges(); assertEquals(19, oldCount); PrepareContractionHierarchies prepare = createPrepareContractionHierarchies(g); @@ -203,7 +195,7 @@ public void testDirectedGraph2() { assertEquals(IntArrayList.from(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10), p.calcNodes()); } - private static void initRoundaboutGraph(Graph g, FlagEncoder encoder) { + private static void initRoundaboutGraph(Graph g, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { // roundabout: //16-0-9-10--11 12<-13 // \ \ / \ @@ -211,8 +203,6 @@ private static void initRoundaboutGraph(Graph g, FlagEncoder encoder) { // -15-1--2--3--4 / / // / \-5->6/ / // -14 \________/ - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(16, 0).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 9).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 17).setDistance(1)); @@ -257,7 +247,7 @@ private static void initRoundaboutGraph(Graph g, FlagEncoder encoder) { @Test public void testRoundaboutUnpacking() { - initRoundaboutGraph(g, carEncoder); + initRoundaboutGraph(g, accessEnc, speedEnc); int oldCount = g.getEdges(); PrepareContractionHierarchies prepare = createPrepareContractionHierarchies(g); useNodeOrdering(prepare, new int[]{26, 6, 12, 13, 2, 3, 8, 9, 10, 11, 14, 15, 16, 17, 18, 20, 21, 23, 24, 25, 19, 22, 27, 5, 29, 30, 31, 28, 7, 1, 0, 4}); @@ -282,8 +272,6 @@ public void testDisconnects() { // 2 // v // 7 - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(8, 3).setDistance(1)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(3, 6).setDistance(1)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(6, 1).setDistance(1)); @@ -332,7 +320,7 @@ public void testStallOnDemandViaVirtuaNode_issue1574() { g = createGraph(); // use fastest weighting in this test to be able to fine-tune some weights via the speed (see below) - Weighting fastestWeighting = new FastestWeighting(carEncoder); + Weighting fastestWeighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased("c", fastestWeighting); // the following graph reproduces the issue. note that we will use the node ids as ch levels, so there will // be a shortcut 3->2 visible at node 2 and another one 3->4 visible at node 3. @@ -344,8 +332,6 @@ public void testStallOnDemandViaVirtuaNode_issue1574() { // start 0 - 3 - x - 1 - 2 // \ | // sc ---- 4 - 5 - 6 - 7 finish - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(1)); EdgeIteratorState edge31 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 1).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); @@ -410,7 +396,7 @@ private double getWeight(Graph graph, Weighting w, int from, int to, boolean inc } private EdgeIteratorState getEdge(Graph graph, int from, int to, boolean incoming) { - EdgeFilter filter = incoming ? AccessFilter.inEdges(carEncoder.getAccessEnc()) : AccessFilter.outEdges(carEncoder.getAccessEnc()); + EdgeFilter filter = incoming ? AccessFilter.inEdges(accessEnc) : AccessFilter.outEdges(accessEnc); EdgeIterator iter = graph.createEdgeExplorer(filter).setBaseNode(from); while (iter.next()) { if (iter.getAdjNode() == to) { @@ -435,8 +421,6 @@ public void testCircleBug() { // /--1 // -0--/ // | - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(4)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 2).setDistance(10)); @@ -453,8 +437,6 @@ public void testBug178() { // 0-1->-2--3--4 // \-<-/ // - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(2, 1).setDistance(1)); @@ -483,19 +465,24 @@ public void testBits() { @Test public void testMultiplePreparationsIdenticalView() { - FlagEncoder tmpCarEncoder = FlagEncoders.createCar(); - FlagEncoder tmpBikeEncoder = FlagEncoders.createBike(); - EncodingManager tmpEncodingManager = EncodingManager.create(tmpCarEncoder, tmpBikeEncoder); + BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + BooleanEncodedValue bikeAccessEnc = new SimpleBooleanEncodedValue("bike_access", true); + DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + DecimalEncodedValue bikeSpeedEnc = new DecimalEncodedValueImpl("bike_speed", 4, 2, false); + EncodingManager tmpEncodingManager = EncodingManager.start() + .add(carAccessEnc).add(carSpeedEnc) + .add(bikeAccessEnc).add(bikeSpeedEnc) + .build(); // FastestWeighting would lead to different shortcuts due to different default speeds for bike and car - CHConfig carProfile = CHConfig.nodeBased("c1", new ShortestWeighting(tmpCarEncoder.getAccessEnc(), tmpCarEncoder.getAverageSpeedEnc())); - CHConfig bikeProfile = CHConfig.nodeBased("c2", new ShortestWeighting(tmpBikeEncoder.getAccessEnc(), tmpBikeEncoder.getAverageSpeedEnc())); + CHConfig carProfile = CHConfig.nodeBased("c1", new ShortestWeighting(carAccessEnc, carSpeedEnc)); + CHConfig bikeProfile = CHConfig.nodeBased("c2", new ShortestWeighting(bikeAccessEnc, bikeSpeedEnc)); BaseGraph graph = new BaseGraph.Builder(tmpEncodingManager).create(); - initShortcutsGraph(graph, tmpCarEncoder); + initShortcutsGraph(graph, carAccessEnc, carSpeedEnc); AllEdgesIterator iter = graph.getAllEdges(); while (iter.next()) { - GHUtility.setSpeed(18, true, true, tmpBikeEncoder.getAccessEnc(), tmpBikeEncoder.getAverageSpeedEnc(), iter); + GHUtility.setSpeed(18, true, true, bikeAccessEnc, bikeSpeedEnc, iter); } graph.freeze(); @@ -505,22 +492,27 @@ public void testMultiplePreparationsIdenticalView() { @Test public void testMultiplePreparationsDifferentView() { - FlagEncoder tmpCarEncoder = FlagEncoders.createCar(); - FlagEncoder tmpBikeEncoder = FlagEncoders.createBike(); - EncodingManager tmpEncodingManager = EncodingManager.create(tmpCarEncoder, tmpBikeEncoder); - - CHConfig carConfig = CHConfig.nodeBased("c1", new FastestWeighting(tmpCarEncoder)); - CHConfig bikeConfig = CHConfig.nodeBased("c2", new FastestWeighting(tmpBikeEncoder)); + BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + BooleanEncodedValue bikeAccessEnc = new SimpleBooleanEncodedValue("bike_access", true); + DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + DecimalEncodedValue bikeSpeedEnc = new DecimalEncodedValueImpl("bike_speed", 4, 2, false); + EncodingManager tmpEncodingManager = EncodingManager.start() + .add(carAccessEnc).add(carSpeedEnc) + .add(bikeAccessEnc).add(bikeSpeedEnc) + .build(); + + CHConfig carConfig = CHConfig.nodeBased("c1", new FastestWeighting(carAccessEnc, carSpeedEnc)); + CHConfig bikeConfig = CHConfig.nodeBased("c2", new FastestWeighting(bikeAccessEnc, bikeSpeedEnc)); BaseGraph graph = new BaseGraph.Builder(tmpEncodingManager).create(); - initShortcutsGraph(graph, tmpCarEncoder); + initShortcutsGraph(graph, carAccessEnc, carSpeedEnc); AllEdgesIterator iter = graph.getAllEdges(); while (iter.next()) { - GHUtility.setSpeed(18, true, true, tmpBikeEncoder.getAccessEnc(), tmpBikeEncoder.getAverageSpeedEnc(), iter); + GHUtility.setSpeed(18, true, true, bikeAccessEnc, bikeSpeedEnc, iter); } GHUtility.getEdge(graph, 9, 14). - set(tmpBikeEncoder.getAccessEnc(), false). - setReverse(tmpBikeEncoder.getAccessEnc(), false); + set(bikeAccessEnc, false). + setReverse(bikeAccessEnc, false); graph.freeze(); @@ -531,25 +523,31 @@ public void testMultiplePreparationsDifferentView() { @Test public void testReusingNodeOrdering() { - FlagEncoder car1FlagEncoder = FlagEncoders.createCar(new PMap("name=car1|turn_costs=true|speed_two_directions=true")); - FlagEncoder car2FlagEncoder = FlagEncoders.createCar(new PMap("name=car2|turn_costs=true|speed_two_directions=true")); - EncodingManager em = EncodingManager.create(car1FlagEncoder, car2FlagEncoder); - CHConfig car1Config = CHConfig.nodeBased("c1", new FastestWeighting(car1FlagEncoder)); - CHConfig car2Config = CHConfig.nodeBased("c2", new FastestWeighting(car2FlagEncoder)); + BooleanEncodedValue car1AccessEnc = new SimpleBooleanEncodedValue("car1_access", true); + BooleanEncodedValue car2AccessEnc = new SimpleBooleanEncodedValue("car2_access", true); + DecimalEncodedValue car1SpeedEnc = new DecimalEncodedValueImpl("car1_speed", 5, 5, true); + DecimalEncodedValue car2SpeedEnc = new DecimalEncodedValueImpl("car2_speed", 5, 5, true); + DecimalEncodedValue car1TurnCostEnc = TurnCost.create("car1", 1); + DecimalEncodedValue car2TurnCostEnc = TurnCost.create("car2", 1); + EncodingManager em = EncodingManager.start() + .add(car1AccessEnc).add(car1SpeedEnc).addTurnCostEncodedValue(car1TurnCostEnc) + .add(car2AccessEnc).add(car2SpeedEnc).addTurnCostEncodedValue(car2TurnCostEnc) + .build(); + CHConfig car1Config = CHConfig.nodeBased("c1", new FastestWeighting(car1AccessEnc, car1SpeedEnc)); + CHConfig car2Config = CHConfig.nodeBased("c2", new FastestWeighting(car2AccessEnc, car2SpeedEnc)); BaseGraph graph = new BaseGraph.Builder(em).create(); int numNodes = 5_000; int numQueries = 100; long seed = System.nanoTime(); Random rnd = new Random(seed); - GHUtility.buildRandomGraph(graph, rnd, numNodes, 1.3, true, true, - car1FlagEncoder.getAccessEnc(), null, null, 0.7, 0.9, 0.8); + GHUtility.buildRandomGraph(graph, rnd, numNodes, 1.3, true, true, car1AccessEnc, null, null, 0.7, 0.9, 0.8); AllEdgesIterator iter = graph.getAllEdges(); while (iter.next()) { - iter.set(car1FlagEncoder.getAccessEnc(), rnd.nextDouble() > 0.05, rnd.nextDouble() > 0.05); - iter.set(car2FlagEncoder.getAccessEnc(), rnd.nextDouble() > 0.05, rnd.nextDouble() > 0.05); - iter.set(car1FlagEncoder.getAverageSpeedEnc(), rnd.nextDouble() * 100, rnd.nextDouble() * 100); - iter.set(car2FlagEncoder.getAverageSpeedEnc(), rnd.nextDouble() * 100, rnd.nextDouble() * 100); + iter.set(car1AccessEnc, rnd.nextDouble() > 0.05, rnd.nextDouble() > 0.05); + iter.set(car2AccessEnc, rnd.nextDouble() > 0.05, rnd.nextDouble() > 0.05); + iter.set(car1SpeedEnc, rnd.nextDouble() * 100, rnd.nextDouble() * 100); + iter.set(car2SpeedEnc, rnd.nextDouble() * 100, rnd.nextDouble() * 100); } graph.freeze(); diff --git a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java index 37ca18a0904..7445b2c1cc5 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueTest.java @@ -1,17 +1,11 @@ package com.graphhopper.routing.ev; -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.reader.osm.conditional.DateRangeParser; -import com.graphhopper.routing.util.CarTagParser; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; public class DecimalEncodedValueTest { @@ -26,33 +20,17 @@ public void testInit() { @Test public void testMaxValue() { - FlagEncoder carEncoder = FlagEncoders.createCar(new PMap("speed_bits=10|speed_factor=0.5")); - EncodingManager em = EncodingManager.create(carEncoder); - DecimalEncodedValue carAverageSpeedEnc = em.getDecimalEncodedValue(EncodingManager.getKey(carEncoder, "average_speed")); - CarTagParser carTagParser = new CarTagParser(em, new PMap()); - carTagParser.init(new DateRangeParser()); - - ReaderWay way = new ReaderWay(1); - way.setTag("highway", "motorway_link"); - way.setTag("maxspeed", "70 mph"); - IntsRef flags = carTagParser.handleWayTags(em.createEdgeFlags(), way); - assertEquals(101.5, carAverageSpeedEnc.getDecimal(true, flags), 1e-1); - - DecimalEncodedValue instance1 = new DecimalEncodedValueImpl("test1", 8, 0.5, false); - instance1.init(new EncodedValue.InitializerConfig()); - flags = em.createEdgeFlags(); - instance1.setDecimal(false, flags, 100d); - assertEquals(100, instance1.getDecimal(false, flags), 1e-1); + DecimalEncodedValue ev = new DecimalEncodedValueImpl("test1", 8, 0.5, false); + EncodingManager em = EncodingManager.start().add(ev).build(); + IntsRef flags = em.createEdgeFlags(); + ev.setDecimal(false, flags, 100d); + assertEquals(100, ev.getDecimal(false, flags), 1e-1); } @Test public void testNegativeBounds() { DecimalEncodedValue prop = new DecimalEncodedValueImpl("test", 10, 5, false); prop.init(new EncodedValue.InitializerConfig()); - try { - prop.setDecimal(false, new IntsRef(1), -1); - assertTrue(false); - } catch (Exception ex) { - } + assertThrows(Exception.class, () -> prop.setDecimal(false, new IntsRef(1), -1)); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/lm/LMApproximatorTest.java b/core/src/test/java/com/graphhopper/routing/lm/LMApproximatorTest.java index c5686aede95..760f0014065 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/LMApproximatorTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/LMApproximatorTest.java @@ -20,15 +20,16 @@ import com.graphhopper.routing.Dijkstra; import com.graphhopper.routing.Path; -import com.graphhopper.routing.ev.Subnetwork; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.util.AccessFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.*; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Directory; import com.graphhopper.storage.RAMDirectory; import com.graphhopper.util.EdgeIterator; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.RepeatedTest; import java.util.Random; @@ -45,15 +46,16 @@ public void randomGraph() { private void run(long seed) { Directory dir = new RAMDirectory(); - FlagEncoder encoder = FlagEncoders.createCar(new PMap("turn_costs=true")); - EncodingManager encodingManager = new EncodingManager.Builder().add(encoder).add(Subnetwork.create("car")).build(); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + DecimalEncodedValue turnCostEnc = TurnCost.create("car", 1); + EncodingManager encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).add(Subnetwork.create("car")).build(); BaseGraph graph = new BaseGraph.Builder(encodingManager).setDir(dir).withTurnCosts(true).create(); Random rnd = new Random(seed); - GHUtility.buildRandomGraph(graph, rnd, 100, 2.2, true, true, - encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), null, 0.7, 0.8, 0.8); + GHUtility.buildRandomGraph(graph, rnd, 100, 2.2, true, true, accessEnc, speedEnc, null, 0.7, 0.8, 0.8); - Weighting weighting = new FastestWeighting(encoder); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc); PrepareLandmarks lm = new PrepareLandmarks(dir, graph, encodingManager, new LMConfig("car", weighting), 16); lm.setMaximumWeight(10000); @@ -106,7 +108,7 @@ private void run(long seed) { // That's a requirement for normal A*-implementations, because if it is violated, // the heap-weight of settled nodes can decrease, and that would mean our // stopping criterion is not sufficient. - EdgeIterator neighbors = graph.createEdgeExplorer(AccessFilter.outEdges(encoder.getAccessEnc())).setBaseNode(v); + EdgeIterator neighbors = graph.createEdgeExplorer(AccessFilter.outEdges(accessEnc)).setBaseNode(v); while (neighbors.next()) { int w = neighbors.getAdjNode(); double vw = weighting.calcEdgeWeight(neighbors, false); @@ -117,7 +119,7 @@ private void run(long seed) { } } - neighbors = graph.createEdgeExplorer(AccessFilter.outEdges(encoder.getAccessEnc())).setBaseNode(v); + neighbors = graph.createEdgeExplorer(AccessFilter.outEdges(accessEnc)).setBaseNode(v); while (neighbors.next()) { int w = neighbors.getAdjNode(); double vw = weighting.calcEdgeWeight(neighbors, false); diff --git a/core/src/test/java/com/graphhopper/routing/lm/LMIssueTest.java b/core/src/test/java/com/graphhopper/routing/lm/LMIssueTest.java index b32f8ce3c75..40c75c2011c 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/LMIssueTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/LMIssueTest.java @@ -19,12 +19,8 @@ package com.graphhopper.routing.lm; import com.graphhopper.routing.*; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.BaseGraph; @@ -32,7 +28,6 @@ import com.graphhopper.storage.NodeAccess; import com.graphhopper.storage.RAMDirectory; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -45,7 +40,6 @@ public class LMIssueTest { private Directory dir; private BaseGraph graph; - private FlagEncoder encoder; private BooleanEncodedValue accessEnc; private DecimalEncodedValue speedEnc; private Weighting weighting; @@ -64,14 +58,15 @@ private enum Algo { @BeforeEach public void init() { dir = new RAMDirectory(); - encoder = FlagEncoders.createCar(new PMap("turn_costs=true")); - encodingManager = new EncodingManager.Builder().add(encoder).add(Subnetwork.create("car")).build(); - accessEnc = encoder.getAccessEnc(); - speedEnc = encoder.getAverageSpeedEnc(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + DecimalEncodedValue turnCostEnc = TurnCost.create("car", 1); + encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).add(Subnetwork.create("car")).build(); graph = new BaseGraph.Builder(encodingManager) + .withTurnCosts(true) .setDir(dir) .create(); - weighting = new FastestWeighting(encoder); + weighting = new FastestWeighting(accessEnc, speedEnc); } private void preProcessGraph() { diff --git a/core/src/test/java/com/graphhopper/routing/lm/LMPreparationHandlerTest.java b/core/src/test/java/com/graphhopper/routing/lm/LMPreparationHandlerTest.java index c8968e5b3c2..30f95866607 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/LMPreparationHandlerTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/LMPreparationHandlerTest.java @@ -3,9 +3,11 @@ import com.graphhopper.GraphHopperConfig; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.storage.BaseGraph; @@ -35,11 +37,12 @@ public void maximumLMWeight() { new LMProfile("conf1").setMaximumLMWeight(65_000), new LMProfile("conf2").setMaximumLMWeight(20_000) ); - FlagEncoder car = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(car); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", false); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); List lmConfigs = Arrays.asList( - new LMConfig("conf1", new FastestWeighting(car)), - new LMConfig("conf2", new ShortestWeighting(car.getAccessEnc(), car.getAverageSpeedEnc())) + new LMConfig("conf1", new FastestWeighting(accessEnc, speedEnc)), + new LMConfig("conf2", new ShortestWeighting(accessEnc, speedEnc)) ); List preparations = handler.createPreparations(lmConfigs, new BaseGraph.Builder(em).build(), em, null); assertEquals(1, preparations.get(0).getLandmarkStorage().getFactor(), .1); diff --git a/core/src/test/java/com/graphhopper/routing/lm/LMProfileSelectorTest.java b/core/src/test/java/com/graphhopper/routing/lm/LMProfileSelectorTest.java index 903500f4047..98ffb3f9e1c 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/LMProfileSelectorTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/LMProfileSelectorTest.java @@ -22,9 +22,11 @@ import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; import com.graphhopper.routing.ProfileResolver; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.VehicleAccess; +import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.util.PMap; import com.graphhopper.util.Parameters; import org.junit.jupiter.api.BeforeEach; @@ -50,9 +52,14 @@ public class LMProfileSelectorTest { @BeforeEach public void setup() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - FlagEncoder bikeEncoder = FlagEncoders.createBike(); - encodingManager = EncodingManager.create(carEncoder, bikeEncoder); + BooleanEncodedValue carAccessEnc = VehicleAccess.create("car"); + DecimalEncodedValue carSpeedEnc = VehicleSpeed.create("car", 5, 5, false); + BooleanEncodedValue bikeAccessEnc = VehicleAccess.create("bike"); + DecimalEncodedValue bikeSpeedEnc = VehicleSpeed.create("bike", 4, 2, false); + encodingManager = EncodingManager.start() + .add(carAccessEnc).add(carSpeedEnc) + .add(bikeAccessEnc).add(bikeSpeedEnc) + .build(); fastCar = new Profile("fast_car").setVehicle("car").setWeighting("fastest").setTurnCosts(false); fastCarEdge = new Profile("fast_car_edge").setVehicle("car").setWeighting("fastest").setTurnCosts(true); fastBike = new Profile("fast_bike").setVehicle("bike").setWeighting("fastest").setTurnCosts(false); diff --git a/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java b/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java index 389df1ebb66..cac17ab4678 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/LandmarkStorageTest.java @@ -18,14 +18,10 @@ package com.graphhopper.routing.lm; import com.graphhopper.routing.RoutingAlgorithmTest; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.subnetwork.PrepareRoutingSubnetworks; import com.graphhopper.routing.util.AreaIndex; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.BaseGraph; @@ -49,7 +45,6 @@ */ public class LandmarkStorageTest { private BaseGraph graph; - private FlagEncoder encoder; private BooleanEncodedValue subnetworkEnc; private EncodingManager encodingManager; private BooleanEncodedValue accessEnc; @@ -57,12 +52,11 @@ public class LandmarkStorageTest { @BeforeEach public void setUp() { - encoder = FlagEncoders.createCar(); subnetworkEnc = Subnetwork.create("car"); - encodingManager = new EncodingManager.Builder().add(encoder).add(subnetworkEnc).build(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(subnetworkEnc).build(); graph = new BaseGraph.Builder(encodingManager).create(); - accessEnc = encoder.getAccessEnc(); - speedEnc = encoder.getAverageSpeedEnc(); } @AfterEach @@ -75,7 +69,7 @@ public void tearDown() { public void testInfiniteWeight() { Directory dir = new RAMDirectory(); EdgeIteratorState edge = graph.edge(0, 1); - int res = new LandmarkStorage(graph, encodingManager, dir, new LMConfig("c1", new FastestWeighting(encoder) { + int res = new LandmarkStorage(graph, encodingManager, dir, new LMConfig("c1", new FastestWeighting(accessEnc, speedEnc) { @Override public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { return Integer.MAX_VALUE * 2L; @@ -84,7 +78,7 @@ public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { assertEquals(Integer.MAX_VALUE, res); dir = new RAMDirectory(); - res = new LandmarkStorage(graph, encodingManager, dir, new LMConfig("c2", new FastestWeighting(encoder) { + res = new LandmarkStorage(graph, encodingManager, dir, new LMConfig("c2", new FastestWeighting(accessEnc, speedEnc) { @Override public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { return Double.POSITIVE_INFINITY; @@ -97,7 +91,7 @@ public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { public void testSetGetWeight() { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(40.1)); Directory dir = new RAMDirectory(); - LandmarkStorage lms = new LandmarkStorage(graph, encodingManager, dir, new LMConfig("c1", new FastestWeighting(encoder)), 4). + LandmarkStorage lms = new LandmarkStorage(graph, encodingManager, dir, new LMConfig("c1", new FastestWeighting(accessEnc, speedEnc)), 4). setMaximumWeight(LandmarkStorage.PRECISION); lms._getInternalDA().create(2000); // 2^16=65536, use -1 for infinity and -2 for maximum @@ -128,7 +122,7 @@ public void testWithSubnetworks() { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(10.5)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 6).setDistance(10.6)); - Weighting weighting = new FastestWeighting(encoder); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc); // 1 means => 2 allowed edge keys => excludes the node 6 subnetworkRemoval(weighting, 1); @@ -150,7 +144,7 @@ public void testWithStronglyConnectedComponent() { GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(3, 2).setDistance(10.2)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(10.4)); - Weighting weighting = new FastestWeighting(encoder); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc); // 3 nodes => 6 allowed edge keys but still do not exclude 3 & 4 as strongly connected and not a too small subnetwork! subnetworkRemoval(weighting, 4); @@ -181,7 +175,7 @@ public void testWithOnewaySubnetworks() { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(4, 5).setDistance(10.5)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(5, 2).setDistance(10.2)); - Weighting weighting = new FastestWeighting(encoder); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc); // 1 allowed node => 2 allowed edge keys (exclude 2 and 3 because they are separate too small oneway subnetworks) subnetworkRemoval(weighting, 1); @@ -201,7 +195,7 @@ public void testWeightingConsistence1() { GHUtility.setSpeed(30, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(10)); graph.edge(2, 3).setDistance(10.1).set(accessEnc, true, true); - LandmarkStorage storage = new LandmarkStorage(graph, encodingManager, new RAMDirectory(), new LMConfig("car", new FastestWeighting(encoder)), 2); + LandmarkStorage storage = new LandmarkStorage(graph, encodingManager, new RAMDirectory(), new LMConfig("car", new FastestWeighting(accessEnc, speedEnc)), 2); storage.setMinimumNodes(2); storage.createLandmarks(); @@ -215,7 +209,7 @@ public void testWeightingConsistence2() { graph.edge(2, 3).setDistance(10.1).set(accessEnc, true, true); GHUtility.setSpeed(30, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(10)); - LandmarkStorage storage = new LandmarkStorage(graph, encodingManager, new RAMDirectory(), new LMConfig("car", new FastestWeighting(encoder)), 2); + LandmarkStorage storage = new LandmarkStorage(graph, encodingManager, new RAMDirectory(), new LMConfig("car", new FastestWeighting(accessEnc, speedEnc)), 2); storage.setMinimumNodes(2); storage.createLandmarks(); @@ -226,9 +220,9 @@ public void testWeightingConsistence2() { @Test public void testWithBorderBlocking() { - RoutingAlgorithmTest.initBiGraph(graph, encoder); + RoutingAlgorithmTest.initBiGraph(graph, accessEnc, speedEnc); - LandmarkStorage storage = new LandmarkStorage(graph, encodingManager, new RAMDirectory(), new LMConfig("car", new FastestWeighting(encoder)), 2); + LandmarkStorage storage = new LandmarkStorage(graph, encodingManager, new RAMDirectory(), new LMConfig("car", new FastestWeighting(accessEnc, speedEnc)), 2); final SplitArea right = new SplitArea(emptyList()); final SplitArea left = new SplitArea(emptyList()); final AreaIndex areaIndex = new AreaIndex(emptyList()) { diff --git a/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java b/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java index debbe49a8b3..6dbc26f4d99 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java +++ b/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java @@ -21,11 +21,11 @@ import com.graphhopper.routing.AlgorithmOptions; import com.graphhopper.routing.Path; import com.graphhopper.routing.RoutingAlgorithm; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.QueryGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.BaseGraph; @@ -56,17 +56,19 @@ * @author Peter Karich */ public class PrepareLandmarksTest { + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; + private EncodingManager encodingManager; private BaseGraph graph; - private FlagEncoder encoder; private TraversalMode tm; - private EncodingManager encodingManager; @BeforeEach public void setUp() { - encoder = FlagEncoders.createCar(); - tm = TraversalMode.NODE_BASED; - encodingManager = new EncodingManager.Builder().add(encoder).add(Subnetwork.create("car")).build(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + encodingManager = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(Subnetwork.create("car")).build(); graph = new BaseGraph.Builder(encodingManager).create(); + tm = TraversalMode.NODE_BASED; } @Test @@ -77,8 +79,6 @@ public void testLandmarkStorageAndRouting() { Random rand = new Random(0); int width = 15, height = 15; - DecimalEncodedValue avSpeedEnc = encoder.getAverageSpeedEnc(); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); for (int hIndex = 0; hIndex < height; hIndex++) { for (int wIndex = 0; wIndex < width; wIndex++) { int node = wIndex + hIndex * width; @@ -86,11 +86,11 @@ public void testLandmarkStorageAndRouting() { // do not connect first with last column! double speed = 20 + rand.nextDouble() * 30; if (wIndex + 1 < width) - graph.edge(node, node + 1).set(accessEnc, true, true).set(avSpeedEnc, speed); + graph.edge(node, node + 1).set(accessEnc, true, true).set(speedEnc, speed); // avoid dead ends if (hIndex + 1 < height) - graph.edge(node, node + width).set(accessEnc, true, true).set(avSpeedEnc, speed); + graph.edge(node, node + width).set(accessEnc, true, true).set(speedEnc, speed); updateDistancesFor(graph, node, -hIndex / 50.0, wIndex / 50.0); } @@ -100,7 +100,7 @@ public void testLandmarkStorageAndRouting() { index.prepareIndex(); int lm = 5, activeLM = 2; - Weighting weighting = new FastestWeighting(encoder); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc); LMConfig lmConfig = new LMConfig("car", weighting); LandmarkStorage store = new LandmarkStorage(graph, encodingManager, dir, lmConfig, lm); store.setMinimumNodes(2); @@ -184,13 +184,13 @@ public void testLandmarkStorageAndRouting() { @Test public void testStoreAndLoad() { - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(80_000)); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(80_000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(80_000)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(80_000)); String fileStr = "./target/tmp-lm"; Helper.removeDir(new File(fileStr)); Directory dir = new RAMDirectory(fileStr, true).create(); - Weighting weighting = new FastestWeighting(encoder); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc); LMConfig lmConfig = new LMConfig("car", weighting); PrepareLandmarks plm = new PrepareLandmarks(dir, graph, encodingManager, lmConfig, 2); plm.setMinimumNodes(2); diff --git a/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java b/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java index 5cec19ae916..5dce6b05b38 100644 --- a/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java +++ b/core/src/test/java/com/graphhopper/routing/querygraph/QueryGraphTest.java @@ -20,10 +20,10 @@ import com.carrotsearch.hppc.IntArrayList; import com.carrotsearch.hppc.IntObjectMap; import com.graphhopper.routing.HeadingResolver; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.TurnCost; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.ev.*; +import com.graphhopper.routing.util.AccessFilter; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; @@ -51,17 +51,15 @@ */ public class QueryGraphTest { private EncodingManager encodingManager; - private FlagEncoder encoder; private BooleanEncodedValue accessEnc; private DecimalEncodedValue speedEnc; private BaseGraph g; @BeforeEach public void setUp() { - encoder = FlagEncoders.createCar(); - encodingManager = EncodingManager.create(encoder); - accessEnc = encoder.getAccessEnc(); - speedEnc = encoder.getAverageSpeedEnc(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); g = new BaseGraph.Builder(encodingManager).create(); } @@ -439,8 +437,8 @@ public Snap createLocationResult(double lat, double lon, @Test public void testIteration_Issue163() { - EdgeFilter outEdgeFilter = AccessFilter.outEdges(encodingManager.getEncoder("car").getAccessEnc()); - EdgeFilter inEdgeFilter = AccessFilter.inEdges(encodingManager.getEncoder("car").getAccessEnc()); + EdgeFilter outEdgeFilter = AccessFilter.outEdges(accessEnc); + EdgeFilter inEdgeFilter = AccessFilter.inEdges(accessEnc); EdgeExplorer inExplorer = g.createEdgeExplorer(inEdgeFilter); EdgeExplorer outExplorer = g.createEdgeExplorer(outEdgeFilter); @@ -499,20 +497,21 @@ private void assertEdgeIdsStayingEqual(EdgeExplorer inExplorer, EdgeExplorer out @Test public void testTurnCostsProperlyPropagated_Issue282() { - FlagEncoder encoder = FlagEncoders.createCar(new PMap("max_turn_costs=15")); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + DecimalEncodedValue turnCostEnc = TurnCost.create("car", 15); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); BaseGraph graphWithTurnCosts = new BaseGraph.Builder(em).withTurnCosts(true).create(); TurnCostStorage turnExt = graphWithTurnCosts.getTurnCostStorage(); - DecimalEncodedValue turnCostEnc = em.getDecimalEncodedValue(TurnCost.key(encoder.toString())); NodeAccess na = graphWithTurnCosts.getNodeAccess(); na.setNode(0, .00, .00); na.setNode(1, .00, .01); na.setNode(2, .01, .01); - EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graphWithTurnCosts.edge(0, 1).setDistance(10)); - EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graphWithTurnCosts.edge(2, 1).setDistance(10)); + EdgeIteratorState edge0 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graphWithTurnCosts.edge(0, 1).setDistance(10)); + EdgeIteratorState edge1 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graphWithTurnCosts.edge(2, 1).setDistance(10)); - Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graphWithTurnCosts.getTurnCostStorage())); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graphWithTurnCosts.getTurnCostStorage())); // no turn costs initially assertEquals(0, weighting.calcTurnWeight(edge0.getEdge(), 1, edge1.getEdge()), .1); @@ -827,15 +826,15 @@ public void testVirtualEdgeIds() { // virtual nodes: 2 // 0 - x - 1 // virtual edges: 1 2 - FlagEncoder encoder = FlagEncoders.createCar(new PMap().putObject("speed_two_directions", true)); - EncodingManager encodingManager = EncodingManager.create(encoder); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); - BaseGraph g = new BaseGraph.Builder(encodingManager).create(); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, true); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); + BaseGraph g = new BaseGraph.Builder(em).create(); NodeAccess na = g.getNodeAccess(); na.setNode(0, 50.00, 10.10); na.setNode(1, 50.00, 10.20); double dist = DistanceCalcEarth.DIST_EARTH.calcDist(na.getLat(0), na.getLon(0), na.getLat(1), na.getLon(1)); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(0, 1).setDistance(dist)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(dist)); edge.set(speedEnc, 50); edge.setReverse(speedEnc, 100); @@ -901,16 +900,16 @@ public void testVirtualEdgeIds_reverse() { // virtual nodes: 2 // 0 - x - 1 // virtual edges: 1 2 - FlagEncoder encoder = FlagEncoders.createCar(new PMap().putObject("speed_two_directions", true)); - EncodingManager encodingManager = EncodingManager.create(encoder); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); - BaseGraph g = new BaseGraph.Builder(encodingManager).create(); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, true); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); + BaseGraph g = new BaseGraph.Builder(em).create(); NodeAccess na = g.getNodeAccess(); na.setNode(0, 50.00, 10.10); na.setNode(1, 50.00, 10.20); double dist = DistanceCalcEarth.DIST_EARTH.calcDist(na.getLat(0), na.getLon(0), na.getLat(1), na.getLon(1)); // this time we store the edge the other way - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(1, 0).setDistance(dist)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 0).setDistance(dist)); edge.set(speedEnc, 100, 50); // query graph diff --git a/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java b/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java index 16e1a19feb5..538901fd031 100644 --- a/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java +++ b/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java @@ -18,21 +18,15 @@ package com.graphhopper.routing.subnetwork; import com.carrotsearch.hppc.IntArrayList; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.Subnetwork; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.AllEdgesIterator; -import com.graphhopper.routing.util.DefaultFlagEncoderFactory; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.TurnCostProvider; import com.graphhopper.storage.BaseGraph; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -41,15 +35,14 @@ import static com.graphhopper.routing.weighting.TurnCostProvider.NO_TURN_COST_PROVIDER; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; /** * @author Peter Karich */ public class PrepareRoutingSubnetworksTest { - private static BaseGraph createSubnetworkTestStorage(EncodingManager encodingManager) { - BaseGraph g = new BaseGraph.Builder(encodingManager).create(); + private static BaseGraph createSubnetworkTestStorage(EncodingManager encodingManager, BooleanEncodedValue accessEnc1, DecimalEncodedValue speedEnc1, BooleanEncodedValue accessEnc2, DecimalEncodedValue speedEnc2) { + BaseGraph g = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); // 5 - 6 // | / // 4 @@ -74,113 +67,122 @@ private static BaseGraph createSubnetworkTestStorage(EncodingManager encodingMan // edge 3-4 gets no speed/access by default if (iter.getEdge() == 0) continue; - for (FlagEncoder encoder : encodingManager.fetchEdgeEncoders()) { - iter.set(encoder.getAverageSpeedEnc(), 10); - iter.set(encoder.getAccessEnc(), true, true); - } + iter.set(accessEnc1, true, true); + iter.set(speedEnc1, 10); + if (accessEnc2 != null) + iter.set(accessEnc2, true, true); + if (speedEnc2 != null) + iter.set(speedEnc2, 10); } return g; } @Test public void testPrepareSubnetworks_oneVehicle() { - EncodingManager em = createEncodingManager("car"); - FlagEncoder encoder = em.getEncoder("car"); - BaseGraph g = createSubnetworkTestStorage(em); - PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(createJob(em, encoder, NO_TURN_COST_PROVIDER))); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + BooleanEncodedValue subnetworkEnc = Subnetwork.create("car"); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).add(subnetworkEnc).build(); + BaseGraph g = createSubnetworkTestStorage(em, accessEnc, speedEnc, null, null); + PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(createJob(subnetworkEnc, accessEnc, speedEnc, NO_TURN_COST_PROVIDER))); // this will make the upper small network a subnetwork instance.setMinNetworkSize(4); assertEquals(3, instance.doWork()); - assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, encoder)); + assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, subnetworkEnc)); // this time we lower the threshold and the upper network won't be set to be a subnetwork - g = createSubnetworkTestStorage(em); - instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(createJob(em, encoder, NO_TURN_COST_PROVIDER))); + g = createSubnetworkTestStorage(em, accessEnc, speedEnc, null, null); + instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(createJob(subnetworkEnc, accessEnc, speedEnc, NO_TURN_COST_PROVIDER))); instance.setMinNetworkSize(3); assertEquals(0, instance.doWork()); - assertEquals(IntArrayList.from(), getSubnetworkEdges(g, encoder)); + assertEquals(IntArrayList.from(), getSubnetworkEdges(g, subnetworkEnc)); } @Test public void testPrepareSubnetworks_twoVehicles() { - EncodingManager em = createEncodingManager("car,bike"); - FlagEncoder carEncoder = em.getEncoder("car"); - FlagEncoder bikeEncoder = em.getEncoder("bike"); - BaseGraph g = createSubnetworkTestStorage(em); + BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + BooleanEncodedValue carSubnetworkEnc = Subnetwork.create("car"); + BooleanEncodedValue bikeAccessEnc = new SimpleBooleanEncodedValue("bike_access", true); + DecimalEncodedValue bikeSpeedEnc = new DecimalEncodedValueImpl("bike_speed", 4, 2, false); + BooleanEncodedValue bikeSubnetworkEnc = Subnetwork.create("bike"); + EncodingManager em = EncodingManager.start() + .add(carAccessEnc).add(carSpeedEnc).add(carSubnetworkEnc) + .add(bikeAccessEnc).add(bikeSpeedEnc).add(bikeSubnetworkEnc) + .build(); + BaseGraph g = createSubnetworkTestStorage(em, carAccessEnc, carSpeedEnc, bikeAccessEnc, bikeSpeedEnc); // first we only block the middle edge for cars. this way a subnetwork should be created but only for car EdgeIteratorState edge = GHUtility.getEdge(g, 3, 4); - GHUtility.setSpeed(10, false, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), edge); - GHUtility.setSpeed(5, true, true, bikeEncoder.getAccessEnc(), bikeEncoder.getAverageSpeedEnc(), edge); + GHUtility.setSpeed(10, false, false, carAccessEnc, carSpeedEnc, edge); + GHUtility.setSpeed(5, true, true, bikeAccessEnc, bikeSpeedEnc, edge); List prepareJobs = Arrays.asList( - createJob(em, carEncoder, NO_TURN_COST_PROVIDER), - createJob(em, bikeEncoder, NO_TURN_COST_PROVIDER) + createJob(carSubnetworkEnc, carAccessEnc, carSpeedEnc, NO_TURN_COST_PROVIDER), + createJob(bikeSubnetworkEnc, bikeAccessEnc, bikeSpeedEnc, NO_TURN_COST_PROVIDER) ); PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, prepareJobs); instance.setMinNetworkSize(5); assertEquals(3, instance.doWork()); - assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, carEncoder)); - assertEquals(IntArrayList.from(), getSubnetworkEdges(g, bikeEncoder)); + assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, carSubnetworkEnc)); + assertEquals(IntArrayList.from(), getSubnetworkEdges(g, bikeSubnetworkEnc)); // now we block the edge for both vehicles -> there should be a subnetwork for both vehicles - g = createSubnetworkTestStorage(em); + g = createSubnetworkTestStorage(em, carAccessEnc, carSpeedEnc, bikeAccessEnc, bikeSpeedEnc); edge = GHUtility.getEdge(g, 3, 4); - GHUtility.setSpeed(10, false, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), edge); - GHUtility.setSpeed(5, false, false, bikeEncoder.getAccessEnc(), bikeEncoder.getAverageSpeedEnc(), edge); + GHUtility.setSpeed(10, false, false, carAccessEnc, carSpeedEnc, edge); + GHUtility.setSpeed(5, false, false, bikeAccessEnc, bikeSpeedEnc, edge); instance = new PrepareRoutingSubnetworks(g, prepareJobs); instance.setMinNetworkSize(5); assertEquals(6, instance.doWork()); - assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, carEncoder)); - assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, bikeEncoder)); + assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, carSubnetworkEnc)); + assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, bikeSubnetworkEnc)); } @Test public void testPrepareSubnetwork_withTurnCosts() { - EncodingManager em = createEncodingManager("car|turn_costs=true"); - FlagEncoder encoder = em.fetchEdgeEncoders().iterator().next(); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + DecimalEncodedValue turnCostEnc = TurnCost.create("car", 1); + BooleanEncodedValue subnetworkEnc = Subnetwork.create("car"); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).add(subnetworkEnc).addTurnCostEncodedValue(turnCostEnc).build(); // since the middle edge is blocked the upper component is a subnetwork (regardless of turn costs) - BaseGraph g = createSubnetworkTestStorage(em); + BaseGraph g = createSubnetworkTestStorage(em, accessEnc, speedEnc, null, null); PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList( - createJob(em, encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), g.getTurnCostStorage(), 0)))); + createJob(subnetworkEnc, accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, g.getTurnCostStorage(), 0)))); instance.setMinNetworkSize(4); assertEquals(3, instance.doWork()); - assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, encoder)); + assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, subnetworkEnc)); // if we open the edge it won't be a subnetwork anymore - g = createSubnetworkTestStorage(em); + g = createSubnetworkTestStorage(em, accessEnc, speedEnc, null, null); EdgeIteratorState edge = GHUtility.getEdge(g, 3, 4); - GHUtility.setSpeed(10, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge); + GHUtility.setSpeed(10, true, true, accessEnc, speedEnc, edge); instance = new PrepareRoutingSubnetworks(g, Collections.singletonList( - createJob(em, encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), g.getTurnCostStorage(), 0)))); + createJob(subnetworkEnc, accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, g.getTurnCostStorage(), 0)))); instance.setMinNetworkSize(4); assertEquals(0, instance.doWork()); - assertEquals(IntArrayList.from(), getSubnetworkEdges(g, encoder)); + assertEquals(IntArrayList.from(), getSubnetworkEdges(g, subnetworkEnc)); // ... and now for something interesting: if we open the edge *and* apply turn restrictions it will be a // subnetwork again - g = createSubnetworkTestStorage(em); + g = createSubnetworkTestStorage(em, accessEnc, speedEnc, null, null); edge = GHUtility.getEdge(g, 3, 4); - GHUtility.setSpeed(10, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge); - DecimalEncodedValue turnCostEnc = em.getDecimalEncodedValue(TurnCost.key(encoder.toString())); + GHUtility.setSpeed(10, true, true, accessEnc, speedEnc, edge); g.getTurnCostStorage().set(turnCostEnc, 0, 4, 7, 1); g.getTurnCostStorage().set(turnCostEnc, 0, 4, 9, 1); instance = new PrepareRoutingSubnetworks(g, Collections.singletonList( - createJob(em, encoder, new DefaultTurnCostProvider(turnCostEnc, g.getTurnCostStorage(), 0)))); + createJob(subnetworkEnc, accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, g.getTurnCostStorage(), 0)))); instance.setMinNetworkSize(4); assertEquals(3, instance.doWork()); - assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, encoder)); + assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, subnetworkEnc)); } - private BaseGraph createSubnetworkTestStorageWithOneWays(EncodingManager em, FlagEncoder encoder) { - if (em.fetchEdgeEncoders().size() > 1) - fail("Warning: This method only sets access/speed for a single encoder, but the given encoding manager has multiple encoders"); + private BaseGraph createSubnetworkTestStorageWithOneWays(EncodingManager em, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { BaseGraph g = new BaseGraph.Builder(em).create(); // 0 - 1 - 2 - 3 - 4 <- 5 - 6 - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(1)); @@ -197,12 +199,14 @@ private BaseGraph createSubnetworkTestStorageWithOneWays(EncodingManager em, Fla @Test public void testPrepareSubnetworks_withOneWays() { - EncodingManager em = createEncodingManager("car"); - FlagEncoder encoder = em.fetchEdgeEncoders().iterator().next(); - BaseGraph g = createSubnetworkTestStorageWithOneWays(em, encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + BooleanEncodedValue subnetworkEnc = Subnetwork.create("car"); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).add(subnetworkEnc).build(); + BaseGraph g = createSubnetworkTestStorageWithOneWays(em, accessEnc, speedEnc); assertEquals(11, g.getNodes()); - PrepareRoutingSubnetworks.PrepareJob job = createJob(em, encoder, NO_TURN_COST_PROVIDER); + PrepareRoutingSubnetworks.PrepareJob job = createJob(subnetworkEnc, accessEnc, speedEnc, NO_TURN_COST_PROVIDER); PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(job)). setMinNetworkSize(2); int subnetworkEdges = instance.doWork(); @@ -211,9 +215,9 @@ public void testPrepareSubnetworks_withOneWays() { // note that the subnetworkEV per profile is one bit per *edge*. Before we used the encoder$access with 2 bits // and got more fine grained response here (8 removed *edgeKeys*) assertEquals(3, subnetworkEdges); - assertEquals(IntArrayList.from(4, 5, 6), getSubnetworkEdges(g, encoder)); + assertEquals(IntArrayList.from(4, 5, 6), getSubnetworkEdges(g, subnetworkEnc)); - g = createSubnetworkTestStorageWithOneWays(em, encoder); + g = createSubnetworkTestStorageWithOneWays(em, accessEnc, speedEnc); assertEquals(11, g.getNodes()); instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(job)). @@ -222,58 +226,43 @@ public void testPrepareSubnetworks_withOneWays() { // due to the larger min network size this time also the (8,9,10) component is a subnetwork assertEquals(5, subnetworkEdges); - assertEquals(IntArrayList.from(4, 5, 6, 7, 8), getSubnetworkEdges(g, encoder)); + assertEquals(IntArrayList.from(4, 5, 6, 7, 8), getSubnetworkEdges(g, subnetworkEnc)); } // Previous two-pass implementation failed on 1 -> 2 -> 0 @Test public void testNodeOrderingRegression() { // 1 -> 2 -> 0 - 3 - 4 - 5 - EncodingManager em = createEncodingManager("car"); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + BooleanEncodedValue subnetworkEnc = Subnetwork.create("car"); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).add(subnetworkEnc).build(); BaseGraph g = new BaseGraph.Builder(em).create(); - FlagEncoder encoder = em.fetchEdgeEncoders().iterator().next(); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(1, 2).setDistance(1)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(2, 0).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(1)); - PrepareRoutingSubnetworks.PrepareJob job = createJob(em, encoder, NO_TURN_COST_PROVIDER); + PrepareRoutingSubnetworks.PrepareJob job = createJob(subnetworkEnc, accessEnc, speedEnc, NO_TURN_COST_PROVIDER); PrepareRoutingSubnetworks instance = new PrepareRoutingSubnetworks(g, Collections.singletonList(job)). setMinNetworkSize(2); int subnetworkEdges = instance.doWork(); assertEquals(2, subnetworkEdges); - assertEquals(IntArrayList.from(0, 1), getSubnetworkEdges(g, encoder)); + assertEquals(IntArrayList.from(0, 1), getSubnetworkEdges(g, subnetworkEnc)); } - private static IntArrayList getSubnetworkEdges(BaseGraph graph, FlagEncoder encoder) { - BooleanEncodedValue subnetworkEnc = encoder.getBooleanEncodedValue(Subnetwork.key(encoder.toString())); + private static IntArrayList getSubnetworkEdges(BaseGraph graph, BooleanEncodedValue subnetworkEnc) { IntArrayList result = new IntArrayList(); AllEdgesIterator iter = graph.getAllEdges(); - while (iter.next()) { - if (iter.get(subnetworkEnc)) { + while (iter.next()) + if (iter.get(subnetworkEnc)) result.add(iter.getEdge()); - } - } return result; } - private static EncodingManager createEncodingManager(String flagEncodersStr) { - EncodingManager.Builder builder = new EncodingManager.Builder(); - for (String encoderStr : flagEncodersStr.split(",")) { - encoderStr = encoderStr.trim(); - FlagEncoder encoder = new DefaultFlagEncoderFactory().createFlagEncoder(encoderStr.split("\\|")[0], new PMap(encoderStr)); - builder.add(encoder); - builder.add(Subnetwork.create(encoder.toString())); - } - return builder.build(); - } - - private static PrepareRoutingSubnetworks.PrepareJob createJob(EncodingManager em, FlagEncoder encoder, TurnCostProvider turnCostProvider) { - return new PrepareRoutingSubnetworks.PrepareJob(em.getBooleanEncodedValue(Subnetwork.key(encoder.toString())), - new FastestWeighting(encoder, turnCostProvider)); + private static PrepareRoutingSubnetworks.PrepareJob createJob(BooleanEncodedValue subnetworkEnc, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, TurnCostProvider turnCostProvider) { + return new PrepareRoutingSubnetworks.PrepareJob(subnetworkEnc, new FastestWeighting(accessEnc, speedEnc, turnCostProvider)); } } diff --git a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java index 35a6d243c68..6a7b12f7261 100644 --- a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java @@ -48,12 +48,10 @@ public abstract class AbstractBikeTagParserTester { @BeforeEach public void setUp() { encodingManager = createEncodingManager(); - if (encodingManager.fetchEdgeEncoders().size() > 1) - fail("currently we assume there is only one encoder per test"); parser = createBikeTagParser(encodingManager, new PMap("block_fords=true")); osmParsers = createOSMParsers(parser, encodingManager); roundaboutEnc = encodingManager.getBooleanEncodedValue(Roundabout.KEY); - priorityEnc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(parser.getName(), "priority")); + priorityEnc = encodingManager.getDecimalEncodedValue(VehiclePriority.key(parser.getName())); avgSpeedEnc = parser.getAverageSpeedEnc(); } @@ -78,7 +76,7 @@ protected void assertPriorityAndSpeed(int expectedPrio, double expectedSpeed, Re IntsRef relFlags = osmParsers.handleRelationTags(rel, osmParsers.createRelationFlags()); IntsRef edgeFlags = encodingManager.createEdgeFlags(); edgeFlags = osmParsers.handleWayTags(edgeFlags, way, relFlags); - DecimalEncodedValue enc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(parser.toString(), "priority")); + DecimalEncodedValue enc = encodingManager.getDecimalEncodedValue(VehiclePriority.key(parser.toString())); assertEquals(PriorityCode.getValue(expectedPrio), enc.getDecimal(false, edgeFlags), 0.01); assertEquals(expectedSpeed, parser.getAverageSpeedEnc().getDecimal(false, edgeFlags), 0.1); assertEquals(expectedSpeed, parser.getAverageSpeedEnc().getDecimal(true, edgeFlags), 0.1); @@ -367,7 +365,7 @@ public void testHandleWayTagsCallsHandlePriority() { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "cycleway"); IntsRef edgeFlags = parser.handleWayTags(encodingManager.createEdgeFlags(), osmWay); - DecimalEncodedValue priorityEnc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(parser.getName(), "priority")); + DecimalEncodedValue priorityEnc = encodingManager.getDecimalEncodedValue(VehiclePriority.key(parser.getName())); assertEquals(PriorityCode.getValue(VERY_NICE.getValue()), priorityEnc.getDecimal(false, edgeFlags), 1e-3); } diff --git a/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java index ff4606da89c..1376773011e 100644 --- a/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/AccessFilterTest.java @@ -20,8 +20,7 @@ import com.carrotsearch.hppc.IntHashSet; import com.carrotsearch.hppc.IntSet; import com.graphhopper.routing.ch.PrepareEncoder; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.storage.*; @@ -31,10 +30,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class AccessFilterTest { - private final FlagEncoder encoder = FlagEncoders.createCar(); - private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - private final DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); - private final EncodingManager encodingManager = EncodingManager.create(encoder); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, true); + private final DecimalEncodedValue turnCostEnc = TurnCost.create("car", 1); + private final EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); private final BaseGraph graph = new BaseGraph.Builder(encodingManager) .withTurnCosts(true) .create(); @@ -49,7 +48,7 @@ public void testAccept_fwdLoopShortcut_acceptedByInExplorer() { GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, graph.edge(2, 0).setDistance(3)); graph.freeze(); // add loop shortcut in 'fwd' direction - CHConfig chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()))); + CHConfig chConfig = CHConfig.edgeBased("profile", new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage()))); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); CHStorageBuilder chBuilder = new CHStorageBuilder(chStore); chBuilder.setIdentityLevels(); diff --git a/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java index 7a3a3c12e1d..90473eee929 100644 --- a/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java @@ -36,8 +36,8 @@ public class Car4WDTagParserTest extends CarTagParserTest { @Override - FlagEncoder createEncoder(PMap properties) { - return FlagEncoders.createCar4wd(properties); + protected String getCarName() { + return "car4wd"; } @Override diff --git a/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java index 31f3ddb5bee..f0b1b937a4c 100644 --- a/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java @@ -20,10 +20,7 @@ import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.osm.conditional.DateRangeParser; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.Roundabout; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.Helper; import com.graphhopper.util.PMap; @@ -38,20 +35,27 @@ * @author Peter Karich */ public class CarTagParserTest { - final FlagEncoder encoder = createEncoder(new PMap("turn_costs=true|speed_two_directions=true")); - private final EncodingManager em = new EncodingManager.Builder() - .add(encoder) - .add(FlagEncoders.createBike()) - .add(FlagEncoders.createFoot()) - .build(); + private final EncodingManager em = createEncodingManager(getCarName()); final CarTagParser parser = createParser(em, new PMap("block_fords=true")); - private final BooleanEncodedValue roundaboutEnc = em.getBooleanEncodedValue(Roundabout.KEY); - private final DecimalEncodedValue avSpeedEnc = parser.getAverageSpeedEnc(); private final BooleanEncodedValue accessEnc = parser.getAccessEnc(); + private final DecimalEncodedValue avSpeedEnc = parser.getAverageSpeedEnc(); - FlagEncoder createEncoder(PMap properties) { - return FlagEncoders.createCar(properties); + protected String getCarName() { + return "car"; + } + + private EncodingManager createEncodingManager(String carName) { + return new EncodingManager.Builder() + .add(VehicleAccess.create(carName)) + .add(VehicleSpeed.create(carName, 5, 5, true)) + .addTurnCostEncodedValue(TurnCost.create(carName, 1)) + .add(VehicleAccess.create("bike")) + .add(VehicleSpeed.create("bike", 4, 2, false)) + .add(VehiclePriority.create("bike", 4, PriorityCode.getFactor(1), false)) + .add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)) + .add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)) + .build(); } CarTagParser createParser(EncodedValueLookup lookup, PMap properties) { @@ -267,6 +271,12 @@ public void testMaxSpeed() { way.setTag("maxspeed", "none"); edgeFlags = parser.handleWayTags(edgeFlags, way); assertEquals(135, avSpeedEnc.getDecimal(false, edgeFlags), .1); + + way = new ReaderWay(1); + way.setTag("highway", "motorway_link"); + way.setTag("maxspeed", "70 mph"); + IntsRef flags = parser.handleWayTags(em.createEdgeFlags(), way); + assertEquals(100, avSpeedEnc.getDecimal(true, flags), 1e-1); } @Test @@ -530,10 +540,13 @@ public void testChainBarrier() { @Test public void testMaxValue() { - FlagEncoder encoder = createEncoder(new PMap("speed_bits=10|speed_factor=0.5")); - EncodingManager em = EncodingManager.create(encoder); + DecimalEncodedValueImpl smallFactorSpeedEnc = new DecimalEncodedValueImpl(getCarName() + "_average_speed", 10, 0.5, false); + EncodingManager em = new EncodingManager.Builder() + .add(new SimpleBooleanEncodedValue(getCarName() + "_access", true)) + .add(smallFactorSpeedEnc) + .addTurnCostEncodedValue(TurnCost.create(getCarName(), 1)) + .build(); CarTagParser parser = createParser(em, new PMap()); - DecimalEncodedValue avSpeedEnc = em.getDecimalEncodedValue(EncodingManager.getKey(encoder, "average_speed")); ReaderWay way = new ReaderWay(1); way.setTag("highway", "motorway_link"); way.setTag("maxspeed", "60 mph"); @@ -541,22 +554,15 @@ public void testMaxValue() { // double speed = AbstractFlagEncoder.parseSpeed("60 mph"); // => 96.56 * 0.9 => 86.9 - assertEquals(86.9, avSpeedEnc.getDecimal(false, edgeFlags), 1e-1); - assertEquals(86.9, avSpeedEnc.getDecimal(true, edgeFlags), 1e-1); + assertEquals(86.9, smallFactorSpeedEnc.getDecimal(false, edgeFlags), 1e-1); + assertEquals(86.9, smallFactorSpeedEnc.getDecimal(true, edgeFlags), 1e-1); // test that maxPossibleValue is not exceeded way = new ReaderWay(2); way.setTag("highway", "motorway_link"); way.setTag("maxspeed", "70 mph"); edgeFlags = parser.handleWayTags(em.createEdgeFlags(), way); - assertEquals(101.5, avSpeedEnc.getDecimal(false, edgeFlags), .1); - } - - @Test - public void testRegisterOnlyOnceAllowed() { - FlagEncoder instance = FlagEncoders.createCar(); - EncodingManager.create(instance); - assertThrows(IllegalStateException.class, () -> EncodingManager.create(instance)); + assertEquals(101.5, smallFactorSpeedEnc.getDecimal(false, edgeFlags), .1); } @Test @@ -581,7 +587,7 @@ public void testCombination() { bikeParser.handleWayTags(edgeFlags, way); assertFalse(accessEnc.getBool(true, edgeFlags)); assertFalse(accessEnc.getBool(false, edgeFlags)); - BooleanEncodedValue bikeAccessEnc = em.getEncoder("bike").getAccessEnc(); + BooleanEncodedValue bikeAccessEnc = bikeParser.getAccessEnc(); assertTrue(bikeAccessEnc.getBool(true, edgeFlags)); assertTrue(bikeAccessEnc.getBool(false, edgeFlags)); } @@ -606,10 +612,14 @@ public void testIssue_1256() { assertEquals(5, parser.getAverageSpeedEnc().getDecimal(false, edgeFlags), .1); // for a smaller speed factor the minimum speed is also smaller - FlagEncoder lowFactorCar = createEncoder(new PMap("speed_bits=10|speed_factor=1")); - EncodingManager lowFactorEm = EncodingManager.create(lowFactorCar); + DecimalEncodedValueImpl lowFactorSpeedEnc = new DecimalEncodedValueImpl(getCarName() + "_average_speed", 10, 1, false); + EncodingManager lowFactorEm = new EncodingManager.Builder() + .add(new SimpleBooleanEncodedValue(getCarName() + "_access", true)) + .add(lowFactorSpeedEnc) + .addTurnCostEncodedValue(TurnCost.create(getCarName(), 1)) + .build(); edgeFlags = lowFactorEm.createEdgeFlags(); createParser(lowFactorEm, new PMap()).handleWayTags(edgeFlags, way); - assertEquals(1, lowFactorCar.getAverageSpeedEnc().getDecimal(false, edgeFlags), .1); + assertEquals(1, lowFactorSpeedEnc.getDecimal(false, edgeFlags), .1); } } diff --git a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java index e3c55adb50f..7e6660e5859 100644 --- a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java @@ -17,6 +17,7 @@ */ package com.graphhopper.routing.util; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -34,24 +35,6 @@ public void duplicateNamesNotAllowed() { assertThrows(IllegalArgumentException.class, () -> EncodingManager.create("car,car")); } - @Test - public void testEncoderAcceptNoException() { - EncodingManager manager = EncodingManager.create("car"); - assertTrue(manager.hasEncoder("car")); - assertFalse(manager.hasEncoder("foot")); - } - - @Test - public void testWrongEncoders() { - try { - FlagEncoder foot = FlagEncoders.createFoot(); - EncodingManager.create(foot, foot); - fail("There should have been an exception"); - } catch (Exception ex) { - assertEquals("FlagEncoder already exists: foot", ex.getMessage()); - } - } - @Test public void testSupportFords() { String flagEncoderStrings = "car,bike,foot"; @@ -89,4 +72,12 @@ public void validEV() { assertFalse(EncodingManager.isValidEncodedValue(str), str); } } + + @Test + public void testRegisterOnlyOnceAllowed() { + DecimalEncodedValueImpl speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager.start().add(speedEnc).build(); + assertThrows(IllegalStateException.class, () -> EncodingManager.start().add(speedEnc).build()); + } + } diff --git a/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java index 38bdcfd8420..1f743d54cdd 100644 --- a/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/FootTagParserTest.java @@ -20,8 +20,7 @@ import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.osm.conditional.DateRangeParser; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.*; @@ -36,13 +35,19 @@ * @author Peter Karich */ public class FootTagParserTest { - private final EncodingManager encodingManager = EncodingManager.create("car,bike,foot"); - private final FlagEncoder encoder = encodingManager.getEncoder("foot"); + private final BooleanEncodedValue footAccessEnc = VehicleAccess.create("foot"); + private final DecimalEncodedValue footAvgSpeedEnc = VehicleSpeed.create("foot", 4, 1, false); + private final DecimalEncodedValue footPriorityEnc = VehiclePriority.create("foot", 4, PriorityCode.getFactor(1), false); + private final BooleanEncodedValue bikeAccessEnc = VehicleAccess.create("bike"); + private final DecimalEncodedValue bikeAvgSpeedEnc = VehicleSpeed.create("bike", 4, 2, false); + private final BooleanEncodedValue carAccessEnc = VehicleAccess.create("car"); + private final DecimalEncodedValue carAvSpeedEnc = VehicleSpeed.create("car", 5, 5, false); + private final EncodingManager encodingManager = EncodingManager.start() + .add(footAccessEnc).add(footAvgSpeedEnc).add(footPriorityEnc).add(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)) + .add(bikeAccessEnc).add(bikeAvgSpeedEnc).add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)) + .add(carAccessEnc).add(carAvSpeedEnc) + .build(); private final FootTagParser footParser = new FootTagParser(encodingManager, new PMap()); - private final DecimalEncodedValue footAvgSpeedEnc = encoder.getAverageSpeedEnc(); - private final BooleanEncodedValue footAccessEnc = encoder.getAccessEnc(); - private final DecimalEncodedValue carAvSpeedEnc = encodingManager.getEncoder("car").getAverageSpeedEnc(); - private final BooleanEncodedValue carAccessEnc = encodingManager.getEncoder("car").getAccessEnc(); public FootTagParserTest() { footParser.init(new DateRangeParser()); @@ -457,18 +462,18 @@ public void testBlockByDefault() { @Test public void maxSpeed() { - FlagEncoder encoder = FlagEncoders.createFoot(new PMap().putObject("speed_bits", 4).putObject("speed_factor", 2)); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("foot_speed", 4, 2, true); // The foot max speed is supposed to be 15km/h, but for speed_bits=4,speed_factor=2 as we use here 15 cannot // be stored. In fact, when we set the speed of an edge to 15 and call the getter afterwards we get a value of 16 // because of the internal (scaled) integer representation: - EncodingManager em = EncodingManager.create(encoder); + EncodingManager em = EncodingManager.start().add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); - EdgeIteratorState edge = graph.edge(0, 1).setDistance(100).set(encoder.getAverageSpeedEnc(), 15); - assertEquals(16, edge.get(encoder.getAverageSpeedEnc())); + EdgeIteratorState edge = graph.edge(0, 1).setDistance(100).set(speedEnc, 15); + assertEquals(16, edge.get(speedEnc)); // ... because of this we have to make sure the max speed is set to a value that cannot be exceeded even when // such conversion occurs. in our case it must be 16 not 15! // note that this test made more sense when we used encoders that defined a max speed. - assertEquals(16, encoder.getAverageSpeedEnc().getNextStorableValue(15)); + assertEquals(16, speedEnc.getNextStorableValue(15)); } } diff --git a/core/src/test/java/com/graphhopper/routing/util/HeadingEdgeFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/HeadingEdgeFilterTest.java index 80054eacb8c..b720b89fddd 100644 --- a/core/src/test/java/com/graphhopper/routing/util/HeadingEdgeFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/HeadingEdgeFilterTest.java @@ -1,5 +1,9 @@ package com.graphhopper.routing.util; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.storage.BaseGraph; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.shapes.GHPoint; @@ -12,14 +16,14 @@ class HeadingEdgeFilterTest { @Test public void getHeading() { GHPoint point = new GHPoint(55.67093, 12.577294); - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager encodingManager = new EncodingManager.Builder().add(carEncoder).build(); - BaseGraph g = new BaseGraph.Builder(encodingManager).create(); + BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(carAccessEnc).add(carSpeedEnc).build(); + BaseGraph g = new BaseGraph.Builder(em).create(); EdgeIteratorState edge = g.edge(0, 1); g.getNodeAccess().setNode(0, 55.671044, 12.5771583); g.getNodeAccess().setNode(1, 55.6704136, 12.5784324); - // GHUtility.setSpeed(50, 0, carEncoder, edge.getFlags()); - + // GHUtility.setSpeed(50, 0, carAccessEnc, carSpeedEnc, edge.getFlags()); assertEquals(131.2, HeadingEdgeFilter.getHeadingOfGeometryNearPoint(edge, point, 20), .1); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java index 4a2e6303a18..1f67e1c3e12 100644 --- a/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java @@ -19,7 +19,7 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.osm.conditional.DateRangeParser; -import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.storage.IntsRef; @@ -37,10 +37,17 @@ * @author Peter Karich */ public class MotorcycleTagParserTest { - private final EncodingManager em = EncodingManager.create("motorcycle,foot"); - private final FlagEncoder encoder = em.getEncoder("motorcycle"); + private final BooleanEncodedValue motorcycleAccessEnc = VehicleAccess.create("motorcycle"); + private final DecimalEncodedValue motorcycleSpeedEnc = VehicleSpeed.create("motorcycle", 5, 5, true); + private final DecimalEncodedValue motorcyclePriorityEnc = VehiclePriority.create("motorcycle", 4, PriorityCode.getFactor(1), false); + private final DecimalEncodedValue motorcycleCurvatureEnc = new DecimalEncodedValueImpl("motorcycle_curvature", 4, 0.1, false); + private final BooleanEncodedValue footAccessEnc = VehicleAccess.create("foot"); + private final DecimalEncodedValue footSpeedEnc = VehicleSpeed.create("foot", 4, 1, false); + private final EncodingManager em = EncodingManager.start() + .add(motorcycleAccessEnc).add(motorcycleSpeedEnc).add(motorcyclePriorityEnc).add(motorcycleCurvatureEnc) + .add(footAccessEnc).add(footSpeedEnc) + .build(); private final MotorcycleTagParser parser; - private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); public MotorcycleTagParserTest() { parser = new MotorcycleTagParser(em, new PMap()); @@ -57,7 +64,7 @@ private Graph initExampleGraph() { setWayGeometry(Helper.createPointList3D(51.1, 12.0011, 49, 51.1, 12.0015, 55)); edge.setDistance(100); - edge.set(accessEnc, true, true).set(encoder.getAverageSpeedEnc(), 10.0, 15.0); + edge.set(motorcycleAccessEnc, true, true).set(motorcycleSpeedEnc, 10.0, 15.0); return gs; } @@ -150,8 +157,8 @@ public void testHandleWayTags() { @Test public void testSetSpeed0_issue367() { IntsRef edgeFlags = em.createEdgeFlags(); - accessEnc.setBool(false, edgeFlags, true); - accessEnc.setBool(true, edgeFlags, true); + motorcycleAccessEnc.setBool(false, edgeFlags, true); + motorcycleAccessEnc.setBool(true, edgeFlags, true); parser.getAverageSpeedEnc().setDecimal(false, edgeFlags, 10); parser.getAverageSpeedEnc().setDecimal(true, edgeFlags, 10); @@ -161,8 +168,8 @@ public void testSetSpeed0_issue367() { parser.setSpeed(false, edgeFlags, 0); assertEquals(0, parser.avgSpeedEnc.getDecimal(false, edgeFlags), .1); assertEquals(10, parser.avgSpeedEnc.getDecimal(true, edgeFlags), .1); - assertFalse(accessEnc.getBool(false, edgeFlags)); - assertTrue(accessEnc.getBool(true, edgeFlags)); + assertFalse(motorcycleAccessEnc.getBool(false, edgeFlags)); + assertTrue(motorcycleAccessEnc.getBool(true, edgeFlags)); } @Test @@ -191,6 +198,6 @@ private double getBendiness(EdgeIteratorState edge, double beelineDistance) { IntsRef flags = parser.handleWayTags(em.createEdgeFlags(), way); edge.setFlags(flags); parser.applyWayTags(way, edge); - return edge.get(encoder.getCurvatureEnc()); + return edge.get(motorcycleCurvatureEnc); } } diff --git a/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java index dcf1dac2e47..6e563e4271f 100644 --- a/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java @@ -17,9 +17,15 @@ */ package com.graphhopper.routing.util; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.NodeAccess; -import com.graphhopper.util.*; +import com.graphhopper.util.EdgeIteratorState; +import com.graphhopper.util.FetchMode; +import com.graphhopper.util.GHUtility; +import com.graphhopper.util.PointList; import com.graphhopper.util.shapes.GHPoint; import org.junit.jupiter.api.Test; @@ -82,8 +88,7 @@ public void testAccept() { @Test public void testDistanceFiltering() { - FlagEncoder encoder = FlagEncoders.createCar(); - BaseGraph g = new BaseGraph.Builder(EncodingManager.create(encoder)).create(); + BaseGraph g = new BaseGraph.Builder(1).create(); NodeAccess na = g.getNodeAccess(); GHPoint pointFarAway = new GHPoint(49.458629, 11.146124); @@ -273,8 +278,9 @@ public void curvedWayGeometry_issue2319() { // ----- // // 2 -- 3 - FlagEncoder encoder = FlagEncoders.createCar(new PMap().putObject("speed_two_directions", true)); - EncodingManager em = EncodingManager.create(encoder); + SimpleBooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, true); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); PointList pointList = new PointList(20, false); pointList.add(43.844377, -79.264005); @@ -303,17 +309,17 @@ public void curvedWayGeometry_issue2319() { pointList.add(43.842711, -79.264588); graph.getNodeAccess().setNode(0, 43.844521, -79.263976); graph.getNodeAccess().setNode(1, 43.842775, -79.264649); - EdgeIteratorState doubtfire = graph.edge(0, 1).setWayGeometry(pointList).set(encoder.getAccessEnc(), true, true). - set(encoder.getAverageSpeedEnc(), 60, 60).setKeyValues(singletonMap("name", "Doubtfire Crescent")); - EdgeIteratorState golden = graph.edge(0, 1).set(encoder.getAccessEnc(), true, true).set(encoder.getAverageSpeedEnc(), 60, 60). + EdgeIteratorState doubtfire = graph.edge(0, 1).setWayGeometry(pointList).set(accessEnc, true, true). + set(speedEnc, 60, 60).setKeyValues(singletonMap("name", "Doubtfire Crescent")); + EdgeIteratorState golden = graph.edge(0, 1).set(accessEnc, true, true).set(speedEnc, 60, 60). setKeyValues(singletonMap("name", "Golden Avenue")); graph.getNodeAccess().setNode(2, 43.841501560244744, -79.26366394602502); graph.getNodeAccess().setNode(3, 43.842247922172724, -79.2605663670726); PointList pointList2 = new PointList(1, false); pointList2.add(43.84191413615452, -79.261912128223); - EdgeIteratorState denison = graph.edge(2, 3).setWayGeometry(pointList2).set(encoder.getAccessEnc(), true, true). - set(encoder.getAverageSpeedEnc(), 60, 60).setKeyValues(singletonMap("name", "Denison Street")); + EdgeIteratorState denison = graph.edge(2, 3).setWayGeometry(pointList2).set(accessEnc, true, true). + set(speedEnc, 60, 60).setKeyValues(singletonMap("name", "Denison Street")); double qlat = 43.842122; double qLon = -79.262162; diff --git a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java index 851954a62de..71c321f7838 100644 --- a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java @@ -220,7 +220,14 @@ public void testHandleWayTagsInfluencedByRelation() { public void testPriority_avoidanceOfHighMaxSpeed() { // here we test the priority that would be calculated if the way was accessible (even when it is not) // therefore we need a modified parser that always yields access=WAY - EncodingManager encodingManager = EncodingManager.create("racingbike"); + BooleanEncodedValue accessEnc = VehicleAccess.create("racingbike"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("racingbike", 4, 2, false); + DecimalEncodedValue priorityEnc = VehiclePriority.create("racingbike", 4, PriorityCode.getValue(1), false); + EncodingManager encodingManager = EncodingManager.start() + .add(accessEnc).add(speedEnc).add(priorityEnc) + .add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)) + .add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)) + .build(); BikeCommonTagParser parser = new RacingBikeTagParser(encodingManager, new PMap("block_fords=true")) { @Override public WayAccess getAccess(ReaderWay way) { @@ -230,56 +237,54 @@ public WayAccess getAccess(ReaderWay way) { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "tertiary"); osmWay.setTag("maxspeed", "50"); - assertPriorityAndSpeed(encodingManager, parser, PREFER.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, PREFER.getValue(), 20, osmWay); osmWay.setTag("maxspeed", "60"); - assertPriorityAndSpeed(encodingManager, parser, PREFER.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, PREFER.getValue(), 20, osmWay); osmWay.setTag("maxspeed", "80"); - assertPriorityAndSpeed(encodingManager, parser, PREFER.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, PREFER.getValue(), 20, osmWay); osmWay.setTag("maxspeed", "90"); - assertPriorityAndSpeed(encodingManager, parser, UNCHANGED.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, UNCHANGED.getValue(), 20, osmWay); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, parser, UNCHANGED.getValue(), 20, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, UNCHANGED.getValue(), 20, osmWay); osmWay.setTag("highway", "motorway"); - assertPriorityAndSpeed(encodingManager, parser, AVOID.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, AVOID.getValue(), 18, osmWay); osmWay.setTag("tunnel", "yes"); - assertPriorityAndSpeed(encodingManager, parser, AVOID_MORE.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, AVOID_MORE.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "motorway"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "80"); - assertPriorityAndSpeed(encodingManager, parser, AVOID_MORE.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, AVOID_MORE.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "motorway"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, parser, AVOID_MORE.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, AVOID_MORE.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "notdefined"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, parser, AVOID_MORE.getValue(), 4, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, AVOID_MORE.getValue(), 4, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "notdefined"); osmWay.setTag("maxspeed", "50"); - assertPriorityAndSpeed(encodingManager, parser, UNCHANGED.getValue(), 4, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, UNCHANGED.getValue(), 4, osmWay); } - private void assertPriorityAndSpeed(EncodingManager encodingManager, VehicleTagParser parser, int expectedPrio, double expectedSpeed, ReaderWay way) { + private void assertPriorityAndSpeed(EncodingManager encodingManager, DecimalEncodedValue priorityEnc, DecimalEncodedValue speedEnc, VehicleTagParser parser, int expectedPrio, double expectedSpeed, ReaderWay way) { IntsRef edgeFlags = parser.handleWayTags(encodingManager.createEdgeFlags(), way); - FlagEncoder encoder = encodingManager.fetchEdgeEncoders().iterator().next(); - DecimalEncodedValue enc = encodingManager.getDecimalEncodedValue(EncodingManager.getKey(encoder.toString(), "priority")); - assertEquals(expectedSpeed, encoder.getAverageSpeedEnc().getDecimal(false, edgeFlags), 0.1); - assertEquals(PriorityCode.getValue(expectedPrio), enc.getDecimal(false, edgeFlags), 0.01); + assertEquals(PriorityCode.getValue(expectedPrio), priorityEnc.getDecimal(false, edgeFlags), 0.01); + assertEquals(expectedSpeed, speedEnc.getDecimal(false, edgeFlags), 0.1); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java b/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java index 244ba6cb9d3..78636f71f89 100644 --- a/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java @@ -33,7 +33,6 @@ import java.util.Arrays; import java.util.List; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -44,27 +43,36 @@ public void testCombineRelations() { osmWay.setTag("highway", "track"); ReaderRelation osmRel = new ReaderRelation(1); - FlagEncoder defaultBike = FlagEncoders.createBike(); - FlagEncoder lessRelationCodes = FlagEncoders.createBike(new PMap("name=less_relation_bits")); - - EncodingManager em = EncodingManager.create(defaultBike, lessRelationCodes); - EnumEncodedValue bikeNetworkEnc = em.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class); - BikeTagParser defaultBikeParser = new BikeTagParser(em, new PMap("name=bike")); - defaultBikeParser.init(new DateRangeParser()); - BikeTagParser lessRelationCodesParser = new BikeTagParser(em, new PMap("name=less_relation_bits")) { + BooleanEncodedValue bike1AccessEnc = VehicleAccess.create("bike1"); + DecimalEncodedValue bike1SpeedEnc = VehicleSpeed.create("bike1", 4, 2, false); + DecimalEncodedValue bike1PriorityEnc = VehiclePriority.create("bike1", 4, PriorityCode.getFactor(1), false); + BooleanEncodedValue bike2AccessEnc = VehicleAccess.create("bike2"); + DecimalEncodedValue bike2SpeedEnc = VehicleSpeed.create("bike2", 4, 2, false); + DecimalEncodedValue bike2PriorityEnc = VehiclePriority.create("bike2", 4, PriorityCode.getFactor(1), false); + EnumEncodedValue bikeNetworkEnc = new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class); + EncodingManager em = EncodingManager.start() + .add(bike1AccessEnc).add(bike1SpeedEnc).add(bike1PriorityEnc) + .add(bike2AccessEnc).add(bike2SpeedEnc).add(bike2PriorityEnc) + .add(bikeNetworkEnc) + .add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)) + .build(); + BikeTagParser bike1Parser = new BikeTagParser(em, new PMap("name=bike1")); + bike1Parser.init(new DateRangeParser()); + BikeTagParser bike2Parser = new BikeTagParser(em, new PMap("name=bike2")) { @Override public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { + // accept less relations if (bikeRouteEnc.getEnum(false, edgeFlags) != RouteNetwork.MISSING) priorityEnc.setDecimal(false, edgeFlags, PriorityCode.getFactor(2)); return edgeFlags; } }; - lessRelationCodesParser.init(new DateRangeParser()); + bike2Parser.init(new DateRangeParser()); OSMParsers osmParsers = new OSMParsers() .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(bikeNetworkEnc, relConfig)) .addWayTagParser(new OSMRoadClassParser(em.getEnumEncodedValue(RoadClass.KEY, RoadClass.class))) - .addWayTagParser(defaultBikeParser) - .addWayTagParser(lessRelationCodesParser); + .addWayTagParser(bike1Parser) + .addWayTagParser(bike2Parser); // relation code is PREFER osmRel.setTag("route", "bicycle"); @@ -74,7 +82,7 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { IntsRef edgeFlags = em.createEdgeFlags(); edgeFlags = osmParsers.handleWayTags(edgeFlags, osmWay, relFlags); assertEquals(RouteNetwork.LOCAL, bikeNetworkEnc.getEnum(false, edgeFlags)); - assertTrue(defaultBike.getPriorityEnc().getDecimal(false, edgeFlags) > lessRelationCodes.getPriorityEnc().getDecimal(false, edgeFlags)); + assertTrue(bike1PriorityEnc.getDecimal(false, edgeFlags) > bike2PriorityEnc.getDecimal(false, edgeFlags)); } @Test @@ -85,18 +93,26 @@ public void testMixBikeTypesAndRelationCombination() { ReaderRelation osmRel = new ReaderRelation(1); - FlagEncoder bikeEncoder = FlagEncoders.createBike(); - FlagEncoder mtbEncoder = FlagEncoders.createMountainBike(); - EncodingManager manager = EncodingManager.create(bikeEncoder, mtbEncoder); - - EnumEncodedValue bikeNetworkEnc = manager.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class); - BikeTagParser bikeTagParser = new BikeTagParser(manager, new PMap()); + BooleanEncodedValue bikeAccessEnc = VehicleAccess.create("bike"); + DecimalEncodedValue bikeSpeedEnc = VehicleSpeed.create("bike", 4, 2, false); + DecimalEncodedValue bikePriorityEnc = VehiclePriority.create("bike", 4, PriorityCode.getFactor(1), false); + BooleanEncodedValue mtbAccessEnc = VehicleAccess.create("mtb"); + DecimalEncodedValue mtbSpeedEnc = VehicleSpeed.create("mtb", 4, 2, false); + DecimalEncodedValue mtbPriorityEnc = VehiclePriority.create("mtb", 4, PriorityCode.getFactor(1), false); + EnumEncodedValue bikeNetworkEnc = new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class); + EncodingManager em = EncodingManager.start() + .add(bikeAccessEnc).add(bikeSpeedEnc).add(bikePriorityEnc) + .add(mtbAccessEnc).add(mtbSpeedEnc).add(mtbPriorityEnc) + .add(bikeNetworkEnc) + .add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)) + .build(); + BikeTagParser bikeTagParser = new BikeTagParser(em, new PMap()); bikeTagParser.init(new DateRangeParser()); - MountainBikeTagParser mtbTagParser = new MountainBikeTagParser(manager, new PMap()); + MountainBikeTagParser mtbTagParser = new MountainBikeTagParser(em, new PMap()); mtbTagParser.init(new DateRangeParser()); OSMParsers osmParsers = new OSMParsers() .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(bikeNetworkEnc, relConfig)) - .addWayTagParser(new OSMRoadClassParser(manager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class))) + .addWayTagParser(new OSMRoadClassParser(em.getEnumEncodedValue(RoadClass.KEY, RoadClass.class))) .addWayTagParser(bikeTagParser) .addWayTagParser(mtbTagParser); @@ -105,11 +121,11 @@ public void testMixBikeTypesAndRelationCombination() { osmRel.setTag("network", "rcn"); IntsRef relFlags = osmParsers.createRelationFlags(); relFlags = osmParsers.handleRelationTags(osmRel, relFlags); - IntsRef edgeFlags = manager.createEdgeFlags(); + IntsRef edgeFlags = em.createEdgeFlags(); edgeFlags = osmParsers.handleWayTags(edgeFlags, osmWay, relFlags); // bike: uninfluenced speed for grade but via network => NICE // mtb: uninfluenced speed only PREFER - assertTrue(bikeEncoder.getPriorityEnc().getDecimal(false, edgeFlags) > mtbEncoder.getPriorityEnc().getDecimal(false, edgeFlags)); + assertTrue(bikePriorityEnc.getDecimal(false, edgeFlags) > mtbPriorityEnc.getDecimal(false, edgeFlags)); } @Test @@ -134,18 +150,33 @@ public void testCompatibilityBug() { flags = footParser.handleWayTags(manager.createEdgeFlags(), osmWay); flags = bikeParser.handleWayTags(flags, osmWay); - DecimalEncodedValue bikeSpeedEnc = manager.getDecimalEncodedValue(getKey("bike2", "average_speed")); + DecimalEncodedValue bikeSpeedEnc = manager.getDecimalEncodedValue(VehicleSpeed.key("bike2")); assertEquals(singleSpeed, bikeSpeedEnc.getDecimal(false, flags), 1e-2); assertEquals(singleSpeed, bikeSpeedEnc.getDecimal(true, flags), 1e-2); - DecimalEncodedValue footSpeedEnc = manager.getDecimalEncodedValue(getKey("foot", "average_speed")); + DecimalEncodedValue footSpeedEnc = manager.getDecimalEncodedValue(VehicleSpeed.key("foot")); assertEquals(5, footSpeedEnc.getDecimal(false, flags), 1e-2); assertEquals(5, footSpeedEnc.getDecimal(true, flags), 1e-2); } @Test public void testSharedEncodedValues() { - EncodingManager manager = EncodingManager.create("car,foot,bike,motorcycle,mtb"); + BooleanEncodedValue carAccessEnc = VehicleAccess.create("car"); + BooleanEncodedValue footAccessEnc = VehicleAccess.create("foot"); + BooleanEncodedValue bikeAccessEnc = VehicleAccess.create("bike"); + BooleanEncodedValue motorcycleAccessEnc = VehicleAccess.create("motorcycle"); + BooleanEncodedValue mtbAccessEnc = VehicleAccess.create("mtb"); + List accessEncs = Arrays.asList(carAccessEnc, footAccessEnc, bikeAccessEnc, motorcycleAccessEnc, mtbAccessEnc); + EncodingManager manager = EncodingManager.start() + .add(carAccessEnc).add(VehicleSpeed.create("car", 5, 5, false)) + .add(footAccessEnc).add(VehicleSpeed.create("foot", 4, 1, true)).add(VehiclePriority.create("foot", 4, PriorityCode.getFactor(1), false)) + .add(bikeAccessEnc).add(VehicleSpeed.create("bike", 4, 2, false)).add(VehiclePriority.create("bike", 4, PriorityCode.getFactor(1), false)) + .add(motorcycleAccessEnc).add(VehicleSpeed.create("motorcycle", 5, 5, true)).add(VehiclePriority.create("motorcycle", 4, PriorityCode.getFactor(1), false)).add(new DecimalEncodedValueImpl("motorcycle_curvature", 5, 5, true)) + .add(mtbAccessEnc).add(VehicleSpeed.create("mtb", 4, 2, false)).add(VehiclePriority.create("mtb", 4, PriorityCode.getFactor(1), false)) + .add(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)) + .add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)) + .add(new EnumEncodedValue<>(Smoothness.KEY, Smoothness.class)) + .build(); BooleanEncodedValue roundaboutEnc = manager.getBooleanEncodedValue(Roundabout.KEY); List tagParsers = Arrays.asList( @@ -167,11 +198,9 @@ public void testSharedEncodedValues() { way.setTag("junction", "roundabout"); tagParsers.forEach(p -> p.handleWayTags(edgeFlags, way, relFlags)); - for (FlagEncoder tmp : manager.fetchEdgeEncoders()) { - BooleanEncodedValue accessEnc = tmp.getAccessEnc(); + assertTrue(roundaboutEnc.getBool(false, edgeFlags)); + for (BooleanEncodedValue accessEnc : accessEncs) assertTrue(accessEnc.getBool(false, edgeFlags)); - assertTrue(roundaboutEnc.getBool(false, edgeFlags), tmp.toString()); - } final IntsRef edgeFlags2 = manager.createEdgeFlags(); way.clearTags(); @@ -179,11 +208,9 @@ public void testSharedEncodedValues() { way.setTag("junction", "circular"); tagParsers.forEach(p -> p.handleWayTags(edgeFlags2, way, relFlags)); - for (FlagEncoder tmp : manager.fetchEdgeEncoders()) { - BooleanEncodedValue accessEnc = tmp.getAccessEnc(); + assertTrue(roundaboutEnc.getBool(false, edgeFlags)); + for (BooleanEncodedValue accessEnc : accessEncs) assertTrue(accessEnc.getBool(false, edgeFlags)); - assertTrue(roundaboutEnc.getBool(false, edgeFlags), tmp.toString()); - } } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java index 7739ea9f407..9160b98ae93 100644 --- a/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java @@ -20,8 +20,7 @@ import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.osm.conditional.DateRangeParser; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.*; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.NodeAccess; @@ -37,18 +36,26 @@ * @author don-philipe */ public class WheelchairTagParserTest { - private final EncodingManager encodingManager = EncodingManager.create("car,wheelchair"); - private final WheelchairTagParser wheelchairParser; - private final DecimalEncodedValue wheelchairAvSpeedEnc; private final BooleanEncodedValue wheelchairAccessEnc; - private final DecimalEncodedValue carAvSpeedEnc = encodingManager.getEncoder("car").getAverageSpeedEnc(); - private final BooleanEncodedValue carAccessEnc = encodingManager.getEncoder("car").getAccessEnc(); + private final DecimalEncodedValue wheelchairAvSpeedEnc; + private final DecimalEncodedValue wheelchairPriorityEnc; + private final BooleanEncodedValue carAccessEnc; + private final DecimalEncodedValue carAvSpeedEnc; + private final EncodingManager encodingManager; + private final WheelchairTagParser wheelchairParser; public WheelchairTagParserTest() { + wheelchairAccessEnc = VehicleAccess.create("wheelchair"); + wheelchairAvSpeedEnc = VehicleSpeed.create("wheelchair", 4, 1, true); + wheelchairPriorityEnc = VehiclePriority.create("wheelchair", 4, PriorityCode.getFactor(1), false); + carAccessEnc = VehicleAccess.create("car"); + carAvSpeedEnc = VehicleSpeed.create("car", 5, 5, false); + encodingManager = EncodingManager.start() + .add(wheelchairAccessEnc).add(wheelchairAvSpeedEnc).add(wheelchairPriorityEnc).add(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)) + .add(carAccessEnc).add(carAvSpeedEnc) + .build(); wheelchairParser = new WheelchairTagParser(encodingManager, new PMap()); wheelchairParser.init(new DateRangeParser()); - wheelchairAvSpeedEnc = wheelchairParser.getAverageSpeedEnc(); - wheelchairAccessEnc = wheelchairParser.getAccessEnc(); } @Test @@ -63,7 +70,6 @@ public void testGetSpeed() { @Test public void testCombined() { BaseGraph g = new BaseGraph.Builder(encodingManager).create(); - FlagEncoder carEncoder = encodingManager.getEncoder("car"); EdgeIteratorState edge = g.edge(0, 1); edge.set(wheelchairAvSpeedEnc, 10.0).set(wheelchairAccessEnc, true, true); edge.set(carAvSpeedEnc, 100.0).set(carAccessEnc, true, false); @@ -504,24 +510,21 @@ public void testApplyWayTags() { na.setNode(1, 51.1, 12.0015, 55); EdgeIteratorState edge01 = graph.edge(0, 1).setWayGeometry(Helper.createPointList3D(51.1, 12.0011, 49, 51.1, 12.0015, 55)); edge01.setDistance(100); - FlagEncoder encoder2 = encodingManager.getEncoder("wheelchair"); - GHUtility.setSpeed(5, 5, encoder2.getAccessEnc(), encoder2.getAverageSpeedEnc(), edge01); + GHUtility.setSpeed(5, 5, wheelchairAccessEnc, wheelchairAvSpeedEnc, edge01); // incline of 10% & shorter edge na.setNode(2, 51.2, 12.1010, 50); na.setNode(3, 51.2, 12.1015, 60); EdgeIteratorState edge23 = graph.edge(2, 3).setWayGeometry(Helper.createPointList3D(51.2, 12.1011, 49, 51.2, 12.1015, 55)); edge23.setDistance(30); - FlagEncoder encoder1 = encodingManager.getEncoder("wheelchair"); - GHUtility.setSpeed(5, 5, encoder1.getAccessEnc(), encoder1.getAverageSpeedEnc(), edge23); + GHUtility.setSpeed(5, 5, wheelchairAccessEnc, wheelchairAvSpeedEnc, edge23); // incline of 10% & longer edge na.setNode(4, 51.2, 12.101, 50); na.setNode(5, 51.2, 12.102, 60); EdgeIteratorState edge45 = graph.edge(2, 3).setWayGeometry(Helper.createPointList3D(51.2, 12.1011, 49, 51.2, 12.1015, 55)); edge45.setDistance(100); - FlagEncoder encoder = encodingManager.getEncoder("wheelchair"); - GHUtility.setSpeed(5, 5, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), edge45); + GHUtility.setSpeed(5, 5, wheelchairAccessEnc, wheelchairAvSpeedEnc, edge45); wheelchairParser.applyWayTags(new ReaderWay(1), edge01); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java index c5a3fab4544..03bb29050a6 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java @@ -1,17 +1,12 @@ package com.graphhopper.routing.util.parsers; import com.graphhopper.reader.OSMTurnRelation; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.util.TransportationMode; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.TurnCostStorage; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; import java.util.HashMap; @@ -24,7 +19,10 @@ public class OSMTurnRelationParserTest { @Test public void testGetRestrictionAsEntries() { - FlagEncoder encoder = FlagEncoders.createCar(new PMap("turn_costs=true")); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + DecimalEncodedValue turnCostEnc = TurnCost.create("car", 1); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); final Map osmNodeToInternal = new HashMap<>(); final Map internalToOSMEdge = new HashMap<>(); @@ -33,11 +31,9 @@ public void testGetRestrictionAsEntries() { internalToOSMEdge.put(3, 3L); internalToOSMEdge.put(4, 4L); - EncodingManager em = EncodingManager.create(encoder); - DecimalEncodedValue tce = encoder.getDecimalEncodedValue(TurnCost.key("car")); - OSMTurnRelationParser parser = new OSMTurnRelationParser(encoder.getAccessEnc(), tce, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR)); + OSMTurnRelationParser parser = new OSMTurnRelationParser(accessEnc, turnCostEnc, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR)); BaseGraph graph = new BaseGraph.Builder(em.getIntsForFlags()).withTurnCosts(true).create(); - initGraph(graph, encoder); + initGraph(graph, accessEnc, speedEnc); TurnCostParser.ExternalInternalMap map = new TurnCostParser.ExternalInternalMap() { @Override @@ -59,14 +55,14 @@ public long getOsmIdOfInternalEdge(int edgeId) { parser.addRelationToTCStorage(instance, map, graph); TurnCostStorage tcs = graph.getTurnCostStorage(); - assertTrue(Double.isInfinite(tcs.get(tce, 4, 3, 6))); - assertEquals(0, tcs.get(tce, 4, 3, 3), .1); - assertTrue(Double.isInfinite(tcs.get(tce, 4, 3, 2))); + assertTrue(Double.isInfinite(tcs.get(turnCostEnc, 4, 3, 6))); + assertEquals(0, tcs.get(turnCostEnc, 4, 3, 3), .1); + assertTrue(Double.isInfinite(tcs.get(turnCostEnc, 4, 3, 2))); // TYPE == NOT instance = new OSMTurnRelation(4, 3, 3, OSMTurnRelation.Type.NOT); parser.addRelationToTCStorage(instance, map, graph); - assertTrue(Double.isInfinite(tcs.get(tce, 4, 3, 3))); + assertTrue(Double.isInfinite(tcs.get(turnCostEnc, 4, 3, 3))); } // 0---1 @@ -74,9 +70,7 @@ public long getOsmIdOfInternalEdge(int edgeId) { // 2--3--4 // | | | // 5--6--7 - private static void initGraph(BaseGraph graph, FlagEncoder encoder) { - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + private static void initGraph(BaseGraph graph, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(3)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 3).setDistance(1)); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/BlockAreaWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/BlockAreaWeightingTest.java index 410f129e1ba..f9b4cb3b3e4 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/BlockAreaWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/BlockAreaWeightingTest.java @@ -1,11 +1,13 @@ package com.graphhopper.routing.weighting; import com.graphhopper.coll.GHIntHashSet; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.GraphEdgeIdFinder; import com.graphhopper.storage.index.LocationIndex; @@ -23,17 +25,18 @@ public class BlockAreaWeightingTest { - private FlagEncoder encoder = FlagEncoders.createCar(); - private EncodingManager em; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; private BaseGraph graph; @BeforeEach public void setUp() { - encoder = FlagEncoders.createCar(); - em = EncodingManager.create(encoder); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); graph = new BaseGraph.Builder(em).create(); // 0-1 - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(1)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); updateDistancesFor(graph, 0, 0.00, 0.00); updateDistancesFor(graph, 1, 0.01, 0.01); } @@ -42,13 +45,13 @@ public void setUp() { public void testBlockedById() { GraphEdgeIdFinder.BlockArea bArea = new GraphEdgeIdFinder.BlockArea(graph); EdgeIteratorState edge = graph.getEdgeIteratorState(0, 1); - BlockAreaWeighting instance = new BlockAreaWeighting(new FastestWeighting(encoder), bArea); + BlockAreaWeighting instance = new BlockAreaWeighting(new FastestWeighting(accessEnc, speedEnc), bArea); assertEquals(94.35, instance.calcEdgeWeight(edge, false), .01); GHIntHashSet set = new GHIntHashSet(); set.add(0); bArea.add(null, set); - instance = new BlockAreaWeighting(new FastestWeighting(encoder), bArea); + instance = new BlockAreaWeighting(new FastestWeighting(accessEnc, speedEnc), bArea); assertEquals(Double.POSITIVE_INFINITY, instance.calcEdgeWeight(edge, false), .01); } @@ -56,14 +59,14 @@ public void testBlockedById() { public void testBlockedByShape() { EdgeIteratorState edge = graph.getEdgeIteratorState(0, 1); GraphEdgeIdFinder.BlockArea bArea = new GraphEdgeIdFinder.BlockArea(graph); - BlockAreaWeighting instance = new BlockAreaWeighting(new FastestWeighting(encoder), bArea); + BlockAreaWeighting instance = new BlockAreaWeighting(new FastestWeighting(accessEnc, speedEnc), bArea); assertEquals(94.35, instance.calcEdgeWeight(edge, false), 0.01); bArea.add(new Circle(0.01, 0.01, 100)); assertEquals(Double.POSITIVE_INFINITY, instance.calcEdgeWeight(edge, false), .01); bArea = new GraphEdgeIdFinder.BlockArea(graph); - instance = new BlockAreaWeighting(new FastestWeighting(encoder), bArea); + instance = new BlockAreaWeighting(new FastestWeighting(accessEnc, speedEnc), bArea); // Do not match 1,1 of edge bArea.add(new Circle(0.1, 0.1, 100)); assertEquals(94.35, instance.calcEdgeWeight(edge, false), .01); @@ -81,7 +84,7 @@ public void testBlockVirtualEdges_QueryGraph() { Snap snap = index.findClosest(0.005, 0.005, EdgeFilter.ALL_EDGES); QueryGraph queryGraph = QueryGraph.create(graph, snap); - BlockAreaWeighting instance = new BlockAreaWeighting(new FastestWeighting(encoder), bArea); + BlockAreaWeighting instance = new BlockAreaWeighting(new FastestWeighting(accessEnc, speedEnc), bArea); EdgeIterator iter = queryGraph.createEdgeExplorer().setBaseNode(snap.getClosestNode()); int blockedEdges = 0, totalEdges = 0; while (iter.next()) { diff --git a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java index 7d6b1dd024f..a2aeffd187c 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java @@ -21,8 +21,6 @@ import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.VirtualEdgeIteratorState; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.storage.IntsRef; @@ -30,6 +28,8 @@ import com.graphhopper.util.Parameters.Routing; import org.junit.jupiter.api.Test; +import static com.graphhopper.routing.weighting.FastestWeighting.DESTINATION_FACTOR; +import static com.graphhopper.routing.weighting.FastestWeighting.PRIVATE_FACTOR; import java.util.Collections; import static com.graphhopper.util.GHUtility.createMockedEdgeIteratorState; @@ -40,24 +40,24 @@ * @author Peter Karich */ public class FastestWeightingTest { - private final FlagEncoder encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", 10)); - private final EncodingManager encodingManager = EncodingManager.create(encoder); - private final BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - private final DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + private final DecimalEncodedValue turnCostEnc = TurnCost.create("car", 10); + private final EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); @Test public void testMinWeightHasSameUnitAs_getWeight() { - IntsRef flags = GHUtility.setSpeed(140, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags()); - Weighting instance = new FastestWeighting(encoder); + IntsRef flags = GHUtility.setSpeed(140, 0, accessEnc, speedEnc, encodingManager.createEdgeFlags()); + Weighting instance = new FastestWeighting(accessEnc, speedEnc); assertEquals(instance.getMinWeight(10), instance.calcEdgeWeight(createMockedEdgeIteratorState(10, flags), false), 1e-8); } @Test public void testWeightWrongHeading() { - Weighting instance = new FastestWeighting(encoder, new PMap().putObject(Parameters.Routing.HEADING_PENALTY, 100)); + Weighting instance = new FastestWeighting(accessEnc, speedEnc, null, new PMap().putObject(Parameters.Routing.HEADING_PENALTY, 100), TurnCostProvider.NO_TURN_COST_PROVIDER); VirtualEdgeIteratorState virtEdge = new VirtualEdgeIteratorState(0, GHUtility.createEdgeKey(1, false, false), 1, 2, 10, - GHUtility.setSpeed(10, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags()), Collections.singletonMap("name", "test"), Helper.createPointList(51, 0, 51, 1), false); + GHUtility.setSpeed(10, 0, accessEnc, speedEnc, encodingManager.createEdgeFlags()), Collections.singletonMap("name", "test"), Helper.createPointList(51, 0, 51, 1), false); double time = instance.calcEdgeWeight(virtEdge, false); virtEdge.setUnfavored(true); @@ -72,15 +72,15 @@ public void testWeightWrongHeading() { // test default penalty virtEdge.setUnfavored(true); - instance = new FastestWeighting(encoder); + instance = new FastestWeighting(accessEnc, speedEnc); assertEquals(time + Routing.DEFAULT_HEADING_PENALTY, instance.calcEdgeWeight(virtEdge, false), 1e-8); } @Test public void testSpeed0() { - Weighting instance = new FastestWeighting(encoder); + Weighting instance = new FastestWeighting(accessEnc, speedEnc); IntsRef edgeFlags = encodingManager.createEdgeFlags(); - encoder.getAverageSpeedEnc().setDecimal(false, edgeFlags, 0); + speedEnc.setDecimal(false, edgeFlags, 0); assertEquals(1.0 / 0, instance.calcEdgeWeight(createMockedEdgeIteratorState(10, edgeFlags), false), 1e-8); // 0 / 0 returns NaN but calcWeight should not return NaN! @@ -89,28 +89,23 @@ public void testSpeed0() { @Test public void testTime() { - FlagEncoder tmpEnc = FlagEncoders.createBike2(); - EncodingManager em = EncodingManager.create(tmpEnc); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 4, 2, true); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph g = new BaseGraph.Builder(em).create(); - Weighting w = new FastestWeighting(tmpEnc); - - IntsRef edgeFlags = GHUtility.setSpeed(15, 15, tmpEnc.getAccessEnc(), tmpEnc.getAverageSpeedEnc(), em.createEdgeFlags()); - tmpEnc.getAverageSpeedEnc().setDecimal(true, edgeFlags, 10.0); - - EdgeIteratorState edge = GHUtility.createMockedEdgeIteratorState(100000, edgeFlags); - + Weighting w = new FastestWeighting(accessEnc, speedEnc); + EdgeIteratorState edge = g.edge(0, 1).setDistance(100_000); + GHUtility.setSpeed(15, 10, accessEnc, speedEnc, edge); assertEquals(375 * 60 * 1000, w.calcEdgeMillis(edge, false)); assertEquals(600 * 60 * 1000, w.calcEdgeMillis(edge, true)); - - g.close(); } @Test public void calcWeightAndTime_withTurnCosts() { - BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); - Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage())); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(100)); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2).setDistance(100)); + BaseGraph graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage())); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(100)); // turn costs are given in seconds setTurnCost(graph, 0, 1, 2, 5); assertEquals(6 + 5, GHUtility.calcWeightWithTurnWeight(weighting, edge, false, 0), 1.e-6); @@ -119,17 +114,17 @@ public void calcWeightAndTime_withTurnCosts() { @Test public void calcWeightAndTime_uTurnCosts() { - BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); - Weighting weighting = new FastestWeighting(encoder, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage(), 40)); - EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(0, 1).setDistance(100)); + BaseGraph graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage(), 40)); + EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); assertEquals(6 + 40, GHUtility.calcWeightWithTurnWeight(weighting, edge, false, 0), 1.e-6); assertEquals((6 + 40) * 1000, GHUtility.calcMillisWithTurnMillis(weighting, edge, false, 0), 1.e-6); } @Test public void calcWeightAndTime_withTurnCosts_shortest() { - BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); - Weighting weighting = new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage())); + BaseGraph graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); + Weighting weighting = new ShortestWeighting(accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage())); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(100)); EdgeIteratorState edge = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(100)); // turn costs are given in seconds @@ -142,27 +137,29 @@ public void calcWeightAndTime_withTurnCosts_shortest() { @Test public void testDestinationTag() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - FlagEncoder bikeEncoder = FlagEncoders.createBike(); - EncodingManager em = EncodingManager.create(carEncoder, bikeEncoder); + BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + BooleanEncodedValue bikeAccessEnc = new SimpleBooleanEncodedValue("bike_access", true); + DecimalEncodedValue bikeSpeedEnc = new DecimalEncodedValueImpl("bike_speed", 4, 2, false); + EncodingManager em = EncodingManager.start().add(carAccessEnc).add(carSpeedEnc).add(bikeAccessEnc).add(bikeSpeedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); EdgeIteratorState edge = graph.edge(0, 1).setDistance(1000); - for (FlagEncoder encoder : em.fetchEdgeEncoders()) { - edge.set(encoder.getAccessEnc(), true); - edge.setReverse(encoder.getAccessEnc(), true); - } - edge.set(carEncoder.getAverageSpeedEnc(), 60); - edge.set(bikeEncoder.getAverageSpeedEnc(), 18); + edge.set(carAccessEnc, true, true); + edge.set(bikeAccessEnc, true, true); + edge.set(carSpeedEnc, 60); + edge.set(bikeSpeedEnc, 18); EnumEncodedValue roadAccessEnc = em.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class); - FastestWeighting weighting = new FastestWeighting(carEncoder); - FastestWeighting bikeWeighting = new FastestWeighting(bikeEncoder); + FastestWeighting weighting = new FastestWeighting(carAccessEnc, carSpeedEnc, roadAccessEnc, + new PMap().putObject(DESTINATION_FACTOR, 10), TurnCostProvider.NO_TURN_COST_PROVIDER); + FastestWeighting bikeWeighting = new FastestWeighting(bikeAccessEnc, bikeSpeedEnc, roadAccessEnc, + new PMap().putObject(DESTINATION_FACTOR, 1), TurnCostProvider.NO_TURN_COST_PROVIDER); edge.set(roadAccessEnc, RoadAccess.YES); assertEquals(60, weighting.calcEdgeWeight(edge, false), 1.e-6); assertEquals(200, bikeWeighting.calcEdgeWeight(edge, false), 1.e-6); - // the destination tag does not change the weight for bikes! + // the destination tag does not change the weight for the bike weighting edge.set(roadAccessEnc, RoadAccess.DESTINATION); assertEquals(600, weighting.calcEdgeWeight(edge, false), 0.1); assertEquals(200, bikeWeighting.calcEdgeWeight(edge, false), 0.1); @@ -170,21 +167,23 @@ public void testDestinationTag() { @Test public void testPrivateTag() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - FlagEncoder bikeEncoder = FlagEncoders.createBike(); - EncodingManager em = EncodingManager.create(carEncoder, bikeEncoder); + BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + BooleanEncodedValue bikeAccessEnc = new SimpleBooleanEncodedValue("bike_access", true); + DecimalEncodedValue bikeSpeedEnc = new DecimalEncodedValueImpl("bike_speed", 4, 2, false); + EncodingManager em = EncodingManager.start().add(carAccessEnc).add(carSpeedEnc).add(bikeAccessEnc).add(bikeSpeedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); EdgeIteratorState edge = graph.edge(0, 1).setDistance(1000); - for (FlagEncoder encoder : em.fetchEdgeEncoders()) { - edge.set(encoder.getAccessEnc(), true); - edge.setReverse(encoder.getAccessEnc(), true); - } - edge.set(carEncoder.getAverageSpeedEnc(), 60); - edge.set(bikeEncoder.getAverageSpeedEnc(), 18); + edge.set(carAccessEnc, true, true); + edge.set(bikeAccessEnc, true, true); + edge.set(carSpeedEnc, 60); + edge.set(bikeSpeedEnc, 18); EnumEncodedValue roadAccessEnc = em.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class); - FastestWeighting weighting = new FastestWeighting(carEncoder); - FastestWeighting bikeWeighting = new FastestWeighting(bikeEncoder); + FastestWeighting weighting = new FastestWeighting(carAccessEnc, carSpeedEnc, roadAccessEnc, + new PMap().putObject(PRIVATE_FACTOR, 10), TurnCostProvider.NO_TURN_COST_PROVIDER); + FastestWeighting bikeWeighting = new FastestWeighting(bikeAccessEnc, bikeSpeedEnc, roadAccessEnc, + new PMap().putObject(PRIVATE_FACTOR, 1.2), TurnCostProvider.NO_TURN_COST_PROVIDER); ReaderWay way = new ReaderWay(1); way.setTag("highway", "secondary"); @@ -200,7 +199,7 @@ public void testPrivateTag() { } private void setTurnCost(Graph graph, int from, int via, int to, double turnCost) { - graph.getTurnCostStorage().set(((EncodedValueLookup) encodingManager).getDecimalEncodedValue(TurnCost.key(encoder.toString())), getEdge(graph, from, via).getEdge(), via, getEdge(graph, via, to).getEdge(), turnCost); + graph.getTurnCostStorage().set(turnCostEnc, getEdge(graph, from, via).getEdge(), via, getEdge(graph, via, to).getEdge(), turnCost); } } diff --git a/core/src/test/java/com/graphhopper/routing/weighting/ShortFastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/ShortFastestWeightingTest.java index 56cd3d69493..289a9406c1d 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/ShortFastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/ShortFastestWeightingTest.java @@ -17,8 +17,11 @@ */ package com.graphhopper.routing.weighting; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; import com.graphhopper.util.PMap; @@ -26,33 +29,30 @@ import static com.graphhopper.util.GHUtility.createMockedEdgeIteratorState; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * @author Peter Karich */ public class ShortFastestWeightingTest { - EncodingManager encodingManager = EncodingManager.create("car"); - private final FlagEncoder encoder = encodingManager.getEncoder("car"); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + private final EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); @Test public void testShort() { - EdgeIteratorState edge = createMockedEdgeIteratorState(10, GHUtility.setSpeed(50, 0, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), encodingManager.createEdgeFlags())); - Weighting instance = new ShortFastestWeighting(encoder, 0.03); - assertEquals(1.02, instance.calcEdgeWeight(edge, false), 1e-8); + EdgeIteratorState edge = createMockedEdgeIteratorState(10, GHUtility.setSpeed(50, 0, accessEnc, speedEnc, encodingManager.createEdgeFlags())); + Weighting instance = new ShortFastestWeighting(accessEnc, speedEnc, null, new PMap("short_fastest.distance_factor=0.03"), TurnCostProvider.NO_TURN_COST_PROVIDER); + assertEquals(1.02, instance.calcEdgeWeight(edge, false), 1e-6); // more influence from distance - instance = new ShortFastestWeighting(encoder, 0.1); - assertEquals(1.72, instance.calcEdgeWeight(edge, false), 1e-8); + instance = new ShortFastestWeighting(accessEnc, speedEnc, null, new PMap("short_fastest.distance_factor=0.1"), TurnCostProvider.NO_TURN_COST_PROVIDER); + assertEquals(1.72, instance.calcEdgeWeight(edge, false), 1e-6); } @Test public void testTooSmall() { - try { - new ShortFastestWeighting(encoder, new PMap("short_fastest.distance_factor=0|short_fastest.time_factor=0"), - TurnCostProvider.NO_TURN_COST_PROVIDER); - fail(); - } catch (Exception ex) { - } + assertThrows(Exception.class, () -> new ShortFastestWeighting(accessEnc, speedEnc, null, new PMap("short_fastest.distance_factor=0|short_fastest.time_factor=0"), + TurnCostProvider.NO_TURN_COST_PROVIDER)); } } diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java index 8b6117b7a22..352d250ea3b 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java @@ -20,8 +20,6 @@ import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.BaseGraph; import com.graphhopper.util.CustomModel; import com.graphhopper.util.EdgeIteratorState; @@ -44,23 +42,22 @@ import static org.junit.jupiter.api.Assertions.*; class CustomModelParserTest { - - FlagEncoder encoder; BaseGraph graph; EncodingManager encodingManager; EnumEncodedValue roadClassEnc; + BooleanEncodedValue accessEnc; DecimalEncodedValue avgSpeedEnc; StringEncodedValue countryEnc; double maxSpeed; @BeforeEach void setup() { - encoder = FlagEncoders.createCar(); + accessEnc = VehicleAccess.create("car"); + avgSpeedEnc = VehicleSpeed.create("car", 5, 5, false); countryEnc = new StringEncodedValue("country", 10); - encodingManager = new EncodingManager.Builder().add(encoder).add(countryEnc). - add(MaxSpeed.create()).add(new EnumEncodedValue<>(Surface.KEY, Surface.class)).build(); + encodingManager = new EncodingManager.Builder().add(accessEnc).add(avgSpeedEnc) + .add(countryEnc).add(MaxSpeed.create()).add(new EnumEncodedValue<>(Surface.KEY, Surface.class)).build(); graph = new BaseGraph.Builder(encodingManager).create(); - avgSpeedEnc = encoder.getAverageSpeedEnc(); roadClassEnc = encodingManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); maxSpeed = 140; } @@ -83,11 +80,11 @@ void setPriorityForRoadClass() { @Test void testPriority() { EdgeIteratorState primary = graph.edge(0, 1).setDistance(10). - set(roadClassEnc, PRIMARY).set(avgSpeedEnc, 80).set(encoder.getAccessEnc(), true, true); + set(roadClassEnc, PRIMARY).set(avgSpeedEnc, 80).set(accessEnc, true, true); EdgeIteratorState secondary = graph.edge(1, 2).setDistance(10). - set(roadClassEnc, SECONDARY).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); + set(roadClassEnc, SECONDARY).set(avgSpeedEnc, 70).set(accessEnc, true, true); EdgeIteratorState tertiary = graph.edge(1, 2).setDistance(10). - set(roadClassEnc, TERTIARY).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); + set(roadClassEnc, TERTIARY).set(avgSpeedEnc, 70).set(accessEnc, true, true); CustomModel customModel = new CustomModel(); customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.5")); @@ -114,9 +111,9 @@ void testPriority() { @Test public void testBrackets() { - EdgeIteratorState primary = graph.edge(0, 1).setDistance(10).set(encoder.getAccessEnc(), true, true). + EdgeIteratorState primary = graph.edge(0, 1).setDistance(10).set(accessEnc, true, true). set(roadClassEnc, PRIMARY).set(avgSpeedEnc, 80); - EdgeIteratorState secondary = graph.edge(0, 1).setDistance(10).set(encoder.getAccessEnc(), true, true). + EdgeIteratorState secondary = graph.edge(0, 1).setDistance(10).set(accessEnc, true, true). set(roadClassEnc, SECONDARY).set(avgSpeedEnc, 40); CustomModel customModel = new CustomModel(); @@ -130,9 +127,9 @@ public void testBrackets() { @Test public void testSpeedFactorAndPriorityAndMaxSpeed() { EdgeIteratorState primary = graph.edge(0, 1).setDistance(10). - set(roadClassEnc, PRIMARY).set(avgSpeedEnc, 80).set(encoder.getAccessEnc(), true, true); + set(roadClassEnc, PRIMARY).set(avgSpeedEnc, 80).set(accessEnc, true, true); EdgeIteratorState secondary = graph.edge(1, 2).setDistance(10). - set(roadClassEnc, SECONDARY).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); + set(roadClassEnc, SECONDARY).set(avgSpeedEnc, 70).set(accessEnc, true, true); CustomModel customModel = new CustomModel(); customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.9")); @@ -155,9 +152,9 @@ public void testSpeedFactorAndPriorityAndMaxSpeed() { @Test public void testString() { EdgeIteratorState deu = graph.edge(0, 1).setDistance(10). - set(countryEnc, "DEU").set(avgSpeedEnc, 80).set(encoder.getAccessEnc(), true, true); + set(countryEnc, "DEU").set(avgSpeedEnc, 80).set(accessEnc, true, true); EdgeIteratorState blup = graph.edge(1, 2).setDistance(10). - set(countryEnc, "blup").set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); + set(countryEnc, "blup").set(avgSpeedEnc, 70).set(accessEnc, true, true); CustomModel customModel = new CustomModel(); customModel.addToPriority(If("country == \"DEU\"", MULTIPLY, "0.9")); @@ -240,9 +237,9 @@ public void multipleAreas() { public void parseValue() { DecimalEncodedValue maxSpeedEnc = encodingManager.getDecimalEncodedValue(MaxSpeed.KEY); EdgeIteratorState maxLower = graph.edge(0, 1).setDistance(10). - set(maxSpeedEnc, 60).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); + set(maxSpeedEnc, 60).set(avgSpeedEnc, 70).set(accessEnc, true, true); EdgeIteratorState maxSame = graph.edge(1, 2).setDistance(10). - set(maxSpeedEnc, 70).set(avgSpeedEnc, 70).set(encoder.getAccessEnc(), true, true); + set(maxSpeedEnc, 70).set(avgSpeedEnc, 70).set(accessEnc, true, true); CustomModel customModel = new CustomModel(); customModel.addToSpeed(If("true", LIMIT, "max_speed * 1.1")); diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index 8ed89caa3c9..ccc987fa140 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -5,12 +5,13 @@ import com.graphhopper.json.Statement; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.BaseGraph; -import com.graphhopper.util.*; +import com.graphhopper.util.CustomModel; +import com.graphhopper.util.EdgeIteratorState; +import com.graphhopper.util.GHUtility; +import com.graphhopper.util.JsonFeature; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -28,18 +29,16 @@ class CustomWeightingTest { DecimalEncodedValue maxSpeedEnc; EnumEncodedValue roadClassEnc; EncodingManager encodingManager; - FlagEncoder carFE; @BeforeEach public void setup() { - carFE = FlagEncoders.createCar(new PMap().putObject("speed_two_directions", true)); - encodingManager = new EncodingManager.Builder().add(carFE) + accessEnc = VehicleAccess.create("car"); + avSpeedEnc = VehicleSpeed.create("car", 5, 5, true); + encodingManager = new EncodingManager.Builder().add(accessEnc).add(avSpeedEnc) .add(new EnumEncodedValue<>(Toll.KEY, Toll.class)) .add(new EnumEncodedValue<>(Hazmat.KEY, Hazmat.class)) .add(new EnumEncodedValue<>(BikeNetwork.KEY, RouteNetwork.class)) .build(); - avSpeedEnc = carFE.getAverageSpeedEnc(); - accessEnc = carFE.getAccessEnc(); maxSpeedEnc = encodingManager.getDecimalEncodedValue(MaxSpeed.KEY); roadClassEnc = encodingManager.getEnumEncodedValue(KEY, RoadClass.class); graph = new BaseGraph.Builder(encodingManager).create(); @@ -65,9 +64,9 @@ public void withPriority() { set(roadClassEnc, SECONDARY); // without priority costs fastest weighting is the same as custom weighting - assertEquals(144, new FastestWeighting(carFE, NO_TURN_COST_PROVIDER).calcEdgeWeight(slow, false), .1); - assertEquals(72, new FastestWeighting(carFE, NO_TURN_COST_PROVIDER).calcEdgeWeight(medium, false), .1); - assertEquals(36, new FastestWeighting(carFE, NO_TURN_COST_PROVIDER).calcEdgeWeight(fast, false), .1); + assertEquals(144, new FastestWeighting(accessEnc, avSpeedEnc, NO_TURN_COST_PROVIDER).calcEdgeWeight(slow, false), .1); + assertEquals(72, new FastestWeighting(accessEnc, avSpeedEnc, NO_TURN_COST_PROVIDER).calcEdgeWeight(medium, false), .1); + assertEquals(36, new FastestWeighting(accessEnc, avSpeedEnc, NO_TURN_COST_PROVIDER).calcEdgeWeight(fast, false), .1); CustomModel model = new CustomModel().setDistanceInfluence(0); assertEquals(144, createWeighting(model).calcEdgeWeight(slow, false), .1); @@ -117,19 +116,21 @@ public void testSpeedFactorBooleanEV() { @Test public void testBoolean() { - carFE = FlagEncoders.createCar(); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue avSpeedEnc = VehicleSpeed.create("car", 5, 5, false); BooleanEncodedValue specialEnc = new SimpleBooleanEncodedValue("special", true); - encodingManager = new EncodingManager.Builder().add(carFE).add(specialEnc).build(); + encodingManager = new EncodingManager.Builder().add(accessEnc).add(avSpeedEnc).add(specialEnc).build(); graph = new BaseGraph.Builder(encodingManager).create(); EdgeIteratorState edge = graph.edge(0, 1).set(accessEnc, true).setReverse(accessEnc, true). set(avSpeedEnc, 15).set(specialEnc, false).setReverse(specialEnc, true).setDistance(10); CustomModel vehicleModel = new CustomModel(); - assertEquals(3.1, createWeighting(vehicleModel).calcEdgeWeight(edge, false), 0.01); + Weighting weighting = CustomModelParser.createWeighting(accessEnc, avSpeedEnc, null, encodingManager, NO_TURN_COST_PROVIDER, vehicleModel); + assertEquals(3.1, weighting.calcEdgeWeight(edge, false), 0.01); vehicleModel.addToPriority(If("special == true", MULTIPLY, "0.8")); vehicleModel.addToPriority(If("special == false", MULTIPLY, "0.4")); - Weighting weighting = createWeighting(vehicleModel); + weighting = CustomModelParser.createWeighting(accessEnc, avSpeedEnc, null, encodingManager, NO_TURN_COST_PROVIDER, vehicleModel); assertEquals(6.7, weighting.calcEdgeWeight(edge, false), 0.01); assertEquals(3.7, weighting.calcEdgeWeight(edge, true), 0.01); } @@ -259,6 +260,7 @@ public void testMaxSpeed() { @Test public void testMaxPriority() { + assertEquals(155, avSpeedEnc.getMaxOrMaxStorableDecimal(), 0.1); double maxSpeed = 155; assertEquals(1000.0 / maxSpeed / 0.5 * 3.6, createWeighting(new CustomModel(). addToPriority(If("true", MULTIPLY, "0.5")).setDistanceInfluence(0)).getMinWeight(1000), 1.e-6); @@ -306,6 +308,6 @@ public void maxSpeedViolated_bug_2307() { } private Weighting createWeighting(CustomModel vehicleModel) { - return CustomModelParser.createWeighting(carFE, encodingManager, NO_TURN_COST_PROVIDER, vehicleModel); + return CustomModelParser.createWeighting(accessEnc, avSpeedEnc, null, encodingManager, NO_TURN_COST_PROVIDER, vehicleModel); } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java index e476f8da013..1135327a05d 100644 --- a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java +++ b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java @@ -19,7 +19,11 @@ import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; +import com.graphhopper.routing.util.AccessFilter; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; import org.junit.jupiter.api.AfterEach; @@ -29,7 +33,6 @@ import java.io.File; import java.util.Collections; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static org.junit.jupiter.api.Assertions.*; /** @@ -43,15 +46,22 @@ public abstract class AbstractGraphStorageTester { private final String locationParent = "./target/graphstorage"; protected int defaultSize = 100; protected String defaultGraphLoc = "./target/graphstorage/default"; - protected FlagEncoder carEncoder = createCarFlagEncoder(); - protected EncodingManager encodingManager = new EncodingManager.Builder().add(carEncoder).add(FlagEncoders.createFoot()).build(); - protected BooleanEncodedValue carAccessEnc = carEncoder.getAccessEnc(); - protected DecimalEncodedValue carAvSpeedEnc = carEncoder.getAverageSpeedEnc(); - protected FlagEncoder footEncoder = encodingManager.getEncoder("foot"); - protected BooleanEncodedValue footAccessEnc = footEncoder.getAccessEnc(); + protected BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + protected DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + protected BooleanEncodedValue footAccessEnc = new SimpleBooleanEncodedValue("foot_access", true); + protected DecimalEncodedValue footSpeedEnc = new DecimalEncodedValueImpl("foot_speed", 4, 1, true); + protected EncodingManager encodingManager = createEncodingManager(); + + protected EncodingManager createEncodingManager() { + return new EncodingManager.Builder() + .add(carAccessEnc).add(carSpeedEnc) + .add(footAccessEnc).add(footSpeedEnc) + .build(); + } + protected BaseGraph graph; - EdgeFilter carOutFilter = AccessFilter.outEdges(carEncoder.getAccessEnc()); - EdgeFilter carInFilter = AccessFilter.inEdges(carEncoder.getAccessEnc()); + EdgeFilter carOutFilter = AccessFilter.outEdges(carAccessEnc); + EdgeFilter carInFilter = AccessFilter.inEdges(carAccessEnc); EdgeExplorer carOutExplorer; EdgeExplorer carInExplorer; EdgeExplorer carAllExplorer; @@ -86,10 +96,6 @@ public static int getIdOf(Graph g, double latitude, double longitude) { throw new IllegalArgumentException("did not find node with location " + (float) latitude + "," + (float) longitude); } - FlagEncoder createCarFlagEncoder() { - return FlagEncoders.createCar(); - } - protected BaseGraph createGHStorage() { BaseGraph g = createGHStorage(defaultGraphLoc, false); carOutExplorer = g.createEdgeExplorer(carOutFilter); @@ -431,19 +437,19 @@ public void testBounds() { public void testFlags() { graph = createGHStorage(); graph.edge(0, 1).set(carAccessEnc, true, true).setDistance(10) - .set(carAvSpeedEnc, 100); + .set(carSpeedEnc, 100); graph.edge(2, 3).set(carAccessEnc, true, false).setDistance(10) - .set(carAvSpeedEnc, 10); + .set(carSpeedEnc, 10); EdgeIterator iter = carAllExplorer.setBaseNode(0); assertTrue(iter.next()); - assertEquals(100, iter.get(carAvSpeedEnc), 1); + assertEquals(100, iter.get(carSpeedEnc), 1); assertTrue(iter.get(carAccessEnc)); assertTrue(iter.getReverse(carAccessEnc)); iter = carAllExplorer.setBaseNode(2); assertTrue(iter.next()); - assertEquals(10, iter.get(carAvSpeedEnc), 1); + assertEquals(10, iter.get(carSpeedEnc), 1); assertTrue(iter.get(carAccessEnc)); assertFalse(iter.getReverse(carAccessEnc)); @@ -612,7 +618,7 @@ public void testFootMix() { EdgeIteratorState edge = graph.edge(0, 3).setDistance(10); edge.set(footAccessEnc, true, true); edge.set(carAccessEnc, true, true); - EdgeExplorer footOutExplorer = graph.createEdgeExplorer(AccessFilter.outEdges(footEncoder.getAccessEnc())); + EdgeExplorer footOutExplorer = graph.createEdgeExplorer(AccessFilter.outEdges(footAccessEnc)); assertEquals(GHUtility.asSet(3, 1), GHUtility.getNeighbors(footOutExplorer.setBaseNode(0))); assertEquals(GHUtility.asSet(3, 2), GHUtility.getNeighbors(carOutExplorer.setBaseNode(0))); } @@ -659,9 +665,15 @@ public void testEdgeKVStorage() { @Test public void test8AndMoreBytesForEdgeFlags() { - FlagEncoder car0 = FlagEncoders.createCar(new PMap("name=car0|speed_bits=29|speed_factor=0.001")); - FlagEncoder car = FlagEncoders.createCar(new PMap("speed_bits=29|speed_factor=0.001")); - EncodingManager manager = EncodingManager.create(car0, car); + BooleanEncodedValue access0Enc = new SimpleBooleanEncodedValue("car0_access", true); + DecimalEncodedValue speed0Enc = new DecimalEncodedValueImpl("car0_speed", 29, 0.001, false); + BooleanEncodedValue access1Enc = new SimpleBooleanEncodedValue("car1_access", true); + DecimalEncodedValue speed1Enc = new DecimalEncodedValueImpl("car1_speed", 29, 0.001, false); + + EncodingManager manager = EncodingManager.start() + .add(access0Enc).add(speed0Enc) + .add(access1Enc).add(speed1Enc) + .build(); graph = new BaseGraph.Builder(manager).create(); EdgeIteratorState edge = graph.edge(0, 1); @@ -674,33 +686,29 @@ public void test8AndMoreBytesForEdgeFlags() { graph = new BaseGraph.Builder(manager).create(); - DecimalEncodedValue avSpeed0Enc = manager.getDecimalEncodedValue(getKey("car0", "average_speed")); - BooleanEncodedValue access0Enc = manager.getBooleanEncodedValue(getKey("car0", "access")); - DecimalEncodedValue avSpeed1Enc = manager.getDecimalEncodedValue(getKey("car", "average_speed")); - BooleanEncodedValue access1Enc = manager.getBooleanEncodedValue(getKey("car", "access")); edge = graph.edge(0, 1); - GHUtility.setSpeed(99.123, true, true, access0Enc, avSpeed0Enc, edge); - assertEquals(99.123, edge.get(avSpeed0Enc), 1e-3); + GHUtility.setSpeed(99.123, true, true, access0Enc, speed0Enc, edge); + assertEquals(99.123, edge.get(speed0Enc), 1e-3); EdgeIteratorState edgeIter = GHUtility.getEdge(graph, 1, 0); - assertEquals(99.123, edgeIter.get(avSpeed0Enc), 1e-3); + assertEquals(99.123, edgeIter.get(speed0Enc), 1e-3); assertTrue(edgeIter.get(access0Enc)); assertTrue(edgeIter.getReverse(access0Enc)); edge = graph.edge(2, 3); - GHUtility.setSpeed(44.123, true, false, access1Enc, avSpeed1Enc, edge); - assertEquals(44.123, edge.get(avSpeed1Enc), 1e-3); + GHUtility.setSpeed(44.123, true, false, access1Enc, speed1Enc, edge); + assertEquals(44.123, edge.get(speed1Enc), 1e-3); edgeIter = GHUtility.getEdge(graph, 3, 2); - assertEquals(44.123, edgeIter.get(avSpeed1Enc), 1e-3); - assertEquals(44.123, edgeIter.getReverse(avSpeed1Enc), 1e-3); + assertEquals(44.123, edgeIter.get(speed1Enc), 1e-3); + assertEquals(44.123, edgeIter.getReverse(speed1Enc), 1e-3); assertFalse(edgeIter.get(access1Enc)); assertTrue(edgeIter.getReverse(access1Enc)); - manager = EncodingManager.create( - FlagEncoders.createCar(new PMap("name=car0|speed_bits=29|speed_factor=0.001")), - FlagEncoders.createCar(new PMap("speed_bits=29|speed_factor=0.001")), - FlagEncoders.createCar(new PMap("name=car2|speed_bits=30|speed_factor=0.001")) - ); + manager = EncodingManager.start() + .add(new SimpleBooleanEncodedValue("car0_access", true)).add(new DecimalEncodedValueImpl("car0_speed", 29, 0.001, false)) + .add(new SimpleBooleanEncodedValue("car1_access", true)).add(new DecimalEncodedValueImpl("car1_speed", 29, 0.001, false)) + .add(new SimpleBooleanEncodedValue("car2_access", true)).add(new DecimalEncodedValueImpl("car2_speed", 30, 0.001, false)) + .build(); graph = new BaseGraph.Builder(manager).create(); edgeIter = graph.edge(0, 1).set(access0Enc, true, false); assertTrue(edgeIter.get(access0Enc)); diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java index 8bbdd257292..16e99b61dee 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java @@ -81,7 +81,7 @@ public void testSave_and_fileFormat() { assertEquals("named street1", graph.getEdgeIteratorState(iter1.getEdge(), iter1.getAdjNode()).getName()); assertEquals("named street2", graph.getEdgeIteratorState(iter2.getEdge(), iter2.getAdjNode()).getName()); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 4).setDistance(123)). + GHUtility.setSpeed(60, true, true, carAccessEnc, carSpeedEnc, graph.edge(3, 4).setDistance(123)). setWayGeometry(Helper.createPointList3D(4.4, 5.5, 0, 6.6, 7.7, 0)); checkGraph(graph); } @@ -202,9 +202,9 @@ public void testDecoupledEdgeIteratorStates() { Graph graph = storage.getBaseGraph(); IntsRef ref = encodingManager.createEdgeFlags(); ref.ints[0] = 12; - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(10)).setFlags(ref); + GHUtility.setSpeed(60, true, true, carAccessEnc, carSpeedEnc, graph.edge(1, 2).setDistance(10)).setFlags(ref); ref.ints[0] = 13; - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 3).setDistance(10)).setFlags(ref); + GHUtility.setSpeed(60, true, true, carAccessEnc, carSpeedEnc, graph.edge(1, 3).setDistance(10)).setFlags(ref); EdgeIterator iter = graph.createEdgeExplorer().setBaseNode(1); assertTrue(iter.next()); @@ -221,7 +221,7 @@ public void testDecoupledEdgeIteratorStates() { @Test public void testEdgeKey() { BaseGraph g = new BaseGraph.Builder(encodingManager).create(); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(0, 1).setDistance(10)); + GHUtility.setSpeed(60, true, true, carAccessEnc, carSpeedEnc, g.edge(0, 1).setDistance(10)); // storage direction assertEdge(g.getEdgeIteratorState(0, Integer.MIN_VALUE), 0, 1, false, 0, 0); // reverse direction @@ -235,7 +235,7 @@ public void testEdgeKey() { @Test public void testEdgeKey_loop() { BaseGraph g = new BaseGraph.Builder(encodingManager).create(); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(0, 0).setDistance(10)); + GHUtility.setSpeed(60, true, true, carAccessEnc, carSpeedEnc, g.edge(0, 0).setDistance(10)); // storage direction assertEdge(g.getEdgeIteratorState(0, Integer.MIN_VALUE), 0, 0, false, 0, 0); // reverse direction cannot be retrieved, we get forward direction anyway diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java index b2e7d27cb2c..eb3a5136ca5 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java @@ -17,13 +17,11 @@ */ package com.graphhopper.storage; -import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.TurnCost; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; +import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.Helper; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; import java.util.Collections; @@ -36,9 +34,16 @@ * @author Karl Hübner */ public class BaseGraphWithTurnCostsTest extends BaseGraphTest { + + private DecimalEncodedValue turnCostEnc; + @Override - FlagEncoder createCarFlagEncoder() { - return FlagEncoders.createCar(new PMap().putObject("max_turn_costs", 1400)); + protected EncodingManager createEncodingManager() { + turnCostEnc = TurnCost.create("car", 1400); + return EncodingManager.start() + .add(carAccessEnc).add(carSpeedEnc).addTurnCostEncodedValue(turnCostEnc) + .add(footAccessEnc).add(footSpeedEnc) + .build(); } @Override @@ -157,10 +162,10 @@ public void testInitializeTurnCost() { } private double getTurnCost(EdgeIteratorState fromEdge, int viaNode, EdgeIteratorState toEdge) { - return graph.getTurnCostStorage().get(((EncodedValueLookup) encodingManager).getDecimalEncodedValue(TurnCost.key("car")), toEdge.getEdge(), viaNode, fromEdge.getEdge()); + return graph.getTurnCostStorage().get(turnCostEnc, toEdge.getEdge(), viaNode, fromEdge.getEdge()); } private void setTurnCost(int fromEdge, int viaNode, int toEdge, int cost) { - graph.getTurnCostStorage().set(((EncodedValueLookup) encodingManager).getDecimalEncodedValue(TurnCost.key("car")), fromEdge, viaNode, toEdge, cost); + graph.getTurnCostStorage().set(turnCostEnc, fromEdge, viaNode, toEdge, cost); } } diff --git a/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java b/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java index 116a2474e9b..c608b529dea 100644 --- a/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java +++ b/core/src/test/java/com/graphhopper/storage/GraphEdgeIdFinderTest.java @@ -19,7 +19,11 @@ import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; +import com.graphhopper.routing.util.AccessFilter; +import com.graphhopper.routing.util.AllEdgesIterator; +import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.LocationIndexTree; import com.graphhopper.util.GHUtility; @@ -39,14 +43,13 @@ public class GraphEdgeIdFinderTest { @Test public void testParseStringHints() { - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); // 0-1-2 // | | // 3-4 - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(3, 4).setDistance(1)); @@ -73,8 +76,9 @@ public void testParseStringHints() { @Test public void testBlockAreasWithPolygon() { - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).create(); // 00-01-02-03 @@ -82,8 +86,6 @@ public void testBlockAreasWithPolygon() { // 04-05-06-07 // | | // 08-09-10-11 - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1).setDistance(1)); // 0 GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2).setDistance(1)); // 1 GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(2, 3).setDistance(1)); // 2 diff --git a/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java b/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java index 6add1ee811c..8653aa956f8 100644 --- a/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java +++ b/core/src/test/java/com/graphhopper/storage/ShortcutUnpackerTest.java @@ -4,17 +4,13 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ch.PrepareEncoder; import com.graphhopper.routing.ch.ShortcutUnpacker; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.TurnCostProvider; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -34,16 +30,20 @@ public class ShortcutUnpackerTest { private static final class Fixture { private final boolean edgeBased; private final EncodingManager encodingManager; - private final FlagEncoder encoder; + private final BooleanEncodedValue accessEnc; + private final DecimalEncodedValue speedEnc; + private final DecimalEncodedValue turnCostEnc; private final BaseGraph graph; private CHStorageBuilder chBuilder; private RoutingCHGraph routingCHGraph; Fixture(boolean edgeBased) { this.edgeBased = edgeBased; - encoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", 10).putObject("speed_two_directions", true)); - encodingManager = EncodingManager.create(encoder); - graph = new BaseGraph.Builder(encodingManager).create(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, true); + turnCostEnc = TurnCost.create("car", 10); + encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).addTurnCostEncodedValue(turnCostEnc).build(); + graph = new BaseGraph.Builder(encodingManager).withTurnCosts(true).create(); } @Override @@ -53,8 +53,8 @@ public String toString() { private void freeze() { graph.freeze(); - TurnCostProvider turnCostProvider = edgeBased ? new DefaultTurnCostProvider(encoder.getTurnCostEnc(), graph.getTurnCostStorage()) : NO_TURN_COST_PROVIDER; - CHConfig chConfig = new CHConfig("profile", new FastestWeighting(encoder, turnCostProvider), edgeBased); + TurnCostProvider turnCostProvider = edgeBased ? new DefaultTurnCostProvider(turnCostEnc, graph.getTurnCostStorage()) : NO_TURN_COST_PROVIDER; + CHConfig chConfig = new CHConfig("profile", new FastestWeighting(accessEnc, speedEnc, turnCostProvider), edgeBased); CHStorage chStore = CHStorage.fromGraph(graph, chConfig); chBuilder = new CHStorageBuilder(chStore); routingCHGraph = RoutingCHGraphImpl.fromGraph(graph, chStore, chConfig); @@ -79,7 +79,7 @@ private ShortcutUnpacker createShortcutUnpacker(ShortcutUnpacker.Visitor visitor } private void setTurnCost(int fromEdge, int viaNode, int toEdge, double cost) { - graph.getTurnCostStorage().set(((EncodedValueLookup) encodingManager).getDecimalEncodedValue(TurnCost.key(encoder.toString())), fromEdge, viaNode, toEdge, cost); + graph.getTurnCostStorage().set(turnCostEnc, fromEdge, viaNode, toEdge, cost); } private void shortcut(int baseNode, int adjNode, int skip1, int skip2, int origKeyFirst, int origKeyLast, boolean reverse) { @@ -108,7 +108,7 @@ public Stream provideArguments(ExtensionContext context) { @ArgumentsSource(FixtureProvider.class) public void testUnpacking(Fixture f) { // 0-1-2-3-4-5-6 - GHUtility.setSpeed(60, 30, f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 30, f.accessEnc, f.speedEnc, f.graph.edge(0, 1).setDistance(1), f.graph.edge(1, 2).setDistance(1), f.graph.edge(2, 3).setDistance(1), @@ -197,7 +197,7 @@ public void loopShortcut(Fixture f) { // 2 4 // \ / // 0 - 1 - 5 - GHUtility.setSpeed(60, 30, f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 30, f.accessEnc, f.speedEnc, f.graph.edge(0, 1).setDistance(1), f.graph.edge(1, 2).setDistance(1), f.graph.edge(2, 3).setDistance(1), @@ -274,7 +274,7 @@ public void withTurnWeighting(Fixture f) { // prev 0-1-2-3-4-5-6 next // 1 0 1 4 2 3 2 turn costs <- EdgeIteratorState edge0, edge1, edge2, edge3, edge4, edge5; - GHUtility.setSpeed(60, 30, f.encoder.getAccessEnc(), f.encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 30, f.accessEnc, f.speedEnc, edge0 = f.graph.edge(0, 1).setDistance(1), edge1 = f.graph.edge(1, 2).setDistance(1), edge2 = f.graph.edge(2, 3).setDistance(1), diff --git a/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java b/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java index 8570ec03808..6da4ff09932 100644 --- a/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java +++ b/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java @@ -18,13 +18,9 @@ package com.graphhopper.storage; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.util.GHUtility; -import com.graphhopper.util.PMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -40,12 +36,20 @@ public class TurnCostStorageTest { private EncodingManager manager; + private DecimalEncodedValue carTurnCostEnc; + private DecimalEncodedValue bikeTurnCostEnc; + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; @BeforeEach public void setup() { - FlagEncoder carEncoder = FlagEncoders.createCar(new PMap().putObject("max_turn_costs", 3)); - FlagEncoder bikeEncoder = FlagEncoders.createBike(new PMap().putObject("max_turn_costs", 3)); - manager = EncodingManager.create(carEncoder, bikeEncoder); + accessEnc = new SimpleBooleanEncodedValue("car_access", true); + speedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + carTurnCostEnc = TurnCost.create("car", 3); + bikeTurnCostEnc = TurnCost.create("bike", 3); + manager = EncodingManager.start() + .add(accessEnc).add(speedEnc) + .addTurnCostEncodedValue(carTurnCostEnc).addTurnCostEncodedValue(bikeTurnCostEnc).build(); } // 0---1 @@ -53,8 +57,8 @@ public void setup() { // 2--3 // | // 4 - public static void initGraph(BaseGraph g, FlagEncoder encoder) { - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + public static void initGraph(BaseGraph g, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, g.edge(0, 1).setDistance(3), g.edge(0, 2).setDistance(1), g.edge(1, 3).setDistance(1), @@ -67,12 +71,12 @@ public static void initGraph(BaseGraph g, FlagEncoder encoder) { */ @Test public void testMultipleTurnCosts() { - BaseGraph g = new BaseGraph.Builder(manager).create(); - initGraph(g, manager.getEncoder("car")); + BaseGraph g = new BaseGraph.Builder(manager).withTurnCosts(true).create(); + initGraph(g, accessEnc, speedEnc); TurnCostStorage turnCostStorage = g.getTurnCostStorage(); - DecimalEncodedValue carEnc = manager.getDecimalEncodedValue(TurnCost.key("car")); - DecimalEncodedValue bikeEnc = manager.getDecimalEncodedValue(TurnCost.key("bike")); + DecimalEncodedValue carEnc = carTurnCostEnc; + DecimalEncodedValue bikeEnc = bikeTurnCostEnc; int edge42 = getEdge(g, 4, 2).getEdge(); int edge23 = getEdge(g, 2, 3).getEdge(); int edge31 = getEdge(g, 3, 1).getEdge(); @@ -124,12 +128,12 @@ public void testMultipleTurnCosts() { @Test public void testMergeFlagsBeforeAdding() { - BaseGraph g = new BaseGraph.Builder(manager).create(); - initGraph(g, manager.getEncoder("car")); + BaseGraph g = new BaseGraph.Builder(manager).withTurnCosts(true).create(); + initGraph(g, accessEnc, speedEnc); TurnCostStorage turnCostStorage = g.getTurnCostStorage(); - DecimalEncodedValue carEnc = manager.getDecimalEncodedValue(TurnCost.key("car")); - DecimalEncodedValue bikeEnc = manager.getDecimalEncodedValue(TurnCost.key("bike")); + DecimalEncodedValue carEnc = carTurnCostEnc; + DecimalEncodedValue bikeEnc = bikeTurnCostEnc; int edge23 = getEdge(g, 2, 3).getEdge(); int edge02 = getEdge(g, 0, 2).getEdge(); @@ -153,8 +157,8 @@ public void testMergeFlagsBeforeAdding() { @Test public void testIterateEmptyStore() { - BaseGraph g = new BaseGraph.Builder(manager).create(); - initGraph(g, manager.getEncoder("car")); + BaseGraph g = new BaseGraph.Builder(manager).withTurnCosts(true).create(); + initGraph(g, accessEnc, speedEnc); TurnCostStorage turnCostStorage = g.getTurnCostStorage(); TurnCostStorage.TurnRelationIterator iterator = turnCostStorage.getAllTurnRelations(); diff --git a/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java b/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java index 6d1d0de9675..a7723b48960 100644 --- a/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java +++ b/core/src/test/java/com/graphhopper/storage/index/LocationIndexTreeTest.java @@ -20,7 +20,12 @@ import com.carrotsearch.hppc.IntArrayList; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; +import com.graphhopper.routing.util.AccessFilter; +import com.graphhopper.routing.util.AllEdgesIterator; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.*; import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; @@ -38,7 +43,9 @@ * @author Peter Karich */ public class LocationIndexTreeTest { - protected final EncodingManager encodingManager = EncodingManager.create("car"); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + protected final EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); public static void initSimpleGraph(Graph g) { // 6 | 4 @@ -84,8 +91,7 @@ private LocationIndexTree createIndexNoPrepare(Graph g, int resolution) { // |1----3-\| // |____/ 4 // 2-------/ - Graph createTestGraph(EncodingManager em) { - FlagEncoder encoder = em.getEncoder("car"); + Graph createTestGraph(EncodingManager em, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { BaseGraph graph = new BaseGraph.Builder(em).create(); NodeAccess na = graph.getNodeAccess(); na.setNode(0, 0.5, -0.5); @@ -93,8 +99,6 @@ Graph createTestGraph(EncodingManager em) { na.setNode(2, -1, -1); na.setNode(3, -0.4, 0.9); na.setNode(4, -0.6, 1.6); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 4)); @@ -107,7 +111,7 @@ Graph createTestGraph(EncodingManager em) { @Test public void testSnappedPointAndGeometry() { - Graph graph = createTestGraph(encodingManager); + Graph graph = createTestGraph(encodingManager, accessEnc, speedEnc); LocationIndex index = createIndexNoPrepare(graph, 500000).prepareIndex(); // query directly the tower node Snap res = index.findClosest(-0.4, 0.9, EdgeFilter.ALL_EDGES); @@ -147,16 +151,13 @@ public void testBoundingBoxQuery1() { @Test public void testMoreReal() { - FlagEncoder encoder = FlagEncoders.createCar(); - BaseGraph graph = new BaseGraph.Builder(EncodingManager.create(encoder)).create(); + BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); NodeAccess na = graph.getNodeAccess(); na.setNode(1, 51.2492152, 9.4317166); na.setNode(0, 52, 9); na.setNode(2, 51.2, 9.4); na.setNode(3, 49, 10); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 0)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 3)).setWayGeometry(Helper.createPointList(51.21, 9.43)); @@ -175,15 +176,12 @@ public void testMoreReal() { // | private Graph createTestGraphWithWayGeometry() { BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); - FlagEncoder encoder = encodingManager.getEncoder("car"); NodeAccess na = graph.getNodeAccess(); na.setNode(0, 0.5, -0.5); na.setNode(1, -0.5, -0.5); na.setNode(2, -1, -1); na.setNode(3, -0.4, 0.9); na.setNode(4, -0.6, 1.6); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(0, 2)); // insert A and B, without this we would get 0 for 0,0 @@ -208,15 +206,14 @@ public void testWayGeometry() { @Test public void testFindingWayGeometry() { BaseGraph g = new BaseGraph.Builder(encodingManager).create(); - FlagEncoder encoder = encodingManager.getEncoder("car"); NodeAccess na = g.getNodeAccess(); na.setNode(10, 51.2492152, 9.4317166); na.setNode(20, 52, 9); na.setNode(30, 51.2, 9.4); na.setNode(50, 49, 10); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(20, 50)).setWayGeometry(Helper.createPointList(51.25, 9.43)); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(10, 20)); - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), g.edge(20, 30)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(20, 50)).setWayGeometry(Helper.createPointList(51.25, 9.43)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(10, 20)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(20, 30)); LocationIndex index = createIndexNoPrepare(g, 2000).prepareIndex(); assertEquals(0, findClosestEdge(index, 51.25, 9.43)); @@ -224,7 +221,7 @@ public void testFindingWayGeometry() { @Test public void testEdgeFilter() { - Graph graph = createTestGraph(encodingManager); + Graph graph = createTestGraph(encodingManager, accessEnc, speedEnc); LocationIndexTree index = (LocationIndexTree) createIndexNoPrepare(graph, 500000).prepareIndex(); assertEquals(1, index.findClosest(-.6, -.6, EdgeFilter.ALL_EDGES).getClosestNode()); @@ -233,7 +230,6 @@ public void testEdgeFilter() { // see testgraph2.jpg Graph createTestGraph2() { - FlagEncoder encoder = encodingManager.getEncoder("car"); BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); NodeAccess na = graph.getNodeAccess(); @@ -285,7 +281,7 @@ Graph createTestGraph2() { // top right na.setNode(101, 49.96053, 11.58814); - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 1), graph.edge(1, 2), graph.edge(2, 3), @@ -329,7 +325,7 @@ Graph createTestGraph2() { @Test public void testRMin() { - Graph graph = createTestGraph(encodingManager); + Graph graph = createTestGraph(encodingManager, accessEnc, speedEnc); LocationIndexTree index = (LocationIndexTree) createIndexNoPrepare(graph, 50000).prepareIndex(); DistanceCalc distCalc = new DistancePlaneProjection(); double rmin2 = index.calculateRMin(0.05, -0.3, 1); @@ -339,10 +335,12 @@ public void testRMin() { @Test public void testSearchWithFilter_issue318() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - FlagEncoder bikeEncoder = FlagEncoders.createBike(); + BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + BooleanEncodedValue bikeAccessEnc = new SimpleBooleanEncodedValue("bike_access", true); + DecimalEncodedValue bikeSpeedEnc = new DecimalEncodedValueImpl("bike_speed", 4, 2, false); - EncodingManager tmpEM = EncodingManager.create(carEncoder, bikeEncoder); + EncodingManager tmpEM = EncodingManager.start().add(carAccessEnc).add(carSpeedEnc).add(bikeAccessEnc).add(bikeSpeedEnc).build(); BaseGraph graph = new BaseGraph.Builder(tmpEM).create(); NodeAccess na = graph.getNodeAccess(); @@ -353,33 +351,32 @@ public void testSearchWithFilter_issue318() { int index = lonIdx * 10 + latIdx; na.setNode(index, 0.01 * latIdx, 0.01 * lonIdx); if (latIdx < MAX - 1) - GHUtility.setSpeed(60, true, true, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(index, index + 1)); + GHUtility.setSpeed(60, true, true, carAccessEnc, carSpeedEnc, graph.edge(index, index + 1)); if (lonIdx < MAX - 1) - GHUtility.setSpeed(60, true, true, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), graph.edge(index, index + 10)); + GHUtility.setSpeed(60, true, true, carAccessEnc, carSpeedEnc, graph.edge(index, index + 10)); } } // reduce access for bike to two edges only AllEdgesIterator iter = graph.getAllEdges(); - BooleanEncodedValue accessEnc = bikeEncoder.getAccessEnc(); while (iter.next()) { - iter.set(accessEnc, false, false); + iter.set(bikeAccessEnc, false, false); } for (EdgeIteratorState edge : Arrays.asList(GHUtility.getEdge(graph, 0, 1), GHUtility.getEdge(graph, 1, 2))) { - edge.set(accessEnc, true, true); + edge.set(bikeAccessEnc, true, true); } LocationIndexTree index = createIndexNoPrepare(graph, 500); index.prepareIndex(); index.setMaxRegionSearch(8); - EdgeFilter carFilter = AccessFilter.allEdges(carEncoder.getAccessEnc()); + EdgeFilter carFilter = AccessFilter.allEdges(carAccessEnc); Snap snap = index.findClosest(0.03, 0.03, carFilter); assertTrue(snap.isValid()); assertEquals(33, snap.getClosestNode()); - EdgeFilter bikeFilter = AccessFilter.allEdges(bikeEncoder.getAccessEnc()); + EdgeFilter bikeFilter = AccessFilter.allEdges(bikeAccessEnc); snap = index.findClosest(0.03, 0.03, bikeFilter); assertTrue(snap.isValid()); assertEquals(2, snap.getClosestNode()); @@ -390,7 +387,6 @@ public void testSearchWithFilter_issue318() { // 4--5--6--7 @Test public void testCrossBoundaryNetwork_issue667() { - FlagEncoder encoder = encodingManager.getEncoder("car"); BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); NodeAccess na = graph.getNodeAccess(); na.setNode(0, 0.1, 179.5); @@ -403,7 +399,7 @@ public void testCrossBoundaryNetwork_issue667() { na.setNode(7, 0, -179.5); // just use 1 as distance which is incorrect but does not matter in this unit case - GHUtility.setSpeed(60, 60, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, graph.edge(0, 1), graph.edge(0, 4), graph.edge(1, 5), @@ -417,9 +413,9 @@ public void testCrossBoundaryNetwork_issue667() { // as last edges: create cross boundary edges // See #667 where the recommendation is to adjust the import and introduce two pillar nodes // where the connection is cross boundary and would be okay if ignored as real length is 0 - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(1, 2)).setWayGeometry(Helper.createPointList(0, 180, 0, -180)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(1, 2)).setWayGeometry(Helper.createPointList(0, 180, 0, -180)); // but this unit test succeeds even without this adjusted import: - GHUtility.setSpeed(60, true, true, encoder.getAccessEnc(), encoder.getAverageSpeedEnc(), graph.edge(5, 6)); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(5, 6)); LocationIndexTree index = createIndexNoPrepare(graph, 500); index.prepareIndex(); @@ -443,12 +439,14 @@ private int findClosestEdge(LocationIndex index, double lat, double lon) { @Test public void testSimpleGraph() { - EncodingManager em = EncodingManager.create("car"); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph g = new BaseGraph.Builder(em).create(); initSimpleGraph(g); AllEdgesIterator edge = g.getAllEdges(); while (edge.next()) - GHUtility.setSpeed(60, 60, em.getEncoder("car").getAccessEnc(), em.getEncoder("car").getAverageSpeedEnc(), edge); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, edge); LocationIndexTree idx = (LocationIndexTree) createIndexNoPrepare(g, 500000).prepareIndex(); assertEquals(3, findClosestEdge(idx, 5, 2)); assertEquals(3, findClosestEdge(idx, 1.5, 2)); @@ -459,12 +457,14 @@ public void testSimpleGraph() { @Test public void testSimpleGraph2() { - EncodingManager em = EncodingManager.create("car"); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph g = new BaseGraph.Builder(em).create(); initSimpleGraph(g); AllEdgesIterator edge = g.getAllEdges(); while (edge.next()) - GHUtility.setSpeed(60, 60, em.getEncoder("car").getAccessEnc(), em.getEncoder("car").getAverageSpeedEnc(), edge); + GHUtility.setSpeed(60, 60, accessEnc, speedEnc, edge); LocationIndexTree idx = (LocationIndexTree) createIndexNoPrepare(g, 500000).prepareIndex(); assertEquals(3, findClosestEdge(idx, 5, 2)); @@ -480,7 +480,7 @@ public void testSimpleGraph2() { @Test public void testSinglePoints120() { - BaseGraph g = createSampleGraph(EncodingManager.create("car")); + BaseGraph g = createSampleGraph(encodingManager, accessEnc, speedEnc); LocationIndexTree idx = (LocationIndexTree) createIndexNoPrepare(g, 500000).prepareIndex(); assertEquals(3, findClosestEdge(idx, 1.637, 2.23)); @@ -495,7 +495,7 @@ public void testSinglePoints120() { @Test public void testSinglePoints32() { - BaseGraph g = createSampleGraph(EncodingManager.create("car")); + BaseGraph g = createSampleGraph(encodingManager, accessEnc, speedEnc); LocationIndexTree idx = (LocationIndexTree) createIndexNoPrepare(g, 500000).prepareIndex(); assertEquals(10, findClosestEdge(idx, 3.649, 1.375)); @@ -519,7 +519,7 @@ public void testNoErrorOnEdgeCase_lastIndex() { g.close(); } - public BaseGraph createSampleGraph(EncodingManager encodingManager) { + public BaseGraph createSampleGraph(EncodingManager encodingManager, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { BaseGraph graph = new BaseGraph.Builder(encodingManager).create(); // length does not matter here but lat,lon and outgoing edges do! @@ -575,9 +575,6 @@ public BaseGraph createSampleGraph(EncodingManager encodingManager) { na.setNode(16, 5, 5); // => 17 locations - FlagEncoder encoder = encodingManager.getEncoder("car"); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(a0, b1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(c2, b1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, graph.edge(c2, d3)); @@ -603,28 +600,28 @@ public BaseGraph createSampleGraph(EncodingManager encodingManager) { @Test public void testDifferentVehicles() { - final EncodingManager encodingManager = EncodingManager.create("car,foot"); - BaseGraph g = new BaseGraph.Builder(encodingManager).create(); + BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true); + DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false); + BooleanEncodedValue footAccessEnc = new SimpleBooleanEncodedValue("foot_access", true); + DecimalEncodedValue footSpeedEnc = new DecimalEncodedValueImpl("foot_speed", 4, 1, false); + EncodingManager em = EncodingManager.start().add(carAccessEnc).add(carSpeedEnc).add(footAccessEnc).add(footSpeedEnc).build(); + BaseGraph g = new BaseGraph.Builder(em).create(); initSimpleGraph(g); AllEdgesIterator edge = g.getAllEdges(); while (edge.next()) { - GHUtility.setSpeed(60, 60, encodingManager.getEncoder("car").getAccessEnc(), encodingManager.getEncoder("car").getAverageSpeedEnc(), edge); - GHUtility.setSpeed(10, 10, encodingManager.getEncoder("foot").getAccessEnc(), encodingManager.getEncoder("foot").getAverageSpeedEnc(), edge); + GHUtility.setSpeed(60, 60, carAccessEnc, carSpeedEnc, edge); + GHUtility.setSpeed(10, 10, footAccessEnc, footSpeedEnc, edge); } LocationIndexTree idx = (LocationIndexTree) createIndexNoPrepare(g, 500000).prepareIndex(); assertEquals(0, findClosestEdge(idx, 1, -1)); // now make all edges from node 1 accessible for CAR only EdgeIterator iter = g.createEdgeExplorer().setBaseNode(1); - FlagEncoder encoder = encodingManager.getEncoder("foot"); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - while (iter.next()) { - iter.set(accessEnc, false, false); - } + while (iter.next()) + iter.set(footAccessEnc, false, false); idx = (LocationIndexTree) createIndexNoPrepare(g, 500000).prepareIndex(); - FlagEncoder footEncoder = encodingManager.getEncoder("foot"); - assertEquals(2, idx.findClosest(1, -1, AccessFilter.allEdges(footEncoder.getAccessEnc())).getClosestNode()); + assertEquals(2, idx.findClosest(1, -1, AccessFilter.allEdges(footAccessEnc)).getClosestNode()); g.close(); } diff --git a/core/src/test/java/com/graphhopper/util/GHUtilityTest.java b/core/src/test/java/com/graphhopper/util/GHUtilityTest.java index aed7727c678..bc60fd2b423 100644 --- a/core/src/test/java/com/graphhopper/util/GHUtilityTest.java +++ b/core/src/test/java/com/graphhopper/util/GHUtilityTest.java @@ -20,10 +20,10 @@ import com.graphhopper.coll.GHIntLongHashMap; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.AllEdgesIterator; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.storage.NodeAccess; @@ -35,8 +35,9 @@ * @author Peter Karich */ public class GHUtilityTest { - private final FlagEncoder carEncoder = FlagEncoders.createCar(); - private final EncodingManager encodingManager = EncodingManager.create(carEncoder); + private final BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + private final DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + private final EncodingManager encodingManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph createGraph() { return new BaseGraph.Builder(encodingManager).create(); @@ -49,7 +50,7 @@ BaseGraph createGraph() { // 6 \1 // ______/ // 0/ - Graph initUnsorted(Graph g, FlagEncoder encoder) { + Graph initUnsorted(Graph g, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { NodeAccess na = g.getNodeAccess(); na.setNode(0, 0, 1); na.setNode(1, 2.5, 4.5); @@ -60,8 +61,6 @@ Graph initUnsorted(Graph g, FlagEncoder encoder) { na.setNode(6, 2.3, 2.2); na.setNode(7, 5, 1.5); na.setNode(8, 4.6, 4); - BooleanEncodedValue accessEnc = encoder.getAccessEnc(); - DecimalEncodedValue speedEnc = encoder.getAverageSpeedEnc(); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 2).setDistance(0.5)); GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(7, 3).setDistance(2.1)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 0).setDistance(3.9)); @@ -86,7 +85,7 @@ Graph initUnsorted(Graph g, FlagEncoder encoder) { @Test public void testSort() { - Graph g = initUnsorted(createGraph(), carEncoder); + Graph g = initUnsorted(createGraph(), accessEnc, speedEnc); Graph newG = GHUtility.sortDFS(g, createGraph()); assertEquals(g.getNodes(), newG.getNodes()); assertEquals(g.getEdges(), newG.getEdges()); @@ -120,8 +119,8 @@ public void testSortDirected() { na.setNode(0, 0, 1); na.setNode(1, 2.5, 2); na.setNode(2, 3.5, 3); - GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), g.edge(0, 1).setDistance(1.1)); - GHUtility.setSpeed(60, true, false, carEncoder.getAccessEnc(), carEncoder.getAverageSpeedEnc(), g.edge(2, 1).setDistance(1.1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(0, 1).setDistance(1.1)); + GHUtility.setSpeed(60, true, false, accessEnc, speedEnc, g.edge(2, 1).setDistance(1.1)); GHUtility.sortDFS(g, createGraph()); } diff --git a/core/src/test/java/com/graphhopper/util/InstructionListTest.java b/core/src/test/java/com/graphhopper/util/InstructionListTest.java index 03978d9db52..805a84d7d72 100644 --- a/core/src/test/java/com/graphhopper/util/InstructionListTest.java +++ b/core/src/test/java/com/graphhopper/util/InstructionListTest.java @@ -22,13 +22,9 @@ import com.graphhopper.routing.Dijkstra; import com.graphhopper.routing.InstructionsFromEdges; import com.graphhopper.routing.Path; -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; +import com.graphhopper.routing.util.PriorityCode; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.DefaultTurnCostProvider; import com.graphhopper.routing.weighting.FastestWeighting; @@ -57,16 +53,14 @@ public class InstructionListTest { private static final Translation usTR = trMap.getWithFallBack(Locale.US); private final TraversalMode tMode = TraversalMode.NODE_BASED; private EncodingManager carManager; - private FlagEncoder carEncoder; private BooleanEncodedValue accessEnc; private DecimalEncodedValue speedEnc; @BeforeEach public void setUp() { - carEncoder = FlagEncoders.createCar(); - carManager = EncodingManager.create(carEncoder); - accessEnc = carEncoder.getAccessEnc(); - speedEnc = carEncoder.getAverageSpeedEnc(); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + carManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); } private static List getTurnDescriptions(InstructionList instructionList) { @@ -133,7 +127,7 @@ Graph createTestGraph() { public void testWayList() { Graph g = createTestGraph(); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED).calcPath(0, 10); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, usTR); List tmpList = getTurnDescriptions(wayList); @@ -202,7 +196,7 @@ public void testWayList2() { list.add(10.20, 10.05); iter.setWayGeometry(list); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(2, 3); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, usTR); @@ -241,7 +235,7 @@ public void testNoInstructionIfSameStreet() { list.add(10.20, 10.05); iter.setWayGeometry(list); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(2, 3); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, usTR); List tmpList = getTurnDescriptions(wayList); @@ -270,7 +264,7 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp() { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(10)); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 3); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, usTR); List tmpList = getTurnDescriptions(wayList); @@ -299,7 +293,7 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp2() { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10)); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(10)); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 3); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, usTR); List tmpList = getTurnDescriptions(wayList); @@ -308,8 +302,9 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp2() { @Test public void testNoInstructionIfSlightTurnAndAlternativeIsSharp3() { - FlagEncoder bike = FlagEncoders.createBike(); - EncodingManager tmpEM = new EncodingManager.Builder().add(bike).build(); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 4, 2, false); + EncodingManager tmpEM = new EncodingManager.Builder().add(accessEnc).add(speedEnc).build(); EnumEncodedValue rcEV = tmpEM.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BaseGraph g = new BaseGraph.Builder(tmpEM).create(); // real world example: https://graphhopper.com/maps/?point=48.411549,15.599567&point=48.411663%2C15.600527&profile=bike @@ -327,15 +322,15 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp3() { na.setNode(3, 48.411610, 15.600409); na.setNode(4, 48.411322, 15.600459); - GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(1, 2).setDistance(20)); - GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20)); - GHUtility.setSpeed(4, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20)); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(20)); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(20)); + GHUtility.setSpeed(4, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(20)); g.edge(1, 2).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(singletonMap("name", "pfarr")); g.edge(2, 3).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(singletonMap("name", "pfarr")); g.edge(2, 4).set(rcEV, RoadClass.PEDESTRIAN).setKeyValues(singletonMap("name", "markt")); - FastestWeighting weighting = new FastestWeighting(bike); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 3); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, tmpEM, usTR); List tmpList = getTurnDescriptions(wayList); @@ -346,8 +341,9 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp3() { @Test public void testInstructionIfTurn() { - FlagEncoder bike = FlagEncoders.createBike(); - EncodingManager tmpEM = new EncodingManager.Builder().add(bike).build(); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 4, 2, false); + EncodingManager tmpEM = new EncodingManager.Builder().add(accessEnc).add(speedEnc).build(); EnumEncodedValue rcEV = tmpEM.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BaseGraph g = new BaseGraph.Builder(tmpEM).create(); // real world example: https://graphhopper.com/maps/?point=48.412169%2C15.604888&point=48.412251%2C15.60543&profile=bike @@ -365,14 +361,14 @@ public void testInstructionIfTurn() { na.setNode(3, 48.412614, 15.604872); na.setNode(4, 48.412148, 15.605543); - GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(1, 2).setDistance(20)) + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(20)) .set(rcEV, RoadClass.RESIDENTIAL); - GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20)) + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(20)) .set(rcEV, RoadClass.SECONDARY); - GHUtility.setSpeed(18, true, true, bike.getAccessEnc(), bike.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20)) + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(20)) .set(rcEV, RoadClass.SECONDARY); - FastestWeighting weighting = new FastestWeighting(bike); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 4); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, tmpEM, usTR); List tmpList = getTurnDescriptions(wayList); @@ -383,8 +379,10 @@ public void testInstructionIfTurn() { @Test public void testInstructionIfSlightTurnForCustomProfile() { - FlagEncoder foot = FlagEncoders.createFoot(); - EncodingManager tmpEM = new EncodingManager.Builder().add(foot).build(); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 4, 1, false); + DecimalEncodedValue priorityEnc = new DecimalEncodedValueImpl("priority", 4, PriorityCode.getFactor(1), false); + EncodingManager tmpEM = new EncodingManager.Builder().add(accessEnc).add(speedEnc).add(priorityEnc).build(); BaseGraph g = new BaseGraph.Builder(tmpEM).create(); // real world example: https://graphhopper.com/maps/?point=43.729379,7.417697&point=43.729798,7.417263&profile=foot // From 4 to 3 and 4 to 1 @@ -403,14 +401,16 @@ public void testInstructionIfSlightTurnForCustomProfile() { na.setNode(3, 43.729821, 7.41725); na.setNode(4, 43.729476, 7.417633); - DecimalEncodedValue priorityEnc = tmpEM.getDecimalEncodedValue(EncodingManager.getKey(foot.toString(), "priority")); // default is priority=0 so set it to 1 - GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(1, 2).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1)); - GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(2, 3).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1)); + // default is priority=0 so set it to 1 + GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1)); + GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1)); PointList pointList = new PointList(); pointList.add(43.729627, 7.41749); - GHUtility.setSpeed(5, true, true, foot.getAccessEnc(), foot.getAverageSpeedEnc(), g.edge(2, 4).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1).setWayGeometry(pointList)); + GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1).setWayGeometry(pointList)); - Weighting weighting = CustomModelParser.createWeighting(foot, tmpEM, DefaultTurnCostProvider.NO_TURN_COST_PROVIDER, new CustomModel().setDistanceInfluence(0)); + Weighting weighting = CustomModelParser.createWeighting(accessEnc, speedEnc, + priorityEnc, tmpEM, DefaultTurnCostProvider.NO_TURN_COST_PROVIDER, + new CustomModel().setDistanceInfluence(0)); Path p = new Dijkstra(g, weighting, tMode).calcPath(4, 3); assertTrue(p.isFound()); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, tmpEM, usTR); @@ -429,8 +429,9 @@ public void testInstructionIfSlightTurnForCustomProfile() { @Test public void testInstructionWithHighlyCustomProfileWithRoadsBase() { - FlagEncoder roads = FlagEncoders.createRoads(new PMap()); - EncodingManager tmpEM = EncodingManager.create(roads); + BooleanEncodedValue roadsAccessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue roadsSpeedEnc = new DecimalEncodedValueImpl("speed", 7, 2, true); + EncodingManager tmpEM = EncodingManager.start().add(roadsAccessEnc).add(roadsSpeedEnc).build(); EnumEncodedValue rcEV = tmpEM.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BaseGraph g = new BaseGraph.Builder(tmpEM).create(); // real world example: https://graphhopper.com/maps/?point=55.691214%2C12.57065&point=55.689957%2C12.570387 @@ -449,8 +450,6 @@ public void testInstructionWithHighlyCustomProfileWithRoadsBase() { na.setNode(4, 55.690849, 12.571004); na.setNode(5, 55.690864, 12.570886); - BooleanEncodedValue roadsAccessEnc = roads.getAccessEnc(); - DecimalEncodedValue roadsSpeedEnc = roads.getAverageSpeedEnc(); GHUtility.setSpeed(50, true, true, roadsAccessEnc, roadsSpeedEnc, g.edge(3, 2).setDistance(10)); GHUtility.setSpeed(40, true, true, roadsAccessEnc, roadsSpeedEnc, g.edge(2, 4).setDistance(10)); GHUtility.setSpeed(40, true, true, roadsAccessEnc, roadsSpeedEnc, g.edge(2, 1).setDistance(10)); @@ -458,7 +457,7 @@ public void testInstructionWithHighlyCustomProfileWithRoadsBase() { CustomModel customModel = new CustomModel(); customModel.addToPriority(Statement.If("road_class == PEDESTRIAN", Statement.Op.MULTIPLY, "0")); - Weighting weighting = CustomModelParser.createWeighting(roads, tmpEM, TurnCostProvider.NO_TURN_COST_PROVIDER, customModel); + Weighting weighting = CustomModelParser.createWeighting(roadsAccessEnc, roadsSpeedEnc, null, tmpEM, TurnCostProvider.NO_TURN_COST_PROVIDER, customModel); Path p = new Dijkstra(g, weighting, tMode).calcPath(3, 4); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, tmpEM, usTR); List tmpList = getTurnDescriptions(wayList); @@ -469,7 +468,7 @@ public void testInstructionWithHighlyCustomProfileWithRoadsBase() { public void testEmptyList() { BaseGraph g = new BaseGraph.Builder(carManager).create(); g.getNodeAccess().setNode(1, 0, 0); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(0, 1); InstructionList il = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, usTR); assertEquals(0, il.size()); @@ -501,7 +500,7 @@ public void testFind() { GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000)).setKeyValues(singletonMap("name", "3-7")); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000)).setKeyValues(singletonMap("name", "4-5")); - FastestWeighting weighting = new FastestWeighting(carEncoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 5); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, usTR); diff --git a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java index 15635cd3a27..be640d46524 100644 --- a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java +++ b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java @@ -23,9 +23,9 @@ import com.graphhopper.routing.Path; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.storage.BaseGraph; @@ -53,8 +53,9 @@ public class PathSimplificationTest { @Test public void testScenario() { - FlagEncoder carEncoder = FlagEncoders.createCar(); - EncodingManager carManager = EncodingManager.create(carEncoder); + BooleanEncodedValue accessEnc = new SimpleBooleanEncodedValue("access", true); + DecimalEncodedValue speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + EncodingManager carManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph g = new BaseGraph.Builder(carManager).create(); // 0-1-2 // | | | @@ -75,8 +76,6 @@ public void testScenario() { na.setNode(7, 1.0, 1.1); na.setNode(8, 1.0, 1.2); - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(singletonMap("name", "0-1")); GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(singletonMap("name", "1-2")); diff --git a/example/src/main/java/com/graphhopper/example/IsochroneExample.java b/example/src/main/java/com/graphhopper/example/IsochroneExample.java index ff80ed904bd..ff339b7d839 100644 --- a/example/src/main/java/com/graphhopper/example/IsochroneExample.java +++ b/example/src/main/java/com/graphhopper/example/IsochroneExample.java @@ -3,11 +3,10 @@ import com.graphhopper.GraphHopper; import com.graphhopper.config.Profile; import com.graphhopper.isochrone.algorithm.ShortestPathTree; -import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.storage.index.Snap; @@ -20,10 +19,11 @@ public static void main(String[] args) { GraphHopper hopper = createGraphHopperInstance(relDir + "core/files/andorra.osm.pbf"); // get encoder from GraphHopper instance EncodingManager encodingManager = hopper.getEncodingManager(); - FlagEncoder encoder = encodingManager.getEncoder("car"); + BooleanEncodedValue accessEnc = encodingManager.getBooleanEncodedValue(VehicleAccess.key("car")); + DecimalEncodedValue speedEnc = encodingManager.getDecimalEncodedValue(VehicleSpeed.key("car")); // snap some GPS coordinates to the routing graph and build a query graph - FastestWeighting weighting = new FastestWeighting(encoder); + FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Snap snap = hopper.getLocationIndex().findClosest(42.508679, 1.532078, new DefaultSnapFilter(weighting, encodingManager.getBooleanEncodedValue(Subnetwork.key("car")))); QueryGraph queryGraph = QueryGraph.create(hopper.getBaseGraph(), snap); diff --git a/example/src/main/java/com/graphhopper/example/LocationIndexExample.java b/example/src/main/java/com/graphhopper/example/LocationIndexExample.java index dbf599a3665..2ab4c8a2821 100644 --- a/example/src/main/java/com/graphhopper/example/LocationIndexExample.java +++ b/example/src/main/java/com/graphhopper/example/LocationIndexExample.java @@ -3,8 +3,6 @@ import com.graphhopper.GraphHopper; import com.graphhopper.config.Profile; import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.LocationIndexTree; @@ -37,7 +35,7 @@ public static void graphhopperLocationIndex(String relDir) { public static void lowLevelLocationIndex() { // If you don't use the GraphHopper class you have to use the low level API: - BaseGraph graph = new BaseGraph.Builder(EncodingManager.create(FlagEncoders.createCar())).create(); + BaseGraph graph = new BaseGraph.Builder(1).create(); graph.edge(0, 1).setKeyValues(Collections.singletonMap("name", "test edge")); graph.getNodeAccess().setNode(0, 12, 42); graph.getNodeAccess().setNode(1, 12.01, 42.01); diff --git a/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java b/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java index 4761cb58979..221ea352037 100644 --- a/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java +++ b/example/src/main/java/com/graphhopper/example/LowLevelAPIExample.java @@ -5,8 +5,14 @@ import com.graphhopper.routing.Path; import com.graphhopper.routing.ch.CHRoutingAlgorithmFactory; import com.graphhopper.routing.ch.PrepareContractionHierarchies; +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.VehicleAccess; +import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.routing.querygraph.QueryGraph; -import com.graphhopper.routing.util.*; +import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.*; @@ -31,15 +37,16 @@ public static void main(String[] args) { public static void createAndSaveGraph() { { - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).setDir(new RAMDirectory(graphLocation, true)).create(); // Make a weighted edge between two nodes and set average speed to 50km/h - EdgeIteratorState edge = graph.edge(0, 1).setDistance(1234).set(encoder.getAverageSpeedEnc(), 50); + EdgeIteratorState edge = graph.edge(0, 1).setDistance(1234).set(speedEnc, 50); // Set node coordinates and build location index NodeAccess na = graph.getNodeAccess(); - graph.edge(0, 1).set(encoder.getAccessEnc(), true).set(encoder.getAverageSpeedEnc(), 10).setDistance(1530); + graph.edge(0, 1).set(accessEnc, true).set(speedEnc, 10).setDistance(1530); na.setNode(0, 15.15, 20.20); na.setNode(1, 15.25, 20.21); LocationIndexTree index = new LocationIndexTree(graph, graph.getDirectory()); @@ -55,8 +62,9 @@ public static void createAndSaveGraph() { { // Load the graph ... can be also in a different code location // note that the EncodingManager must be the same - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); BaseGraph graph = new BaseGraph.Builder(em).setDir(new RAMDirectory(graphLocation, true)).build(); graph.loadExisting(); @@ -69,7 +77,7 @@ public static void createAndSaveGraph() { Snap fromSnap = index.findClosest(15.15, 20.20, EdgeFilter.ALL_EDGES); Snap toSnap = index.findClosest(15.25, 20.21, EdgeFilter.ALL_EDGES); QueryGraph queryGraph = QueryGraph.create(graph, fromSnap, toSnap); - Weighting weighting = new FastestWeighting(encoder); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc); Path path = new Dijkstra(queryGraph, weighting, TraversalMode.NODE_BASED).calcPath(fromSnap.getClosestNode(), toSnap.getClosestNode()); assert Helper.round(path.getDistance(), -2) == 1500; @@ -81,9 +89,10 @@ public static void createAndSaveGraph() { public static void useContractionHierarchiesToMakeQueriesFaster() { // Creating and saving the graph - FlagEncoder encoder = FlagEncoders.createCar(); - EncodingManager em = EncodingManager.create(encoder); - Weighting weighting = new FastestWeighting(encoder); + BooleanEncodedValue accessEnc = VehicleAccess.create("car"); + DecimalEncodedValue speedEnc = VehicleSpeed.create("car", 5, 5, false); + EncodingManager em = EncodingManager.start().add(accessEnc).add(speedEnc).build(); + Weighting weighting = new FastestWeighting(accessEnc, speedEnc); CHConfig chConfig = CHConfig.nodeBased("my_profile", weighting); BaseGraph graph = new BaseGraph.Builder(em) .setDir(new RAMDirectory(graphLocation, true)) @@ -92,7 +101,7 @@ public static void useContractionHierarchiesToMakeQueriesFaster() { // Set node coordinates and build location index NodeAccess na = graph.getNodeAccess(); - graph.edge(0, 1).set(encoder.getAccessEnc(), true).set(encoder.getAverageSpeedEnc(), 10).setDistance(1020); + graph.edge(0, 1).set(accessEnc, true).set(speedEnc, 10).setDistance(1020); na.setNode(0, 15.15, 20.20); na.setNode(1, 15.25, 20.21); diff --git a/example/src/main/java/com/graphhopper/example/RoutingExampleTC.java b/example/src/main/java/com/graphhopper/example/RoutingExampleTC.java index c356f2c61b0..9f61e591c1e 100644 --- a/example/src/main/java/com/graphhopper/example/RoutingExampleTC.java +++ b/example/src/main/java/com/graphhopper/example/RoutingExampleTC.java @@ -7,7 +7,6 @@ import com.graphhopper.ResponsePath; import com.graphhopper.config.CHProfile; import com.graphhopper.config.Profile; -import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.util.Parameters; import java.util.Arrays; @@ -68,10 +67,8 @@ static GraphHopper createGraphHopperInstance(String ghLoc) { GraphHopper hopper = new GraphHopper(); hopper.setOSMFile(ghLoc); hopper.setGraphHopperLocation("target/routing-tc-graph-cache"); - // by enabling turn costs for the FlagEncoder, turn restriction constraints like 'no_left_turn' will be taken - // from OSM Profile profile = new Profile("car").setVehicle("car").setWeighting("fastest") - // to actually use the turn restrictions when routing we have to enable turn costs for our routing profile + // enabling turn costs means OSM turn restriction constraints like 'no_left_turn' will be taken into account .setTurnCosts(true) // we can also set u_turn_costs (in seconds). by default no u-turns are allowed, but with this setting // we will consider u-turns at all junctions with a 40s time penalty diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java index 8847de0a08a..cca17ef1f23 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/GtfsReader.java @@ -22,11 +22,10 @@ import com.conveyal.gtfs.model.*; import com.google.common.collect.HashMultimap; import com.google.transit.realtime.GtfsRealtime; -import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.InMemConstructionIndex; @@ -104,8 +103,9 @@ static class TripWithStopTimes { } void connectStopsToStreetNetwork() { - FlagEncoder footEncoder = encodingManager.getEncoder("foot"); - final EdgeFilter filter = new DefaultSnapFilter(new FastestWeighting(footEncoder), encodingManager.getBooleanEncodedValue(Subnetwork.key("foot"))); + BooleanEncodedValue accessEnc = encodingManager.getBooleanEncodedValue(VehicleAccess.key("foot")); + DecimalEncodedValue speedEnc = encodingManager.getDecimalEncodedValue(VehicleSpeed.key("foot")); + final EdgeFilter filter = new DefaultSnapFilter(new FastestWeighting(accessEnc, speedEnc), encodingManager.getBooleanEncodedValue(Subnetwork.key("foot"))); for (Stop stop : feed.stops.values()) { if (stop.location_type == 0) { // Only stops. Not interested in parent stations for now. Snap locationSnap = walkNetworkIndex.findClosest(stop.stop_lat, stop.stop_lon, filter); diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java index 7cd6e9f414c..8ca431599e3 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterFreeWalkImpl.java @@ -27,6 +27,8 @@ import com.graphhopper.routing.DefaultWeightingFactory; import com.graphhopper.routing.WeightingFactory; import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.VehicleAccess; +import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.util.EdgeFilter; @@ -64,7 +66,10 @@ public final class PtRouterFreeWalkImpl implements PtRouter { public PtRouterFreeWalkImpl(GraphHopperConfig config, TranslationMap translationMap, BaseGraph baseGraph, EncodingManager encodingManager, LocationIndex locationIndex, GtfsStorage gtfsStorage, RealtimeFeed realtimeFeed, PathDetailsBuilderFactory pathDetailsBuilderFactory) { this.config = config; this.weightingFactory = new DefaultWeightingFactory(baseGraph.getBaseGraph(), encodingManager); - this.accessEgressWeighting = new FastestWeighting(encodingManager.getEncoder("foot")); + this.accessEgressWeighting = new FastestWeighting( + encodingManager.getBooleanEncodedValue(VehicleAccess.key("foot")), + encodingManager.getDecimalEncodedValue(VehicleSpeed.key("foot")) + ); this.translationMap = translationMap; this.baseGraph = baseGraph; this.encodingManager = encodingManager; @@ -166,10 +171,16 @@ private class RequestHandler { requestedPathDetails = request.getPathDetails(); accessProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getAccessProfile())).findFirst().get(); accessWeighting = weightingFactory.createWeighting(accessProfile, new PMap(), false); - accessSnapFilter = new DefaultSnapFilter(new FastestWeighting(encodingManager.getEncoder(accessProfile.getVehicle())), encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); + accessSnapFilter = new DefaultSnapFilter(new FastestWeighting( + encodingManager.getBooleanEncodedValue(VehicleAccess.key(accessProfile.getVehicle())), + encodingManager.getDecimalEncodedValue(VehicleSpeed.key(accessProfile.getVehicle())) + ), encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); egressProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getEgressProfile())).findFirst().get(); egressWeighting = weightingFactory.createWeighting(egressProfile, new PMap(), false); - egressSnapFilter = new DefaultSnapFilter(new FastestWeighting(encodingManager.getEncoder(egressProfile.getVehicle())), encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); + egressSnapFilter = new DefaultSnapFilter(new FastestWeighting( + encodingManager.getBooleanEncodedValue(VehicleAccess.key(egressProfile.getVehicle())), + encodingManager.getDecimalEncodedValue(VehicleSpeed.key(egressProfile.getVehicle())) + ), encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); } GHResponse route() { diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java index 573679469d5..be9c6094b74 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/PtRouterImpl.java @@ -27,6 +27,8 @@ import com.graphhopper.routing.DefaultWeightingFactory; import com.graphhopper.routing.WeightingFactory; import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.VehicleAccess; +import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.util.EdgeFilter; @@ -166,10 +168,16 @@ private class RequestHandler { requestedPathDetails = request.getPathDetails(); accessProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getAccessProfile())).findFirst().get(); accessWeighting = weightingFactory.createWeighting(accessProfile, new PMap(), false); - accessSnapFilter = new DefaultSnapFilter(new FastestWeighting(encodingManager.getEncoder(accessProfile.getVehicle())), encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); + accessSnapFilter = new DefaultSnapFilter(new FastestWeighting( + encodingManager.getBooleanEncodedValue(VehicleAccess.key(accessProfile.getVehicle())), + encodingManager.getDecimalEncodedValue(VehicleSpeed.key(accessProfile.getVehicle())) + ), encodingManager.getBooleanEncodedValue(Subnetwork.key(accessProfile.getVehicle()))); egressProfile = config.getProfiles().stream().filter(p -> p.getName().equals(request.getEgressProfile())).findFirst().get(); egressWeighting = weightingFactory.createWeighting(egressProfile, new PMap(), false); - egressSnapFilter = new DefaultSnapFilter(new FastestWeighting(encodingManager.getEncoder(egressProfile.getVehicle())), encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); + egressSnapFilter = new DefaultSnapFilter(new FastestWeighting( + encodingManager.getBooleanEncodedValue(VehicleAccess.key(egressProfile.getVehicle())), + encodingManager.getDecimalEncodedValue(VehicleSpeed.key(egressProfile.getVehicle())) + ), encodingManager.getBooleanEncodedValue(Subnetwork.key(egressProfile.getVehicle()))); } GHResponse route() { diff --git a/tools/src/main/java/com/graphhopper/tools/Measurement.java b/tools/src/main/java/com/graphhopper/tools/Measurement.java index 5e74ee264f2..01caf87902f 100644 --- a/tools/src/main/java/com/graphhopper/tools/Measurement.java +++ b/tools/src/main/java/com/graphhopper/tools/Measurement.java @@ -28,7 +28,10 @@ import com.graphhopper.config.Profile; import com.graphhopper.jackson.Jackson; import com.graphhopper.routing.ch.PrepareContractionHierarchies; +import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.TurnCost; +import com.graphhopper.routing.ev.VehicleAccess; import com.graphhopper.routing.lm.LMConfig; import com.graphhopper.routing.lm.PrepareLandmarks; import com.graphhopper.routing.util.*; @@ -177,10 +180,8 @@ protected void importOSM() { BaseGraph g = hopper.getBaseGraph(); EncodingManager encodingManager = hopper.getEncodingManager(); - if (encodingManager.fetchEdgeEncoders().size() != 1) { - throw new IllegalArgumentException("There has to be exactly one encoder for each measurement"); - } - FlagEncoder encoder = encodingManager.fetchEdgeEncoders().get(0); + BooleanEncodedValue accessEnc = encodingManager.getBooleanEncodedValue(VehicleAccess.key(vehicle)); + boolean withTurnCosts = encodingManager.hasEncodedValue(TurnCost.key(vehicle)); StopWatch sw = new StopWatch().start(); try { @@ -188,7 +189,7 @@ protected void importOSM() { final boolean runSlow = args.getBool("measurement.run_slow_routing", true); printGraphDetails(g, vehicle); - measureGraphTraversal(g, encoder, count * 100); + measureGraphTraversal(g, accessEnc, count * 100); measureLocationIndex(g, hopper.getLocationIndex(), count); if (runSlow) { @@ -198,7 +199,7 @@ protected void importOSM() { withInstructions()); measureRouting(hopper, new QuerySettings("routing_alt", count / 500, isCH, isLM). alternative()); - if (encoder.supportsTurnCosts()) { + if (withTurnCosts) { measureRouting(hopper, new QuerySettings("routing_edge", count / 20, isCH, isLM). withInstructions().edgeBased()); // unfortunately alt routes are so slow that we cannot really afford many iterations @@ -221,7 +222,7 @@ protected void importOSM() { withInstructions().activeLandmarks(activeLMCount)); measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_alt", count / 500, isCH, isLM). activeLandmarks(activeLMCount).alternative()); - if (args.getBool("measurement.lm.edge_based", encoder.supportsTurnCosts())) { + if (args.getBool("measurement.lm.edge_based", withTurnCosts)) { measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_edge", count / 20, isCH, isLM). withInstructions().activeLandmarks(activeLMCount).edgeBased()); measureRouting(hopper, new QuerySettings("routingLM" + activeLMCount + "_alt_edge", count / 500, isCH, isLM). @@ -307,13 +308,8 @@ protected void importOSM() { private GraphHopperConfig createConfigFromArgs(PMap args) { GraphHopperConfig ghConfig = new GraphHopperConfig(args); - String encodingManagerString = args.getString("graph.flag_encoders", "car"); - List tmpEncoders = EncodingManager.create(encodingManagerString).fetchEdgeEncoders(); - if (tmpEncoders.size() != 1) { - logger.warn("You configured multiple encoders, only the first one is used for the measurements"); - } - vehicle = tmpEncoders.get(0).toString(); - boolean turnCosts = tmpEncoders.get(0).supportsTurnCosts(); + vehicle = args.getString("measurement.vehicle", "car"); + boolean turnCosts = args.getBool("measurement.turn_costs", false); int uTurnCosts = args.getInt("measurement.u_turn_costs", 40); String weighting = args.getString("measurement.weighting", "fastest"); boolean useCHEdge = args.getBool("measurement.ch.edge", true); @@ -447,10 +443,10 @@ private void measureLocationIndex(Graph g, final LocationIndex idx, int count) { print("location_index", miniPerf); } - private void measureGraphTraversal(final Graph graph, final FlagEncoder encoder, int count) { + private void measureGraphTraversal(final Graph graph, BooleanEncodedValue accessEnc, int count) { final Random rand = new Random(seed); - EdgeFilter outFilter = AccessFilter.outEdges(encoder.getAccessEnc()); + EdgeFilter outFilter = AccessFilter.outEdges(accessEnc); final EdgeExplorer outExplorer = graph.createEdgeExplorer(outFilter); MiniPerfTest miniPerf = new MiniPerfTest().setIterations(count).start((warmup, run) -> { int nodeId = rand.nextInt(maxNode); diff --git a/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java b/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java index 2decd67a603..06fb256a847 100644 --- a/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java +++ b/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java @@ -28,13 +28,14 @@ import com.graphhopper.routing.*; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.VehicleAccess; +import com.graphhopper.routing.ev.VehicleSpeed; import com.graphhopper.routing.lm.LMRoutingAlgorithmFactory; import com.graphhopper.routing.lm.LandmarkStorage; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.querygraph.QueryRoutingCHGraph; import com.graphhopper.routing.util.AllEdgesIterator; import com.graphhopper.routing.util.EdgeFilter; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.storage.BaseGraph; @@ -75,7 +76,6 @@ public class MiniGraphUI { private final BaseGraph graph; private final NodeAccess na; private final MapLayer pathLayer; - private final FlagEncoder encoder; private final DecimalEncodedValue avSpeedEnc; private final BooleanEncodedValue accessEnc; private final boolean useCH; @@ -120,9 +120,9 @@ public static void main(String[] strs) { public MiniGraphUI(GraphHopper hopper, boolean debug, boolean useCH) { this.graph = hopper.getBaseGraph(); this.na = graph.getNodeAccess(); - encoder = hopper.getEncodingManager().fetchEdgeEncoders().get(0); - avSpeedEnc = encoder.getAverageSpeedEnc(); - accessEnc = encoder.getAccessEnc(); + String vehicle = hopper.getProfiles().get(0).getVehicle(); + accessEnc = hopper.getEncodingManager().getBooleanEncodedValue(VehicleAccess.key(vehicle)); + avSpeedEnc = hopper.getEncodingManager().getDecimalEncodedValue(VehicleSpeed.key(vehicle)); this.useCH = useCH; logger.info("locations:" + graph.getNodes() + ", debug:" + debug); @@ -333,7 +333,7 @@ private RoutingAlgorithm createAlgo(GraphHopper hopper, QueryGraph qGraph) { }; AlgorithmOptions algoOpts = new AlgorithmOptions().setAlgorithm(Algorithms.ASTAR_BI). setTraversalMode(TraversalMode.EDGE_BASED); - return algoFactory.createAlgo(qGraph, new FastestWeighting(encoder), algoOpts); + return algoFactory.createAlgo(qGraph, new FastestWeighting(accessEnc, avSpeedEnc), algoOpts); } } diff --git a/web-bundle/src/main/java/com/graphhopper/resources/InfoResource.java b/web-bundle/src/main/java/com/graphhopper/resources/InfoResource.java index 58564c0151a..448881366f5 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/InfoResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/InfoResource.java @@ -33,7 +33,10 @@ import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; /** * @author Peter Karich @@ -93,8 +96,7 @@ public Info getInfo() { info.profiles.add(new Info.ProfileData("pt", "pt")); info.elevation = hasElevation; - List encoderNames = Arrays.asList(encodingManager.toString().split(",")); - info.supported_vehicles = new ArrayList<>(encoderNames); + info.supported_vehicles = encodingManager.getVehicles(); if (config.has("gtfs.file")) { info.supported_vehicles.add("pt"); } diff --git a/web-bundle/src/main/java/com/graphhopper/resources/PtIsochroneResource.java b/web-bundle/src/main/java/com/graphhopper/resources/PtIsochroneResource.java index f364f1dff41..ec079d52ec0 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/PtIsochroneResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/PtIsochroneResource.java @@ -25,10 +25,9 @@ import com.graphhopper.isochrone.algorithm.ContourBuilder; import com.graphhopper.isochrone.algorithm.ReadableTriangulation; import com.graphhopper.jackson.ResponsePathSerializer; -import com.graphhopper.routing.ev.Subnetwork; +import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.DefaultSnapFilter; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.storage.BaseGraph; @@ -94,8 +93,9 @@ public Response doGet( double targetZ = seconds * 1000; GeometryFactory geometryFactory = new GeometryFactory(); - final FlagEncoder footEncoder = encodingManager.getEncoder("foot"); - final Weighting weighting = new FastestWeighting(footEncoder); + BooleanEncodedValue accessEnc = encodingManager.getBooleanEncodedValue(VehicleAccess.key("foot")); + DecimalEncodedValue speedEnc = encodingManager.getDecimalEncodedValue(VehicleSpeed.key("foot")); + final Weighting weighting = new FastestWeighting(accessEnc, speedEnc); DefaultSnapFilter snapFilter = new DefaultSnapFilter(weighting, encodingManager.getBooleanEncodedValue(Subnetwork.key("foot"))); PtLocationSnapper.Result snapResult = new PtLocationSnapper(baseGraph, locationIndex, gtfsStorage).snapAll(Arrays.asList(location), Arrays.asList(snapFilter)); diff --git a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java index 7649e4651b5..4289aa42d26 100644 --- a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java +++ b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java @@ -23,9 +23,9 @@ import com.graphhopper.routing.Path; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.SimpleBooleanEncodedValue; import com.graphhopper.routing.util.EncodingManager; -import com.graphhopper.routing.util.FlagEncoder; -import com.graphhopper.routing.util.FlagEncoders; import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.storage.BaseGraph; @@ -51,14 +51,16 @@ public class GpxConversionsTest { + private BooleanEncodedValue accessEnc; + private DecimalEncodedValue speedEnc; private EncodingManager carManager; - private FlagEncoder carEncoder; private TranslationMap trMap; @BeforeEach public void setUp() { - carEncoder = FlagEncoders.createCar(); - carManager = EncodingManager.create(carEncoder); + accessEnc = new SimpleBooleanEncodedValue("access", true); + speedEnc = new DecimalEncodedValueImpl("speed", 5, 5, false); + carManager = EncodingManager.start().add(accessEnc).add(speedEnc).build(); trMap = new TranslationMap().doImport(); } @@ -79,8 +81,6 @@ public void testInstructionsWithTimeAndPlace() { na.setNode(6, 15.1, 10.1); na.setNode(7, 15.1, 9.8); - BooleanEncodedValue accessEnc = carEncoder.getAccessEnc(); - DecimalEncodedValue speedEnc = carEncoder.getAverageSpeedEnc(); GHUtility.setSpeed(63, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(7000).setKeyValues(singletonMap("name", "1-2"))); GHUtility.setSpeed(72, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(8000).setKeyValues(singletonMap("name", "2-3"))); GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000).setKeyValues(singletonMap("name", "2-6"))); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java index 82b52cc222e..44b93c1a97d 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java @@ -492,7 +492,7 @@ public void testGraphHopperWebRealExceptions(boolean usePost) { ex = rsp.getErrors().get(0); assertTrue(ex instanceof IllegalArgumentException, "Wrong exception found: " + ex.getClass().getName() + ", IllegalArgumentException expected."); - assertTrue(ex.getMessage().contains("Vehicle not supported: `space-shuttle`. Supported are: `car`" + + assertTrue(ex.getMessage().contains("Vehicle not supported: `space-shuttle`. Supported are: `[car]`" + "\nYou should consider using the `profile` parameter instead of specifying a vehicle." + "\nAvailable profiles: [my_car]"), ex.getMessage()); From ffaf119685d59a8e0255c6049673ae871853a807 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 5 Jul 2022 22:10:15 +0200 Subject: [PATCH 084/389] EdgeKVStorage: remove smallCache as too much complexity. we accept disk usage increases by 12% and more uniq keys later possible --- .../com/graphhopper/search/EdgeKVStorage.java | 87 ++------------ .../com/graphhopper/storage/BaseGraph.java | 4 +- .../java/com/graphhopper/util/Constants.java | 2 +- .../graphhopper/search/EdgeKVStorageTest.java | 111 +++++++++--------- 4 files changed, 69 insertions(+), 135 deletions(-) diff --git a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java index 3c692e9a832..8b048349793 100644 --- a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java +++ b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java @@ -35,7 +35,7 @@ public class EdgeKVStorage { private static final long EMPTY_POINTER = 0, START_POINTER = 1; - // Store the key index in 2 bytes. Use negative values for marking the value as duplicate. + // Store the key index in 2 bytes (for now ignore the highest bit) static final int MAX_UNIQUE_KEYS = (1 << 15); // Store string value as byte array and store the length into 1 byte private static final int MAX_LENGTH = (1 << 8) - 1; @@ -61,28 +61,21 @@ public class EdgeKVStorage { // So more generic: the values could be of dynamic length, fixed length like int or be duplicates: // vals count (1 byte) // --- 1. key-value pair (store String or byte[] with dynamic length) - // key_idx_0 (2 byte) + // key_idx_0 (2 byte, of which the first 2bits are to know if this is valid for fwd and/or bwd direction) // val_length_0 (1 byte) // val_0 (x bytes) // --- 2. key-value pair (store int with fixed length) // key_idx_1 (2 byte) // int (4 byte) - // --- 3. key-value pair (store duplicate, then key is negative and the value is a pointer to the actual value (relative to the current pointer) - // -key_idx_2 (2 byte) - // delta_pointer_2 (4 byte) // - // Note: - // 1. The key strings are limited to 32767 unique values (see MAX_UNIQUE_KEYS). A dynamic value has a maximum byte length of 255. + // Notes: + // 1. The key strings are limited MAX_UNIQUE_KEYS. A dynamic value has a maximum byte length of 255. // 2. Every key can store values only of the same type // 3. We need to loop through X entries to get the start val_x. - // 4. We detect duplicate values for byte[] and String values via smallCache and then use the negative key index as - // 'duplicate' marker. We then store only the delta (signed int) instead of the absolute unsigned long value to - // reduce memory usage when there are duplicate values. private final DataAccess vals; private final Map keyToIndex = new HashMap<>(); private final List> indexToClass = new ArrayList<>(); private final List indexToKey = new ArrayList<>(); - private final Map smallCache; private final BitUtil bitUtil = BitUtil.LITTLE; private long bytePointer = START_POINTER; private long lastEntryPointer = -1; @@ -98,13 +91,6 @@ public EdgeKVStorage(Directory dir) { public EdgeKVStorage(Directory dir, final int cacheSize) { keys = dir.create("edgekv_keys", 10 * 1024); vals = dir.create("edgekv_vals"); - - smallCache = new LinkedHashMap(cacheSize, 0.75f, true) { - @Override - protected boolean removeEldestEntry(Map.Entry entry) { - return size() > cacheSize; - } - }; } public EdgeKVStorage create(long initBytes) { @@ -217,29 +203,9 @@ else if (entryMap.size() > 200) currentPointer += 3; continue; } - - Long existingRef = smallCache.get(value); - if (existingRef != null) { - long delta = lastEntryPointer - existingRef; - if (delta < Integer.MAX_VALUE && delta > Integer.MIN_VALUE) { - vals.ensureCapacity(currentPointer + 2 + 4); - vals.setShort(currentPointer, (short) -keyIndex); - currentPointer += 2; - // do not store valueBytes.length as we know it already: it is 4! - byte[] valueBytes = new byte[4]; - bitUtil.fromInt(valueBytes, (int) delta); - vals.setBytes(currentPointer, valueBytes, valueBytes.length); - currentPointer += valueBytes.length; - continue; - } else { - smallCache.remove(value); - } - } } final byte[] valueBytes = getBytesForValue(clazz, value); - // only cache value if storing via duplicate marker is valuable (the delta costs 4 bytes minus 1 due to omitted valueBytes.length storage) - if (hasDynLength && valueBytes.length > 3) smallCache.put(value, currentPointer); vals.ensureCapacity(currentPointer + 2 + 1 + valueBytes.length); vals.setShort(currentPointer, keyIndex.shortValue()); currentPointer += 2; @@ -288,23 +254,8 @@ public Map getAll(final long entryPointer) { int currentKeyIndex = vals.getShort(tmpPointer); tmpPointer += 2; - Object object; - if (currentKeyIndex < 0) { - // deserialize duplicate - currentKeyIndex = -currentKeyIndex; - byte[] valueBytes = new byte[4]; - vals.getBytes(tmpPointer, valueBytes, valueBytes.length); - tmpPointer += 4; - - long dupPointer = entryPointer - bitUtil.toInt(valueBytes); - dupPointer += 2; - if (dupPointer > bytePointer) - throw new IllegalStateException("dup marker should exist but points into not yet allocated area " + dupPointer + " > " + bytePointer); - object = deserializeObj(null, dupPointer, indexToClass.get(currentKeyIndex)); - } else { - object = deserializeObj(sizeOfObject, tmpPointer, indexToClass.get(currentKeyIndex)); - tmpPointer += sizeOfObject.get(); - } + Object object = deserializeObj(sizeOfObject, tmpPointer, indexToClass.get(currentKeyIndex)); + tmpPointer += sizeOfObject.get(); String key = indexToKey.get(currentKeyIndex); map.put(key, object); } @@ -400,7 +351,7 @@ private Object deserializeObj(AtomicInteger sizeOfObject, long pointer, Class } } - public Object get(final long entryPointer, String key) { + public Object get(final long entryPointer, String key, boolean reverse) { if (entryPointer < 0) throw new IllegalStateException("Pointer to access EdgeKVStorage cannot be negative:" + entryPointer); @@ -418,27 +369,13 @@ public Object get(final long entryPointer, String key) { int keyIndexPositive = Math.abs(currentKeyIndexRaw); assert keyIndexPositive < indexToKey.size() : "invalid key index " + keyIndexPositive + ">=" + indexToKey.size() + ", entryPointer=" + entryPointer + ", max=" + bytePointer; tmpPointer += 2; - if (keyIndexPositive == keyIndex) { - if (currentKeyIndexRaw < 0) { - byte[] valueBytes = new byte[4]; - vals.getBytes(tmpPointer, valueBytes, valueBytes.length); - tmpPointer = entryPointer - bitUtil.toInt(valueBytes); - tmpPointer += 2; - if (tmpPointer > bytePointer) - throw new IllegalStateException("dup marker " + bytePointer + " should exist but points into not yet allocated area " + tmpPointer); - } - + if (keyIndexPositive == keyIndex) return deserializeObj(null, tmpPointer, indexToClass.get(keyIndex)); - } - // skip to next entry of same edge either via skipping the pointer (raw<0) or the real value - if (currentKeyIndexRaw < 0) { - tmpPointer += 4; - } else { - Class clazz = indexToClass.get(keyIndexPositive); - int valueLength = hasDynLength(clazz) ? 1 + vals.getByte(tmpPointer) & 0xFF : getFixLength(clazz); - tmpPointer += valueLength; - } + // skip to next entry of same edge via skipping the real value + Class clazz = indexToClass.get(keyIndexPositive); + int valueLength = hasDynLength(clazz) ? 1 + vals.getByte(tmpPointer) & 0xFF : getFixLength(clazz); + tmpPointer += valueLength; } // value for specified key does not exist for the specified pointer diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index cf2606b4325..bdffe30f94c 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -963,13 +963,13 @@ public Map getKeyValues() { @Override public Object getValue(String key) { int kvEntryRef = store.getKeyValuesRef(edgePointer); - return baseGraph.edgeKVStorage.get(kvEntryRef, key); + return baseGraph.edgeKVStorage.get(kvEntryRef, key, reverse); } @Override public String getName() { int kvEntryRef = store.getKeyValuesRef(edgePointer); - String name = (String) baseGraph.edgeKVStorage.get(kvEntryRef, "name"); + String name = (String) baseGraph.edgeKVStorage.get(kvEntryRef, "name", reverse); // preserve backward compatibility (returns empty string if name tag missing) return name == null ? "" : name; } diff --git a/core/src/main/java/com/graphhopper/util/Constants.java b/core/src/main/java/com/graphhopper/util/Constants.java index e233e3a9669..7367b3b4cf5 100644 --- a/core/src/main/java/com/graphhopper/util/Constants.java +++ b/core/src/main/java/com/graphhopper/util/Constants.java @@ -74,7 +74,7 @@ public class Constants { public static final int VERSION_NODE_CH = 0; public static final int VERSION_GEOMETRY = 6; public static final int VERSION_LOCATION_IDX = 5; - public static final int VERSION_EDGEKV_STORAGE = 1; + public static final int VERSION_EDGEKV_STORAGE = 2; /** * The version without the snapshot string */ diff --git a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java index 34d315f7825..55ffbf4c3b5 100644 --- a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java +++ b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java @@ -35,14 +35,14 @@ public void putSame() { EdgeKVStorage index = create(); long aPointer = index.add(createMap("a", "same name", "b", "same name")); - assertNull(index.get(aPointer, "")); - assertEquals("same name", index.get(aPointer, "a")); - assertEquals("same name", index.get(aPointer, "b")); - assertNull(index.get(aPointer, "c")); + assertNull(index.get(aPointer, "", false)); + assertEquals("same name", index.get(aPointer, "a", false)); + assertEquals("same name", index.get(aPointer, "b", false)); + assertNull(index.get(aPointer, "c", false)); index = create(); aPointer = index.add(createMap("a", "a name", "b", "same name")); - assertEquals("a name", index.get(aPointer, "a")); + assertEquals("a name", index.get(aPointer, "a", false)); } @Test @@ -50,11 +50,33 @@ public void putAB() { EdgeKVStorage index = create(); long aPointer = index.add(createMap("a", "a name", "b", "b name")); - assertNull(index.get(aPointer, "")); - assertEquals("a name", index.get(aPointer, "a")); - assertEquals("b name", index.get(aPointer, "b")); + assertNull(index.get(aPointer, "", false)); + assertEquals("a name", index.get(aPointer, "a", false)); + assertEquals("b name", index.get(aPointer, "b", false)); } +// @Test +// public void getForwardBackward() { +// EdgeKVStorage index = create(); +// // special keys like :forward and :backward have a meaning +// // TODO NOW use first two bits of short value (key) and check if deduplication with negative bit is really necessary +// long aPointer = index.add(createMap("keyA:forward", "FORWARD", "keyB:backward", "BACKWARD", "keyC", "BOTH")); +// +// assertNull(index.get(aPointer, "", false)); +// +// assertEquals("FORWARD", index.get(aPointer, "keyA", false)); +// assertNull(index.get(aPointer, "keyA", true)); +// +// assertNull(index.get(aPointer, "keyB", false)); +// assertEquals("BACKWARD", index.get(aPointer, "keyB", true)); +// +// assertEquals("BOTH", index.get(aPointer, "keyC", false)); +// assertEquals("BOTH", index.get(aPointer, "keyC", true)); +// +// assertEquals(createMap("keyA:forward", "FORWARD", "keyB:backward", "BACKWARD", "keyC", "BOTH"), +// index.getAll(aPointer)); +// } + @Test public void putEmpty() { EdgeKVStorage index = create(); @@ -64,7 +86,7 @@ public void putEmpty() { assertThrows(IllegalArgumentException.class, () -> index.add(createMap("blup", null))); assertThrows(IllegalArgumentException.class, () -> index.add(createMap(null, null))); - assertNull(index.get(0, "")); + assertNull(index.get(0, "", false)); assertEquals(5, index.add(createMap("else", "else"))); } @@ -80,12 +102,12 @@ public void putMany() { tmpPointer = aPointer; } - assertEquals("b name 9999", index.get(aPointer, "b")); - assertEquals("c name 9999", index.get(aPointer, "c")); + assertEquals("b name 9999", index.get(aPointer, "b", false)); + assertEquals("c name 9999", index.get(aPointer, "c", false)); - assertEquals("a name 567", index.get(tmpPointer, "a")); - assertEquals("b name 567", index.get(tmpPointer, "b")); - assertEquals("c name 567", index.get(tmpPointer, "c")); + assertEquals("a name 567", index.get(tmpPointer, "a", false)); + assertEquals("b name 567", index.get(tmpPointer, "b", false)); + assertEquals("c name 567", index.get(tmpPointer, "c", false)); } @Test @@ -102,31 +124,6 @@ public void putManyKeys() { } } - @Test - public void putDuplicate() { - EdgeKVStorage index = create(); - long aPointer = index.add(createMap("a", "longer name", "b", "longer name")); - long bPointer = index.add(createMap("c", "longer other name")); - // value storage: 1 byte for count, 2 bytes for keyIndex and 4 bytes for delta of dup_marker and 3 bytes (keyIndex + length for "longer name") - assertEquals(aPointer + 1 + (2 + 4) + 3 + "longer name".getBytes(Helper.UTF_CS).length, bPointer); - // no de-duplication as too short: - long cPointer = index.add(createMap("temp", "temp")); - assertEquals(bPointer + 1 + 3 + "longer other name".getBytes(Helper.UTF_CS).length, cPointer); - assertEquals("longer name", index.get(aPointer, "a")); - assertEquals("longer name", index.get(aPointer, "b")); - assertEquals("longer other name", index.get(bPointer, "c")); - assertEquals("temp", index.get(cPointer, "temp")); - - index = create(); - index.add(createMap("a", "longer name", "b", "longer name")); - bPointer = index.add(createMap("a", "longer name", "b", "longer name")); - cPointer = index.add(createMap("a", "longer name", "b", "longer name")); - assertEquals(bPointer, cPointer); - - assertEquals("{a=longer name, b=longer name}", index.getAll(aPointer).toString()); - assertEquals("{a=longer name, b=longer name}", index.getAll(cPointer).toString()); - } - @Test public void testNoErrorOnLargeStringValue() { EdgeKVStorage index = create(); @@ -136,7 +133,7 @@ public void testNoErrorOnLargeStringValue() { } assertEquals(254, str.getBytes(Helper.UTF_CS).length); long result = index.add(createMap("", str)); - assertEquals(127, ((String) index.get(result, "")).length()); + assertEquals(127, ((String) index.get(result, "", false)).length()); } @Test @@ -163,7 +160,7 @@ public void testNoErrorOnLargestByteArray() { copy[i] = bytes[i]; } long result = index.add(Collections.singletonMap("myval", bytes)); - bytes = (byte[]) index.get(result, "myval"); + bytes = (byte[]) index.get(result, "myval", false); assertArrayEquals(copy, bytes); final byte[] biggerByteArray = Arrays.copyOf(bytes, 256); @@ -183,10 +180,10 @@ public void testIntLongDoubleFloat() { // initial point is 1, then twice plus 1 + (2+4) and twice plus 1 + (2+8) assertEquals(1 + 36, after4Inserts); - assertEquals(4f, index.get(floatres, "floatres")); - assertEquals(4L, index.get(longres, "longres")); - assertEquals(4d, index.get(doubleres, "doubleres")); - assertEquals(4, index.get(intres, "intres")); + assertEquals(4f, index.get(floatres, "floatres", false)); + assertEquals(4L, index.get(longres, "longres", false)); + assertEquals(4d, index.get(doubleres, "doubleres", false)); + assertEquals(4, index.get(intres, "intres", false)); } @Test @@ -222,7 +219,7 @@ public void testFlush() { index = new EdgeKVStorage(new RAMDirectory(location, true), 1000); assertTrue(index.loadExisting()); - assertEquals("test", index.get(pointer, "")); + assertEquals("test", index.get(pointer, "", false)); // make sure bytePointer is correctly set after loadExisting long newPointer = index.add(createMap("", "testing")); assertEquals(pointer + 1 + 3 + "test".getBytes().length, newPointer, newPointer + ">" + pointer); @@ -247,12 +244,12 @@ public void testLoadKeys() { index = new EdgeKVStorage(new RAMDirectory(location, true), 1000); assertTrue(index.loadExisting()); assertEquals("[, c, a, b]", index.getKeys().toString()); - assertEquals("test value", index.get(pointerA, "c")); - assertNull(index.get(pointerA, "b")); + assertEquals("test value", index.get(pointerA, "c", false)); + assertNull(index.get(pointerA, "b", false)); - assertNull(index.get(pointerB, "")); - assertEquals("value", index.get(pointerB, "a")); - assertEquals("another value", index.get(pointerB, "b")); + assertNull(index.get(pointerB, "", false)); + assertEquals("value", index.get(pointerB, "a", false)); + assertEquals("another value", index.get(pointerB, "b", false)); assertEquals("{a=value, b=another value}", index.getAll(pointerB).toString()); index.close(); @@ -265,11 +262,11 @@ public void testEmptyKey() { long pointerA = index.add(createMap("", "test value")); long pointerB = index.add(createMap("a", "value", "b", "another value")); - assertEquals("test value", index.get(pointerA, "")); - assertNull(index.get(pointerA, "a")); + assertEquals("test value", index.get(pointerA, "", false)); + assertNull(index.get(pointerA, "a", false)); - assertEquals("value", index.get(pointerB, "a")); - assertNull(index.get(pointerB, "")); + assertEquals("value", index.get(pointerB, "a", false)); + assertNull(index.get(pointerB, "", false)); } @Test @@ -319,7 +316,7 @@ public void testRandom() { Map map = index.getAll(pointers.get(i)); assertTrue(map.size() > 0, i + " " + map); for (Map.Entry entry : map.entrySet()) { - Object value = index.get(pointers.get(i), entry.getKey()); + Object value = index.get(pointers.get(i), entry.getKey(), false); assertEquals(entry.getValue(), value, i + " " + map); } } @@ -332,7 +329,7 @@ public void testRandom() { Map map = index.getAll(pointers.get(i)); assertTrue(map.size() > 0, i + " " + map); for (Map.Entry entry : map.entrySet()) { - Object value = index.get(pointers.get(i), entry.getKey()); + Object value = index.get(pointers.get(i), entry.getKey(), false); assertEquals(entry.getValue(), value, i + " " + map); } } From c9488df13ef26f2eee7d5f8c32b3e12700a427b1 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 6 Jul 2022 19:25:41 +0200 Subject: [PATCH 085/389] Move outdoor vehicles list --- .../com/graphhopper/routing/DefaultWeightingFactory.java | 8 ++------ .../graphhopper/routing/util/VehicleEncodedValues.java | 4 ++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java index b7f3d51ad2e..34ffd51866f 100644 --- a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java +++ b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java @@ -21,6 +21,7 @@ import com.graphhopper.config.Profile; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.routing.util.VehicleEncodedValues; import com.graphhopper.routing.weighting.*; import com.graphhopper.routing.weighting.custom.CustomModelParser; import com.graphhopper.routing.weighting.custom.CustomProfile; @@ -30,10 +31,6 @@ import com.graphhopper.util.PMap; import com.graphhopper.util.Parameters; -import java.util.Arrays; -import java.util.List; - -import static com.graphhopper.routing.util.VehicleEncodedValuesFactory.*; import static com.graphhopper.routing.weighting.FastestWeighting.DESTINATION_FACTOR; import static com.graphhopper.routing.weighting.FastestWeighting.PRIVATE_FACTOR; import static com.graphhopper.routing.weighting.TurnCostProvider.NO_TURN_COST_PROVIDER; @@ -41,7 +38,6 @@ import static com.graphhopper.util.Helper.toLowerCase; public class DefaultWeightingFactory implements WeightingFactory { - private static final List OUTDOOR_VEHICLES = Arrays.asList(BIKE, BIKE2, RACINGBIKE, MOUNTAINBIKE, FOOT, HIKE, WHEELCHAIR); private final BaseGraph graph; private final EncodingManager encodingManager; @@ -133,6 +129,6 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis } public boolean isOutdoorVehicle(String name) { - return OUTDOOR_VEHICLES.contains(name); + return VehicleEncodedValues.OUTDOOR_VEHICLES.contains(name); } } \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index f7e83945bb4..59828288b7b 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -21,11 +21,15 @@ import com.graphhopper.routing.ev.*; import com.graphhopper.util.PMap; +import java.util.Arrays; import java.util.List; import static com.graphhopper.routing.util.EncodingManager.getKey; +import static com.graphhopper.routing.util.VehicleEncodedValuesFactory.*; public class VehicleEncodedValues { + public static final List OUTDOOR_VEHICLES = Arrays.asList(BIKE, BIKE2, RACINGBIKE, MOUNTAINBIKE, FOOT, HIKE, WHEELCHAIR); + private final String name; private final BooleanEncodedValue accessEnc; private final DecimalEncodedValue avgSpeedEnc; From 344e969439862e2641c269cffac8507bc00e2d00 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 6 Jul 2022 22:18:43 +0200 Subject: [PATCH 086/389] Relax speed EV requirement for EncodingManager#getVehicles --- .../graphhopper/routing/util/EncodingManager.java | 5 +++-- .../routing/util/EncodingManagerTest.java | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java index d958780ba18..bb587c56f94 100644 --- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java +++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java @@ -186,11 +186,12 @@ public boolean hasEncodedValue(String key) { } public List getVehicles() { - // the supported vehicles are all those prefixes for which there is an access and speed EV + // we define the 'vehicles' as all the prefixes for which there is an access and speed EV + // any EVs that contain prefix_average_speed are accepted return getEncodedValues().stream() .filter(ev -> ev.getName().endsWith("_access")) .map(ev -> ev.getName().replaceAll("_access", "")) - .filter(v -> hasEncodedValue(VehicleSpeed.key(v))) + .filter(v -> getEncodedValues().stream().anyMatch(ev -> ev.getName().contains(VehicleSpeed.key(v)))) .collect(Collectors.toList()); } diff --git a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java index 7e6660e5859..cdab04a1643 100644 --- a/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/EncodingManagerTest.java @@ -17,7 +17,7 @@ */ package com.graphhopper.routing.util; -import com.graphhopper.routing.ev.DecimalEncodedValueImpl; +import com.graphhopper.routing.ev.*; import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; @@ -80,4 +80,17 @@ public void testRegisterOnlyOnceAllowed() { assertThrows(IllegalStateException.class, () -> EncodingManager.start().add(speedEnc).build()); } + @Test + public void testGetVehicles() { + EncodingManager em = EncodingManager.start() + .add(VehicleAccess.create("car")) + .add(VehicleAccess.create("bike")).add(VehicleSpeed.create("bike", 4, 2, true)) + .add(VehicleSpeed.create("roads", 5, 5, false)) + .add(VehicleAccess.create("hike")).add(new DecimalEncodedValueImpl("whatever_hike_average_speed_2022", 5, 5, true)) + .add(new EnumEncodedValue<>(RoadAccess.KEY, RoadAccess.class)) + .build(); + // only for bike+hike there is access+'speed' + assertEquals(Arrays.asList("bike", "hike"), em.getVehicles()); + } + } From f4beff02273b6208eaf4dccc1eed47cde50e09ad Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 6 Jul 2022 22:39:21 +0200 Subject: [PATCH 087/389] Check vehicle instead of access/speed in checkProfilesConsistency --- core/src/main/java/com/graphhopper/GraphHopper.java | 6 ++---- .../main/java/com/graphhopper/routing/ProfileResolver.java | 2 +- .../java/com/graphhopper/routing/ProfileResolverTest.java | 2 +- .../application/resources/RouteResourceTest.java | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 5159f766cce..3468b7ee46d 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -976,11 +976,9 @@ private void checkProfilesConsistency() { throw new IllegalArgumentException("There has to be at least one profile"); EncodingManager encodingManager = getEncodingManager(); for (Profile profile : profilesByName.values()) { - String accessEncName = VehicleAccess.key(profile.getVehicle()); - String speedEncName = VehicleSpeed.key(profile.getVehicle()); - if (!encodingManager.hasEncodedValue(accessEncName) || !encodingManager.hasEncodedValue(speedEncName)) + if (!encodingManager.getVehicles().contains(profile.getVehicle())) throw new IllegalArgumentException("Unknown vehicle '" + profile.getVehicle() + "' in profile: " + profile + ". " + - "Encoded values " + accessEncName + " and " + speedEncName + " are required"); + "Available vehicles: " + String.join(",", encodingManager.getVehicles())); DecimalEncodedValue turnCostEnc = encodingManager.hasEncodedValue(TurnCost.key(profile.getVehicle())) ? encodingManager.getDecimalEncodedValue(TurnCost.key(profile.getVehicle())) : null; diff --git a/core/src/main/java/com/graphhopper/routing/ProfileResolver.java b/core/src/main/java/com/graphhopper/routing/ProfileResolver.java index 5083b06052b..684b448d64b 100644 --- a/core/src/main/java/com/graphhopper/routing/ProfileResolver.java +++ b/core/src/main/java/com/graphhopper/routing/ProfileResolver.java @@ -82,7 +82,7 @@ public Profile resolveProfile(PMap hints) { if (!vehicle.isEmpty()) { List availableVehicles = encodingManager.getVehicles(); if (!availableVehicles.contains(vehicle)) - throw new IllegalArgumentException("Vehicle not supported: `" + vehicle + "`. Supported are: `" + availableVehicles + + throw new IllegalArgumentException("Vehicle not supported: `" + vehicle + "`. Supported are: `" + String.join(",", availableVehicles) + "`\nYou should consider using the `profile` parameter instead of specifying a vehicle." + "\nAvailable profiles: " + getProfileNames() + "\nTo learn more about profiles, see: docs/core/profiles.md"); diff --git a/core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java b/core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java index 3d859d5d4e5..62e1766f159 100644 --- a/core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java +++ b/core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java @@ -170,7 +170,7 @@ private void assertProfileNotFound(ProfileResolver profileResolver, PMap hints) private void assertUnsupportedVehicle(ProfileResolver profileResolver, String vehicle, List supported) { IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> profileResolver.resolveProfile(new PMap().putObject("vehicle", vehicle))); - assertTrue(e.getMessage().contains("Vehicle not supported: `" + vehicle + "`. Supported are: `" + supported + "`"), e.getMessage()); + assertTrue(e.getMessage().contains("Vehicle not supported: `" + vehicle + "`. Supported are: `" + String.join(",", supported) + "`"), e.getMessage()); } } \ No newline at end of file diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java index 44b93c1a97d..82b52cc222e 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java @@ -492,7 +492,7 @@ public void testGraphHopperWebRealExceptions(boolean usePost) { ex = rsp.getErrors().get(0); assertTrue(ex instanceof IllegalArgumentException, "Wrong exception found: " + ex.getClass().getName() + ", IllegalArgumentException expected."); - assertTrue(ex.getMessage().contains("Vehicle not supported: `space-shuttle`. Supported are: `[car]`" + + assertTrue(ex.getMessage().contains("Vehicle not supported: `space-shuttle`. Supported are: `car`" + "\nYou should consider using the `profile` parameter instead of specifying a vehicle." + "\nAvailable profiles: [my_car]"), ex.getMessage()); From 366240262c670fa54e71d925b4d9457b03d80fab Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 7 Jul 2022 14:30:09 +0200 Subject: [PATCH 088/389] reduce distance when average_speed path details can be missing, fixes #2620 --- .../com/graphhopper/util/details/AverageSpeedDetails.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java b/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java index 4abf1b837f9..25e92bbeef6 100644 --- a/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java @@ -36,9 +36,9 @@ protected Object getCurrentValue() { @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { // for very short edges we might not be able to calculate a proper value for speed. dividing by calcMillis can - // even lead to speed=Infinity -> just ignore these cases here, see #1848 + // even lead to speed=Infinity -> just ignore these cases here, see #1848 and #2620 final double distance = edge.getDistance(); - if (distance < 0.1) { + if (distance < 0.01) { if (decimalValue != null) return false; From 031faec4c6861a3dc49854de35c6c39742813cdf Mon Sep 17 00:00:00 2001 From: Rafael Sanches Telles Date: Thu, 7 Jul 2022 08:36:36 -0400 Subject: [PATCH 089/389] Valid if PathDetail is null (#2618) * Valid if object is null * Adding my name in contributors * Adjusting indentation * Update CONTRIBUTORS.md Co-authored-by: Rafael Telles Co-authored-by: Peter --- CONTRIBUTORS.md | 13 ++++++------ .../jackson/PathDetailDeserializer.java | 6 ++++-- .../jackson/PathDetailDeserializerTest.java | 20 +++++++++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 web-api/src/test/java/com/graphhopper/jackson/PathDetailDeserializerTest.java diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 6133a0c6545..6ad9db58041 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -4,11 +4,11 @@ Most of the contributors are mentioned at Github as [Members](https://github.com Here is an overview: + * agouge, discussion and API refactoring * AnahitaS, docs for Android, Android, Tomcat * andreaswolf, flag encoder versioning and more * andreylh, polygon for blocked area #1306 - * Anvoker, fixes like #1614 and helped with JUnit 5 migration #1632 - * agouge, discussion and API refactoring + * Anvoker, fixes like #1614 and helped with JUnit 5 migration #1632 * b3nn0, Android improvements * baumboi, path detail and landmark improvements * boldtrn, one of the core developers with motorcycle knowledge :) @@ -29,7 +29,7 @@ Here is an overview: * elibar, fix for alternative route calculation * fbonzon, several UI improvements like #615 * florent-morel, improvements regarding fords, #320 - * fredao, translations + * fredao, translations * gberaudo, improvements regarding elevation * GProbo, fixes like #2241 * HarelM, improvements regarding elevation @@ -63,23 +63,24 @@ Here is an overview: * oschlueter, fixes like #1185 * otbutz, added multiple EncodedValues * PGWelch, shapefile reader #874 + * rafaelstelles, fix deserializer web-api * rajanski, script to do routing via PostGIS * ratrun, route relations, GPX information, bike handling etc * rodneyodonnell, improved dead end removal (PrepareRoutingSubnetworks) and fords * rodo, more descriptions * rory, support milisecond gpx timestamps, see #4 + * samruston, improved point hint matching * seeebiii, motorcycle improvements * sguill, fixes like #1683 + * shunfan-shao, fix potential flaky tests * skienzl, imperial units for /navigate, related to #2071 * stefanholder, Stefan Holder, BMW AG, creating and integrating the hmm-lib (#49, #66, #69) and penalizing inner-link U-turns (#88, #91), refactored unfavoring of virtual edges #885 - * stevensnoeijen, fixes like #1568 + * stevensnoeijen, fixes like #1568 * Svantulden, improved documentation and nearest API * taulinger, hopefully more to come * thehereward, code cleanups like #620 * vvikas, ideas for many to many improvements and #616 * zstadler, multiple fixes and car4wd - * samruston, improved point hint matching - * shunfan-shao, fix potential flaky tests ## Translations diff --git a/web-api/src/main/java/com/graphhopper/jackson/PathDetailDeserializer.java b/web-api/src/main/java/com/graphhopper/jackson/PathDetailDeserializer.java index 7dc84ecda30..7db6383c0d7 100644 --- a/web-api/src/main/java/com/graphhopper/jackson/PathDetailDeserializer.java +++ b/web-api/src/main/java/com/graphhopper/jackson/PathDetailDeserializer.java @@ -17,6 +17,8 @@ */ package com.graphhopper.jackson; +import java.io.IOException; + import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; @@ -24,8 +26,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.graphhopper.util.details.PathDetail; -import java.io.IOException; - public class PathDetailDeserializer extends JsonDeserializer { @Override @@ -47,6 +47,8 @@ else if (val.canConvertToLong()) pd = new PathDetail(val.asLong()); else if (val.isTextual()) pd = new PathDetail(val.asText()); + else if (val.isNull()) + pd = new PathDetail(null); else throw new JsonParseException(jp, "Unsupported type of PathDetail value " + pathDetail.getNodeType().name()); diff --git a/web-api/src/test/java/com/graphhopper/jackson/PathDetailDeserializerTest.java b/web-api/src/test/java/com/graphhopper/jackson/PathDetailDeserializerTest.java new file mode 100644 index 00000000000..7cf953db2b1 --- /dev/null +++ b/web-api/src/test/java/com/graphhopper/jackson/PathDetailDeserializerTest.java @@ -0,0 +1,20 @@ +package com.graphhopper.jackson; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.graphhopper.GHResponse; + +class PathDetailDeserializerTest { + + @Test + public void else_null_detail_average_speed() throws JsonProcessingException { + final ObjectMapper objectMapper = Jackson.newObjectMapper(); + final String result = "{\"hints\":{\"visited_nodes.sum\":90,\"visited_nodes.average\":90},\"info\":{\"copyrights\":[\"GraphHopper\",\"OpenStreetMap contributors\"],\"took\":1},\"paths\":[{\"distance\":9863.287,\"weight\":888.630785,\"time\":740658,\"transfers\":0,\"points_encoded\":false,\"bbox\":[-58.476658,-34.650384,-58.429018,-34.628717],\"points\":{\"type\":\"LineString\",\"coordinates\":[[-58.465985,-34.650384],[-58.465985,-34.650384],[-58.46555,-34.649904],[-58.465416,-34.649686],[-58.464935,-34.649033],[-58.464199,-34.648446],[-58.464014,-34.648262],[-58.463675,-34.647783],[-58.462575,-34.645549],[-58.462426,-34.645311],[-58.462031,-34.644079],[-58.461681,-34.643299],[-58.461561,-34.643099],[-58.461258,-34.642675],[-58.460623,-34.642013],[-58.460372,-34.641799],[-58.458082,-34.640102],[-58.456072,-34.638467],[-58.45555,-34.638104],[-58.453825,-34.637045],[-58.453518,-34.636894],[-58.453287,-34.636799],[-58.452854,-34.636647],[-58.452399,-34.636541],[-58.451783,-34.636477],[-58.451437,-34.636461],[-58.45096,-34.636455],[-58.449346,-34.636492],[-58.448718,-34.636475],[-58.448065,-34.636381],[-58.447576,-34.636252],[-58.447071,-34.636088],[-58.446624,-34.635893],[-58.445336,-34.635105],[-58.443767,-34.633999],[-58.441687,-34.632678],[-58.440299,-34.631866],[-58.439234,-34.631214],[-58.43877,-34.630985],[-58.437805,-34.630657],[-58.436974,-34.630468],[-58.434133,-34.630075],[-58.432415,-34.629923],[-58.430902,-34.629722],[-58.430437,-34.62966],[-58.430367,-34.629977],[-58.429018,-34.629782],[-58.429325,-34.628717],[-58.430635,-34.628917],[-58.430561,-34.62922],[-58.432879,-34.629618],[-58.434549,-34.629933],[-58.436946,-34.630326],[-58.437878,-34.630532],[-58.438762,-34.630822],[-58.439319,-34.63109],[-58.440885,-34.632045],[-58.442483,-34.632958],[-58.443484,-34.633603],[-58.445463,-34.634973],[-58.446519,-34.635643],[-58.446771,-34.635791],[-58.447069,-34.635926],[-58.447557,-34.636096],[-58.448078,-34.636254],[-58.44873,-34.636348],[-58.451367,-34.636297],[-58.452221,-34.636358],[-58.452712,-34.636448],[-58.453267,-34.636623],[-58.453552,-34.63673],[-58.453854,-34.636872],[-58.454214,-34.637075],[-58.455065,-34.637593],[-58.456306,-34.638427],[-58.457424,-34.639367],[-58.45823,-34.640018],[-58.460244,-34.641438],[-58.460783,-34.641844],[-58.461038,-34.642077],[-58.461295,-34.642353],[-58.461474,-34.64258],[-58.461901,-34.643196],[-58.462073,-34.643528],[-58.462269,-34.644017],[-58.462687,-34.645211],[-58.463101,-34.645982],[-58.463506,-34.646562],[-58.463782,-34.646898],[-58.464636,-34.647832],[-58.465174,-34.648395],[-58.4654,-34.648587],[-58.465807,-34.648882],[-58.466103,-34.649053],[-58.466435,-34.6492],[-58.466725,-34.649293],[-58.467056,-34.649351],[-58.467634,-34.649388],[-58.469992,-34.64935],[-58.47232,-34.64918],[-58.473264,-34.649091],[-58.474569,-34.648922],[-58.475036,-34.648843],[-58.475346,-34.648771],[-58.475799,-34.648596],[-58.476658,-34.648084]]},\"instructions\":[{\"distance\":3923.699,\"heading\":90,\"sign\":0,\"interval\":[0,41],\"text\":\"Continue na Autopista Teniente General Luis Dellepiane\",\"time\":228978,\"street_name\":\"Autopista Teniente General Luis Dellepiane\"},{\"distance\":341.449,\"sign\":7,\"interval\":[41,44],\"text\":\"Mantenha-se à direita\",\"time\":52395,\"street_name\":\"\"},{\"distance\":35.813,\"sign\":2,\"interval\":[44,45],\"text\":\"Vire à direita na Viel\",\"time\":7162,\"street_name\":\"Viel\"},{\"distance\":125.343,\"sign\":-2,\"interval\":[45,46],\"text\":\"Vire à esquerda na Tejedor\",\"time\":25068,\"street_name\":\"Tejedor\"},{\"distance\":121.839,\"sign\":-2,\"interval\":[46,47],\"text\":\"Vire à esquerda na Doblas\",\"time\":31329,\"street_name\":\"Doblas\"},{\"distance\":121.976,\"sign\":-2,\"interval\":[47,48],\"text\":\"Vire à esquerda na Zuviría\",\"time\":24395,\"street_name\":\"Zuviría\"},{\"distance\":34.367,\"sign\":-2,\"interval\":[48,49],\"text\":\"Vire à esquerda na Viel\",\"time\":6873,\"street_name\":\"Viel\"},{\"distance\":3623.263,\"sign\":2,\"interval\":[49,85],\"text\":\"Vire à direita\",\"time\":234503,\"street_name\":\"\"},{\"distance\":1535.538,\"sign\":7,\"interval\":[85,105],\"text\":\"Mantenha-se à direita\",\"time\":129955,\"street_name\":\"\"},{\"distance\":0,\"sign\":4,\"last_heading\":305.9709217557622,\"interval\":[105,105],\"text\":\"Destino alcançado!\",\"time\":0,\"street_name\":\"\"}],\"legs\":[],\"details\":{\"average_speed\":[[0,1,null],[1,2,16],[2,7,78],[7,41,64],[41,43,26],[43,44,14],[44,46,18],[46,47,14],[47,49,18],[49,51,26],[51,85,64],[85,96,40],[96,103,48],[103,105,32]]},\"ascend\":40.208499908447266,\"descend\":36.19799995422363,\"snapped_waypoints\":{\"type\":\"LineString\",\"coordinates\":[[-58.465985,-34.650384],[-58.476658,-34.648084]]}}]}"; + final GHResponse ghResponse = objectMapper.readValue(result, GHResponse.class); + assertNotNull(ghResponse); + } +} From d6df61a5d8bfc403fdabb812f274bda5fea19ca1 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 7 Jul 2022 14:42:28 +0200 Subject: [PATCH 090/389] Support for forward & backward key value pairs (#2622) --- .../com/graphhopper/reader/osm/OSMReader.java | 9 +- .../querygraph/QueryOverlayBuilder.java | 3 +- .../querygraph/VirtualEdgeIterator.java | 8 +- .../querygraph/VirtualEdgeIteratorState.java | 20 +- .../com/graphhopper/search/EdgeKVStorage.java | 127 ++++++++---- .../com/graphhopper/storage/BaseGraph.java | 7 +- .../graphhopper/util/EdgeIteratorState.java | 36 ++-- .../java/com/graphhopper/util/GHUtility.java | 5 +- .../com/graphhopper/routing/PathTest.java | 137 ++++++------- .../util/NameSimilarityEdgeFilterTest.java | 13 +- .../weighting/FastestWeightingTest.java | 5 +- .../graphhopper/search/EdgeKVStorageTest.java | 182 +++++++++--------- .../storage/AbstractGraphStorageTester.java | 8 +- .../graphhopper/storage/BaseGraphTest.java | 26 ++- .../storage/BaseGraphWithTurnCostsTest.java | 6 +- .../graphhopper/util/InstructionListTest.java | 61 +++--- .../util/PathSimplificationTest.java | 22 +-- .../example/LocationIndexExample.java | 7 +- .../gtfs/analysis/PtGraphAsAdjacencyList.java | 7 +- .../graphhopper/gpx/GpxConversionsTest.java | 14 +- .../resources/ExtendedJsonResponseTest.java | 3 +- 21 files changed, 400 insertions(+), 306 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index e12353d87bd..d4332942e86 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -35,6 +35,7 @@ import com.graphhopper.routing.util.countryrules.CountryRule; import com.graphhopper.routing.util.countryrules.CountryRuleFactory; import com.graphhopper.routing.util.parsers.TurnCostParser; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.NodeAccess; @@ -332,14 +333,14 @@ protected void addEdge(int fromIndex, int toIndex, PointList pointList, ReaderWa if (edgeFlags.isEmpty()) return; - Map map = new HashMap<>(2); + List list = new ArrayList<>(2); // the storage does not accept too long strings -> Helper.cutStringForKV if (way.hasTag("way_name")) // do not store empty string if missing tag - map.put("name", Helper.cutStringForKV(way.getTag("way_name", ""))); + list.add(new EdgeKVStorage.KeyValue("name", Helper.cutStringForKV(way.getTag("way_name", "")))); if (way.hasTag("way_ref")) - map.put("ref", Helper.cutStringForKV(way.getTag("way_ref", ""))); + list.add(new EdgeKVStorage.KeyValue("ref", Helper.cutStringForKV(way.getTag("way_ref", "")))); EdgeIteratorState edge = baseGraph.edge(fromIndex, toIndex).setDistance(distance).setFlags(edgeFlags). - setKeyValues(map); + setKeyValues(list); // If the entire way is just the first and last point, do not waste space storing an empty way geometry if (pointList.size() > 2) { diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java b/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java index 54948a849ee..e3f09656a43 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/QueryOverlayBuilder.java @@ -20,6 +20,7 @@ import com.carrotsearch.hppc.predicates.IntObjectPredicate; import com.graphhopper.coll.GHIntObjectHashMap; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.Graph; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.index.Snap; @@ -222,7 +223,7 @@ private void createEdges(int origEdgeKey, int origRevEdgeKey, boolean reverse = closestEdge.get(EdgeIteratorState.REVERSE_STATE); // edges between base and snapped point - Map keyValues = closestEdge.getKeyValues(); + List keyValues = closestEdge.getKeyValues(); VirtualEdgeIteratorState baseEdge = new VirtualEdgeIteratorState(origEdgeKey, GHUtility.createEdgeKey(virtEdgeId, prevNodeId == nodeId, false), prevNodeId, nodeId, baseDistance, closestEdge.getFlags(), keyValues, basePoints, reverse); VirtualEdgeIteratorState baseReverseEdge = new VirtualEdgeIteratorState(origRevEdgeKey, GHUtility.createEdgeKey(virtEdgeId, prevNodeId == nodeId, true), diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java index b01f0fd8977..c47272890b9 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIterator.java @@ -19,6 +19,7 @@ import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.EdgeIterator; import com.graphhopper.util.EdgeIteratorState; @@ -26,7 +27,6 @@ import com.graphhopper.util.PointList; import java.util.List; -import java.util.Map; /** * @author Peter Karich @@ -262,13 +262,13 @@ public String getName() { } @Override - public Map getKeyValues() { + public List getKeyValues() { return getCurrentEdge().getKeyValues(); } @Override - public EdgeIteratorState setKeyValues(Map map) { - return getCurrentEdge().setKeyValues(map); + public EdgeIteratorState setKeyValues(List list) { + return getCurrentEdge().setKeyValues(list); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java index 002b8b06f98..cb99cadec62 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java @@ -18,13 +18,14 @@ package com.graphhopper.routing.querygraph; import com.graphhopper.routing.ev.*; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.FetchMode; import com.graphhopper.util.GHUtility; import com.graphhopper.util.PointList; -import java.util.Map; +import java.util.List; /** * Creates an edge state decoupled from a graph where nodes, pointList, etc are kept in memory. @@ -40,14 +41,14 @@ public class VirtualEdgeIteratorState implements EdgeIteratorState { private final int originalEdgeKey; private double distance; private IntsRef edgeFlags; - private Map keyValues; + private List keyValues; // true if edge should be avoided as start/stop private boolean unfavored; private EdgeIteratorState reverseEdge; private final boolean reverse; public VirtualEdgeIteratorState(int originalEdgeKey, int edgeKey, int baseNode, int adjNode, double distance, - IntsRef edgeFlags, Map keyValues, PointList pointList, boolean reverse) { + IntsRef edgeFlags, List keyValues, PointList pointList, boolean reverse) { this.originalEdgeKey = originalEdgeKey; this.edgeKey = edgeKey; this.baseNode = baseNode; @@ -309,25 +310,28 @@ public EdgeIteratorState set(StringEncodedValue property, String fwd, String bwd @Override public String getName() { - String name = (String) keyValues.get("name"); + String name = (String) getValue("name"); // preserve backward compatibility (returns empty string if name tag missing) return name == null ? "" : name; } @Override - public EdgeIteratorState setKeyValues(Map map) { - this.keyValues = map; + public EdgeIteratorState setKeyValues(List list) { + this.keyValues = list; return this; } @Override - public Map getKeyValues() { + public List getKeyValues() { return keyValues; } @Override public Object getValue(String key) { - return keyValues.get(key); + for (EdgeKVStorage.KeyValue keyValue : keyValues) { + if (keyValue.key.equals(key)) return keyValue.value; + } + return null; } /** diff --git a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java index 8b048349793..2c31e8e1db6 100644 --- a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java +++ b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java @@ -35,8 +35,8 @@ public class EdgeKVStorage { private static final long EMPTY_POINTER = 0, START_POINTER = 1; - // Store the key index in 2 bytes (for now ignore the highest bit) - static final int MAX_UNIQUE_KEYS = (1 << 15); + // Store the key index in 2 bytes. Use first 2 bits for marking fwd+bwd existence. + static final int MAX_UNIQUE_KEYS = (1 << 14); // Store string value as byte array and store the length into 1 byte private static final int MAX_LENGTH = (1 << 8) - 1; @@ -72,6 +72,7 @@ public class EdgeKVStorage { // 1. The key strings are limited MAX_UNIQUE_KEYS. A dynamic value has a maximum byte length of 255. // 2. Every key can store values only of the same type // 3. We need to loop through X entries to get the start val_x. + // 4. The key index (14 bits) is stored along with the availability (2 bits), i.e. whether they KeyValue is available in forward and/or backward directions private final DataAccess vals; private final Map keyToIndex = new HashMap<>(); private final List> indexToClass = new ArrayList<>(); @@ -79,7 +80,7 @@ public class EdgeKVStorage { private final BitUtil bitUtil = BitUtil.LITTLE; private long bytePointer = START_POINTER; private long lastEntryPointer = -1; - private Map lastEntryMap; + private List lastEntries; public EdgeKVStorage(Directory dir) { this(dir, 1000); @@ -148,33 +149,33 @@ Collection getKeys() { * * @return entryPointer with which you can later fetch the entryMap via the get or getAll method */ - public long add(final Map entryMap) { - if (entryMap == null) throw new IllegalArgumentException("specified Map must not be null"); - if (entryMap.isEmpty()) return EMPTY_POINTER; - else if (entryMap.size() > 200) + public long add(final List entries) { + if (entries == null) throw new IllegalArgumentException("specified List must not be null"); + if (entries.isEmpty()) return EMPTY_POINTER; + else if (entries.size() > 200) throw new IllegalArgumentException("Cannot store more than 200 entries per entry"); // This is a very important "compression" mechanism because one OSM way is split into multiple edges and so we // can often re-use the serialized key-value pairs of the previous edge. - if (isEquals(entryMap, lastEntryMap)) return lastEntryPointer; + if (isEquals(entries, lastEntries)) return lastEntryPointer; // If the Class of a value is unknown it should already fail here, before we modify internal data. (see #2597#discussion_r896469840) - for (Map.Entry entry : entryMap.entrySet()) - if (keyToIndex.get(entry.getKey()) != null) - getBytesForValue(indexToClass.get(keyToIndex.get(entry.getKey())), entry.getValue()); + for (KeyValue kv : entries) + if (keyToIndex.get(kv.key) != null) + getBytesForValue(indexToClass.get(keyToIndex.get(kv.key)), kv.value); - lastEntryMap = entryMap; + lastEntries = entries; lastEntryPointer = bytePointer; // while adding there could be exceptions and we need to avoid that the bytePointer is modified long currentPointer = bytePointer; vals.ensureCapacity(currentPointer + 1); - vals.setByte(currentPointer, (byte) entryMap.size()); + vals.setByte(currentPointer, (byte) entries.size()); currentPointer += 1; - for (Map.Entry entry : entryMap.entrySet()) { - String key = entry.getKey(); + for (KeyValue entry : entries) { + String key = entry.key; if (key == null) throw new IllegalArgumentException("key cannot be null"); - Object value = entry.getValue(); + Object value = entry.value; if (value == null) throw new IllegalArgumentException("value for key " + key + " cannot be null"); Integer keyIndex = keyToIndex.get(key); Class clazz; @@ -207,7 +208,7 @@ else if (entryMap.size() > 200) final byte[] valueBytes = getBytesForValue(clazz, value); vals.ensureCapacity(currentPointer + 2 + 1 + valueBytes.length); - vals.setShort(currentPointer, keyIndex.shortValue()); + vals.setShort(currentPointer, (short) (keyIndex << 2 | (entry.fwd ? 2 : 0) | (entry.bwd ? 1 : 0))); currentPointer += 2; if (hasDynLength) { vals.setByte(currentPointer, (byte) valueBytes.length); @@ -222,45 +223,46 @@ else if (entryMap.size() > 200) return lastEntryPointer; } - private boolean isEquals(Map entryMap, Map lastEntryMap) { - if (lastEntryMap != null && entryMap.size() == lastEntryMap.size()) { - for (Map.Entry entry : entryMap.entrySet()) { - Object val = entry.getValue(); - if (val == null) - throw new IllegalArgumentException("value for key " + entry.getKey() + " cannot be null"); - Object lastVal = lastEntryMap.get(entry.getKey()); - if (val instanceof byte[] && lastVal instanceof byte[] && Arrays.equals((byte[]) lastVal, (byte[]) val) - || val.equals(lastVal)) continue; - return false; + // compared to entries.equals(lastEntries) this method avoids a NPE if a value is null and throws an IAE instead + private boolean isEquals(List entries, List lastEntries) { + if (lastEntries != null && entries.size() == lastEntries.size()) { + for (int i = 0; i < entries.size(); i++) { + KeyValue kv = entries.get(i); + if (kv.value == null) + throw new IllegalArgumentException("value for key " + kv.key + " cannot be null"); + if (!kv.equals(lastEntries.get(i))) return false; } return true; } return false; } - public Map getAll(final long entryPointer) { + public List getAll(final long entryPointer) { if (entryPointer < 0) throw new IllegalStateException("Pointer to access EdgeKVStorage cannot be negative:" + entryPointer); - if (entryPointer == EMPTY_POINTER) return Collections.emptyMap(); + if (entryPointer == EMPTY_POINTER) return Collections.emptyList(); int keyCount = vals.getByte(entryPointer) & 0xFF; - if (keyCount == 0) return Collections.emptyMap(); + if (keyCount == 0) return Collections.emptyList(); - Map map = new HashMap<>(keyCount); + List list = new ArrayList<>(keyCount); long tmpPointer = entryPointer + 1; AtomicInteger sizeOfObject = new AtomicInteger(); for (int i = 0; i < keyCount; i++) { - int currentKeyIndex = vals.getShort(tmpPointer); + int currentKeyIndexRaw = vals.getShort(tmpPointer); + boolean bwd = (currentKeyIndexRaw & 1) == 1; + boolean fwd = (currentKeyIndexRaw & 2) == 2; + int currentKeyIndex = currentKeyIndexRaw >>> 2; tmpPointer += 2; Object object = deserializeObj(sizeOfObject, tmpPointer, indexToClass.get(currentKeyIndex)); tmpPointer += sizeOfObject.get(); String key = indexToKey.get(currentKeyIndex); - map.put(key, object); + list.add(new KeyValue(key, object, fwd, bwd)); } - return map; + return list; } private boolean hasDynLength(Class clazz) { @@ -366,14 +368,17 @@ public Object get(final long entryPointer, String key, boolean reverse) { long tmpPointer = entryPointer + 1; for (int i = 0; i < keyCount; i++) { int currentKeyIndexRaw = vals.getShort(tmpPointer); - int keyIndexPositive = Math.abs(currentKeyIndexRaw); - assert keyIndexPositive < indexToKey.size() : "invalid key index " + keyIndexPositive + ">=" + indexToKey.size() + ", entryPointer=" + entryPointer + ", max=" + bytePointer; + boolean bwd = (currentKeyIndexRaw & 1) == 1; + boolean fwd = (currentKeyIndexRaw & 2) == 2; + int currentKeyIndex = currentKeyIndexRaw >>> 2; + + assert currentKeyIndex < indexToKey.size() : "invalid key index " + currentKeyIndex + ">=" + indexToKey.size() + ", entryPointer=" + entryPointer + ", max=" + bytePointer; tmpPointer += 2; - if (keyIndexPositive == keyIndex) + if ((!reverse && fwd || reverse && bwd) && currentKeyIndex == keyIndex) return deserializeObj(null, tmpPointer, indexToClass.get(keyIndex)); // skip to next entry of same edge via skipping the real value - Class clazz = indexToClass.get(keyIndexPositive); + Class clazz = indexToClass.get(currentKeyIndex); int valueLength = hasDynLength(clazz) ? 1 + vals.getByte(tmpPointer) & 0xFF : getFixLength(clazz); tmpPointer += valueLength; } @@ -425,4 +430,50 @@ public boolean isClosed() { public long getCapacity() { return vals.getCapacity() + keys.getCapacity(); } + + public static class KeyValue { + public String key; + public Object value; + public boolean fwd, bwd; + + public KeyValue(String key, Object value) { + this.key = key; + this.value = value; + this.fwd = true; + this.bwd = true; + } + + public KeyValue(String key, Object value, boolean fwd, boolean bwd) { + this.key = key; + this.value = value; + this.fwd = fwd; + this.bwd = bwd; + } + + public static List createKV(String key, Object value) { + return Collections.singletonList(new KeyValue(key, value)); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + KeyValue keyValue = (KeyValue) o; + return key.equals(keyValue.key) + && fwd == keyValue.fwd + && bwd == keyValue.bwd + && (value instanceof byte[] && keyValue.value instanceof byte[] && + Arrays.equals((byte[]) value, (byte[]) keyValue.value) || value.equals(keyValue.value)); + } + + @Override + public int hashCode() { + return Objects.hash(key, value, fwd, bwd); + } + + @Override + public String toString() { + return key + '=' + value + " (" + fwd + "|" + bwd + ")"; + } + } } diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index bdffe30f94c..67124c80b27 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -27,6 +27,7 @@ import com.graphhopper.util.shapes.BBox; import java.io.Closeable; +import java.util.List; import java.util.Map; import static com.graphhopper.util.Helper.nf; @@ -946,8 +947,8 @@ public int getReverseEdgeKey() { } @Override - public EdgeIteratorState setKeyValues(Map map) { - long pointer = baseGraph.edgeKVStorage.add(map); + public EdgeIteratorState setKeyValues(List entries) { + long pointer = baseGraph.edgeKVStorage.add(entries); if (pointer > Integer.MAX_VALUE) throw new IllegalStateException("Too many key value pairs are stored, currently limited to " + Integer.MAX_VALUE + " was " + pointer); store.setKeyValuesRef(edgePointer, (int) pointer); @@ -955,7 +956,7 @@ public EdgeIteratorState setKeyValues(Map map) { } @Override - public Map getKeyValues() { + public List getKeyValues() { int kvEntryRef = store.getKeyValuesRef(edgePointer); return baseGraph.edgeKVStorage.getAll(kvEntryRef); } diff --git a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java index dec8a2568ba..c53b56a38b6 100644 --- a/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/util/EdgeIteratorState.java @@ -18,10 +18,11 @@ package com.graphhopper.util; import com.graphhopper.routing.ev.*; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.Graph; import com.graphhopper.storage.IntsRef; -import java.util.Map; +import java.util.List; /** * This interface represents an edge and is one possible state of an EdgeIterator. @@ -194,30 +195,33 @@ public boolean isStoreTwoDirections() { EdgeIteratorState set(StringEncodedValue property, String fwd, String bwd); /** - * Identical to calling getKeyValues().get("name"). I.e. if you need other properties you should prefer to call - * getKeyValues directly instead of getName. Please note that for backward compatibility getName returns an empty - * String instead of null if there was no name set. + * Identical to calling getKeyValues().get("name") if name is stored for both directions. Note that for backward + * compatibility this method returns an empty String instead of null if there was no KeyPair with key==name stored. * - * @return the stored value for the key "name" in the key-values space of this edge + * @return the stored value for the key "name" in the KeyValue list of this EdgeIteratorState. */ String getName(); /** - * This stores the specified key-value pairs in the storage of the current edge. This is more flexible compared to - * the mechanism of flags and EncodedValue and allows to store sparse key value pairs much more efficient. - * But it is slower and more inefficient on retrieval and this setKeyValues method - * should be called only once per edge as it allocates new space everytime this method is called. I.e. for many - * usages like in a custom_model currently the EncodedValue-approach should be preferred. + * This stores the specified key-value pairs in the storage of this EdgeIteratorState. This is more flexible + * compared to the mechanism of flags and EncodedValue and allows storing sparse key value pairs more efficient. + * But it might be slow and more inefficient on retrieval. Call this setKeyValues method only once per + * EdgeIteratorState as it allocates new space everytime this method is called. */ - EdgeIteratorState setKeyValues(Map map); - - Map getKeyValues(); + EdgeIteratorState setKeyValues(List map); /** - * This method returns the value of the specified key. If you need more than one value you should likely better use - * getKeyValues(). + * This method returns KeyValue pairs for both directions in contrast to {@link #getValue(String)}. * - * @see #setKeyValues(Map) + * @see #setKeyValues(List) + */ + List getKeyValues(); + + /** + * This method returns the *first* value for the specified key and only if stored for the direction of this + * EdgeIteratorState. If you need more than one value see also {@link #getKeyValues()}. Avoid storing KeyPairs with + * duplicate keys as only the first will be reachable with this method. Currently, there is no support to use this + * method in a custom_model, and you should use EncodedValues instead. */ Object getValue(String key); diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index 6d11467edb3..69a5baa7ef6 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -29,6 +29,7 @@ import com.graphhopper.routing.util.CustomArea; import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.*; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.Snap; @@ -789,12 +790,12 @@ public String getName() { } @Override - public EdgeIteratorState setKeyValues(Map keyValues) { + public EdgeIteratorState setKeyValues(List keyValues) { throw new UnsupportedOperationException("Not supported. Edge is empty."); } @Override - public Map getKeyValues() { + public List getKeyValues() { throw new UnsupportedOperationException("Not supported. Edge is empty."); } diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index e6b0af10645..066bb1e5eab 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -34,9 +34,10 @@ import java.util.*; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static com.graphhopper.storage.AbstractGraphStorageTester.assertPList; import static com.graphhopper.util.Parameters.Details.*; -import static java.util.Collections.singletonMap; +import com.graphhopper.search.EdgeKVStorage.KeyValue; import static org.junit.jupiter.api.Assertions.*; /** @@ -104,7 +105,7 @@ public void testWayList() { assertEquals(path.calcPoints().size() - 1, acc); // force minor change for instructions - edge2.setKeyValues(singletonMap("name", "2")); + edge2.setKeyValues(createKV("name", "2")); na.setNode(3, 1.0, 1.0); g.edge(1, 3).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 10.0); @@ -171,16 +172,16 @@ public void testFindInstruction() { EdgeIteratorState edge1 = g.edge(0, 1).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge1.setWayGeometry(Helper.createPointList()); - edge1.setKeyValues(singletonMap("name", "Street 1")); + edge1.setKeyValues(createKV("name", "Street 1")); EdgeIteratorState edge2 = g.edge(1, 2).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge2.setWayGeometry(Helper.createPointList()); - edge2.setKeyValues(singletonMap("name", "Street 2")); + edge2.setKeyValues(createKV("name", "Street 2")); EdgeIteratorState edge3 = g.edge(2, 3).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge3.setWayGeometry(Helper.createPointList()); - edge3.setKeyValues(singletonMap("name", "Street 3")); + edge3.setKeyValues(createKV("name", "Street 3")); EdgeIteratorState edge4 = g.edge(3, 4).setDistance(500).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge4.setWayGeometry(Helper.createPointList()); - edge4.setKeyValues(singletonMap("name", "Street 4")); + edge4.setKeyValues(createKV("name", "Street 4")); g.edge(1, 5).setDistance(10000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); g.edge(2, 5).setDistance(10000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); @@ -499,32 +500,32 @@ public void testCalcInstructionsRoundaboutIssue353() { na.setNode(10, 52.5135, 13.348); na.setNode(11, 52.514, 13.347); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 1).setDistance(5)).setKeyValues(singletonMap("name", "MainStreet 2 1")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 11).setDistance(5)).setKeyValues(singletonMap("name", "MainStreet 1 11")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 1).setDistance(5)).setKeyValues(createKV("name", "MainStreet 2 1")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 11).setDistance(5)).setKeyValues(createKV("name", "MainStreet 1 11")); // roundabout EdgeIteratorState tmpEdge; - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 9).setDistance(2)).setKeyValues(singletonMap("name", "3-9")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 9).setDistance(2)).setKeyValues(createKV("name", "3-9")); BooleanEncodedValue carManagerRoundabout = carManager.getBooleanEncodedValue(Roundabout.KEY); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(9, 10).setDistance(2)).setKeyValues(singletonMap("name", "9-10")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(9, 10).setDistance(2)).setKeyValues(createKV("name", "9-10")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(6, 10).setDistance(2)).setKeyValues(singletonMap("name", "6-10")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(6, 10).setDistance(2)).setKeyValues(createKV("name", "6-10")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(10, 1).setDistance(2)).setKeyValues(singletonMap("name", "10-1")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(10, 1).setDistance(2)).setKeyValues(createKV("name", "10-1")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 2).setDistance(5)).setKeyValues(singletonMap("name", "2-3")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 2).setDistance(5)).setKeyValues(createKV("name", "2-3")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 3).setDistance(5)).setKeyValues(singletonMap("name", "3-4")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 3).setDistance(5)).setKeyValues(createKV("name", "3-4")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(5, 4).setDistance(5)).setKeyValues(singletonMap("name", "4-5")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(5, 4).setDistance(5)).setKeyValues(createKV("name", "4-5")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 5).setDistance(5)).setKeyValues(singletonMap("name", "5-2")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 5).setDistance(5)).setKeyValues(createKV("name", "5-2")); tmpEdge.set(carManagerRoundabout, true); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 7).setDistance(5)).setKeyValues(singletonMap("name", "MainStreet 4 7")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 8).setDistance(5)).setKeyValues(singletonMap("name", "5-8")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 6).setDistance(5)).setKeyValues(singletonMap("name", "3-6")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 7).setDistance(5)).setKeyValues(createKV("name", "MainStreet 4 7")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 8).setDistance(5)).setKeyValues(createKV("name", "5-8")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 6).setDistance(5)).setKeyValues(createKV("name", "3-6")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) @@ -600,8 +601,8 @@ public void testCalcInstructionForForkWithSameName() { na.setNode(3, 48.982611, 13.121012); na.setNode(4, 48.982336, 13.121002); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "Regener Weg")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setKeyValues(singletonMap("name", "Regener Weg")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "Regener Weg")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setKeyValues(createKV("name", "Regener Weg")); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); @@ -633,8 +634,8 @@ public void testCalcInstructionForMotorwayFork() { EnumEncodedValue roadClassEnc = carManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BooleanEncodedValue roadClassLinkEnc = carManager.getBooleanEncodedValue(RoadClassLink.KEY); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "A 8")).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setKeyValues(singletonMap("name", "A 8")).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "A 8")).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setKeyValues(createKV("name", "A 8")).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, true); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); @@ -661,9 +662,9 @@ public void testCalcInstructionsEnterMotorway() { na.setNode(3, 48.630558, 9.459851); na.setNode(4, 48.63054, 9.459406); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 2).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 2).setDistance(5)).setKeyValues(createKV("name", "A 8")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) @@ -690,9 +691,9 @@ public void testCalcInstructionsMotorwayJunction() { na.setNode(3, 48.706805, 9.162995); na.setNode(4, 48.706705, 9.16329); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(singletonMap("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(createKV("name", "A 8")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -720,9 +721,9 @@ public void testCalcInstructionsOntoOneway() { na.setNode(3, -33.824415, 151.188177); na.setNode(4, -33.824437, 151.187925); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "Pacific Highway")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "Pacific Highway")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(4, 2).setDistance(5)).setKeyValues(singletonMap("name", "Greenwich Road")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "Pacific Highway")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "Pacific Highway")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(4, 2).setDistance(5)).setKeyValues(createKV("name", "Greenwich Road")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -755,9 +756,9 @@ public void testCalcInstructionIssue1047() { EnumEncodedValue roadClassEnc = carManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BooleanEncodedValue roadClassLinkEnc = carManager.getBooleanEncodedValue(RoadClassLink.KEY); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "B 156")).set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(singletonMap("name", "S 108")).set(roadClassEnc, RoadClass.SECONDARY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "B 156")).set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "B 156")).set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(createKV("name", "S 108")).set(roadClassEnc, RoadClass.SECONDARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "B 156")).set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -789,9 +790,9 @@ public void testCalcInstructionContinueLeavingStreet() { na.setNode(3, 48.982611, 13.121012); na.setNode(4, 48.982565, 13.121002); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "Regener Weg")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "Regener Weg")); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "Regener Weg")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "Regener Weg")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -819,9 +820,9 @@ public void testCalcInstructionSlightTurn() { na.setNode(3, 48.412034, 15.599411); na.setNode(4, 48.411927, 15.599197); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "Stöhrgasse")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "Stöhrgasse")); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(singletonMap("name", "Stöhrgasse")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(createKV("name", "Stöhrgasse")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -853,13 +854,13 @@ public void testUTurnLeft() { na.setNode(7, 48.402604, 9.994962); GHUtility.setSpeed(60, 0, carAccessEnc, carAvSpeedEnc, - g.edge(1, 2).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße")), - g.edge(2, 3).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße")), - g.edge(6, 5).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße")), - g.edge(5, 4).setDistance(5).setKeyValues(singletonMap("name", "Olgastraße"))); + g.edge(1, 2).setDistance(5).setKeyValues(createKV("name", "Olgastraße")), + g.edge(2, 3).setDistance(5).setKeyValues(createKV("name", "Olgastraße")), + g.edge(6, 5).setDistance(5).setKeyValues(createKV("name", "Olgastraße")), + g.edge(5, 4).setDistance(5).setKeyValues(createKV("name", "Olgastraße"))); GHUtility.setSpeed(60, 60, carAccessEnc, carAvSpeedEnc, - g.edge(2, 5).setDistance(5).setKeyValues(singletonMap("name", "Neithardtstraße")), - g.edge(5, 7).setDistance(5).setKeyValues(singletonMap("name", "Neithardtstraße"))); + g.edge(2, 5).setDistance(5).setKeyValues(createKV("name", "Neithardtstraße")), + g.edge(5, 7).setDistance(5).setKeyValues(createKV("name", "Neithardtstraße"))); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -891,13 +892,13 @@ public void testUTurnRight() { na.setNode(7, -33.885692, 151.181445); GHUtility.setSpeed(60, 0, carAccessEnc, carAvSpeedEnc, - g.edge(1, 2).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road")), - g.edge(2, 3).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road")), - g.edge(4, 5).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road")), - g.edge(5, 6).setDistance(5).setKeyValues(singletonMap("name", "Parramatta Road"))); + g.edge(1, 2).setDistance(5).setKeyValues(createKV("name", "Parramatta Road")), + g.edge(2, 3).setDistance(5).setKeyValues(createKV("name", "Parramatta Road")), + g.edge(4, 5).setDistance(5).setKeyValues(createKV("name", "Parramatta Road")), + g.edge(5, 6).setDistance(5).setKeyValues(createKV("name", "Parramatta Road"))); GHUtility.setSpeed(60, 60, carAccessEnc, carAvSpeedEnc, - g.edge(2, 5).setDistance(5).setKeyValues(singletonMap("name", "Larkin Street")), - g.edge(5, 7).setDistance(5).setKeyValues(singletonMap("name", "Larkin Street"))); + g.edge(2, 5).setDistance(5).setKeyValues(createKV("name", "Larkin Street")), + g.edge(5, 7).setDistance(5).setKeyValues(createKV("name", "Larkin Street"))); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -954,9 +955,9 @@ public void testCalcInstructionsForSlightTurnOntoDifferentStreet() { na.setNode(3, 48.764149, 8.678926); na.setNode(4, 48.764085, 8.679183); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 3).setDistance(5)).setKeyValues(singletonMap("name", "Talstraße, K 4313")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "Calmbacher Straße, K 4312")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(3, 4).setDistance(5)).setKeyValues(singletonMap("name", "Calmbacher Straße, K 4312")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 3).setDistance(5)).setKeyValues(createKV("name", "Talstraße, K 4313")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "Calmbacher Straße, K 4312")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(3, 4).setDistance(5)).setKeyValues(createKV("name", "Calmbacher Straße, K 4312")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -1000,11 +1001,11 @@ private Graph generatePathDetailsGraph() { na.setNode(5, 52.516, 13.3452); na.setNode(6, 52.516, 13.344); - GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(singletonMap("name", "1-2")); - GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 5).setDistance(5)).setKeyValues(singletonMap("name", "4-5")); - GHUtility.setSpeed(90, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(singletonMap("name", "2-3")); - GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 4).setDistance(10)).setKeyValues(singletonMap("name", "3-4")); - GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 6).setDistance(0.01)).setKeyValues(singletonMap("name", "3-4")); + GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "1-2")); + GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 5).setDistance(5)).setKeyValues(createKV("name", "4-5")); + GHUtility.setSpeed(90, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "2-3")); + GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 4).setDistance(10)).setKeyValues(createKV("name", "3-4")); + GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 6).setDistance(0.01)).setKeyValues(createKV("name", "3-4")); return graph; } @@ -1050,20 +1051,20 @@ private RoundaboutGraph() { na.setNode(19, 52.515, 13.368); // roundabout - roundaboutEdges.add(g.edge(3, 2).setDistance(5).setKeyValues(singletonMap("name", "2-3"))); - roundaboutEdges.add(g.edge(4, 3).setDistance(5).setKeyValues(singletonMap("name", "3-4"))); - roundaboutEdges.add(g.edge(5, 4).setDistance(5).setKeyValues(singletonMap("name", "4-5"))); - roundaboutEdges.add(g.edge(2, 5).setDistance(5).setKeyValues(singletonMap("name", "5-2"))); + roundaboutEdges.add(g.edge(3, 2).setDistance(5).setKeyValues(createKV("name", "2-3"))); + roundaboutEdges.add(g.edge(4, 3).setDistance(5).setKeyValues(createKV("name", "3-4"))); + roundaboutEdges.add(g.edge(5, 4).setDistance(5).setKeyValues(createKV("name", "4-5"))); + roundaboutEdges.add(g.edge(2, 5).setDistance(5).setKeyValues(createKV("name", "5-2"))); List bothDir = new ArrayList<>(); List oneDir = new ArrayList<>(roundaboutEdges); - bothDir.add(g.edge(1, 2).setDistance(5).setKeyValues(singletonMap("name", "MainStreet 1 2"))); - bothDir.add(g.edge(4, 7).setDistance(5).setKeyValues(singletonMap("name", "MainStreet 4 7"))); - bothDir.add(g.edge(5, 8).setDistance(5).setKeyValues(singletonMap("name", "5-8"))); + bothDir.add(g.edge(1, 2).setDistance(5).setKeyValues(createKV("name", "MainStreet 1 2"))); + bothDir.add(g.edge(4, 7).setDistance(5).setKeyValues(createKV("name", "MainStreet 4 7"))); + bothDir.add(g.edge(5, 8).setDistance(5).setKeyValues(createKV("name", "5-8"))); - bothDir.add(edge3to6 = g.edge(3, 6).setDistance(5).setKeyValues(singletonMap("name", "3-6"))); - oneDir.add(edge3to9 = g.edge(3, 9).setDistance(5).setKeyValues(singletonMap("name", "3-9"))); + bothDir.add(edge3to6 = g.edge(3, 6).setDistance(5).setKeyValues(createKV("name", "3-6"))); + oneDir.add(edge3to9 = g.edge(3, 9).setDistance(5).setKeyValues(createKV("name", "3-9"))); bothDir.add(g.edge(7, 10).setDistance(5)); bothDir.add(g.edge(10, 11).setDistance(5)); diff --git a/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java index 6e563e4271f..bf1bb2cd1ad 100644 --- a/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java @@ -29,7 +29,7 @@ import com.graphhopper.util.shapes.GHPoint; import org.junit.jupiter.api.Test; -import static java.util.Collections.singletonMap; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; /** @@ -104,11 +104,11 @@ public void testDistanceFiltering() { na.setNode(nodeID200, point200mAway.lat, point200mAway.lon); // Check that it matches a street 50m away - EdgeIteratorState edge1 = g.edge(nodeId50, farAwayId).setKeyValues(singletonMap("name", "Wentworth Street")); + EdgeIteratorState edge1 = g.edge(nodeId50, farAwayId).setKeyValues(createKV("name", "Wentworth Street")); assertTrue(createNameSimilarityEdgeFilter("Wentworth Street").accept(edge1)); // Check that it doesn't match streets 200m away - EdgeIteratorState edge2 = g.edge(nodeID200, farAwayId).setKeyValues(singletonMap("name", "Wentworth Street")); + EdgeIteratorState edge2 = g.edge(nodeID200, farAwayId).setKeyValues(createKV("name", "Wentworth Street")); assertFalse(createNameSimilarityEdgeFilter("Wentworth Street").accept(edge2)); } @@ -309,17 +309,18 @@ public void curvedWayGeometry_issue2319() { pointList.add(43.842711, -79.264588); graph.getNodeAccess().setNode(0, 43.844521, -79.263976); graph.getNodeAccess().setNode(1, 43.842775, -79.264649); + EdgeIteratorState doubtfire = graph.edge(0, 1).setWayGeometry(pointList).set(accessEnc, true, true). - set(speedEnc, 60, 60).setKeyValues(singletonMap("name", "Doubtfire Crescent")); + set(speedEnc, 60, 60).setKeyValues(createKV("name", "Doubtfire Crescent")); EdgeIteratorState golden = graph.edge(0, 1).set(accessEnc, true, true).set(speedEnc, 60, 60). - setKeyValues(singletonMap("name", "Golden Avenue")); + setKeyValues(createKV("name", "Golden Avenue")); graph.getNodeAccess().setNode(2, 43.841501560244744, -79.26366394602502); graph.getNodeAccess().setNode(3, 43.842247922172724, -79.2605663670726); PointList pointList2 = new PointList(1, false); pointList2.add(43.84191413615452, -79.261912128223); EdgeIteratorState denison = graph.edge(2, 3).setWayGeometry(pointList2).set(accessEnc, true, true). - set(speedEnc, 60, 60).setKeyValues(singletonMap("name", "Denison Street")); + set(speedEnc, 60, 60).setKeyValues(createKV("name", "Denison Street")); double qlat = 43.842122; double qLon = -79.262162; diff --git a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java index a2aeffd187c..313c38f779f 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/FastestWeightingTest.java @@ -30,8 +30,7 @@ import static com.graphhopper.routing.weighting.FastestWeighting.DESTINATION_FACTOR; import static com.graphhopper.routing.weighting.FastestWeighting.PRIVATE_FACTOR; -import java.util.Collections; - +import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static com.graphhopper.util.GHUtility.createMockedEdgeIteratorState; import static com.graphhopper.util.GHUtility.getEdge; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -57,7 +56,7 @@ public void testWeightWrongHeading() { Weighting instance = new FastestWeighting(accessEnc, speedEnc, null, new PMap().putObject(Parameters.Routing.HEADING_PENALTY, 100), TurnCostProvider.NO_TURN_COST_PROVIDER); VirtualEdgeIteratorState virtEdge = new VirtualEdgeIteratorState(0, GHUtility.createEdgeKey(1, false, false), 1, 2, 10, - GHUtility.setSpeed(10, 0, accessEnc, speedEnc, encodingManager.createEdgeFlags()), Collections.singletonMap("name", "test"), Helper.createPointList(51, 0, 51, 1), false); + GHUtility.setSpeed(10, 0, accessEnc, speedEnc, encodingManager.createEdgeFlags()), createKV("name", "test"), Helper.createPointList(51, 0, 51, 1), false); double time = instance.calcEdgeWeight(virtEdge, false); virtEdge.setUnfavored(true); diff --git a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java index 55ffbf4c3b5..29a476f8edc 100644 --- a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java +++ b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java @@ -1,6 +1,7 @@ package com.graphhopper.search; import com.carrotsearch.hppc.LongArrayList; +import com.graphhopper.search.EdgeKVStorage.KeyValue; import com.graphhopper.storage.RAMDirectory; import com.graphhopper.util.Helper; import org.junit.jupiter.api.RepeatedTest; @@ -9,6 +10,7 @@ import java.io.File; import java.util.*; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static com.graphhopper.search.EdgeKVStorage.MAX_UNIQUE_KEYS; import static org.junit.jupiter.api.Assertions.*; @@ -20,12 +22,12 @@ private EdgeKVStorage create() { return new EdgeKVStorage(new RAMDirectory(), 1000).create(1000); } - Map createMap(Object... keyValues) { + List createList(Object... keyValues) { if (keyValues.length % 2 != 0) - throw new IllegalArgumentException("Cannot create map from " + Arrays.toString(keyValues)); - Map map = new LinkedHashMap<>(); + throw new IllegalArgumentException("Cannot create list from " + Arrays.toString(keyValues)); + List map = new ArrayList<>(); for (int i = 0; i < keyValues.length; i += 2) { - map.put((String) keyValues[i], keyValues[i + 1]); + map.add(new KeyValue((String) keyValues[i], keyValues[i + 1])); } return map; } @@ -33,7 +35,7 @@ Map createMap(Object... keyValues) { @Test public void putSame() { EdgeKVStorage index = create(); - long aPointer = index.add(createMap("a", "same name", "b", "same name")); + long aPointer = index.add(createList("a", "same name", "b", "same name")); assertNull(index.get(aPointer, "", false)); assertEquals("same name", index.get(aPointer, "a", false)); @@ -41,54 +43,55 @@ public void putSame() { assertNull(index.get(aPointer, "c", false)); index = create(); - aPointer = index.add(createMap("a", "a name", "b", "same name")); + aPointer = index.add(createList("a", "a name", "b", "same name")); assertEquals("a name", index.get(aPointer, "a", false)); } @Test public void putAB() { EdgeKVStorage index = create(); - long aPointer = index.add(createMap("a", "a name", "b", "b name")); + long aPointer = index.add(createList("a", "a name", "b", "b name")); assertNull(index.get(aPointer, "", false)); assertEquals("a name", index.get(aPointer, "a", false)); assertEquals("b name", index.get(aPointer, "b", false)); } -// @Test -// public void getForwardBackward() { -// EdgeKVStorage index = create(); -// // special keys like :forward and :backward have a meaning -// // TODO NOW use first two bits of short value (key) and check if deduplication with negative bit is really necessary -// long aPointer = index.add(createMap("keyA:forward", "FORWARD", "keyB:backward", "BACKWARD", "keyC", "BOTH")); -// -// assertNull(index.get(aPointer, "", false)); -// -// assertEquals("FORWARD", index.get(aPointer, "keyA", false)); -// assertNull(index.get(aPointer, "keyA", true)); -// -// assertNull(index.get(aPointer, "keyB", false)); -// assertEquals("BACKWARD", index.get(aPointer, "keyB", true)); -// -// assertEquals("BOTH", index.get(aPointer, "keyC", false)); -// assertEquals("BOTH", index.get(aPointer, "keyC", true)); -// -// assertEquals(createMap("keyA:forward", "FORWARD", "keyB:backward", "BACKWARD", "keyC", "BOTH"), -// index.getAll(aPointer)); -// } + @Test + public void getForwardBackward() { + EdgeKVStorage index = create(); + List list = new ArrayList<>(); + list.add(new KeyValue("keyA", "FORWARD", true, false)); + list.add(new KeyValue("keyB", "BACKWARD", false, true)); + list.add(new KeyValue("keyC", "BOTH", true, true)); + long aPointer = index.add(list); + + assertNull(index.get(aPointer, "", false)); + List deserializedList = index.getAll(aPointer); + assertEquals(list, deserializedList); + + assertEquals("FORWARD", index.get(aPointer, "keyA", false)); + assertNull(index.get(aPointer, "keyA", true)); + + assertNull(index.get(aPointer, "keyB", false)); + assertEquals("BACKWARD", index.get(aPointer, "keyB", true)); + + assertEquals("BOTH", index.get(aPointer, "keyC", false)); + assertEquals("BOTH", index.get(aPointer, "keyC", true)); + } @Test public void putEmpty() { EdgeKVStorage index = create(); - assertEquals(1, index.add(createMap("", ""))); + assertEquals(1, index.add(createList("", ""))); // cannot store null (in its first version we accepted null once it was clear which type the value has, but this is inconsequential) - assertThrows(IllegalArgumentException.class, () -> assertEquals(5, index.add(createMap("", null)))); - assertThrows(IllegalArgumentException.class, () -> index.add(createMap("blup", null))); - assertThrows(IllegalArgumentException.class, () -> index.add(createMap(null, null))); + assertThrows(IllegalArgumentException.class, () -> assertEquals(5, index.add(createList("", null)))); + assertThrows(IllegalArgumentException.class, () -> index.add(createList("blup", null))); + assertThrows(IllegalArgumentException.class, () -> index.add(createList(null, null))); assertNull(index.get(0, "", false)); - assertEquals(5, index.add(createMap("else", "else"))); + assertEquals(5, index.add(createList("else", "else"))); } @Test @@ -97,7 +100,7 @@ public void putMany() { long aPointer = 0, tmpPointer = 0; for (int i = 0; i < 10000; i++) { - aPointer = index.add(createMap("a", "a name " + i, "b", "b name " + i, "c", "c name " + i)); + aPointer = index.add(createList("a", "a name " + i, "b", "b name " + i, "c", "c name " + i)); if (i == 567) tmpPointer = aPointer; } @@ -115,10 +118,10 @@ public void putManyKeys() { EdgeKVStorage index = create(); // one key is already stored => empty key for (int i = 1; i < MAX_UNIQUE_KEYS; i++) { - index.add(createMap("a" + i, "a name")); + index.add(createList("a" + i, "a name")); } try { - index.add(createMap("new", "a name")); + index.add(createList("new", "a name")); fail(); } catch (IllegalArgumentException ex) { } @@ -132,14 +135,14 @@ public void testNoErrorOnLargeStringValue() { str += "ß"; } assertEquals(254, str.getBytes(Helper.UTF_CS).length); - long result = index.add(createMap("", str)); + long result = index.add(createList("", str)); assertEquals(127, ((String) index.get(result, "", false)).length()); } @Test public void testTooLongStringValueError() { EdgeKVStorage index = create(); - assertThrows(IllegalArgumentException.class, () -> index.add(createMap("", "Бухарестская улица (http://ru.wikipedia.org/wiki" + + assertThrows(IllegalArgumentException.class, () -> index.add(createList("", "Бухарестская улица (http://ru.wikipedia.org/wiki" + "/%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))"))); String str = "sdfsdfds"; @@ -147,7 +150,7 @@ public void testTooLongStringValueError() { str += "Б"; } final String finalStr = str; - assertThrows(IllegalArgumentException.class, () -> index.add(createMap("", finalStr))); + assertThrows(IllegalArgumentException.class, () -> index.add(createList("", finalStr))); } @Test @@ -159,23 +162,23 @@ public void testNoErrorOnLargestByteArray() { bytes[i] = (byte) (i % 255); copy[i] = bytes[i]; } - long result = index.add(Collections.singletonMap("myval", bytes)); + long result = index.add(createKV("myval", bytes)); bytes = (byte[]) index.get(result, "myval", false); assertArrayEquals(copy, bytes); final byte[] biggerByteArray = Arrays.copyOf(bytes, 256); - IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> index.add(Collections.singletonMap("myval2", biggerByteArray))); + IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> index.add(createKV("myval2", biggerByteArray))); assertTrue(e.getMessage().contains("bytes.length cannot be > 255")); } @Test public void testIntLongDoubleFloat() { EdgeKVStorage index = create(); - long intres = index.add(Collections.singletonMap("intres", 4)); - long doubleres = index.add(Collections.singletonMap("doubleres", 4d)); - long floatres = index.add(Collections.singletonMap("floatres", 4f)); - long longres = index.add(Collections.singletonMap("longres", 4L)); - long after4Inserts = index.add(Collections.singletonMap("somenext", 0)); + long intres = index.add(createKV("intres", 4)); + long doubleres = index.add(createKV("doubleres", 4d)); + long floatres = index.add(createKV("floatres", 4f)); + long longres = index.add(createKV("longres", 4L)); + long after4Inserts = index.add(createKV("somenext", 0)); // initial point is 1, then twice plus 1 + (2+4) and twice plus 1 + (2+8) assertEquals(1 + 36, after4Inserts); @@ -189,23 +192,23 @@ public void testIntLongDoubleFloat() { @Test public void testIntLongDoubleFloat2() { EdgeKVStorage index = create(); - Map map = new HashMap<>(); - map.put("int", 4); - map.put("long", 4L); - map.put("double", 4d); - map.put("float", 4f); - long allInOne = index.add(map); + List list = new ArrayList<>(); + list.add(new KeyValue("int", 4)); + list.add(new KeyValue("long", 4L)); + list.add(new KeyValue("double", 4d)); + list.add(new KeyValue("float", 4f)); + long allInOne = index.add(list); - long afterMapInsert = index.add(Collections.singletonMap("somenext", 0)); + long afterMapInsert = index.add(createKV("somenext", 0)); // 1 + 1 + (2+4) + (2+8) + (2+8) + (2+4) assertEquals(1 + 1 + 32, afterMapInsert); - Map resMap = index.getAll(allInOne); - assertEquals(4, resMap.get("int")); - assertEquals(4L, resMap.get("long")); - assertEquals(4d, resMap.get("double")); - assertEquals(4f, resMap.get("float")); + List resMap = index.getAll(allInOne); + assertEquals(4, resMap.get(0).value); + assertEquals(4L, resMap.get(1).value); + assertEquals(4d, resMap.get(2).value); + assertEquals(4f, resMap.get(3).value); } @Test @@ -213,7 +216,7 @@ public void testFlush() { Helper.removeDir(new File(location)); EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create(), 1000); - long pointer = index.add(createMap("", "test")); + long pointer = index.add(createList("", "test")); index.flush(); index.close(); @@ -221,7 +224,7 @@ public void testFlush() { assertTrue(index.loadExisting()); assertEquals("test", index.get(pointer, "", false)); // make sure bytePointer is correctly set after loadExisting - long newPointer = index.add(createMap("", "testing")); + long newPointer = index.add(createList("", "testing")); assertEquals(pointer + 1 + 3 + "test".getBytes().length, newPointer, newPointer + ">" + pointer); index.close(); @@ -233,9 +236,9 @@ public void testLoadKeys() { Helper.removeDir(new File(location)); EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create(), 1000).create(1000); - long pointerA = index.add(createMap("c", "test value")); + long pointerA = index.add(createList("c", "test value")); assertEquals(2, index.getKeys().size()); - long pointerB = index.add(createMap("a", "value", "b", "another value")); + long pointerB = index.add(createList("a", "value", "b", "another value")); // empty string is always the first key assertEquals("[, c, a, b]", index.getKeys().toString()); index.flush(); @@ -250,7 +253,7 @@ public void testLoadKeys() { assertNull(index.get(pointerB, "", false)); assertEquals("value", index.get(pointerB, "a", false)); assertEquals("another value", index.get(pointerB, "b", false)); - assertEquals("{a=value, b=another value}", index.getAll(pointerB).toString()); + assertEquals("[a=value (true|true), b=another value (true|true)]", index.getAll(pointerB).toString()); index.close(); Helper.removeDir(new File(location)); @@ -259,8 +262,8 @@ public void testLoadKeys() { @Test public void testEmptyKey() { EdgeKVStorage index = create(); - long pointerA = index.add(createMap("", "test value")); - long pointerB = index.add(createMap("a", "value", "b", "another value")); + long pointerA = index.add(createList("", "test value")); + long pointerB = index.add(createList("a", "value", "b", "another value")); assertEquals("test value", index.get(pointerA, "", false)); assertNull(index.get(pointerA, "a", false)); @@ -273,20 +276,20 @@ public void testEmptyKey() { public void testSameByteArray() { EdgeKVStorage index = create(); - long pointerA = index.add(createMap("mykey", new byte[]{1, 2, 3, 4})); - long pointerB = index.add(createMap("mykey", new byte[]{1, 2, 3, 4})); + long pointerA = index.add(createList("mykey", new byte[]{1, 2, 3, 4})); + long pointerB = index.add(createList("mykey", new byte[]{1, 2, 3, 4})); assertEquals(pointerA, pointerB); byte[] sameRef = new byte[]{1, 2, 3, 4}; - pointerA = index.add(createMap("mykey", sameRef)); - pointerB = index.add(createMap("mykey", sameRef)); + pointerA = index.add(createList("mykey", sameRef)); + pointerB = index.add(createList("mykey", sameRef)); assertEquals(pointerA, pointerB); } @Test public void testUnknownValueClass() { EdgeKVStorage index = create(); - IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> index.add(createMap("mykey", new Object()))); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> index.add(createList("mykey", new Object()))); assertTrue(ex.getMessage().contains("The Class of a value was Object, currently supported"), ex.getMessage()); } @@ -302,22 +305,22 @@ public void testRandom() { int size = 10000; LongArrayList pointers = new LongArrayList(size); for (int i = 0; i < size; i++) { - Map map = createRandomMap(random, keys, values); - long pointer = index.add(map); + List list = createRandomList(random, keys, values); + long pointer = index.add(list); try { - assertEquals(map.size(), index.getAll(pointer).size(), "" + i); + assertEquals(list.size(), index.getAll(pointer).size(), "" + i); } catch (Exception ex) { - throw new RuntimeException(i + " " + map + ", " + pointer, ex); + throw new RuntimeException(i + " " + list + ", " + pointer, ex); } pointers.add(pointer); } for (int i = 0; i < size; i++) { - Map map = index.getAll(pointers.get(i)); - assertTrue(map.size() > 0, i + " " + map); - for (Map.Entry entry : map.entrySet()) { - Object value = index.get(pointers.get(i), entry.getKey(), false); - assertEquals(entry.getValue(), value, i + " " + map); + List list = index.getAll(pointers.get(i)); + assertTrue(list.size() > 0, i + " " + list); + for (KeyValue entry : list) { + Object value = index.get(pointers.get(i), entry.key, false); + assertEquals(entry.value, value, i + " " + list); } } index.flush(); @@ -326,11 +329,11 @@ public void testRandom() { index = new EdgeKVStorage(new RAMDirectory(location, true).create()); assertTrue(index.loadExisting()); for (int i = 0; i < size; i++) { - Map map = index.getAll(pointers.get(i)); - assertTrue(map.size() > 0, i + " " + map); - for (Map.Entry entry : map.entrySet()) { - Object value = index.get(pointers.get(i), entry.getKey(), false); - assertEquals(entry.getValue(), value, i + " " + map); + List list = index.getAll(pointers.get(i)); + assertTrue(list.size() > 0, i + " " + list); + for (KeyValue entry : list) { + Object value = index.get(pointers.get(i), entry.key, false); + assertEquals(entry.value, value, i + " " + list); } } index.close(); @@ -355,14 +358,17 @@ private List createRandomStringList(Random random, String postfix, int s return list; } - private Map createRandomMap(Random random, List keys, List values) { + private List createRandomList(Random random, List keys, List values) { int count = random.nextInt(10) + 2; - Map map = new HashMap<>(); + Set avoidDuplicates = new HashSet<>(); // otherwise index.get returns potentially wrong value + List list = new ArrayList<>(); for (int i = 0; i < count; i++) { String key = keys.get(random.nextInt(keys.size())); + if (!avoidDuplicates.add(key)) + continue; Object o = values.get(random.nextInt(values.size())); - map.put(key, key.endsWith("_s") ? o + "_s" : o); + list.add(new KeyValue(key, key.endsWith("_s") ? o + "_s" : o)); } - return map; + return list; } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java index 1135327a05d..78effe6318b 100644 --- a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java +++ b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java @@ -31,8 +31,8 @@ import org.junit.jupiter.api.Test; import java.io.File; -import java.util.Collections; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; /** @@ -266,7 +266,7 @@ public void testUpdateUnidirectional() { public void testCopyProperties() { graph = createGHStorage(); EdgeIteratorState edge = graph.edge(1, 3).setDistance(10).set(carAccessEnc, true, false). - setKeyValues(Collections.singletonMap("name", "testing")).setWayGeometry(Helper.createPointList(1, 2)); + setKeyValues(createKV("name", "testing")).setWayGeometry(Helper.createPointList(1, 2)); EdgeIteratorState newEdge = graph.edge(1, 3).setDistance(10).set(carAccessEnc, true, false); newEdge.copyPropertiesFrom(edge); @@ -654,10 +654,10 @@ public void testGetAllEdges() { public void testEdgeKVStorage() { graph = createGHStorage(); EdgeIteratorState iter1 = graph.edge(0, 1).setDistance(10).set(carAccessEnc, true, true); - iter1.setKeyValues(Collections.singletonMap("name", "named street1")); + iter1.setKeyValues(createKV("name", "named street1")); EdgeIteratorState iter2 = graph.edge(0, 1).setDistance(10).set(carAccessEnc, true, true); - iter2.setKeyValues(Collections.singletonMap("name", "named street2")); + iter2.setKeyValues(createKV("name", "named street2")); assertEquals(graph.getEdgeIteratorState(iter1.getEdge(), iter1.getAdjNode()).getName(), "named street1"); assertEquals(graph.getEdgeIteratorState(iter2.getEdge(), iter2.getAdjNode()).getName(), "named street2"); diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java index 16e99b61dee..63d9ecd804a 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java @@ -19,11 +19,13 @@ import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.search.EdgeKVStorage.KeyValue; import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; import org.junit.jupiter.api.Test; -import java.util.Collections; +import java.util.ArrayList; +import java.util.List; import static com.graphhopper.util.EdgeIteratorState.REVERSE_STATE; import static com.graphhopper.util.FetchMode.*; @@ -61,13 +63,20 @@ public void testSave_and_fileFormat() { EdgeIteratorState iter2 = graph.edge(0, 1).setDistance(100).set(carAccessEnc, true, true); iter2.setWayGeometry(Helper.createPointList3D(1.5, 1, 0, 2, 3, 0)); EdgeIteratorState iter1 = graph.edge(0, 2).setDistance(200).set(carAccessEnc, true, true); + EdgeIteratorState iter3 = graph.edge(3, 4); iter1.setWayGeometry(Helper.createPointList3D(3.5, 4.5, 0, 5, 6, 0)); graph.edge(9, 10).setDistance(200).set(carAccessEnc, true, true); graph.edge(9, 11).setDistance(200).set(carAccessEnc, true, true); graph.edge(1, 2).setDistance(120).set(carAccessEnc, true, false); - iter1.setKeyValues(Collections.singletonMap("name", "named street1")); - iter2.setKeyValues(Collections.singletonMap("name", "named street2")); + iter1.setKeyValues(KeyValue.createKV("name", "named street1")); + iter2.setKeyValues(KeyValue.createKV("name", "named street2")); + + List list = new ArrayList<>(); + list.add(new KeyValue("keyA", "FORWARD", true, false)); + list.add(new KeyValue("keyB", "BACKWARD", false, true)); + list.add(new KeyValue("keyC", "BOTH", true, true)); + iter3.setKeyValues(list); checkGraph(graph); graph.flush(); @@ -81,6 +90,17 @@ public void testSave_and_fileFormat() { assertEquals("named street1", graph.getEdgeIteratorState(iter1.getEdge(), iter1.getAdjNode()).getName()); assertEquals("named street2", graph.getEdgeIteratorState(iter2.getEdge(), iter2.getAdjNode()).getName()); + iter3 = graph.getEdgeIteratorState(iter3.getEdge(), iter3.getAdjNode()); + assertEquals(list, iter3.getKeyValues()); + assertEquals(list, iter3.detach(true).getKeyValues()); + + assertEquals("FORWARD", iter3.getValue("keyA")); + assertNull(iter3.getValue("keyB")); + assertEquals("BOTH", iter3.getValue("keyC")); + assertNull(iter3.detach(true).getValue("keyA")); + assertEquals("BACKWARD", iter3.detach(true).getValue("keyB")); + assertEquals("BOTH", iter3.detach(true).getValue("keyC")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carSpeedEnc, graph.edge(3, 4).setDistance(123)). setWayGeometry(Helper.createPointList3D(4.4, 5.5, 0, 6.6, 7.7, 0)); checkGraph(graph); diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java index eb3a5136ca5..4b1b04c87cc 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java @@ -20,11 +20,11 @@ import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.TurnCost; import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.search.EdgeKVStorage.KeyValue; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.Helper; import org.junit.jupiter.api.Test; -import java.util.Collections; import java.util.Random; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -78,8 +78,8 @@ public void testSave_and_fileFormat() { setTurnCost(iter2.getEdge(), 0, iter1.getEdge(), 666); setTurnCost(iter1.getEdge(), 1, iter2.getEdge(), 815); - iter1.setKeyValues(Collections.singletonMap("name", "named street1")); - iter2.setKeyValues(Collections.singletonMap("name", "named street2")); + iter1.setKeyValues(KeyValue.createKV("name", "named street1")); + iter2.setKeyValues(KeyValue.createKV("name", "named street2")); checkGraph(graph); graph.flush(); diff --git a/core/src/test/java/com/graphhopper/util/InstructionListTest.java b/core/src/test/java/com/graphhopper/util/InstructionListTest.java index 805a84d7d72..9bd9e529cb7 100644 --- a/core/src/test/java/com/graphhopper/util/InstructionListTest.java +++ b/core/src/test/java/com/graphhopper/util/InstructionListTest.java @@ -42,7 +42,7 @@ import java.util.List; import java.util.Locale; -import static java.util.Collections.singletonMap; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; /** @@ -95,30 +95,30 @@ Graph createTestGraph() { na.setNode(6, 1.0, 1.0); na.setNode(7, 1.0, 1.1); na.setNode(8, 1.0, 1.2); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(singletonMap("name", "0-1")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(singletonMap("name", "1-2")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(createKV("name", "0-1")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(createKV("name", "1-2")); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(11000)); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setKeyValues(singletonMap("name", "1-4")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setKeyValues(singletonMap("name", "5-2")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setKeyValues(createKV("name", "1-4")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setKeyValues(createKV("name", "5-2")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setKeyValues(singletonMap("name", "3-6")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setKeyValues(singletonMap("name", "4-7")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setKeyValues(singletonMap("name", "5-8")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setKeyValues(createKV("name", "3-6")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setKeyValues(createKV("name", "4-7")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setKeyValues(createKV("name", "5-8")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setKeyValues(singletonMap("name", "6-7")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setKeyValues(createKV("name", "6-7")); EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(10000)); PointList list = new PointList(); list.add(1.0, 1.15); list.add(1.0, 1.16); iter.setWayGeometry(list); - iter.setKeyValues(singletonMap("name", "7-8")); + iter.setKeyValues(createKV("name", "7-8")); // missing edge name GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(10000)); EdgeIteratorState iter2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 9).setDistance(20000)); list.clear(); list.add(1.0, 1.3); - iter2.setKeyValues(singletonMap("name", "8-9")); + iter2.setKeyValues(createKV("name", "8-9")); iter2.setWayGeometry(list); return g; } @@ -187,11 +187,11 @@ public void testWayList2() { na.setNode(3, 10.0, 10.08); na.setNode(4, 10.1, 10.10); na.setNode(5, 10.2, 10.13); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setKeyValues(singletonMap("name", "3-4")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setKeyValues(singletonMap("name", "4-5")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setKeyValues(createKV("name", "3-4")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setKeyValues(createKV("name", "4-5")); EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(100)); - iter.setKeyValues(singletonMap("name", "2-4")); + iter.setKeyValues(createKV("name", "2-4")); PointList list = new PointList(); list.add(10.20, 10.05); iter.setWayGeometry(list); @@ -226,11 +226,11 @@ public void testNoInstructionIfSameStreet() { na.setNode(3, 10.0, 10.05); na.setNode(4, 10.1, 10.10); na.setNode(5, 10.2, 10.15); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setKeyValues(singletonMap("name", "street")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setKeyValues(singletonMap("name", "4-5")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setKeyValues(createKV("name", "street")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setKeyValues(createKV("name", "4-5")); EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(100)); - iter.setKeyValues(singletonMap("name", "street")); + iter.setKeyValues(createKV("name", "street")); PointList list = new PointList(); list.add(10.20, 10.05); iter.setWayGeometry(list); @@ -326,9 +326,9 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp3() { GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(20)); GHUtility.setSpeed(4, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(20)); - g.edge(1, 2).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(singletonMap("name", "pfarr")); - g.edge(2, 3).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(singletonMap("name", "pfarr")); - g.edge(2, 4).set(rcEV, RoadClass.PEDESTRIAN).setKeyValues(singletonMap("name", "markt")); + g.edge(1, 2).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(createKV("name", "pfarr")); + g.edge(2, 3).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(createKV("name", "pfarr")); + g.edge(2, 4).set(rcEV, RoadClass.PEDESTRIAN).setKeyValues(createKV("name", "markt")); FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 3); @@ -402,11 +402,14 @@ public void testInstructionIfSlightTurnForCustomProfile() { na.setNode(4, 43.729476, 7.417633); // default is priority=0 so set it to 1 - GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1)); - GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1)); + GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(20). + setKeyValues(createKV("name", "myroad")).set(priorityEnc, 1)); + GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(20). + setKeyValues(createKV("name", "myroad")).set(priorityEnc, 1)); PointList pointList = new PointList(); pointList.add(43.729627, 7.41749); - GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(20).setKeyValues(singletonMap("name", "myroad")).set(priorityEnc, 1).setWayGeometry(pointList)); + GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(20). + setKeyValues(createKV("name", "myroad")).set(priorityEnc, 1).setWayGeometry(pointList)); Weighting weighting = CustomModelParser.createWeighting(accessEnc, speedEnc, priorityEnc, tmpEM, DefaultTurnCostProvider.NO_TURN_COST_PROVIDER, @@ -493,12 +496,12 @@ public void testFind() { na.setNode(6, 15.1, 10.1); na.setNode(7, 15.1, 9.8); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(10000)).setKeyValues(singletonMap("name", "1-2")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10000)).setKeyValues(singletonMap("name", "2-3")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000)).setKeyValues(singletonMap("name", "2-6")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(10000)).setKeyValues(singletonMap("name", "3-4")).setWayGeometry(waypoint); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000)).setKeyValues(singletonMap("name", "3-7")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000)).setKeyValues(singletonMap("name", "4-5")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(10000)).setKeyValues(createKV("name", "1-2")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10000)).setKeyValues(createKV("name", "2-3")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000)).setKeyValues(createKV("name", "2-6")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(10000)).setKeyValues(createKV("name", "3-4")).setWayGeometry(waypoint); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000)).setKeyValues(createKV("name", "3-7")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000)).setKeyValues(createKV("name", "4-5")); FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 5); diff --git a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java index be640d46524..3912e094aeb 100644 --- a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java +++ b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java @@ -37,8 +37,8 @@ import java.util.*; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static com.graphhopper.util.Parameters.Details.AVERAGE_SPEED; -import static java.util.Collections.singletonMap; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -76,24 +76,24 @@ public void testScenario() { na.setNode(7, 1.0, 1.1); na.setNode(8, 1.0, 1.2); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(singletonMap("name", "0-1")); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(singletonMap("name", "1-2")); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(createKV("name", "0-1")); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(createKV("name", "1-2")); GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(11000)); - GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setKeyValues(singletonMap("name", "1-4")); - GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setKeyValues(singletonMap("name", "5-2")); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setKeyValues(createKV("name", "1-4")); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setKeyValues(createKV("name", "5-2")); - GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setKeyValues(singletonMap("name", "3-6")); - GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setKeyValues(singletonMap("name", "4-7")); - GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setKeyValues(singletonMap("name", "5-8")); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setKeyValues(createKV("name", "3-6")); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setKeyValues(createKV("name", "4-7")); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setKeyValues(createKV("name", "5-8")); - GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setKeyValues(singletonMap("name", "6-7")); + GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setKeyValues(createKV("name", "6-7")); EdgeIteratorState tmpEdge = GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(10000)); PointList list = new PointList(); list.add(1.0, 1.15); list.add(1.0, 1.16); tmpEdge.setWayGeometry(list); - tmpEdge.setKeyValues(singletonMap("name", "7-8")); + tmpEdge.setKeyValues(createKV("name", "7-8")); // missing edge name GHUtility.setSpeed(45, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(10000)); @@ -103,7 +103,7 @@ public void testScenario() { list.add(1.0, 1.3001); list.add(1.0, 1.3002); list.add(1.0, 1.3003); - tmpEdge.setKeyValues(singletonMap("name", "8-9")); + tmpEdge.setKeyValues(createKV("name", "8-9")); tmpEdge.setWayGeometry(list); // Path is: [0 0-1, 3 1-4, 6 4-7, 9 7-8, 11 8-9, 10 9-10] diff --git a/example/src/main/java/com/graphhopper/example/LocationIndexExample.java b/example/src/main/java/com/graphhopper/example/LocationIndexExample.java index 2ab4c8a2821..dfd91b58e2b 100644 --- a/example/src/main/java/com/graphhopper/example/LocationIndexExample.java +++ b/example/src/main/java/com/graphhopper/example/LocationIndexExample.java @@ -3,14 +3,13 @@ import com.graphhopper.GraphHopper; import com.graphhopper.config.Profile; import com.graphhopper.routing.util.EdgeFilter; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.storage.index.LocationIndexTree; import com.graphhopper.storage.index.Snap; import com.graphhopper.util.EdgeIteratorState; -import java.util.Collections; - public class LocationIndexExample { public static void main(String[] args) { String relDir = args.length == 1 ? args[0] : ""; @@ -36,7 +35,7 @@ public static void graphhopperLocationIndex(String relDir) { public static void lowLevelLocationIndex() { // If you don't use the GraphHopper class you have to use the low level API: BaseGraph graph = new BaseGraph.Builder(1).create(); - graph.edge(0, 1).setKeyValues(Collections.singletonMap("name", "test edge")); + graph.edge(0, 1).setKeyValues(EdgeKVStorage.KeyValue.createKV("name", "test edge")); graph.getNodeAccess().setNode(0, 12, 42); graph.getNodeAccess().setNode(1, 12.01, 42.01); @@ -47,6 +46,6 @@ public static void lowLevelLocationIndex() { index.prepareIndex(); Snap snap = index.findClosest(12, 42, EdgeFilter.ALL_EDGES); EdgeIteratorState edge = snap.getClosestEdge(); - assert edge.getKeyValues().get("name").equals("test edge"); + assert edge.getValue("name").equals("test edge"); } } diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java index 190ad2aacdc..8a59c834e0c 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/analysis/PtGraphAsAdjacencyList.java @@ -5,12 +5,13 @@ import com.graphhopper.routing.util.AllEdgesIterator; import com.graphhopper.routing.util.EdgeFilter; import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.*; import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; import java.util.Iterator; -import java.util.Map; +import java.util.List; class PtGraphAsAdjacencyList implements Graph { private final PtGraph ptGraph; @@ -303,12 +304,12 @@ public String getName() { } @Override - public EdgeIteratorState setKeyValues(Map map) { + public EdgeIteratorState setKeyValues(List list) { throw new RuntimeException(); } @Override - public Map getKeyValues() { + public List getKeyValues() { throw new RuntimeException(); } diff --git a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java index 4289aa42d26..3be8c4b2e96 100644 --- a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java +++ b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java @@ -46,7 +46,7 @@ import java.util.List; import java.util.Locale; -import static java.util.Collections.singletonMap; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; public class GpxConversionsTest { @@ -81,12 +81,12 @@ public void testInstructionsWithTimeAndPlace() { na.setNode(6, 15.1, 10.1); na.setNode(7, 15.1, 9.8); - GHUtility.setSpeed(63, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(7000).setKeyValues(singletonMap("name", "1-2"))); - GHUtility.setSpeed(72, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(8000).setKeyValues(singletonMap("name", "2-3"))); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000).setKeyValues(singletonMap("name", "2-6"))); - GHUtility.setSpeed(81, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(9000).setKeyValues(singletonMap("name", "3-4"))); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000).setKeyValues(singletonMap("name", "3-7"))); - GHUtility.setSpeed(90, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000).setKeyValues(singletonMap("name", "4-5"))); + GHUtility.setSpeed(63, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(7000).setKeyValues(createKV("name", "1-2"))); + GHUtility.setSpeed(72, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(8000).setKeyValues(createKV("name", "2-3"))); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000).setKeyValues(createKV("name", "2-6"))); + GHUtility.setSpeed(81, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(9000).setKeyValues(createKV("name", "3-4"))); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000).setKeyValues(createKV("name", "3-7"))); + GHUtility.setSpeed(90, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000).setKeyValues(createKV("name", "4-5"))); ShortestWeighting weighting = new ShortestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); diff --git a/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java b/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java index 7771ba85e7c..2a870bfbde6 100644 --- a/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java @@ -25,6 +25,7 @@ import com.graphhopper.matching.State; import com.graphhopper.resources.MapMatchingResource; import com.graphhopper.routing.querygraph.VirtualEdgeIteratorState; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.index.Snap; import com.graphhopper.util.EdgeIteratorState; @@ -88,7 +89,7 @@ private EdgeIteratorState getEdgeIterator() { pointList.add(-3.4445, -38.9990); pointList.add(-3.5550, -38.7990); return new VirtualEdgeIteratorState(0, 0, 0, 1, 10, new IntsRef(1), - Collections.singletonMap("name", "test of iterator"), pointList, false); + EdgeKVStorage.KeyValue.createKV("name", "test of iterator"), pointList, false); } } From af660cdf2fc1a365b279eb6047fc5956e585cfb9 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 7 Jul 2022 14:48:01 +0200 Subject: [PATCH 091/389] fix test --- core/src/test/java/com/graphhopper/routing/PathTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index 066bb1e5eab..9844673ffe9 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -1005,7 +1005,7 @@ private Graph generatePathDetailsGraph() { GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 5).setDistance(5)).setKeyValues(createKV("name", "4-5")); GHUtility.setSpeed(90, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "2-3")); GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 4).setDistance(10)).setKeyValues(createKV("name", "3-4")); - GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 6).setDistance(0.01)).setKeyValues(createKV("name", "3-4")); + GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 6).setDistance(0.001)).setKeyValues(createKV("name", "3-4")); return graph; } From 301730072e83224eacaa6736a5e5a5112a89b9a8 Mon Sep 17 00:00:00 2001 From: Gerard Vico Date: Tue, 12 Jul 2022 15:10:32 +0200 Subject: [PATCH 092/389] Use BaseGraph instead of GraphStorage for creating MatrixRouter --- core/src/main/java/com/graphhopper/GraphHopper.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 982a512bac0..db0f2093734 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -1375,21 +1375,21 @@ public GHMatrixResponse matrix(GHMatrixRequest request) { } private RouterMatrix createMatrixRouter() { - if (ghStorage == null || !fullyLoaded) + if (baseGraph == null || !fullyLoaded) throw new IllegalStateException("Do a successful call to load or importOrLoad before routing"); - if (ghStorage.isClosed()) + if (baseGraph.isClosed()) throw new IllegalStateException("You need to create a new GraphHopper instance as it is already closed"); if (locationIndex == null) throw new IllegalStateException("Location index not initialized"); - return doCreateMatrixRouter(ghStorage, locationIndex, profilesByName, pathBuilderFactory, + return doCreateMatrixRouter(baseGraph, locationIndex, profilesByName, pathBuilderFactory, trMap, routerConfig, createWeightingFactory(), chGraphs, landmarks); } - private RouterMatrix doCreateMatrixRouter(GraphHopperStorage ghStorage, LocationIndex locationIndex, Map profilesByName, + private RouterMatrix doCreateMatrixRouter(BaseGraph baseGraph, LocationIndex locationIndex, Map profilesByName, PathDetailsBuilderFactory pathBuilderFactory, TranslationMap trMap, RouterConfig routerConfig, WeightingFactory weightingFactory, Map chGraphs, Map landmarks) { - return new RouterMatrix(ghStorage.getBaseGraph(), ghStorage.getEncodingManager(), locationIndex, profilesByName, pathBuilderFactory, + return new RouterMatrix(baseGraph, getEncodingManager(), locationIndex, profilesByName, pathBuilderFactory, trMap, routerConfig, weightingFactory, chGraphs, landmarks ); } From 6bbec9b4b3164a048f76e59ac507810703993907 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 16 Jul 2022 09:52:21 +0200 Subject: [PATCH 093/389] minor update to docs for map matching --- map-matching/README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/map-matching/README.md b/map-matching/README.md index 9a2c3d35f47..8842e48940d 100644 --- a/map-matching/README.md +++ b/map-matching/README.md @@ -11,22 +11,26 @@ See the demo in action (black is GPS track, green is matched result): ### Web app -To install GraphHopper and start the GraphHopper server see [these instructions](../README.md#installation). After the import process finished you can access a simple map matching UI via `http://localhost:8989/maps/map-matching/` (including the trailing slash). Note that for map-matching you need a version 3.0 or higher so you probably need to build from source currently. +To install GraphHopper and start the GraphHopper server see [these instructions](../README.md#installation). After the import process finished you can access a simple map matching UI via `http://localhost:8989/maps/map-matching/` (including the trailing slash) where you can upload GPX files. -You can post GPX files and get back snapped results as GPX or as JSON. An example curl request is: +Note, that this can fail for various reasons. Make sure that the imported area has sufficient geographical coverage for the GPX file otherwise you'll can get an error like "Sequence is broken for submitted track at time step 0". + +You can also post GPX files via web API and get back snapped results as GPX or as JSON. An example curl request is: ```bash curl -XPOST -H "Content-Type: application/gpx+xml" -d @web/src/test/resources/test1.gpx "localhost:8989/match?profile=car&type=json" ``` +Note again that for this test1.gpx file a PBF file for that geographical area ([this](./files/leipzig_germany.osm.pbf) or larger) is required to be used for the import. + ### CLI usage You can also use map-matching via the command line without running the GraphHopper server. The usage is very similar to the GraphHopper server. You need a configuration file and running the `match` command will either use existing GraphHopper files or trigger a new import. Use the `match` command like this for example: ```bash -java -jar graphhopper-web-3.0-SNAPSHOT.jar match --file config.yml --profile car web/src/test/resources/*.gpx +java -jar graphhopper-web-*.jar match --file config.yml --profile car web/src/test/resources/*.gpx ``` -where the argument after `-jar` is the GraphHopper jar that you need to build from source or download (3.0 or higher). The profile is chosen via the `--profile` option and the GPX files are specified after the last option. In the above example we use all GPX files found in the test resources. +where the argument after `-jar` is the GraphHopper jar that you need to build from source or download. The profile is chosen via the `--profile` option and the GPX files are specified after the last option. In the above example we use all GPX files found in the test resources. ### Java usage @@ -38,7 +42,7 @@ Use this Maven dependency: com.graphhopper graphhopper-map-matching - 3.0-SNAPSHOT + [LATEST-VERSION] ``` From 2cb8b890d5106e4bf0f4acbf5255829970743b10 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 16 Jul 2022 09:53:49 +0200 Subject: [PATCH 094/389] Update README.md --- map-matching/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/map-matching/README.md b/map-matching/README.md index 8842e48940d..99ea172e412 100644 --- a/map-matching/README.md +++ b/map-matching/README.md @@ -13,14 +13,14 @@ See the demo in action (black is GPS track, green is matched result): To install GraphHopper and start the GraphHopper server see [these instructions](../README.md#installation). After the import process finished you can access a simple map matching UI via `http://localhost:8989/maps/map-matching/` (including the trailing slash) where you can upload GPX files. -Note, that this can fail for various reasons. Make sure that the imported area has sufficient geographical coverage for the GPX file otherwise you'll can get an error like "Sequence is broken for submitted track at time step 0". +Make sure that the imported area has sufficient geographical coverage for the GPX file otherwise you'll can get an error like "Sequence is broken for submitted track at time step 0". You can also post GPX files via web API and get back snapped results as GPX or as JSON. An example curl request is: ```bash curl -XPOST -H "Content-Type: application/gpx+xml" -d @web/src/test/resources/test1.gpx "localhost:8989/match?profile=car&type=json" ``` -Note again that for this test1.gpx file a PBF file for that geographical area ([this](./files/leipzig_germany.osm.pbf) or larger) is required to be used for the import. +Note again that for this file test1.gpx a PBF file with a big enough geographical coverage ([this file](./files/leipzig_germany.osm.pbf) or larger) is required to be used for the import. ### CLI usage From 0e1b13275c71d31c64ff97c1d84e5d478b17a6d4 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 16 Jul 2022 09:29:14 +0200 Subject: [PATCH 095/389] add more info to exception --- .../main/java/com/graphhopper/storage/AbstractDataAccess.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/storage/AbstractDataAccess.java b/core/src/main/java/com/graphhopper/storage/AbstractDataAccess.java index 2b4f378ce91..12f6ec6b1b9 100644 --- a/core/src/main/java/com/graphhopper/storage/AbstractDataAccess.java +++ b/core/src/main/java/com/graphhopper/storage/AbstractDataAccess.java @@ -105,7 +105,7 @@ protected long readHeader(RandomAccessFile raFile) throws IOException { String versionHint = raFile.readUTF(); if (!"GH".equals(versionHint)) - throw new IllegalArgumentException("Not a GraphHopper file! Expected 'GH' as file marker but was " + versionHint); + throw new IllegalArgumentException("Not a GraphHopper file " + getFullName() + "! Expected 'GH' as file marker but was " + versionHint); long bytes = raFile.readLong(); setSegmentSize(raFile.readInt()); From 181df4039f967c322b11ef7fc965595ef4a7a79a Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 16 Jul 2022 10:25:49 +0200 Subject: [PATCH 096/389] profiles.md: updated rhs to strings --- docs/core/profiles.md | 56 ++++++++----------- .../application/resources/json_bike.json | 4 +- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/docs/core/profiles.md b/docs/core/profiles.md index 780f844dcb1..5999a595c41 100644 --- a/docs/core/profiles.md +++ b/docs/core/profiles.md @@ -3,7 +3,7 @@ GraphHopper lets you customize how different kinds of roads shall be prioritized during its route calculations. For example when travelling long distances with a car you typically want to use the highway to minimize your travelling time. However, if you are going by bike you certainly do not want to use the highway and rather take some shorter route, -use designated bike lanes and so on. GraphHopper provides built-in vehicle types that cover some standard vehicles. They +use designated bike lanes and so on. GraphHopper provides built-in vehicle types that cover some standard use cases. They can be used with a few different weightings like the 'fastest' weighting that chooses the fastest route (minimum travelling time), or the 'shortest' weighting that chooses the shortest route (minimum travelling distance). The selection of a vehicle and weighting is called 'profile', and we refer to these built-in choices as 'standard profiles' @@ -65,9 +65,9 @@ parameter, for example `/route?point=49.5,11.1&profile=car` or `/route?point=49. You can adjust the cost function of GraphHopper's route calculations in much more detail by using so called 'custom' profiles. Every custom profile builds on top of a 'base' vehicle from which the profile inherits the road accessibility rules and default speeds for the different road types. However, you can specify a set of rules to change these default -values. For example you can change the speed only for a certain type of road (and much more). +values. For example, you can change the speed only for a certain type of road (and much more). -Custom profiles are specified like this: +Custom profiles are specified in the server-side config.yml file like this: ```yaml profiles: @@ -78,7 +78,7 @@ profiles: "speed": [ { "if": "road_class == MOTORWAY", - "multiply_by": 0.8 + "multiply_by": "0.8" } ] } @@ -153,49 +153,41 @@ and the given profile must be a custom profile. Now you might be wondering which custom model is used, because there is one set for the route request, but there is also the one given for the profile that we specify via the `profile` parameter. The answer is "both" as the two custom models -are merged into one. The two custom models are merged according to the following rules: +are merged into one. The two custom models are merged by appending all expressions of the query custom model to the +server-side custom model. The `distance_influence` of the query custom model overwrites the one from the server-side +custom model *unless* it is not specified. -* all expressions in the custom model of the query are appended to the existing custom model. -* for the custom model of the query all values of `multiply_by` need to be within the range of `[0, 1]` otherwise an - error will be thrown -* the `distance_influence` of the query custom model overwrites the one from the server-side custom model *unless* - it is not specified. However, the given value must not be smaller than the existing one. - -If you're curious about the second rule note that for the Hybrid mode (using Landmarks not just Dijkstra or A*) -the merge process has to ensure that all weights resulting from the merged custom model are equal or larger than those -of the base profile that was used during the preparation process. This is necessary to maintain the optimality of the -underlying routing algorithm. +And if the hybrid mode is used (using Landmarks not just Dijkstra or A*) the merge process has to ensure that all +weights resulting from the merged custom model are equal or larger than those of the base profile that was used during +the preparation process (this is necessary to maintain the optimality of the underlying routing algorithm). This leads +to two limitations while merging: +* for the query custom model all values of `multiply_by` need to be within the range of `[0, 1]` otherwise an error will be thrown +* the `distance_influence` of the query custom model must not be smaller than the existing one. So say your routing request (POST /route) looks like this: ```json { "points": [ - [ - 11.58199, - 50.0141 - ], - [ - 11.5865, - 50.0095 - ] + [ 11.58199, 50.0141 ], + [ 11.5865, 50.0095 ] ], "profile": "my_custom_car", "custom_model": { "speed": [ { "if": "road_class == MOTORWAY", - "multiply_by": 0.8 + "multiply_by": "0.8" }, { - "else": null, - "multiply_by": 0.9 + "else": "", + "multiply_by": "0.9" } ], "priority": [ { "if": "road_environment == TUNNEL", - "multiply_by": 0.95 + "multiply_by": "0.95" } ], "distance_influence": 0.7 @@ -221,7 +213,7 @@ and `my_custom_car.json` looks like this: "speed": [ { "if": "surface == GRAVEL", - "limit_to": 100 + "limit_to": "100" } ] } @@ -234,21 +226,21 @@ then the resulting custom model used for your request will look like this: "speed": [ { "if": "surface == GRAVEL", - "limit_to": 100 + "limit_to": "100" }, { "if": "road_class == MOTORWAY", - "multiply_by": 0.8 + "multiply_by": "0.8" }, { "else": "", - "multiply_by": 0.9 + "multiply_by": "0.9" } ], "priority": [ { "if": "road_environment == TUNNEL", - "multiply_by": 0.95 + "multiply_by": "0.95" } ], "distance_influence": 0.7 diff --git a/web/src/test/resources/com/graphhopper/application/resources/json_bike.json b/web/src/test/resources/com/graphhopper/application/resources/json_bike.json index 9302cc151ac..d70a711b303 100644 --- a/web/src/test/resources/com/graphhopper/application/resources/json_bike.json +++ b/web/src/test/resources/com/graphhopper/application/resources/json_bike.json @@ -1,8 +1,8 @@ { "speed": [ - { "if": "road_class==PRIMARY", "limit_to": 28 } + { "if": "road_class==PRIMARY", "limit_to": "28" } ], "priority": [ - { "if": "max_width < 1.2", "multiply_by": 0 } + { "if": "max_width < 1.2", "multiply_by": "0" } ] } \ No newline at end of file From 416244e6c4c882d75f67caccb08843c4148f4833 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 16 Jul 2022 14:36:43 +0200 Subject: [PATCH 097/389] minor test change to avoid downloading elevation tile --- .../com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index 8dce1d5b190..a46dbb2088d 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -584,7 +584,6 @@ public void testDisconnectedAreaAndMultiplePoints() { GraphHopper hopper = createHopper(DIR + "/krautsand.osm.gz", new Profile("car").setVehicle("car").setWeighting("fastest")); - hopper.setElevationProvider(new SRTMProvider(DIR)); hopper.importOrLoad(); for (Function requestFactory : createRequestFactories()) { From 6367889855fd14081cae6746debcdd912d28ecf3 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 16 Jul 2022 22:23:18 +0200 Subject: [PATCH 098/389] CustomModelParser: minor cleanup --- .../weighting/custom/CustomModelParser.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java index c69181bc7fe..f7db3313f7e 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java @@ -183,9 +183,8 @@ private static Class createClazz(CustomModel customModel, EncodedValueLookup */ private static List createGetSpeedStatements(Set speedVariables, CustomModel customModel, EncodedValueLookup lookup) throws Exception { - List speedStatements = new ArrayList<>(); - speedStatements.addAll(verifyExpressions(new StringBuilder(), "speed entry", speedVariables, - customModel.getSpeed(), lookup)); + List speedStatements = new ArrayList<>(verifyExpressions(new StringBuilder(), + "speed entry", speedVariables, customModel.getSpeed(), lookup)); String speedMethodStartBlock = "double value = super.getRawSpeed(edge, reverse);\n"; // a bit inefficient to possibly define variables twice, but for now we have two separate methods for (String arg : speedVariables) { @@ -203,9 +202,8 @@ private static List createGetSpeedStatements(Set sp */ private static List createGetPriorityStatements(Set priorityVariables, CustomModel customModel, EncodedValueLookup lookup) throws Exception { - List priorityStatements = new ArrayList<>(); - priorityStatements.addAll(verifyExpressions(new StringBuilder(), "priority entry, ", - priorityVariables, customModel.getPriority(), lookup)); + List priorityStatements = new ArrayList<>(verifyExpressions(new StringBuilder(), + "priority entry", priorityVariables, customModel.getPriority(), lookup)); String priorityMethodStartBlock = "double value = super.getRawPriority(edge, reverse);\n"; for (String arg : priorityVariables) { priorityMethodStartBlock += getVariableDeclaration(lookup, arg); @@ -316,7 +314,7 @@ private static String createClassTemplate(long counter, } return "" - + "package com.graphhopper.routing.weighting.custom;" + + "package com.graphhopper.routing.weighting.custom;\n" + "import " + CustomWeightingHelper.class.getName() + ";\n" + "import " + EncodedValueLookup.class.getName() + ";\n" + "import " + EdgeIteratorState.class.getName() + ";\n" @@ -376,7 +374,7 @@ static void parseExpressions(StringBuilder expressions, NameValidator nameInCond if (!Helper.isEmpty(statement.getCondition())) throw new IllegalArgumentException("condition must be empty but was " + statement.getCondition()); - expressions.append("else {" + statement.getOperation().build(statement.getValue()) + "; }\n"); + expressions.append("else {").append(statement.getOperation().build(statement.getValue())).append("; }\n"); } else if (statement.getKeyword() == Statement.Keyword.ELSEIF || statement.getKeyword() == Statement.Keyword.IF) { ParseResult parseResult = ConditionalExpressionVisitor.parse(statement.getCondition(), nameInConditionValidator, lookup); if (!parseResult.ok) @@ -385,7 +383,7 @@ static void parseExpressions(StringBuilder expressions, NameValidator nameInCond createObjects.addAll(parseResult.guessedVariables); if (statement.getKeyword() == Statement.Keyword.ELSEIF) expressions.append("else "); - expressions.append("if (" + parseResult.converted + ") {" + statement.getOperation().build(statement.getValue()) + "; }\n"); + expressions.append("if (").append(parseResult.converted).append(") {").append(statement.getOperation().build(statement.getValue())).append("; }\n"); } else { throw new IllegalArgumentException("The statement must be either 'if', 'else_if' or 'else'"); } @@ -394,7 +392,7 @@ static void parseExpressions(StringBuilder expressions, NameValidator nameInCond } /** - * Injects the already parsed expressions (converted to BlockStatement) via janinos DeepCopier to the provided + * Injects the already parsed expressions (converted to BlockStatement) via Janino's DeepCopier to the provided * CompilationUnit cu (a class file). */ private static Java.CompilationUnit injectStatements(List priorityStatements, From 9421daef8e25dbe09a3b8a47867e65ed30906ad4 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 17 Jul 2022 20:09:54 +0200 Subject: [PATCH 099/389] EncodedValue: bug fix for negateReverseDirection --- .../graphhopper/routing/ev/IntEncodedValueImpl.java | 4 ++-- .../routing/ev/DecimalEncodedValueImplTest.java | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java index 01ef38024d8..9434757e4f6 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java @@ -197,8 +197,8 @@ public final int getInt(boolean reverse, IntsRef ref) { } else { flags = ref.ints[fwdDataIndex + ref.offset]; if (negateReverseDirection && reverse) - return -(minStorableValue + (flags & fwdMask) >>> fwdShift); - return minStorableValue + (flags & fwdMask) >>> fwdShift; + return -(minStorableValue + ((flags & fwdMask) >>> fwdShift)); + return minStorableValue + ((flags & fwdMask) >>> fwdShift); } } diff --git a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java index 340f3adbfe8..8400cf2d7e2 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java @@ -80,6 +80,16 @@ public void testNegateReverse() { testEnc.setDecimal(false, intsRef, 5.5); assertEquals(5.5, testEnc.getDecimal(false, intsRef), .1); assertEquals(-5.5, testEnc.getDecimal(true, intsRef), .1); + + EncodedValue.InitializerConfig config = new EncodedValue.InitializerConfig(); + new DecimalEncodedValueImpl("tmp1", 5, 1, false, false).init(config); + testEnc = new DecimalEncodedValueImpl("tmp2", 5, 0, 1, false, + true, false, false); + testEnc.init(config); + intsRef = new IntsRef(1); + testEnc.setDecimal(false, intsRef, 2.6); + assertEquals(3, testEnc.getDecimal(false, intsRef), .1); + assertEquals(-3, testEnc.getDecimal(true, intsRef), .1); } @Test From fead2102c4795136af8f663ddd1a1ae0f9d2c538 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 17 Jul 2022 21:36:00 +0200 Subject: [PATCH 100/389] ConditionalExpressionVisitor: allow '-' as unary operation --- .../custom/ConditionalExpressionVisitor.java | 1 + .../custom/ConditionalExpressionVisitorTest.java | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitor.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitor.java index 8d76fa76eeb..6d8fd08eda3 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitor.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitor.java @@ -85,6 +85,7 @@ public Boolean visitRvalue(Java.Rvalue rv) throws Exception { } else if (rv instanceof Java.UnaryOperation) { Java.UnaryOperation uo = (Java.UnaryOperation) rv; if (uo.operator.equals("!")) return uo.operand.accept(this); + if (uo.operator.equals("-")) return uo.operand.accept(this); return false; } else if (rv instanceof Java.MethodInvocation) { Java.MethodInvocation mi = (Java.MethodInvocation) rv; diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java index 4b5caec9940..c7ae3fc1b65 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/ConditionalExpressionVisitorTest.java @@ -1,6 +1,5 @@ package com.graphhopper.routing.weighting.custom; -import com.graphhopper.json.Statement; import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.ev.StringEncodedValue; import com.graphhopper.routing.util.EncodingManager; @@ -10,9 +9,7 @@ import org.junit.jupiter.api.Test; import java.util.Arrays; -import java.util.HashSet; -import static com.graphhopper.json.Statement.If; import static com.graphhopper.routing.weighting.custom.ConditionalExpressionVisitor.parse; import static com.graphhopper.routing.weighting.custom.CustomModelParser.isValidVariableName; import static org.junit.jupiter.api.Assertions.*; @@ -132,4 +129,14 @@ public void isValidAndSimpleCondition() { assertTrue(result.ok); assertEquals("[toll, road_class]", result.guessedVariables.toString()); } + + @Test + public void testNegativeConstant() { + ParseResult result = parse("average_slope < -0.5", "average_slope"::equals, lookup); + assertTrue(result.ok); + assertEquals("[average_slope]", result.guessedVariables.toString()); + result = parse("-average_slope > -0.5", "average_slope"::equals, lookup); + assertTrue(result.ok); + assertEquals("[average_slope]", result.guessedVariables.toString()); + } } \ No newline at end of file From 06b261a3650c9f9ece9b394c65bc7dfe71a3ae04 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 17 Jul 2022 23:04:33 +0200 Subject: [PATCH 101/389] fixed link to CGIAR attribution --- NOTICE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NOTICE.md b/NOTICE.md index b2ff5f1b14c..c3689edbf7c 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -48,7 +48,7 @@ web: |---------|-----------|---------|------| |OpenStreetMap data for the road network | [ODBL](https://www.openstreetmap.org/copyright) | yes | yes | SRTM elevation | [public domain](https://www2.jpl.nasa.gov/srtm/), [acknowledgement](https://lpdaac.usgs.gov/citing_our_data) | no | yes -| CGIAR elevation | [allowed usage for GraphHopper](https://graphhopper.com/public/license/CGIAR.txt) | no | no +| CGIAR elevation | [allowed usage for GraphHopper](https://gist.githubusercontent.com/karussell/4b54a289041ee48a16c00fd4e30e21b8/raw/45edf8ae85322cb20976baa30654093d0ca9bcd8/CGIAR.txt) | no | no | SRTMGL1 elevation | [acknowledgement](https://lpdaac.usgs.gov/citing_our_data) | no | no |OpenTopography mirror for SRTMGL1 | [acknowledgement OpenTopoGraphy](http://www.opentopography.org/citations) and [data source](http://opentopo.sdsc.edu/datasetMetadata?otCollectionID=OT.042013.4326.1) + SRTMGL1 | no | no | GMTED | [public domain, acknowledgment](https://lta.cr.usgs.gov/citation) | no | no From 4d499a29760ea90fd2bdbbae2fd567ea4b69f0f9 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 18 Jul 2022 10:30:56 +0200 Subject: [PATCH 102/389] make global time&distance values consistent with path details and instructions (#2626) * make global time&distance values consistent with time&distance path details and also the sum of time&distance of the instructions * minor simplification * mention change in changelog --- CHANGELOG.md | 1 + .../routing/InstructionsFromEdges.java | 6 +- .../util/details/DistanceDetails.java | 9 +- .../util/details/EdgeIdDetails.java | 8 +- .../util/details/EdgeKeyDetails.java | 17 +--- .../graphhopper/util/details/TimeDetails.java | 9 +- .../java/com/graphhopper/GraphHopperTest.java | 88 +++++++++++++++---- .../routing/HeadingRoutingTest.java | 20 ++--- .../java/com/graphhopper/ResponsePath.java | 30 +------ 9 files changed, 102 insertions(+), 86 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e3a5ff216d..c3c094f00f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### 6.0 [not yet released] +- path details at via-points are no longer separated, see #2626 - removed the FlagEncoder interface. for example encoder.getAccessEnc() is now encodingManager.getBooleanEncodedValue( VehicleAccess.key("car")), #2611 - backward incompatible change as instructions and the street_name path detail do no longer contain the ref #2598 diff --git a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java index a87cb9f1f6d..537e58b80b4 100644 --- a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java +++ b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java @@ -430,8 +430,10 @@ private void updatePointsAndInstruction(EdgeIteratorState edge, PointList pl) { } double newDist = edge.getDistance(); prevInstruction.setDistance(newDist + prevInstruction.getDistance()); - // todo: why do we not account for turn times here ? - prevInstruction.setTime(weighting.calcEdgeMillis(edge, false) + prevInstruction.getTime()); + if (prevEdge != null) + prevInstruction.setTime(GHUtility.calcMillisWithTurnMillis(weighting, edge, false, prevEdge.getEdge()) + prevInstruction.getTime()); + else + prevInstruction.setTime(weighting.calcEdgeMillis(edge, false) + prevInstruction.getTime()); } } \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/util/details/DistanceDetails.java b/core/src/main/java/com/graphhopper/util/details/DistanceDetails.java index c36e1cf4585..4380bc498d3 100644 --- a/core/src/main/java/com/graphhopper/util/details/DistanceDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/DistanceDetails.java @@ -23,7 +23,6 @@ public class DistanceDetails extends AbstractPathDetailsBuilder { - private int edgeId = -1; private double distance = 0; public DistanceDetails() { @@ -32,12 +31,8 @@ public DistanceDetails() { @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { - if (edge.getEdge() != edgeId) { - edgeId = edge.getEdge(); - distance = edge.getDistance(); - return true; - } - return false; + distance = edge.getDistance(); + return true; } @Override diff --git a/core/src/main/java/com/graphhopper/util/details/EdgeIdDetails.java b/core/src/main/java/com/graphhopper/util/details/EdgeIdDetails.java index f093c82e70e..1fff5a16302 100644 --- a/core/src/main/java/com/graphhopper/util/details/EdgeIdDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/EdgeIdDetails.java @@ -38,12 +38,8 @@ public EdgeIdDetails() { @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { - int thisEdgeId = edgeId(edge); - if (thisEdgeId != edgeId) { - edgeId = thisEdgeId; - return true; - } - return false; + edgeId = edgeId(edge); + return true; } private int edgeId(EdgeIteratorState edge) { diff --git a/core/src/main/java/com/graphhopper/util/details/EdgeKeyDetails.java b/core/src/main/java/com/graphhopper/util/details/EdgeKeyDetails.java index 83cfc3a8a18..dd5bf3cfc5b 100644 --- a/core/src/main/java/com/graphhopper/util/details/EdgeKeyDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/EdgeKeyDetails.java @@ -19,7 +19,6 @@ import com.graphhopper.routing.querygraph.VirtualEdgeIteratorState; import com.graphhopper.util.EdgeIteratorState; -import com.graphhopper.util.GHUtility; import static com.graphhopper.util.Parameters.Details.EDGE_KEY; @@ -34,9 +33,10 @@ public EdgeKeyDetails() { @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { - int newEdgeKey = getEdgeKey(edge); - if (newEdgeKey != edgeKey) { - edgeKey = newEdgeKey; + int newKey = edge instanceof VirtualEdgeIteratorState + ? ((VirtualEdgeIteratorState) edge).getOriginalEdgeKey() : edge.getEdgeKey(); + if (newKey != edgeKey) { // do not duplicate path detail if going over via point (two virtual edges) + edgeKey = newKey; return true; } return false; @@ -46,13 +46,4 @@ public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { public Object getCurrentValue() { return this.edgeKey; } - - static int getEdgeKey(EdgeIteratorState edge) { - if (edge instanceof VirtualEdgeIteratorState) { - return ((VirtualEdgeIteratorState) edge).getOriginalEdgeKey(); - } else { - return edge.getEdge() * 2 + (edge.get(EdgeIteratorState.REVERSE_STATE) ? 1 : 0); - } - } - } diff --git a/core/src/main/java/com/graphhopper/util/details/TimeDetails.java b/core/src/main/java/com/graphhopper/util/details/TimeDetails.java index 1a1a486193d..3dd6e861f1b 100644 --- a/core/src/main/java/com/graphhopper/util/details/TimeDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/TimeDetails.java @@ -42,12 +42,9 @@ public TimeDetails(Weighting weighting) { @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { - if (edge.getEdge() != prevEdgeId) { - time = GHUtility.calcMillisWithTurnMillis(weighting, edge, false, prevEdgeId); - prevEdgeId = edge.getEdge(); - return true; - } - return false; + time = GHUtility.calcMillisWithTurnMillis(weighting, edge, false, prevEdgeId); + prevEdgeId = edge.getEdge(); + return true; } @Override diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 00d1b5134e0..8deaa43da46 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -787,11 +787,11 @@ public void testMonacoPathDetails() { Map> details = res.getPathDetails(); assertEquals(1, details.size()); List detailList = details.get(Parameters.Details.AVERAGE_SPEED); - assertEquals(9, detailList.size()); + assertEquals(10, detailList.size()); assertEquals(5.0, detailList.get(0).getValue()); assertEquals(0, detailList.get(0).getFirst()); assertEquals(3.0, detailList.get(1).getValue()); - assertEquals(res.getPoints().size() - 1, detailList.get(8).getLast()); + assertEquals(res.getPoints().size() - 1, detailList.get(9).getLast()); } @Test @@ -1860,17 +1860,23 @@ public void testTurnCostsOnOff() { setOSMFile(MOSCOW). // add profile with turn costs first when no flag encoder is explicitly added setProfiles( - new Profile(profile2).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true), + new Profile(profile2).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true).putHint(U_TURN_COSTS, 30), new Profile(profile1).setVehicle(vehicle).setWeighting(weighting).setTurnCosts(false) ). setStoreOnFlush(true); hopper.importOrLoad(); GHRequest req = new GHRequest(55.813357, 37.5958585, 55.811042, 37.594689); + req.setPathDetails(Arrays.asList("distance", "time")).getHints().putObject("instructions", true); req.setProfile("profile_no_turn_costs"); - assertEquals(400, hopper.route(req).getBest().getDistance(), 1); + ResponsePath best = hopper.route(req).getBest(); + assertEquals(400, best.getDistance(), 1); + consistenceCheck(best); + req.setProfile("profile_turn_costs"); - assertEquals(1044, hopper.route(req).getBest().getDistance(), 1); + best = hopper.route(req).getBest(); + assertEquals(476, best.getDistance(), 1); + consistenceCheck(best); } @Test @@ -2225,20 +2231,22 @@ public void simplifyWithInstructionsAndPathDetails() { List speeds = path.getPathDetails().get("max_speed"); assertDetail(speeds.get(0), "null [0, 4]"); assertDetail(speeds.get(1), "70.0 [4, 6]"); - assertDetail(speeds.get(2), "100.0 [6, 31]"); - assertDetail(speeds.get(3), "80.0 [31, 32]"); - assertDetail(speeds.get(4), "null [32, 37]"); - assertDetail(speeds.get(5), "50.0 [37, 38]"); - assertDetail(speeds.get(6), "null [38, 40]"); + assertDetail(speeds.get(2), "100.0 [6, 16]"); + assertDetail(speeds.get(3), "100.0 [16, 31]"); // we do not merge path details at via points + assertDetail(speeds.get(4), "80.0 [31, 32]"); + assertDetail(speeds.get(5), "null [32, 37]"); + assertDetail(speeds.get(6), "50.0 [37, 38]"); + assertDetail(speeds.get(7), "null [38, 40]"); // check street_names List streetNames = path.getPathDetails().get("street_ref"); assertDetail(streetNames.get(0), "KU 11 [0, 4]"); - assertDetail(streetNames.get(1), "B 85 [4, 32]"); - assertDetail(streetNames.get(2), "null [32, 34]"); - assertDetail(streetNames.get(3), "KU 18 [34, 37]"); - assertDetail(streetNames.get(4), "St 2189 [37, 38]"); - assertDetail(streetNames.get(5), "null [38, 40]"); + assertDetail(streetNames.get(1), "B 85 [4, 16]"); + assertDetail(streetNames.get(2), "B 85 [16, 32]"); + assertDetail(streetNames.get(3), "null [32, 34]"); + assertDetail(streetNames.get(4), "KU 18 [34, 37]"); + assertDetail(streetNames.get(5), "St 2189 [37, 38]"); + assertDetail(streetNames.get(6), "null [38, 40]"); } private void assertInstruction(Instruction instruction, String expectedRef, String expectedInterval, int expectedLength, int expectedPoints) { @@ -2532,6 +2540,55 @@ void averageSpeedPathDetailBug() { assertEquals(467, distance, 1); } + @Test + void timeDetailBug() { + final String profile = "profile"; + GraphHopper hopper = new GraphHopper() + .setProfiles(new Profile(profile).setVehicle("car").setWeighting("fastest").setTurnCosts(true).putHint(U_TURN_COSTS, 80)) + .setGraphHopperLocation(GH_LOCATION) + .setMinNetworkSize(200) + .setOSMFile(BAYREUTH); + hopper.importOrLoad(); + GHRequest request = new GHRequest(Arrays.asList( + new GHPoint(50.020838, 11.494918), + new GHPoint(50.024795, 11.498973), + new GHPoint(50.023141, 11.496441))); + request.setProfile(profile); + request.getHints().putObject("instructions", true); + request.setPathDetails(Arrays.asList("distance", "time")); + GHResponse response = hopper.route(request); + assertFalse(response.hasErrors(), response.getErrors().toString()); + + consistenceCheck(response.getBest()); + } + + private void consistenceCheck(ResponsePath path) { + double distance = path.getDistance(); + long time = path.getTime(); + + double instructionDistance = 0; + long instructionTime = 0; + for (Instruction i : path.getInstructions()) { + instructionDistance += i.getDistance(); + instructionTime += i.getTime(); + } + + assertEquals(time, instructionTime); + assertEquals(distance, instructionDistance, 1e-3); + + double pathDetailDistance = 0; + for (PathDetail pd : path.getPathDetails().get("distance")) { + pathDetailDistance += (Double) pd.getValue(); + } + assertEquals(distance, pathDetailDistance, 1e-3); + + long pathDetailTime = 0; + for (PathDetail pd : path.getPathDetails().get("time")) { + pathDetailTime += (Long) pd.getValue(); + } + assertEquals(time, pathDetailTime); + } + @Test public void testLoadGraph_implicitEncodedValues_issue1862() { GraphHopper hopper = new GraphHopper() @@ -2595,3 +2652,4 @@ void testLoadingWithAnotherSpeedFactorWorks() { } } + diff --git a/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java b/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java index 53036f2bf65..607d10bfe0f 100644 --- a/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java +++ b/core/src/test/java/com/graphhopper/routing/HeadingRoutingTest.java @@ -126,7 +126,7 @@ public void headingTest3() { setPathDetails(Collections.singletonList("edge_key")); GHResponse response = router.route(req); assertFalse(response.hasErrors()); - assertArrayEquals(new int[]{4, 5, 6, 7, 8, 3, 2}, calcNodes(graph, response.getAll().get(0))); + assertArrayEquals(new int[]{4, 5, 6, 7, 7, 8, 3, 2}, calcNodes(graph, response.getAll().get(0))); } @Test @@ -152,7 +152,7 @@ public void headingTest4() { GHResponse response = router.route(req); assertFalse(response.hasErrors()); assertEquals(1, response.getAll().size()); - assertArrayEquals(new int[]{5, 4, 3, 8, 1, 2, 3}, calcNodes(graph, response.getAll().get(0))); + assertArrayEquals(new int[]{5, 4, 3, 3, 8, 1, 2, 3}, calcNodes(graph, response.getAll().get(0))); } @Test @@ -166,10 +166,10 @@ public void headingTest5() { // Start in middle of edge 4-5 GHPoint start = new GHPoint(0.0015, 0.002); + // First go south and then come from west to via-point at 7-6. Then go back over previously punished (11)-4 edge + GHPoint via = new GHPoint(0.000, 0.0015); // End at middle of edge 2-3 GHPoint end = new GHPoint(0.002, 0.0005); - // First go south and than come from west to via-point at 7-6. Then go back over previously punished (11)-4 edge - GHPoint via = new GHPoint(0.000, 0.0015); GHRequest req = new GHRequest(). setPoints(Arrays.asList(start, via, end)). setHeadings(Arrays.asList(0., 90., Double.NaN)). @@ -178,7 +178,7 @@ public void headingTest5() { req.putHint(Parameters.Routing.PASS_THROUGH, true); GHResponse response = router.route(req); assertFalse(response.hasErrors()); - assertArrayEquals(new int[]{5, 4, 3, 8, 7, 6, 5, 4, 3, 2}, calcNodes(graph, response.getAll().get(0))); + assertArrayEquals(new int[]{5, 4, 3, 8, 7, 7, 6, 5, 4, 3, 2}, calcNodes(graph, response.getBest())); } @Test @@ -383,12 +383,10 @@ private int[] calcNodes(Graph graph, ResponsePath responsePath) { List edgeKeys = responsePath.getPathDetails().get("edge_key"); int[] result = new int[edgeKeys.size() + 1]; for (int i = 0; i < edgeKeys.size(); i++) { - int edgeKey = (int) edgeKeys.get(i).getValue(); - int edgeId = edgeKey / 2; - EdgeIteratorState edgeIteratorState = graph.getEdgeIteratorState(edgeId, Integer.MIN_VALUE); - result[i] = edgeKey % 2 == 0 ? edgeIteratorState.getBaseNode() : edgeIteratorState.getAdjNode(); - if (i == edgeKeys.size() - 1) - result[edgeKeys.size()] = edgeKey % 2 == 0 ? edgeIteratorState.getAdjNode() : edgeIteratorState.getBaseNode(); + EdgeIteratorState edgeIteratorState = graph.getEdgeIteratorStateForKey((int) edgeKeys.get(i).getValue()); + result[i] = edgeIteratorState.getBaseNode(); + // last entry needs an additional node: + if (i == edgeKeys.size() - 1) result[edgeKeys.size()] = edgeIteratorState.getAdjNode(); } return result; } diff --git a/web-api/src/main/java/com/graphhopper/ResponsePath.java b/web-api/src/main/java/com/graphhopper/ResponsePath.java index 881323b35b1..20cf74a3b1b 100644 --- a/web-api/src/main/java/com/graphhopper/ResponsePath.java +++ b/web-api/src/main/java/com/graphhopper/ResponsePath.java @@ -254,37 +254,15 @@ public void addPathDetails(Map> details) { throw new IllegalStateException("Details have to be the same size"); } for (Map.Entry> detailEntry : details.entrySet()) { - if (this.pathDetails.containsKey(detailEntry.getKey())) { - List pd = this.pathDetails.get(detailEntry.getKey()); - merge(pd, detailEntry.getValue()); + String key = detailEntry.getKey(); + if (this.pathDetails.containsKey(key)) { + this.pathDetails.get(key).addAll(detailEntry.getValue()); } else { - this.pathDetails.put(detailEntry.getKey(), detailEntry.getValue()); + this.pathDetails.put(key, detailEntry.getValue()); } } } - /** - * Merges otherDetails into the pathDetails. - *

- * This method makes sure that Entry list around via points are merged correctly. - * See #1091 and the misplaced PathDetail after waypoints. - */ - public static void merge(List pathDetails, List otherDetails) { - // Make sure that the PathDetail list is merged correctly at via points - if (!pathDetails.isEmpty() && !otherDetails.isEmpty()) { - PathDetail lastDetail = pathDetails.get(pathDetails.size() - 1); - boolean extend = lastDetail.getValue() != null - ? lastDetail.getValue().equals(otherDetails.get(0).getValue()) - : otherDetails.get(0).getValue() != null; - if (extend) { - lastDetail.setLast(otherDetails.get(0).getLast()); - otherDetails.remove(0); - } - } - - pathDetails.addAll(otherDetails); - } - public Map> getPathDetails() { return this.pathDetails; } From 13d1f7b40dd4527af0401a6f13d16620a3d45a70 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 18 Jul 2022 10:32:34 +0200 Subject: [PATCH 103/389] minor comment fix for #2626 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3c094f00f0..c7343f034da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ ### 6.0 [not yet released] -- path details at via-points are no longer separated, see #2626 +- path details at via-points are no longer merged, see #2626 - removed the FlagEncoder interface. for example encoder.getAccessEnc() is now encodingManager.getBooleanEncodedValue( VehicleAccess.key("car")), #2611 - backward incompatible change as instructions and the street_name path detail do no longer contain the ref #2598 From e59b5dfe118b2bf7b3aa420a4695f139f40fbea9 Mon Sep 17 00:00:00 2001 From: easbar Date: Mon, 18 Jul 2022 11:51:41 +0200 Subject: [PATCH 104/389] Update github actions v2->v3 --- .github/workflows/push-packages.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/push-packages.yml b/.github/workflows/push-packages.yml index 9a9d4a2305a..937e1b71183 100644 --- a/.github/workflows/push-packages.yml +++ b/.github/workflows/push-packages.yml @@ -4,27 +4,27 @@ jobs: publish: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 with: java-version: 17 distribution: temurin - name: Cache Maven artifacts - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven- - name: Cache node - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: web-bundle/node key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os}}-node- - name: Cache node_modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: web-bundle/node_modules key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml', '**/package.json') }} @@ -43,27 +43,27 @@ jobs: matrix: java-version: [ 18 ] steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 with: java-version: ${{ matrix.java-version }} distribution: temurin - name: Cache Maven artifacts - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven- - name: Cache node - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: web-bundle/node key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os}}-node- - name: Cache node_modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: web-bundle/node_modules key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml', '**/package.json') }} From 9dcfe7fb5f7e5718541fb1f1e6f233fb26cfc9b7 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 18 Jul 2022 16:52:22 +0200 Subject: [PATCH 105/389] Include destination in instructions (#2624) * support for destination and add test for non repetitive instructions when destination is included * include destination:ref * add missing osm file * try getKeyValues instead getValue * try speed of getKeyValues (fetching REVERSE_STATE necessary as getKeyValues is align with 'internal' storage direction) * use simpler edge.getValue call again --- core/files/bautzen.osm | 2691 +++++++++++++++++ .../com/graphhopper/reader/osm/OSMReader.java | 39 +- .../routing/InstructionsFromEdges.java | 36 +- .../com/graphhopper/search/EdgeKVStorage.java | 2 + .../util/details/KVStringDetails.java | 2 +- .../details/PathDetailsBuilderFactory.java | 2 + .../resources/com/graphhopper/util/ar.txt | 2 + .../resources/com/graphhopper/util/ast.txt | 2 + .../resources/com/graphhopper/util/bg.txt | 2 + .../resources/com/graphhopper/util/bn_BN.txt | 2 + .../resources/com/graphhopper/util/ca.txt | 2 + .../resources/com/graphhopper/util/cs_CZ.txt | 2 + .../resources/com/graphhopper/util/da_DK.txt | 2 + .../resources/com/graphhopper/util/de_DE.txt | 2 + .../resources/com/graphhopper/util/el.txt | 2 + .../resources/com/graphhopper/util/en_US.txt | 2 + .../resources/com/graphhopper/util/eo.txt | 2 + .../resources/com/graphhopper/util/es.txt | 2 + .../resources/com/graphhopper/util/fa.txt | 2 + .../resources/com/graphhopper/util/fi.txt | 2 + .../resources/com/graphhopper/util/fil.txt | 2 + .../resources/com/graphhopper/util/fr_CH.txt | 2 + .../resources/com/graphhopper/util/fr_FR.txt | 2 + .../resources/com/graphhopper/util/gl.txt | 2 + .../resources/com/graphhopper/util/he.txt | 2 + .../resources/com/graphhopper/util/hr_HR.txt | 2 + .../resources/com/graphhopper/util/hsb.txt | 2 + .../resources/com/graphhopper/util/hu_HU.txt | 2 + .../resources/com/graphhopper/util/in_ID.txt | 2 + .../resources/com/graphhopper/util/it.txt | 2 + .../resources/com/graphhopper/util/ja.txt | 2 + .../resources/com/graphhopper/util/ko.txt | 2 + .../resources/com/graphhopper/util/lt_LT.txt | 2 + .../resources/com/graphhopper/util/ne.txt | 2 + .../resources/com/graphhopper/util/nl.txt | 2 + .../resources/com/graphhopper/util/pl_PL.txt | 2 + .../resources/com/graphhopper/util/pt_BR.txt | 2 + .../resources/com/graphhopper/util/pt_PT.txt | 2 + .../resources/com/graphhopper/util/ro.txt | 2 + .../resources/com/graphhopper/util/ru.txt | 2 + .../resources/com/graphhopper/util/sk.txt | 2 + .../resources/com/graphhopper/util/sl_SI.txt | 2 + .../resources/com/graphhopper/util/sr_RS.txt | 2 + .../resources/com/graphhopper/util/sv_SE.txt | 2 + .../resources/com/graphhopper/util/tr.txt | 2 + .../resources/com/graphhopper/util/uk.txt | 2 + .../resources/com/graphhopper/util/vi_VN.txt | 2 + .../resources/com/graphhopper/util/zh_CN.txt | 2 + .../resources/com/graphhopper/util/zh_HK.txt | 2 + .../resources/com/graphhopper/util/zh_TW.txt | 2 + .../java/com/graphhopper/GraphHopperTest.java | 27 +- .../com/graphhopper/util/Instruction.java | 11 +- .../java/com/graphhopper/util/Parameters.java | 1 + 53 files changed, 2871 insertions(+), 28 deletions(-) create mode 100644 core/files/bautzen.osm diff --git a/core/files/bautzen.osm b/core/files/bautzen.osm new file mode 100644 index 00000000000..282ba16b18b --- /dev/null +++ b/core/files/bautzen.osm @@ -0,0 +1,2691 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index d4332942e86..1daa0232b41 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -333,14 +333,10 @@ protected void addEdge(int fromIndex, int toIndex, PointList pointList, ReaderWa if (edgeFlags.isEmpty()) return; - List list = new ArrayList<>(2); - // the storage does not accept too long strings -> Helper.cutStringForKV - if (way.hasTag("way_name")) // do not store empty string if missing tag - list.add(new EdgeKVStorage.KeyValue("name", Helper.cutStringForKV(way.getTag("way_name", "")))); - if (way.hasTag("way_ref")) - list.add(new EdgeKVStorage.KeyValue("ref", Helper.cutStringForKV(way.getTag("way_ref", "")))); - EdgeIteratorState edge = baseGraph.edge(fromIndex, toIndex).setDistance(distance).setFlags(edgeFlags). - setKeyValues(list); + EdgeIteratorState edge = baseGraph.edge(fromIndex, toIndex).setDistance(distance).setFlags(edgeFlags); + List list = way.getTag("key_values", Collections.emptyList()); + if (!list.isEmpty()) + edge.setKeyValues(list); // If the entire way is just the first and last point, do not waste space storing an empty way geometry if (pointList.size() > 2) { @@ -385,6 +381,7 @@ else if (Math.abs(edgeDistance - geometryDistance) > tolerance) */ protected void preprocessWay(ReaderWay way, WaySegmentParser.CoordinateSupplier coordinateSupplier) { // storing the road name does not yet depend on the flagEncoder so manage it directly + List list = new ArrayList<>(); if (config.isParseWayNames()) { // http://wiki.openstreetmap.org/wiki/Key:name String name = ""; @@ -392,15 +389,32 @@ protected void preprocessWay(ReaderWay way, WaySegmentParser.CoordinateSupplier name = fixWayName(way.getTag("name:" + config.getPreferredLanguage())); if (name.isEmpty()) name = fixWayName(way.getTag("name")); - if (!name.isEmpty()) - way.setTag("way_name", name); + list.add(new EdgeKVStorage.KeyValue("name", name)); // http://wiki.openstreetmap.org/wiki/Key:ref String refName = fixWayName(way.getTag("ref")); if (!refName.isEmpty()) - way.setTag("way_ref", refName); + list.add(new EdgeKVStorage.KeyValue("ref", refName)); + + if (way.hasTag("destination:ref")) { + list.add(new EdgeKVStorage.KeyValue("destination_ref", fixWayName(way.getTag("destination:ref")))); + } else { + if (way.hasTag("destination:ref:forward")) + list.add(new EdgeKVStorage.KeyValue("destination_ref", fixWayName(way.getTag("destination:ref:forward")), true, false)); + if (way.hasTag("destination:ref:backward")) + list.add(new EdgeKVStorage.KeyValue("destination_ref", fixWayName(way.getTag("destination:ref:backward")), false, true)); + } + if (way.hasTag("destination")) { + list.add(new EdgeKVStorage.KeyValue("destination", fixWayName(way.getTag("destination")))); + } else { + if (way.hasTag("destination:forward")) + list.add(new EdgeKVStorage.KeyValue("destination", fixWayName(way.getTag("destination:forward")), true, false)); + if (way.hasTag("destination:backward")) + list.add(new EdgeKVStorage.KeyValue("destination", fixWayName(way.getTag("destination:backward")), false, true)); + } } + way.setTag("key_values", list); if (!isCalculateWayDistance(way)) return; @@ -451,7 +465,8 @@ protected void preprocessWay(ReaderWay way, WaySegmentParser.CoordinateSupplier static String fixWayName(String str) { if (str == null) return ""; - return WAY_NAME_PATTERN.matcher(str).replaceAll(", "); + // the EdgeKVStorage does not accept too long strings -> Helper.cutStringForKV + return Helper.cutStringForKV(WAY_NAME_PATTERN.matcher(str).replaceAll(", ")); } /** diff --git a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java index 537e58b80b4..e22ba4102b9 100644 --- a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java +++ b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java @@ -73,6 +73,7 @@ public class InstructionsFromEdges implements Path.EdgeVisitor { private double prevInstructionPrevOrientation = Double.NaN; private Instruction prevInstruction; private boolean prevInRoundabout; + private String prevDestinationAndRef; private String prevName; private String prevInstructionName; @@ -138,17 +139,23 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { } final String name = (String) edge.getValue("name"); + final String ref = (String) edge.getValue("ref"); + final String destination = (String) edge.getValue("destination"); // getValue is fast if it does not exist in edge + final String destinationRef = (String) edge.getValue("destination_ref"); if ((prevInstruction == null) && (!isRoundabout)) // very first instruction (if not in Roundabout) { int sign = Instruction.CONTINUE_ON_STREET; prevInstruction = new Instruction(sign, name, new PointList(10, nodeAccess.is3D())); - prevInstruction.setExtraInfo("ref", edge.getValue("ref")); + prevInstruction.setExtraInfo("ref", ref); + prevInstruction.setExtraInfo("destination", destination); + prevInstruction.setExtraInfo("destination_ref", destinationRef); double startLat = nodeAccess.getLat(baseNode); double startLon = nodeAccess.getLon(baseNode); double heading = AngleCalc.ANGLE_CALC.calcAzimuth(startLat, startLon, latitude, longitude); prevInstruction.setExtraInfo("heading", Helper.round(heading, 2)); ways.add(prevInstruction); prevName = name; + prevDestinationAndRef = destination + destinationRef; } else if (isRoundabout) { // remark: names and annotations within roundabout are ignored @@ -182,6 +189,7 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { { prevOrientation = AngleCalc.ANGLE_CALC.calcOrientation(prevLat, prevLon, latitude, longitude); prevName = name; + prevDestinationAndRef = destination + destinationRef; } prevInstruction = roundaboutInstruction; ways.add(prevInstruction); @@ -200,7 +208,9 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { } else if (prevInRoundabout) //previously in roundabout but not anymore { prevInstruction.setName(name); - prevInstruction.setExtraInfo("ref", edge.getValue("ref")); + prevInstruction.setExtraInfo("ref", ref); + prevInstruction.setExtraInfo("destination", destination); + prevInstruction.setExtraInfo("destination_ref", destinationRef); // calc angle between roundabout entrance and exit double orientation = AngleCalc.ANGLE_CALC.calcOrientation(prevLat, prevLon, latitude, longitude); @@ -220,10 +230,10 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { prevInstructionName = prevName; prevName = name; + prevDestinationAndRef = destination + destinationRef; } else { - int sign = getTurn(edge, baseNode, prevNode, adjNode, name); - + int sign = getTurn(edge, baseNode, prevNode, adjNode, name, destination + destinationRef); if (sign != Instruction.IGNORE) { /* Check if the next instruction is likely to only be a short connector to execute a u-turn @@ -274,11 +284,14 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { prevInstructionName = prevName; ways.add(prevInstruction); } - prevInstruction.setExtraInfo("ref", edge.getValue("ref")); + prevInstruction.setExtraInfo("ref", ref); + prevInstruction.setExtraInfo("destination", destination); + prevInstruction.setExtraInfo("destination_ref", destinationRef); } // Update the prevName, since we don't always create an instruction on name changes the previous // name can be an old name. This leads to incorrect turn instructions due to name changes prevName = name; + prevDestinationAndRef = destination + destinationRef; } updatePointsAndInstruction(edge, wayGeo); @@ -316,7 +329,7 @@ public void finish() { ways.add(finishInstruction); } - private int getTurn(EdgeIteratorState edge, int baseNode, int prevNode, int adjNode, String name) { + private int getTurn(EdgeIteratorState edge, int baseNode, int prevNode, int adjNode, String name, String destinationAndRef) { GHPoint point = InstructionsHelper.getPointForOrientationCalculation(edge, nodeAccess); double lat = point.getLat(); double lon = point.getLon(); @@ -377,6 +390,7 @@ private int getTurn(EdgeIteratorState edge, int baseNode, int prevNode, int adjN if (otherContinue != null) { // We are at a fork if (!InstructionsHelper.isNameSimilar(name, prevName) + || !InstructionsHelper.isNameSimilar(destinationAndRef, prevDestinationAndRef) || InstructionsHelper.isNameSimilar(otherContinue.getName(), prevName) || !outgoingEdgesAreSlower) { @@ -410,13 +424,9 @@ private int getTurn(EdgeIteratorState edge, int baseNode, int prevNode, int adjN } } - if (!outgoingEdgesAreSlower) { - if (Math.abs(delta) > .6 - || outgoingEdges.isLeavingCurrentStreet(prevName, name)) { - // Leave the current road -> create instruction - return sign; - - } + if (!outgoingEdgesAreSlower && (Math.abs(delta) > .6 || outgoingEdges.isLeavingCurrentStreet(prevName, name))) { + // Leave the current road -> create instruction + return sign; } return Instruction.IGNORE; diff --git a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java index 2c31e8e1db6..a62a96cb057 100644 --- a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java +++ b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java @@ -177,6 +177,8 @@ else if (entries.size() > 200) if (key == null) throw new IllegalArgumentException("key cannot be null"); Object value = entry.value; if (value == null) throw new IllegalArgumentException("value for key " + key + " cannot be null"); + if (!entry.fwd && !entry.bwd) + throw new IllegalArgumentException("Do not add KeyValue pair where fwd and bwd is false"); Integer keyIndex = keyToIndex.get(key); Class clazz; if (keyIndex == null) { diff --git a/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java b/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java index eb2b50a2e13..5eb0e48f8db 100644 --- a/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java @@ -37,7 +37,7 @@ public KVStringDetails(String name, String key) { @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { if (curString == null) { - // TODO it would be a bit more efficient if we fetch the Map only once per edge when more than one KVStringDetails are requested + // TODO it might be more efficient if we fetch the Map only once per edge when more than one KVStringDetails are requested curString = (String) edge.getValue(key); return true; } diff --git a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java index 5eed6db5692..a8f2a24a3bc 100644 --- a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java +++ b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java @@ -39,6 +39,8 @@ public List createPathDetailsBuilders(List requested builders.add(new KVStringDetails(STREET_NAME, "name")); if (requestedPathDetails.contains(STREET_REF)) builders.add(new KVStringDetails(STREET_REF, "ref")); + if (requestedPathDetails.contains(STREET_DESTINATION)) + builders.add(new KVStringDetails(STREET_DESTINATION, "destination")); if (requestedPathDetails.contains(AVERAGE_SPEED)) builders.add(new AverageSpeedDetails(weighting)); diff --git a/core/src/main/resources/com/graphhopper/util/ar.txt b/core/src/main/resources/com/graphhopper/util/ar.txt index 832198046f6..c650977196c 100644 --- a/core/src/main/resources/com/graphhopper/util/ar.txt +++ b/core/src/main/resources/com/graphhopper/util/ar.txt @@ -14,6 +14,8 @@ turn_sharp_left=اتجه قليلاً لليسار turn_sharp_right=اتجه قليلاً لليمين u_turn=الدوران للإتجاه المعاكس toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=علامة غير معرفة '%1$s' via=من خلال hour_abbr=ساعة diff --git a/core/src/main/resources/com/graphhopper/util/ast.txt b/core/src/main/resources/com/graphhopper/util/ast.txt index 760da8f4f73..6026ca35ec5 100644 --- a/core/src/main/resources/com/graphhopper/util/ast.txt +++ b/core/src/main/resources/com/graphhopper/util/ast.txt @@ -14,6 +14,8 @@ turn_sharp_left=xira fuerte a la izquierda turn_sharp_right=xira fuerte a la drecha u_turn=da vuelta atrás toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=signu indicador desconocíu '%1$s' via=pasando per hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/bg.txt b/core/src/main/resources/com/graphhopper/util/bg.txt index ce530055c36..b915e15fc89 100644 --- a/core/src/main/resources/com/graphhopper/util/bg.txt +++ b/core/src/main/resources/com/graphhopper/util/bg.txt @@ -14,6 +14,8 @@ turn_sharp_left=завий рязко наляво turn_sharp_right=завий рязко надясно u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=през hour_abbr=ч diff --git a/core/src/main/resources/com/graphhopper/util/bn_BN.txt b/core/src/main/resources/com/graphhopper/util/bn_BN.txt index bd9e1be684e..5ec088414d8 100644 --- a/core/src/main/resources/com/graphhopper/util/bn_BN.txt +++ b/core/src/main/resources/com/graphhopper/util/bn_BN.txt @@ -14,6 +14,8 @@ turn_sharp_left=bame jan turn_sharp_right=dane jan u_turn=u turn nin toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via= hour_abbr= diff --git a/core/src/main/resources/com/graphhopper/util/ca.txt b/core/src/main/resources/com/graphhopper/util/ca.txt index ce859a90167..10409490eed 100644 --- a/core/src/main/resources/com/graphhopper/util/ca.txt +++ b/core/src/main/resources/com/graphhopper/util/ca.txt @@ -14,6 +14,8 @@ turn_sharp_left=gira just a l'esquerra turn_sharp_right=gira just a la dreta u_turn=fes la volta toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=instrucció desconeguda «%1$s» via=passant per hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/cs_CZ.txt b/core/src/main/resources/com/graphhopper/util/cs_CZ.txt index d996b198382..40bea3bd71f 100644 --- a/core/src/main/resources/com/graphhopper/util/cs_CZ.txt +++ b/core/src/main/resources/com/graphhopper/util/cs_CZ.txt @@ -14,6 +14,8 @@ turn_sharp_left=odbočte ostře vlevo turn_sharp_right=odbočte ostře vpravo u_turn=otočte se toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=neznámý pokyn „%1$s“ via=přes hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/da_DK.txt b/core/src/main/resources/com/graphhopper/util/da_DK.txt index 89d50190080..43b825433d9 100644 --- a/core/src/main/resources/com/graphhopper/util/da_DK.txt +++ b/core/src/main/resources/com/graphhopper/util/da_DK.txt @@ -14,6 +14,8 @@ turn_sharp_left=drej skarpt til venstre turn_sharp_right=drej skarpt til højre u_turn=foretag en U-vending toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=ukendt instruktionsskilt '%1$s' via=via hour_abbr=t diff --git a/core/src/main/resources/com/graphhopper/util/de_DE.txt b/core/src/main/resources/com/graphhopper/util/de_DE.txt index 23e5dcb03a6..ee795d80a5a 100644 --- a/core/src/main/resources/com/graphhopper/util/de_DE.txt +++ b/core/src/main/resources/com/graphhopper/util/de_DE.txt @@ -14,6 +14,8 @@ turn_sharp_left=scharf links abbiegen turn_sharp_right=scharf rechts abbiegen u_turn=wenden toward_destination=%1$s und Richtung %2$s fahren +toward_destination_ref_only=%1$s zur %2$s +toward_destination_with_ref=%1$s und fahre zur %2$s in Richtung %3$s unknown=unbekanntes Richtungszeichen '%1$s' via=über hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/el.txt b/core/src/main/resources/com/graphhopper/util/el.txt index 8ead1ab5fa3..fd3e86eedcb 100644 --- a/core/src/main/resources/com/graphhopper/util/el.txt +++ b/core/src/main/resources/com/graphhopper/util/el.txt @@ -14,6 +14,8 @@ turn_sharp_left=στρίψτε κλειστά αριστερά turn_sharp_right=στρίψτε κλειστά δεξιά u_turn=κάνετε αναστροφή toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=άγνωστη οδηγία '%1$s' via=μέσω hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/en_US.txt b/core/src/main/resources/com/graphhopper/util/en_US.txt index b7ff0e335a6..6b6d791f870 100644 --- a/core/src/main/resources/com/graphhopper/util/en_US.txt +++ b/core/src/main/resources/com/graphhopper/util/en_US.txt @@ -14,6 +14,8 @@ turn_sharp_left=turn sharp left turn_sharp_right=turn sharp right u_turn=make a U-turn toward_destination=%1$s and drive toward %2$s +toward_destination_ref_only=%1$s toward %2$s +toward_destination_with_ref=%1$s and take %2$s toward %3$s unknown=unknown instruction sign '%1$s' via=via hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/eo.txt b/core/src/main/resources/com/graphhopper/util/eo.txt index 704ffcf1a76..ba0d3b6e219 100644 --- a/core/src/main/resources/com/graphhopper/util/eo.txt +++ b/core/src/main/resources/com/graphhopper/util/eo.txt @@ -14,6 +14,8 @@ turn_sharp_left=turniĝegu maldekstren turn_sharp_right=turniĝegu dekstren u_turn=turniĝu malantaŭen toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=nekonata instrukcio “%1$s” via=tra hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/es.txt b/core/src/main/resources/com/graphhopper/util/es.txt index b93fa203a05..b8321cc9a33 100644 --- a/core/src/main/resources/com/graphhopper/util/es.txt +++ b/core/src/main/resources/com/graphhopper/util/es.txt @@ -14,6 +14,8 @@ turn_sharp_left=gira fuerte a la izquierda turn_sharp_right=gira fuerte a la derecha u_turn=da la vuelta toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=señal de instrucción «%1$s» desconocida via=pasando por hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/fa.txt b/core/src/main/resources/com/graphhopper/util/fa.txt index b83f2bd98ac..3ba36440034 100644 --- a/core/src/main/resources/com/graphhopper/util/fa.txt +++ b/core/src/main/resources/com/graphhopper/util/fa.txt @@ -14,6 +14,8 @@ turn_sharp_left=در پیچ تند به چپ بپیچید turn_sharp_right=در پیچ تند به راست بپیچید u_turn=دور بزنید toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=علامت راهنمایی ناشناخته: '%1$s' via=با گذر از hour_abbr=ساعت diff --git a/core/src/main/resources/com/graphhopper/util/fi.txt b/core/src/main/resources/com/graphhopper/util/fi.txt index dfb77bb6452..520965f13a4 100644 --- a/core/src/main/resources/com/graphhopper/util/fi.txt +++ b/core/src/main/resources/com/graphhopper/util/fi.txt @@ -14,6 +14,8 @@ turn_sharp_left=käänny jyrkästi vasemmalle turn_sharp_right=käänny jyrkästi oikealle u_turn=tee U-käännös toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=tuntematon ohje '%1$s' via=kautta hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/fil.txt b/core/src/main/resources/com/graphhopper/util/fil.txt index b6344f44421..758195d00b8 100644 --- a/core/src/main/resources/com/graphhopper/util/fil.txt +++ b/core/src/main/resources/com/graphhopper/util/fil.txt @@ -14,6 +14,8 @@ turn_sharp_left=pagliko matalim kaliwa turn_sharp_right=pagliko matalim karapatan u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=sa pamamagitan ng hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/fr_CH.txt b/core/src/main/resources/com/graphhopper/util/fr_CH.txt index 5247e76dbbc..712d2a3b412 100644 --- a/core/src/main/resources/com/graphhopper/util/fr_CH.txt +++ b/core/src/main/resources/com/graphhopper/util/fr_CH.txt @@ -14,6 +14,8 @@ turn_sharp_left=tournez fort à gauche turn_sharp_right=tournez fort à droite u_turn=faites demi-tour toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=indication inconnue '%1$s' via=via hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/fr_FR.txt b/core/src/main/resources/com/graphhopper/util/fr_FR.txt index f2dae12a8d8..b26afc5c304 100644 --- a/core/src/main/resources/com/graphhopper/util/fr_FR.txt +++ b/core/src/main/resources/com/graphhopper/util/fr_FR.txt @@ -14,6 +14,8 @@ turn_sharp_left=tournez fort à gauche turn_sharp_right=tournez fort à droite u_turn=faites demi-tour toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=indication inconnue '%1$s' via=via hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/gl.txt b/core/src/main/resources/com/graphhopper/util/gl.txt index 73c63c59583..ac60b569c5d 100644 --- a/core/src/main/resources/com/graphhopper/util/gl.txt +++ b/core/src/main/resources/com/graphhopper/util/gl.txt @@ -14,6 +14,8 @@ turn_sharp_left=vire por xusto á esquerda turn_sharp_right=vire por xusto á dereita u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=vía hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/he.txt b/core/src/main/resources/com/graphhopper/util/he.txt index 1fb3263fd87..504f6f87bb4 100644 --- a/core/src/main/resources/com/graphhopper/util/he.txt +++ b/core/src/main/resources/com/graphhopper/util/he.txt @@ -14,6 +14,8 @@ turn_sharp_left=שמאלה בחדות turn_sharp_right=ימינה בחדות u_turn=לבצע פניית פרסה toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=שלט הנחייה לא מוכר '%1$s' via=דרך hour_abbr=שע׳ diff --git a/core/src/main/resources/com/graphhopper/util/hr_HR.txt b/core/src/main/resources/com/graphhopper/util/hr_HR.txt index d1c40107422..10bbe81ac55 100644 --- a/core/src/main/resources/com/graphhopper/util/hr_HR.txt +++ b/core/src/main/resources/com/graphhopper/util/hr_HR.txt @@ -14,6 +14,8 @@ turn_sharp_left=skrenite oštro lijevo turn_sharp_right=skrenite oštro desno u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=preko hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/hsb.txt b/core/src/main/resources/com/graphhopper/util/hsb.txt index ec21e45427e..ffac8212de7 100644 --- a/core/src/main/resources/com/graphhopper/util/hsb.txt +++ b/core/src/main/resources/com/graphhopper/util/hsb.txt @@ -14,6 +14,8 @@ turn_sharp_left=wótrje nalěwo wotbočić turn_sharp_right=wótrje naprawo wotbočić u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=via hour_abbr=hodź. diff --git a/core/src/main/resources/com/graphhopper/util/hu_HU.txt b/core/src/main/resources/com/graphhopper/util/hu_HU.txt index 511587c31b1..cb7aadbbdf9 100644 --- a/core/src/main/resources/com/graphhopper/util/hu_HU.txt +++ b/core/src/main/resources/com/graphhopper/util/hu_HU.txt @@ -14,6 +14,8 @@ turn_sharp_left=forduljon élesen balra turn_sharp_right=forduljon élesen jobbra u_turn=forduljon meg toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=ismeretlen jelzőtábla: %1$s via=ezen át: hour_abbr=óra diff --git a/core/src/main/resources/com/graphhopper/util/in_ID.txt b/core/src/main/resources/com/graphhopper/util/in_ID.txt index 670ca889eda..25b5fdf3942 100644 --- a/core/src/main/resources/com/graphhopper/util/in_ID.txt +++ b/core/src/main/resources/com/graphhopper/util/in_ID.txt @@ -14,6 +14,8 @@ turn_sharp_left=belok kiri tajam turn_sharp_right=belok kanan tajam u_turn=putar balik toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=petunjuk baru %1$s via=melalui hour_abbr=jam diff --git a/core/src/main/resources/com/graphhopper/util/it.txt b/core/src/main/resources/com/graphhopper/util/it.txt index ada708620f8..0c60aa6617f 100644 --- a/core/src/main/resources/com/graphhopper/util/it.txt +++ b/core/src/main/resources/com/graphhopper/util/it.txt @@ -14,6 +14,8 @@ turn_sharp_left=gira nettamente a sinistra turn_sharp_right=gira nettamente a destra u_turn=fai una inversione a U toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=sconosciuto %1$s via=via hour_abbr=hh diff --git a/core/src/main/resources/com/graphhopper/util/ja.txt b/core/src/main/resources/com/graphhopper/util/ja.txt index f9c35e1afe1..6b6be6d8600 100644 --- a/core/src/main/resources/com/graphhopper/util/ja.txt +++ b/core/src/main/resources/com/graphhopper/util/ja.txt @@ -14,6 +14,8 @@ turn_sharp_left=左に曲がる turn_sharp_right=右に曲がる u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=経由 hour_abbr=時間 diff --git a/core/src/main/resources/com/graphhopper/util/ko.txt b/core/src/main/resources/com/graphhopper/util/ko.txt index 52017df8824..f944dd63e5c 100644 --- a/core/src/main/resources/com/graphhopper/util/ko.txt +++ b/core/src/main/resources/com/graphhopper/util/ko.txt @@ -14,6 +14,8 @@ turn_sharp_left=왼쪽 방향 turn_sharp_right=오른쪽 방향 u_turn=유턴 toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=알 수 없는 안내 '%1$s' via=경유 hour_abbr=시간 diff --git a/core/src/main/resources/com/graphhopper/util/lt_LT.txt b/core/src/main/resources/com/graphhopper/util/lt_LT.txt index a9615e75e8c..d1a00650b54 100644 --- a/core/src/main/resources/com/graphhopper/util/lt_LT.txt +++ b/core/src/main/resources/com/graphhopper/util/lt_LT.txt @@ -14,6 +14,8 @@ turn_sharp_left=staigiai sukite kairėn turn_sharp_right=staigiai sukite dešinėn u_turn=apsisukite toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=nežinomos instrukcijos žymėjimas '%1$s' via=per hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/ne.txt b/core/src/main/resources/com/graphhopper/util/ne.txt index 2c34f64eab7..d5b8edfebc6 100644 --- a/core/src/main/resources/com/graphhopper/util/ne.txt +++ b/core/src/main/resources/com/graphhopper/util/ne.txt @@ -14,6 +14,8 @@ turn_sharp_left=धेरै बाया मोड्नुहोस turn_sharp_right=धेरै दाया मोड्नुहोस u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=बाट hour_abbr=घण्टा diff --git a/core/src/main/resources/com/graphhopper/util/nl.txt b/core/src/main/resources/com/graphhopper/util/nl.txt index ce7c242855b..e97c7c5d988 100644 --- a/core/src/main/resources/com/graphhopper/util/nl.txt +++ b/core/src/main/resources/com/graphhopper/util/nl.txt @@ -14,6 +14,8 @@ turn_sharp_left=ga linksaf turn_sharp_right=ga rechtsaf u_turn=keer om toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=onbekende richtingaanwijzer '%1$s' via=via hour_abbr=u diff --git a/core/src/main/resources/com/graphhopper/util/pl_PL.txt b/core/src/main/resources/com/graphhopper/util/pl_PL.txt index e8ea6553416..5e37a0f2fa0 100644 --- a/core/src/main/resources/com/graphhopper/util/pl_PL.txt +++ b/core/src/main/resources/com/graphhopper/util/pl_PL.txt @@ -14,6 +14,8 @@ turn_sharp_left=skręć ostro w lewo turn_sharp_right=skręć ostro w prawo u_turn=zawróć toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=nieznana instrukcja '%1$s' via=przez hour_abbr=g diff --git a/core/src/main/resources/com/graphhopper/util/pt_BR.txt b/core/src/main/resources/com/graphhopper/util/pt_BR.txt index b873fdac350..d7470f426cc 100644 --- a/core/src/main/resources/com/graphhopper/util/pt_BR.txt +++ b/core/src/main/resources/com/graphhopper/util/pt_BR.txt @@ -14,6 +14,8 @@ turn_sharp_left=curva acentuada à esquerda turn_sharp_right=curva acentuada à direita u_turn=faça um retorno toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=sinalização desconhecida '%1$s' via=via hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/pt_PT.txt b/core/src/main/resources/com/graphhopper/util/pt_PT.txt index 4b5dace2c9e..0906887cea5 100644 --- a/core/src/main/resources/com/graphhopper/util/pt_PT.txt +++ b/core/src/main/resources/com/graphhopper/util/pt_PT.txt @@ -14,6 +14,8 @@ turn_sharp_left=vire à curva apertada à esquerda turn_sharp_right=vire à curva apertada à direita u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=por hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/ro.txt b/core/src/main/resources/com/graphhopper/util/ro.txt index bb7f3c60214..7a34042c612 100644 --- a/core/src/main/resources/com/graphhopper/util/ro.txt +++ b/core/src/main/resources/com/graphhopper/util/ro.txt @@ -14,6 +14,8 @@ turn_sharp_left=schimbați direcția la brusc la stânga turn_sharp_right=schimbați direcția la brusc la dreapta u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=prin hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/ru.txt b/core/src/main/resources/com/graphhopper/util/ru.txt index f1a34d0a674..e9ff1e2aaa3 100644 --- a/core/src/main/resources/com/graphhopper/util/ru.txt +++ b/core/src/main/resources/com/graphhopper/util/ru.txt @@ -14,6 +14,8 @@ turn_sharp_left=Резко поверните налево turn_sharp_right=Резко поверните направо u_turn=Развернитесь toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=Неизвестная инструкция '%1$s' via=через hour_abbr=ч diff --git a/core/src/main/resources/com/graphhopper/util/sk.txt b/core/src/main/resources/com/graphhopper/util/sk.txt index cc1e8ac0d33..10782765fb0 100644 --- a/core/src/main/resources/com/graphhopper/util/sk.txt +++ b/core/src/main/resources/com/graphhopper/util/sk.txt @@ -14,6 +14,8 @@ turn_sharp_left=odbočte ostro doľava turn_sharp_right=odbočte ostro doprava u_turn=otočte sa o 180° toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=cez hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/sl_SI.txt b/core/src/main/resources/com/graphhopper/util/sl_SI.txt index f9af219469d..3b6398be2a3 100644 --- a/core/src/main/resources/com/graphhopper/util/sl_SI.txt +++ b/core/src/main/resources/com/graphhopper/util/sl_SI.txt @@ -14,6 +14,8 @@ turn_sharp_left=zavijte ostro levo turn_sharp_right=zavijte ostro desno u_turn=zavijte za 180° toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=neznano navodilo '%1$s' via=preko hour_abbr=ur diff --git a/core/src/main/resources/com/graphhopper/util/sr_RS.txt b/core/src/main/resources/com/graphhopper/util/sr_RS.txt index 0e82deb1cbc..200f1190b37 100644 --- a/core/src/main/resources/com/graphhopper/util/sr_RS.txt +++ b/core/src/main/resources/com/graphhopper/util/sr_RS.txt @@ -14,6 +14,8 @@ turn_sharp_left=skrenite oštro levo turn_sharp_right=skrenite oštro desno u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=preko hour_abbr=h diff --git a/core/src/main/resources/com/graphhopper/util/sv_SE.txt b/core/src/main/resources/com/graphhopper/util/sv_SE.txt index ea0b7d14708..792179e2b62 100644 --- a/core/src/main/resources/com/graphhopper/util/sv_SE.txt +++ b/core/src/main/resources/com/graphhopper/util/sv_SE.txt @@ -14,6 +14,8 @@ turn_sharp_left=sväng kraftigt vänster turn_sharp_right=sväng kraftigt höger u_turn=gör en u-sväng toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=via hour_abbr= tim diff --git a/core/src/main/resources/com/graphhopper/util/tr.txt b/core/src/main/resources/com/graphhopper/util/tr.txt index 39202d875e8..8ac2e3939ee 100644 --- a/core/src/main/resources/com/graphhopper/util/tr.txt +++ b/core/src/main/resources/com/graphhopper/util/tr.txt @@ -14,6 +14,8 @@ turn_sharp_left=sola keskin dön turn_sharp_right=sağa keskin dön u_turn=u dönüşü yap toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=bilinmeyen yön işareti '%1$s' via=yoluyla hour_abbr=s diff --git a/core/src/main/resources/com/graphhopper/util/uk.txt b/core/src/main/resources/com/graphhopper/util/uk.txt index 617c06c8575..81918543cf0 100644 --- a/core/src/main/resources/com/graphhopper/util/uk.txt +++ b/core/src/main/resources/com/graphhopper/util/uk.txt @@ -14,6 +14,8 @@ turn_sharp_left=Різко поверніть ліворуч turn_sharp_right=Різко поверніть праворуч u_turn=Розверніться toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=Невідома інструкція %1$s via=через hour_abbr= год diff --git a/core/src/main/resources/com/graphhopper/util/vi_VN.txt b/core/src/main/resources/com/graphhopper/util/vi_VN.txt index 2f2dee32658..7ddfa8d2653 100644 --- a/core/src/main/resources/com/graphhopper/util/vi_VN.txt +++ b/core/src/main/resources/com/graphhopper/util/vi_VN.txt @@ -14,6 +14,8 @@ turn_sharp_left=rẽ trái ngay lập tức turn_sharp_right=rẽ phải ngay lập tức u_turn=quay đầu xe toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=không xác định %1$s via=qua hour_abbr=giờ diff --git a/core/src/main/resources/com/graphhopper/util/zh_CN.txt b/core/src/main/resources/com/graphhopper/util/zh_CN.txt index aecda848ad4..0204ed2b64b 100644 --- a/core/src/main/resources/com/graphhopper/util/zh_CN.txt +++ b/core/src/main/resources/com/graphhopper/util/zh_CN.txt @@ -14,6 +14,8 @@ turn_sharp_left=左急转 turn_sharp_right=右急转 u_turn=掉头 toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=未知指示标志 '%1$s' via=途经 hour_abbr=小时 diff --git a/core/src/main/resources/com/graphhopper/util/zh_HK.txt b/core/src/main/resources/com/graphhopper/util/zh_HK.txt index 120dd187c00..54594696cf5 100644 --- a/core/src/main/resources/com/graphhopper/util/zh_HK.txt +++ b/core/src/main/resources/com/graphhopper/util/zh_HK.txt @@ -14,6 +14,8 @@ turn_sharp_left=左急轉 turn_sharp_right=右急轉 u_turn= toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown= via=途經 hour_abbr=小時 diff --git a/core/src/main/resources/com/graphhopper/util/zh_TW.txt b/core/src/main/resources/com/graphhopper/util/zh_TW.txt index 87bd675922f..de79e6726d4 100644 --- a/core/src/main/resources/com/graphhopper/util/zh_TW.txt +++ b/core/src/main/resources/com/graphhopper/util/zh_TW.txt @@ -14,6 +14,8 @@ turn_sharp_left=左急轉 turn_sharp_right=右急轉 u_turn=迴轉 toward_destination= +toward_destination_ref_only= +toward_destination_with_ref= unknown=未知指示標誌 '%1$s' via=途經 hour_abbr=小時 diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 8deaa43da46..5554cf90b50 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -78,6 +78,7 @@ public class GraphHopperTest { // map locations private static final String BAYREUTH = DIR + "/north-bayreuth.osm.gz"; + private static final String BAUTZEN = DIR + "/bautzen.osm"; private static final String BERLIN = DIR + "/berlin-siegessaeule.osm.gz"; private static final String KREMS = DIR + "/krems.osm.gz"; private static final String LAUF = DIR + "/Laufamholzstrasse.osm.xml"; @@ -515,7 +516,31 @@ public void testPointHint() { } @Test - public void testNorthBayreuthDestination() { + public void testForwardBackwardDestination() { + final String profile = "profile"; + GraphHopper hopper = new GraphHopper(). + setGraphHopperLocation(GH_LOCATION). + setOSMFile(BAUTZEN). + setProfiles(new Profile(profile).setVehicle("car").setWeighting("fastest")); + hopper.setMinNetworkSize(0); + hopper.importOrLoad(); + + Translation tr = hopper.getTranslationMap().getWithFallBack(Locale.US); + + GHResponse rsp = hopper.route(new GHRequest(51.1915, 14.416, 51.192, 14.412).setProfile(profile)); + assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); + assertEquals("keep right and take B 96 toward Bautzen-West, Hoyerswerda", + rsp.getBest().getInstructions().get(1).getTurnDescription(tr)); + assertEquals("turn left onto Hoyerswerdaer Straße and drive toward Hoyerswerda, Kleinwelka", + rsp.getBest().getInstructions().get(2).getTurnDescription(tr)); + + rsp = hopper.route(new GHRequest(51.191, 14.414, 51.1884, 14.41).setProfile(profile)); + assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); + assertEquals("turn left and take A 4 toward Dresden", rsp.getBest().getInstructions().get(1).getTurnDescription(tr)); + } + + @Test + public void testNorthBayreuthAccessDestination() { final String profile = "profile"; final String vehicle = "car"; final String weighting = "fastest"; diff --git a/web-api/src/main/java/com/graphhopper/util/Instruction.java b/web-api/src/main/java/com/graphhopper/util/Instruction.java index 7bc11d849eb..31132064136 100644 --- a/web-api/src/main/java/com/graphhopper/util/Instruction.java +++ b/web-api/src/main/java/com/graphhopper/util/Instruction.java @@ -96,7 +96,8 @@ public Map getExtraInfoJSON() { } public void setExtraInfo(String key, Object value) { - extraInfo.put(key, value); + if (value != null && key != null) + extraInfo.put(key, value); } /** @@ -217,6 +218,14 @@ public String getTurnDescription(Translation tr) { else str = streetName.isEmpty() ? dir : tr.tr("turn_onto", dir, streetName); } + String dest = (String) extraInfo.get("destination"); + String destRef = (String) extraInfo.get("destination_ref"); + if (dest != null) { + if (destRef != null) + return tr.tr("toward_destination_with_ref", str, destRef, dest); + return tr.tr("toward_destination", str, dest); + } else if (destRef != null) + return tr.tr("toward_destination_ref_only", str, destRef); return str; } } diff --git a/web-api/src/main/java/com/graphhopper/util/Parameters.java b/web-api/src/main/java/com/graphhopper/util/Parameters.java index fa4d9a35b1b..a1a7d490e48 100644 --- a/web-api/src/main/java/com/graphhopper/util/Parameters.java +++ b/web-api/src/main/java/com/graphhopper/util/Parameters.java @@ -200,6 +200,7 @@ public static final class Details { public static final String AVERAGE_SPEED = "average_speed"; public static final String STREET_NAME = "street_name"; public static final String STREET_REF = "street_ref"; + public static final String STREET_DESTINATION = "street_destination"; public static final String EDGE_ID = "edge_id"; public static final String EDGE_KEY = "edge_key"; public static final String TIME = "time"; From b85ba214b574aec7e1892d169d0d7eb7b256e793 Mon Sep 17 00:00:00 2001 From: Andi Date: Thu, 21 Jul 2022 08:44:16 +0200 Subject: [PATCH 106/389] Make profile resolving more flexible for web API (#2629) --- .../graphhopper/http/GraphHopperBundle.java | 28 ++++-- .../http/LegacyProfileResolver.java | 6 +- .../com/graphhopper/http/ProfileResolver.java | 85 +++++++++++++++++++ .../resources/IsochroneResource.java | 17 ++-- .../resources/MapMatchingResource.java | 54 ++++-------- .../graphhopper/resources/RouteResource.java | 63 ++++---------- .../graphhopper/resources/SPTResource.java | 17 ++-- .../http/CHLegacyProfileSelectorTest.java | 9 +- .../http/LMLegacyProfileSelectorTest.java | 9 +- .../http/LegacyProfileResolverTest.java | 26 +++--- .../MapMatchingResourceTurnCostsTest.java | 2 +- .../RouteResourceProfileSelectionTest.java | 2 +- 12 files changed, 182 insertions(+), 136 deletions(-) rename core/src/main/java/com/graphhopper/routing/ProfileResolver.java => web-bundle/src/main/java/com/graphhopper/http/LegacyProfileResolver.java (98%) create mode 100644 web-bundle/src/main/java/com/graphhopper/http/ProfileResolver.java rename core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java => web-bundle/src/test/java/com/graphhopper/http/CHLegacyProfileSelectorTest.java (97%) rename core/src/test/java/com/graphhopper/routing/lm/LMProfileSelectorTest.java => web-bundle/src/test/java/com/graphhopper/http/LMLegacyProfileSelectorTest.java (96%) rename core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java => web-bundle/src/test/java/com/graphhopper/http/LegacyProfileResolverTest.java (90%) diff --git a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java index f1821b35b93..6d748315d8a 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java +++ b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java @@ -29,7 +29,6 @@ import com.graphhopper.isochrone.algorithm.Triangulator; import com.graphhopper.jackson.Jackson; import com.graphhopper.resources.*; -import com.graphhopper.routing.ProfileResolver; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; @@ -125,14 +124,14 @@ public void dispose(LocationIndex instance) { } } - static class ProfileResolverFactory implements Factory { + static class LegacyProfileResolverFactory implements Factory { @Inject GraphHopper graphHopper; @Override - public ProfileResolver provide() { - return new ProfileResolver(graphHopper.getEncodingManager(), + public LegacyProfileResolver provide() { + return new LegacyProfileResolver(graphHopper.getEncodingManager(), graphHopper.getProfiles(), graphHopper.getCHPreparationHandler().getCHProfiles(), graphHopper.getLMPreparationHandler().getLMProfiles() @@ -140,7 +139,25 @@ public ProfileResolver provide() { } @Override - public void dispose(ProfileResolver profileResolver) { + public void dispose(LegacyProfileResolver profileResolver) { + + } + } + + static class ProfileResolverFactory implements Factory { + @Inject + GraphHopper graphHopper; + + @Inject + LegacyProfileResolver legacyProfileResolver; + + @Override + public ProfileResolver provide() { + return new ProfileResolver(graphHopper.getProfiles(), legacyProfileResolver); + } + + @Override + public void dispose(ProfileResolver instance) { } } @@ -237,6 +254,7 @@ protected void configure() { bind(new JTSTriangulator(graphHopper.getRouterConfig())).to(Triangulator.class); bindFactory(PathDetailsBuilderFactoryFactory.class).to(PathDetailsBuilderFactory.class); + bindFactory(LegacyProfileResolverFactory.class).to(LegacyProfileResolver.class); bindFactory(ProfileResolverFactory.class).to(ProfileResolver.class); bindFactory(HasElevation.class).to(Boolean.class).named("hasElevation"); bindFactory(LocationIndexFactory.class).to(LocationIndex.class); diff --git a/core/src/main/java/com/graphhopper/routing/ProfileResolver.java b/web-bundle/src/main/java/com/graphhopper/http/LegacyProfileResolver.java similarity index 98% rename from core/src/main/java/com/graphhopper/routing/ProfileResolver.java rename to web-bundle/src/main/java/com/graphhopper/http/LegacyProfileResolver.java index 684b448d64b..9811040b5cc 100644 --- a/core/src/main/java/com/graphhopper/routing/ProfileResolver.java +++ b/web-bundle/src/main/java/com/graphhopper/http/LegacyProfileResolver.java @@ -16,7 +16,7 @@ * limitations under the License. */ -package com.graphhopper.routing; +package com.graphhopper.http; import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; @@ -40,13 +40,13 @@ * Note that this class is meant to be only used for the top-most web layer, while the GH engine should only deal with * the profile parameter. */ -public class ProfileResolver { +public class LegacyProfileResolver { private final EncodingManager encodingManager; private final List profiles; private final List chProfiles; private final List lmProfiles; - public ProfileResolver(EncodingManager encodingManager, List profiles, List chProfiles, List lmProfiles) { + public LegacyProfileResolver(EncodingManager encodingManager, List profiles, List chProfiles, List lmProfiles) { this.encodingManager = encodingManager; this.profiles = profiles; Map profilesByName = new HashMap<>(profiles.size()); diff --git a/web-bundle/src/main/java/com/graphhopper/http/ProfileResolver.java b/web-bundle/src/main/java/com/graphhopper/http/ProfileResolver.java new file mode 100644 index 00000000000..e8b5527a8de --- /dev/null +++ b/web-bundle/src/main/java/com/graphhopper/http/ProfileResolver.java @@ -0,0 +1,85 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.http; + +import com.graphhopper.config.Profile; +import com.graphhopper.util.PMap; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static com.graphhopper.util.Parameters.Routing.*; + +public class ProfileResolver { + private final Map profilesByName; + private final LegacyProfileResolver legacyProfileResolver; + + public ProfileResolver(List profiles, LegacyProfileResolver legacyProfileResolver) { + profilesByName = new LinkedHashMap<>(profiles.size()); + profiles.forEach(p -> { + if (profilesByName.put(p.getName(), p) != null) + throw new IllegalArgumentException("Profiles must have distinct names"); + }); + this.legacyProfileResolver = legacyProfileResolver; + } + + public Profile resolveProfile(PMap hints) { + if (hints.getString("profile", "").isEmpty()) { + boolean hasCurbsides = hints.getBool("has_curbsides", false); + enableEdgeBasedIfThereAreCurbsides(hasCurbsides, hints); + return legacyProfileResolver.resolveProfile(hints); + } + errorIfLegacyParameters(hints); + Profile profile = doResolveProfile(hints); + if (profile == null) + throw new IllegalArgumentException("The requested profile '" + hints.getString("profile", "") + "' does not exist.\nAvailable profiles: " + profilesByName.keySet()); + return profile; + } + + protected Profile doResolveProfile(PMap hints) { + return profilesByName.get(hints.getString("profile", "")); + } + + public static void enableEdgeBasedIfThereAreCurbsides(boolean hasCurbsides, PMap hints) { + if (hasCurbsides) { + if (!hints.getBool(TURN_COSTS, true)) + throw new IllegalArgumentException("Disabling '" + TURN_COSTS + "' when using '" + CURBSIDE + "' is not allowed"); + if (!hints.getBool(EDGE_BASED, true)) + throw new IllegalArgumentException("Disabling '" + EDGE_BASED + "' when using '" + CURBSIDE + "' is not allowed"); + hints.putObject(EDGE_BASED, true); + } + } + + public static void errorIfLegacyParameters(PMap hints) { + if (hints.has("weighting")) + throw new IllegalArgumentException("Since you are using the 'profile' parameter, do not use the 'weighting' parameter." + + " You used 'weighting=" + hints.getString("weighting", "") + "'"); + if (hints.has("vehicle")) + throw new IllegalArgumentException("Since you are using the 'profile' parameter, do not use the 'vehicle' parameter." + + " You used 'vehicle=" + hints.getString("vehicle", "") + "'"); + if (hints.has("edge_based")) + throw new IllegalArgumentException("Since you are using the 'profile' parameter, do not use the 'edge_based' parameter." + + " You used 'edge_based=" + hints.getBool("edge_based", false) + "'"); + if (hints.has("turn_costs")) + throw new IllegalArgumentException("Since you are using the 'profile' parameter, do not use the 'turn_costs' parameter." + + " You used 'turn_costs=" + hints.getBool("turn_costs", false) + "'"); + } + +} diff --git a/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java b/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java index 0ec76366081..9edbf443fcd 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java @@ -5,11 +5,11 @@ import com.graphhopper.GraphHopper; import com.graphhopper.config.Profile; import com.graphhopper.http.GHPointParam; +import com.graphhopper.http.ProfileResolver; import com.graphhopper.isochrone.algorithm.ContourBuilder; import com.graphhopper.isochrone.algorithm.ShortestPathTree; import com.graphhopper.isochrone.algorithm.Triangulator; import com.graphhopper.jackson.ResponsePathSerializer; -import com.graphhopper.routing.ProfileResolver; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.Subnetwork; import com.graphhopper.routing.querygraph.QueryGraph; @@ -39,7 +39,6 @@ import java.util.function.ToDoubleFunction; import static com.graphhopper.resources.IsochroneResource.ResponseType.geojson; -import static com.graphhopper.resources.RouteResource.errorIfLegacyParameters; import static com.graphhopper.resources.RouteResource.removeLegacyParameters; import static com.graphhopper.routing.util.TraversalMode.EDGE_BASED; import static com.graphhopper.routing.util.TraversalMode.NODE_BASED; @@ -81,15 +80,13 @@ public Response doGet( RouteResource.initHints(hintsMap, uriInfo.getQueryParameters()); hintsMap.putObject(Parameters.CH.DISABLE, true); hintsMap.putObject(Parameters.Landmark.DISABLE, true); - if (Helper.isEmpty(profileName)) { - profileName = profileResolver.resolveProfile(hintsMap).getName(); - removeLegacyParameters(hintsMap); - } - errorIfLegacyParameters(hintsMap); - Profile profile = graphHopper.getProfile(profileName); - if (profile == null) - throw new IllegalArgumentException("The requested profile '" + profileName + "' does not exist"); + PMap profileResolverHints = new PMap(hintsMap); + profileResolverHints.putObject("profile", profileName); + Profile profile = profileResolver.resolveProfile(profileResolverHints); + profileName = profile.getName(); + removeLegacyParameters(hintsMap); + LocationIndex locationIndex = graphHopper.getLocationIndex(); BaseGraph graph = graphHopper.getBaseGraph(); Weighting weighting = graphHopper.createWeighting(profile, hintsMap); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java index e9c819df69d..37543271dae 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java @@ -25,10 +25,10 @@ import com.graphhopper.GraphHopper; import com.graphhopper.ResponsePath; import com.graphhopper.gpx.GpxConversions; +import com.graphhopper.http.ProfileResolver; import com.graphhopper.jackson.Gpx; import com.graphhopper.jackson.ResponsePathSerializer; import com.graphhopper.matching.*; -import com.graphhopper.routing.ProfileResolver; import com.graphhopper.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,9 +36,13 @@ import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; -import javax.ws.rs.core.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; import java.util.*; +import static com.graphhopper.resources.RouteResource.removeLegacyParameters; import static com.graphhopper.util.Parameters.Details.PATH_DETAILS; import static com.graphhopper.util.Parameters.Routing.*; @@ -97,19 +101,21 @@ public Response match( StopWatch sw = new StopWatch().start(); - PMap hints = createHintsMap(uriInfo.getQueryParameters()); + PMap hints = new PMap(); + RouteResource.initHints(hints, uriInfo.getQueryParameters()); + // add values that are not in hints because they were explicitly listed in query params hints.putObject(MAX_VISITED_NODES, maxVisitedNodes); String weightingVehicleLogStr = "weighting: " + hints.getString("weighting", "") + ", vehicle: " + hints.getString("vehicle", ""); - if (Helper.isEmpty(profile)) { - // resolve profile and remove legacy vehicle/weighting parameters - // we need to explicitly disable CH here because map matching does not use it - PMap pMap = new PMap(hints).putObject(Parameters.CH.DISABLE, true); - profile = profileResolver.resolveProfile(pMap).getName(); - removeLegacyParameters(hints); - } + + // resolve profile and remove legacy vehicle/weighting parameters + // we need to explicitly disable CH here because map matching does not use it + PMap profileResolverHints = new PMap(hints); + profileResolverHints.putObject("profile", profile); + profileResolverHints.putObject(Parameters.CH.DISABLE, true); + profile = profileResolver.resolveProfile(profileResolverHints).getName(); hints.putObject("profile", profile); - errorIfLegacyParameters(hints); + removeLegacyParameters(hints); MapMatching matching = new MapMatching(graphHopper, hints); matching.setMeasurementErrorSigma(gpsAccuracy); @@ -177,32 +183,6 @@ public Response match( } } - private void removeLegacyParameters(PMap hints) { - hints.remove("vehicle"); - hints.remove("weighting"); - } - - private static void errorIfLegacyParameters(PMap hints) { - if (hints.has("weighting")) - throw new IllegalArgumentException("Since you are using the 'profile' parameter, do not use the 'weighting' parameter." + - " You used 'weighting=" + hints.getString("weighting", "") + "'"); - if (hints.has("vehicle")) - throw new IllegalArgumentException("Since you are using the 'profile' parameter, do not use the 'vehicle' parameter." + - " You used 'vehicle=" + hints.getString("vehicle", "") + "'"); - } - - private PMap createHintsMap(MultivaluedMap queryParameters) { - PMap m = new PMap(); - for (Map.Entry> e : queryParameters.entrySet()) { - if (e.getValue().size() == 1) { - m.putObject(Helper.camelCaseToUnderScore(e.getKey()), Helper.toObject(e.getValue().get(0))); - } else { - // TODO ugly: ignore multi parameters like point to avoid exception. See RouteResource.initHints - } - } - return m; - } - public static JsonNode convertToTree(MatchResult result, boolean elevation, boolean pointsEncoded) { ObjectNode root = JsonNodeFactory.instance.objectNode(); ObjectNode diary = root.putObject("diary"); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java b/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java index a9b71a152f6..89ca9baaa24 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java @@ -22,9 +22,9 @@ import com.graphhopper.GraphHopper; import com.graphhopper.gpx.GpxConversions; import com.graphhopper.http.GHPointParam; +import com.graphhopper.http.ProfileResolver; import com.graphhopper.jackson.MultiException; import com.graphhopper.jackson.ResponsePathSerializer; -import com.graphhopper.routing.ProfileResolver; import com.graphhopper.util.*; import com.graphhopper.util.shapes.GHPoint; import io.dropwizard.jersey.params.AbstractParam; @@ -103,12 +103,13 @@ public Response doGet( GHRequest request = new GHRequest(); initHints(request.getHints(), uriInfo.getQueryParameters()); String weightingVehicleLogStr = "weighting: " + request.getHints().getString("weighting", "") + ", vehicle: " + request.getHints().getString("vehicle", ""); - if (Helper.isEmpty(profileName)) { - enableEdgeBasedIfThereAreCurbsides(curbsides, request); - profileName = profileResolver.resolveProfile(request.getHints()).getName(); - removeLegacyParameters(request.getHints()); - } - errorIfLegacyParameters(request.getHints()); + + PMap profileResolverHints = new PMap(request.getHints()); + profileResolverHints.putObject("profile", profileName); + profileResolverHints.putObject("has_curbsides", !curbsides.isEmpty()); + profileName = profileResolver.resolveProfile(profileResolverHints).getName(); + removeLegacyParameters(request.getHints()); + request.setPoints(points). setProfile(profileName). setAlgorithm(algoStr). @@ -161,19 +162,16 @@ public Response doGet( @Produces(MediaType.APPLICATION_JSON) public Response doPost(@NotNull GHRequest request, @Context HttpServletRequest httpReq) { StopWatch sw = new StopWatch().start(); - if (request.getCustomModel() == null) { - if (Helper.isEmpty(request.getProfile())) { - // legacy parameter resolution (only used when there is no custom model) - enableEdgeBasedIfThereAreCurbsides(request.getCurbsides(), request); - request.setProfile(profileResolver.resolveProfile(request.getHints()).getName()); - removeLegacyParameters(request.getHints()); - } - } else { - if (Helper.isEmpty(request.getProfile())) - // throw a dedicated exception here, otherwise a missing profile is still caught in Router - throw new IllegalArgumentException("The 'profile' parameter is required when you use the `custom_model` parameter"); - } - errorIfLegacyParameters(request.getHints()); + if (Helper.isEmpty(request.getProfile()) && request.getCustomModel() != null) + // throw a dedicated exception here, otherwise a missing profile is still caught in Router + throw new IllegalArgumentException("The 'profile' parameter is required when you use the `custom_model` parameter"); + + PMap profileResolverHints = new PMap(request.getHints()); + profileResolverHints.putObject("profile", request.getProfile()); + profileResolverHints.putObject("has_curbsides", !request.getCurbsides().isEmpty()); + request.setProfile(profileResolver.resolveProfile(profileResolverHints).getName()); + removeLegacyParameters(request.getHints()); + GHResponse ghResponse = graphHopper.route(request); boolean instructions = request.getHints().getBool(INSTRUCTIONS, true); boolean enableElevation = request.getHints().getBool("elevation", false); @@ -208,31 +206,6 @@ public Response doPost(@NotNull GHRequest request, @Context HttpServletRequest h } } - private void enableEdgeBasedIfThereAreCurbsides(List curbsides, GHRequest request) { - if (!curbsides.isEmpty()) { - if (!request.getHints().getBool(TURN_COSTS, true)) - throw new IllegalArgumentException("Disabling '" + TURN_COSTS + "' when using '" + CURBSIDE + "' is not allowed"); - if (!request.getHints().getBool(EDGE_BASED, true)) - throw new IllegalArgumentException("Disabling '" + EDGE_BASED + "' when using '" + CURBSIDE + "' is not allowed"); - request.getHints().putObject(EDGE_BASED, true); - } - } - - public static void errorIfLegacyParameters(PMap hints) { - if (hints.has("weighting")) - throw new IllegalArgumentException("Since you are using the 'profile' parameter, do not use the 'weighting' parameter." + - " You used 'weighting=" + hints.getString("weighting", "") + "'"); - if (hints.has("vehicle")) - throw new IllegalArgumentException("Since you are using the 'profile' parameter, do not use the 'vehicle' parameter." + - " You used 'vehicle=" + hints.getString("vehicle", "") + "'"); - if (hints.has("edge_based")) - throw new IllegalArgumentException("Since you are using the 'profile' parameter, do not use the 'edge_based' parameter." + - " You used 'edge_based=" + hints.getBool("edge_based", false) + "'"); - if (hints.has("turn_costs")) - throw new IllegalArgumentException("Since you are using the 'profile' parameter, do not use the 'turn_costs' parameter." + - " You used 'turn_costs=" + hints.getBool("turn_costs", false) + "'"); - } - public static void removeLegacyParameters(PMap hints) { // these parameters should only be used to resolve the profile, but should not be passed to GraphHopper hints.remove("weighting"); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java index b4914b0155b..f071ba9fded 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java @@ -3,8 +3,8 @@ import com.graphhopper.GraphHopper; import com.graphhopper.config.Profile; import com.graphhopper.http.GHPointParam; +import com.graphhopper.http.ProfileResolver; import com.graphhopper.isochrone.algorithm.ShortestPathTree; -import com.graphhopper.routing.ProfileResolver; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.querygraph.QueryGraph; import com.graphhopper.routing.util.DefaultSnapFilter; @@ -36,7 +36,6 @@ import java.io.Writer; import java.util.*; -import static com.graphhopper.resources.RouteResource.errorIfLegacyParameters; import static com.graphhopper.resources.RouteResource.removeLegacyParameters; import static com.graphhopper.routing.util.TraversalMode.EDGE_BASED; import static com.graphhopper.routing.util.TraversalMode.NODE_BASED; @@ -85,15 +84,13 @@ public Response doGet( RouteResource.initHints(hintsMap, uriInfo.getQueryParameters()); hintsMap.putObject(Parameters.CH.DISABLE, true); hintsMap.putObject(Parameters.Landmark.DISABLE, true); - if (Helper.isEmpty(profileName)) { - profileName = profileResolver.resolveProfile(hintsMap).getName(); - removeLegacyParameters(hintsMap); - } - errorIfLegacyParameters(hintsMap); - Profile profile = graphHopper.getProfile(profileName); - if (profile == null) - throw new IllegalArgumentException("The requested profile '" + profileName + "' does not exist"); + PMap profileResolverHints = new PMap(hintsMap); + profileResolverHints.putObject("profile", profileName); + Profile profile = profileResolver.resolveProfile(profileResolverHints); + profileName = profile.getName(); + removeLegacyParameters(hintsMap); + LocationIndex locationIndex = graphHopper.getLocationIndex(); BaseGraph graph = graphHopper.getBaseGraph(); Weighting weighting = graphHopper.createWeighting(profile, hintsMap); diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java b/web-bundle/src/test/java/com/graphhopper/http/CHLegacyProfileSelectorTest.java similarity index 97% rename from core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java rename to web-bundle/src/test/java/com/graphhopper/http/CHLegacyProfileSelectorTest.java index 9191ed0555f..71c5786a4f1 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHProfileSelectorTest.java +++ b/web-bundle/src/test/java/com/graphhopper/http/CHLegacyProfileSelectorTest.java @@ -16,12 +16,11 @@ * limitations under the License. */ -package com.graphhopper.routing.ch; +package com.graphhopper.http; import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; -import com.graphhopper.routing.ProfileResolver; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.VehicleAccess; @@ -39,7 +38,7 @@ import static org.junit.jupiter.api.Assertions.*; -public class CHProfileSelectorTest { +public class CHLegacyProfileSelectorTest { private static final String MULTIPLE_MATCHES_ERROR = "There are multiple CH profiles matching your request. Use the `weighting`,`vehicle`,`turn_costs` and/or `u_turn_costs` parameters to be more specific"; private static final String NO_MATCH_ERROR = "Cannot find matching profile that supports CH for your request"; @@ -269,7 +268,7 @@ private void assertProfileFound(Profile expectedProfile, List profiles, private void assertProfileFound(Profile expectedProfile, List profiles, List chProfiles, String vehicle, String weighting, Boolean edgeBased, Integer uTurnCosts) { PMap hintsMap = createHintsMap(vehicle, weighting, edgeBased, uTurnCosts); try { - Profile selectedProfile = new ProfileResolver(encodingManager, profiles, chProfiles, Collections.emptyList()).selectProfileCH(hintsMap); + Profile selectedProfile = new LegacyProfileResolver(encodingManager, profiles, chProfiles, Collections.emptyList()).selectProfileCH(hintsMap); assertEquals(expectedProfile, selectedProfile); } catch (IllegalArgumentException e) { fail("no profile found\nexpected: " + expectedProfile + "\nerror: " + e.getMessage()); @@ -283,7 +282,7 @@ private String assertCHProfileSelectionError(String expectedError, List private String assertCHProfileSelectionError(String expectedError, List profiles, List chProfiles, String vehicle, String weighting, Boolean edgeBased, Integer uTurnCosts) { PMap hintsMap = createHintsMap(vehicle, weighting, edgeBased, uTurnCosts); try { - new ProfileResolver(encodingManager, profiles, chProfiles, Collections.emptyList()).selectProfileCH(hintsMap); + new LegacyProfileResolver(encodingManager, profiles, chProfiles, Collections.emptyList()).selectProfileCH(hintsMap); fail("There should have been an error"); return ""; } catch (IllegalArgumentException e) { diff --git a/core/src/test/java/com/graphhopper/routing/lm/LMProfileSelectorTest.java b/web-bundle/src/test/java/com/graphhopper/http/LMLegacyProfileSelectorTest.java similarity index 96% rename from core/src/test/java/com/graphhopper/routing/lm/LMProfileSelectorTest.java rename to web-bundle/src/test/java/com/graphhopper/http/LMLegacyProfileSelectorTest.java index 98ffb3f9e1c..15306625b2e 100644 --- a/core/src/test/java/com/graphhopper/routing/lm/LMProfileSelectorTest.java +++ b/web-bundle/src/test/java/com/graphhopper/http/LMLegacyProfileSelectorTest.java @@ -16,12 +16,11 @@ * limitations under the License. */ -package com.graphhopper.routing.lm; +package com.graphhopper.http; import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; -import com.graphhopper.routing.ProfileResolver; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.VehicleAccess; @@ -39,7 +38,7 @@ import static org.junit.jupiter.api.Assertions.*; -public class LMProfileSelectorTest { +public class LMLegacyProfileSelectorTest { private static final String MULTIPLE_MATCHES_ERROR = "There are multiple LM profiles matching your request. Use the `weighting`, `vehicle` and `turn_costs` parameters to be more specific"; private static final String NO_MATCH_ERROR = "Cannot find matching LM profile for your request"; @@ -171,7 +170,7 @@ public void withAndWithoutTurnCosts() { private void assertProfileFound(Profile expectedProfile, List profiles, List lmProfiles, String vehicle, String weighting, Boolean edgeBased, Integer uTurnCosts) { PMap hintsMap = createHintsMap(vehicle, weighting, edgeBased, uTurnCosts); try { - Profile selectedProfile = new ProfileResolver(encodingManager, profiles, Collections.emptyList(), lmProfiles).selectProfileLM(hintsMap); + Profile selectedProfile = new LegacyProfileResolver(encodingManager, profiles, Collections.emptyList(), lmProfiles).selectProfileLM(hintsMap); assertEquals(expectedProfile, selectedProfile); } catch (IllegalArgumentException e) { fail("no profile found\nexpected: " + expectedProfile + "\nerror: " + e.getMessage()); @@ -181,7 +180,7 @@ private void assertProfileFound(Profile expectedProfile, List profiles, private String assertLMProfileSelectionError(String expectedError, List profiles, List lmProfiles, String vehicle, String weighting, Boolean edgeBased, Integer uTurnCosts) { PMap hintsMap = createHintsMap(vehicle, weighting, edgeBased, uTurnCosts); try { - new ProfileResolver(encodingManager, profiles, Collections.emptyList(), lmProfiles).selectProfileLM(hintsMap); + new LegacyProfileResolver(encodingManager, profiles, Collections.emptyList(), lmProfiles).selectProfileLM(hintsMap); fail("There should have been an error"); return ""; } catch (IllegalArgumentException e) { diff --git a/core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java b/web-bundle/src/test/java/com/graphhopper/http/LegacyProfileResolverTest.java similarity index 90% rename from core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java rename to web-bundle/src/test/java/com/graphhopper/http/LegacyProfileResolverTest.java index 62e1766f159..b69fa55d838 100644 --- a/core/src/test/java/com/graphhopper/routing/ProfileResolverTest.java +++ b/web-bundle/src/test/java/com/graphhopper/http/LegacyProfileResolverTest.java @@ -16,13 +16,11 @@ * limitations under the License. */ -package com.graphhopper.routing; +package com.graphhopper.http; import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; -import com.graphhopper.routing.ch.CHProfileSelectorTest; -import com.graphhopper.routing.lm.LMProfileSelectorTest; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.util.PMap; import com.graphhopper.util.Parameters; @@ -37,13 +35,13 @@ /** * So far this test is only testing the profile selection in the absence of CH/LM profiles. For CH/LM profile selection * - * @see CHProfileSelectorTest - * @see LMProfileSelectorTest + * @see CHLegacyProfileSelectorTest + * @see LMLegacyProfileSelectorTest */ -public class ProfileResolverTest { +public class LegacyProfileResolverTest { @Test public void defaultVehicle() { - ProfileResolver profileResolver = new ProfileResolver( + LegacyProfileResolver profileResolver = new LegacyProfileResolver( EncodingManager.create("car,foot,bike"), Arrays.asList( new Profile("my_bike").setVehicle("bike"), @@ -59,7 +57,7 @@ public void defaultVehicle() { @Test public void defaultWeighting() { - ProfileResolver profileResolver = new ProfileResolver( + LegacyProfileResolver profileResolver = new LegacyProfileResolver( EncodingManager.create("bike,car,foot"), Arrays.asList( new Profile("fast_bike").setVehicle("bike").setWeighting("fastest"), @@ -75,7 +73,7 @@ public void defaultWeighting() { @Test public void missingProfiles() { - ProfileResolver profileResolver = new ProfileResolver( + LegacyProfileResolver profileResolver = new LegacyProfileResolver( EncodingManager.create("car,bike"), Arrays.asList( new Profile("fast_bike").setVehicle("bike").setWeighting("fastest"), @@ -99,7 +97,7 @@ public void missingProfiles() { @Test public void edgeBasedAndTurnCosts() { - ProfileResolver profileResolver = new ProfileResolver( + LegacyProfileResolver profileResolver = new LegacyProfileResolver( EncodingManager.create("foot"), Collections.singletonList(new Profile("profile").setVehicle("foot").setWeighting("fastest")), Collections.emptyList(), Collections.emptyList()); @@ -117,7 +115,7 @@ public void defaultVehicleAllAlgos() { final String vehicle2 = "car"; final String weighting = "shortest"; - ProfileResolver profileResolver = new ProfileResolver( + LegacyProfileResolver profileResolver = new LegacyProfileResolver( EncodingManager.create(vehicle1 + "," + vehicle2), Arrays.asList( new Profile(profile1).setVehicle(vehicle1).setWeighting(weighting), @@ -145,7 +143,7 @@ public void defaultVehicleAllAlgos() { assertEquals(profile1, profileResolver.resolveProfile(hints.putObject(Parameters.Landmark.DISABLE, true)).getName()); } - private void assertMultiMatchError(ProfileResolver profileResolver, PMap hints, String... expectedErrors) { + private void assertMultiMatchError(LegacyProfileResolver profileResolver, PMap hints, String... expectedErrors) { if (expectedErrors.length == 0) { throw new IllegalArgumentException("there must be at least one expected error"); } @@ -159,7 +157,7 @@ private void assertMultiMatchError(ProfileResolver profileResolver, PMap hints, } } - private void assertProfileNotFound(ProfileResolver profileResolver, PMap hints) { + private void assertProfileNotFound(LegacyProfileResolver profileResolver, PMap hints) { try { profileResolver.resolveProfile(hints); fail(); @@ -168,7 +166,7 @@ private void assertProfileNotFound(ProfileResolver profileResolver, PMap hints) } } - private void assertUnsupportedVehicle(ProfileResolver profileResolver, String vehicle, List supported) { + private void assertUnsupportedVehicle(LegacyProfileResolver profileResolver, String vehicle, List supported) { IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> profileResolver.resolveProfile(new PMap().putObject("vehicle", vehicle))); assertTrue(e.getMessage().contains("Vehicle not supported: `" + vehicle + "`. Supported are: `" + String.join(",", supported) + "`"), e.getMessage()); } diff --git a/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java b/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java index e3c9500d3a9..7f4f786e47e 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java @@ -112,7 +112,7 @@ public void errorOnUnknownProfile() { JsonNode json = response.readEntity(JsonNode.class); assertTrue(json.has("message"), json.toString()); assertEquals(400, response.getStatus()); - assertTrue(json.toString().contains("Could not find profile 'xyz', choose one of: [car, car_no_tc, bike]")); + assertTrue(json.toString().contains("The requested profile 'xyz' does not exist.\\nAvailable profiles: [car, car_no_tc, bike]"), json.toString()); } private void runCar(String urlParams) { diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java index b635cef35f0..e12edd2931b 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java @@ -92,7 +92,7 @@ public void selectUsingProfile(String mode) { @ValueSource(strings = {"CH", "LM", "flex"}) public void withoutProfile(String mode) { // for legacy reasons we can skip the profile parameter and use the vehicle/weighting parameters instead, - // see ProfileResolver + // see LegacyProfileResolver assertDistance(null, "car", "fastest", mode, 3563); assertDistance(null, "foot", "shortest", mode, 2935); assertDistance(null, "bike", "short_fastest", mode, 3085); From 09ed4d2d4694bfe8d8dc36dc9495a1f1a3f2a651 Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 21 Jul 2022 11:02:38 +0200 Subject: [PATCH 107/389] ProfileResolver only resolves name of the profile (#2629) --- .../com/graphhopper/http/ProfileResolver.java | 18 ++++++++++-------- .../resources/IsochroneResource.java | 6 ++++-- .../resources/MapMatchingResource.java | 2 +- .../graphhopper/resources/RouteResource.java | 4 ++-- .../com/graphhopper/resources/SPTResource.java | 6 ++++-- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/web-bundle/src/main/java/com/graphhopper/http/ProfileResolver.java b/web-bundle/src/main/java/com/graphhopper/http/ProfileResolver.java index e8b5527a8de..83ff6d42cf2 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/ProfileResolver.java +++ b/web-bundle/src/main/java/com/graphhopper/http/ProfileResolver.java @@ -28,7 +28,7 @@ import static com.graphhopper.util.Parameters.Routing.*; public class ProfileResolver { - private final Map profilesByName; + protected final Map profilesByName; private final LegacyProfileResolver legacyProfileResolver; public ProfileResolver(List profiles, LegacyProfileResolver legacyProfileResolver) { @@ -40,21 +40,23 @@ public ProfileResolver(List profiles, LegacyProfileResolver legacyProfi this.legacyProfileResolver = legacyProfileResolver; } - public Profile resolveProfile(PMap hints) { - if (hints.getString("profile", "").isEmpty()) { + public String resolveProfile(PMap hints) { + String profileName = hints.getString("profile", ""); + if (profileName.isEmpty()) { boolean hasCurbsides = hints.getBool("has_curbsides", false); enableEdgeBasedIfThereAreCurbsides(hasCurbsides, hints); - return legacyProfileResolver.resolveProfile(hints); + return legacyProfileResolver.resolveProfile(hints).getName(); } errorIfLegacyParameters(hints); - Profile profile = doResolveProfile(hints); + String profile = doResolveProfile(profileName, hints); if (profile == null) - throw new IllegalArgumentException("The requested profile '" + hints.getString("profile", "") + "' does not exist.\nAvailable profiles: " + profilesByName.keySet()); + throw new IllegalArgumentException("The requested profile '" + profileName + "' does not exist.\nAvailable profiles: " + profilesByName.keySet()); return profile; } - protected Profile doResolveProfile(PMap hints) { - return profilesByName.get(hints.getString("profile", "")); + protected String doResolveProfile(String profileName, PMap hints) { + Profile profile = profilesByName.get(profileName); + return profile == null ? null : profile.getName(); } public static void enableEdgeBasedIfThereAreCurbsides(boolean hasCurbsides, PMap hints) { diff --git a/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java b/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java index 9edbf443fcd..bd504b9db07 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/IsochroneResource.java @@ -83,10 +83,12 @@ public Response doGet( PMap profileResolverHints = new PMap(hintsMap); profileResolverHints.putObject("profile", profileName); - Profile profile = profileResolver.resolveProfile(profileResolverHints); - profileName = profile.getName(); + profileName = profileResolver.resolveProfile(profileResolverHints); removeLegacyParameters(hintsMap); + Profile profile = graphHopper.getProfile(profileName); + if (profile == null) + throw new IllegalArgumentException("The requested profile '" + profileName + "' does not exist"); LocationIndex locationIndex = graphHopper.getLocationIndex(); BaseGraph graph = graphHopper.getBaseGraph(); Weighting weighting = graphHopper.createWeighting(profile, hintsMap); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java index 37543271dae..53237ea486c 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java @@ -113,7 +113,7 @@ public Response match( PMap profileResolverHints = new PMap(hints); profileResolverHints.putObject("profile", profile); profileResolverHints.putObject(Parameters.CH.DISABLE, true); - profile = profileResolver.resolveProfile(profileResolverHints).getName(); + profile = profileResolver.resolveProfile(profileResolverHints); hints.putObject("profile", profile); removeLegacyParameters(hints); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java b/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java index 89ca9baaa24..86b2511f502 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java @@ -107,7 +107,7 @@ public Response doGet( PMap profileResolverHints = new PMap(request.getHints()); profileResolverHints.putObject("profile", profileName); profileResolverHints.putObject("has_curbsides", !curbsides.isEmpty()); - profileName = profileResolver.resolveProfile(profileResolverHints).getName(); + profileName = profileResolver.resolveProfile(profileResolverHints); removeLegacyParameters(request.getHints()); request.setPoints(points). @@ -169,7 +169,7 @@ public Response doPost(@NotNull GHRequest request, @Context HttpServletRequest h PMap profileResolverHints = new PMap(request.getHints()); profileResolverHints.putObject("profile", request.getProfile()); profileResolverHints.putObject("has_curbsides", !request.getCurbsides().isEmpty()); - request.setProfile(profileResolver.resolveProfile(profileResolverHints).getName()); + request.setProfile(profileResolver.resolveProfile(profileResolverHints)); removeLegacyParameters(request.getHints()); GHResponse ghResponse = graphHopper.route(request); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java index f071ba9fded..062cc10f10c 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java @@ -87,10 +87,12 @@ public Response doGet( PMap profileResolverHints = new PMap(hintsMap); profileResolverHints.putObject("profile", profileName); - Profile profile = profileResolver.resolveProfile(profileResolverHints); - profileName = profile.getName(); + profileName = profileResolver.resolveProfile(profileResolverHints); removeLegacyParameters(hintsMap); + Profile profile = graphHopper.getProfile(profileName); + if (profile == null) + throw new IllegalArgumentException("The requested profile '" + profileName + "' does not exist"); LocationIndex locationIndex = graphHopper.getLocationIndex(); BaseGraph graph = graphHopper.getBaseGraph(); Weighting weighting = graphHopper.createWeighting(profile, hintsMap); From 785fa2492187a17b4d0a15511bb93ec190c9d08c Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 21 Jul 2022 11:50:00 +0200 Subject: [PATCH 108/389] car: do not pass jersey_barrier https://www.openstreetmap.org/node/8857224952 --- .../src/main/java/com/graphhopper/routing/util/CarTagParser.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java index 77babb47be6..fa4a84444d2 100644 --- a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java @@ -93,6 +93,7 @@ public CarTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, barriers.add("block"); barriers.add("bus_trap"); barriers.add("sump_buster"); + barriers.add("jersey_barrier"); badSurfaceSpeedMap.add("cobblestone"); badSurfaceSpeedMap.add("grass_paver"); From 35d0898fa203d212850265068c378c6868586323 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 21 Jul 2022 14:23:16 +0200 Subject: [PATCH 109/389] move cut string method to EdgeKVStorage --- CHANGELOG.md | 2 +- .../com/graphhopper/reader/osm/OSMReader.java | 2 +- .../com/graphhopper/search/EdgeKVStorage.java | 9 ++++++++ .../graphhopper/search/EdgeKVStorageTest.java | 22 +++++++++++++++++++ .../java/com/graphhopper/util/Helper.java | 9 -------- .../java/com/graphhopper/util/HelperTest.java | 21 ------------------ 6 files changed, 33 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7343f034da..6fe72999978 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ VehicleAccess.key("car")), #2611 - backward incompatible change as instructions and the street_name path detail do no longer contain the ref #2598 - StringIndex is now EdgeKVStorage and can store e.g. byte arrays. String values needs to be limited to 255 bytes before - storing them. See #2597 + storing them. See EdgeKVStorage.cutString and #2597. - the Matrix client changed and users have to adapt the usage, see #2587 - replaced car$access with car_access (and same for $average_speed and $priority) - don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 1daa0232b41..95f582fa1db 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -466,7 +466,7 @@ static String fixWayName(String str) { if (str == null) return ""; // the EdgeKVStorage does not accept too long strings -> Helper.cutStringForKV - return Helper.cutStringForKV(WAY_NAME_PATTERN.matcher(str).replaceAll(", ")); + return EdgeKVStorage.cutString(WAY_NAME_PATTERN.matcher(str).replaceAll(", ")); } /** diff --git a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java index a62a96cb057..b4db8c8fc1e 100644 --- a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java +++ b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java @@ -478,4 +478,13 @@ public String toString() { return key + '=' + value + " (" + fwd + "|" + bwd + ")"; } } + + /** + * This method limits the specified String value to the length currently accepted for values in the EdgeKVStorage. + */ + public static String cutString(String value) { + byte[] bytes = value.getBytes(Helper.UTF_CS); + // See #2609 and test why we use a value < 255 + return bytes.length > 250 ? new String(bytes, 0, 250, Helper.UTF_CS) : value; + } } diff --git a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java index 29a476f8edc..f9371cdc811 100644 --- a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java +++ b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java @@ -12,6 +12,8 @@ import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static com.graphhopper.search.EdgeKVStorage.MAX_UNIQUE_KEYS; +import static com.graphhopper.search.EdgeKVStorage.cutString; +import static com.graphhopper.util.Helper.UTF_CS; import static org.junit.jupiter.api.Assertions.*; public class EdgeKVStorageTest { @@ -371,4 +373,24 @@ private List createRandomList(Random random, List keys, List seed " + seed); + } + + @Test + public void testCutString() { + String s = cutString("Бухарестская улица (http://ru.wikipedia.org/wiki/" + + "%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))"); + assertEquals(250, s.getBytes(UTF_CS).length); + } } \ No newline at end of file diff --git a/web-api/src/main/java/com/graphhopper/util/Helper.java b/web-api/src/main/java/com/graphhopper/util/Helper.java index e50de6cdc86..7185a0a523b 100644 --- a/web-api/src/main/java/com/graphhopper/util/Helper.java +++ b/web-api/src/main/java/com/graphhopper/util/Helper.java @@ -476,13 +476,4 @@ public static int staticHashCode(String str) { } return val; } - - /** - * This method limits the specified String value to the length currently accepted for values in the EdgeKVStorage. - */ - public static String cutStringForKV(String value) { - byte[] bytes = value.getBytes(UTF_CS); - // See #2609 and test why we use a value < 255 - return bytes.length > 250 ? new String(bytes, 0, 250, UTF_CS) : value; - } } diff --git a/web-api/src/test/java/com/graphhopper/util/HelperTest.java b/web-api/src/test/java/com/graphhopper/util/HelperTest.java index 83bf0f54ab4..5b89b97a5bb 100644 --- a/web-api/src/test/java/com/graphhopper/util/HelperTest.java +++ b/web-api/src/test/java/com/graphhopper/util/HelperTest.java @@ -20,7 +20,6 @@ import org.junit.jupiter.api.Test; import java.util.Locale; -import java.util.Random; import static com.graphhopper.util.Helper.UTF_CS; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -107,19 +106,6 @@ public void testUnderscoreToCamelCase() { assertEquals("TestCase_", Helper.underScoreToCamelCase("_test_case_")); } - // @RepeatedTest(1000) - public void ignoreRandomString() { - String s = ""; - long seed = new Random().nextLong(); - Random rand = new Random(seed); - for (int i = 0; i < 255; i++) { - s += (char) rand.nextInt(); - } - - s = Helper.cutStringForKV(s); - assertTrue(s.getBytes(UTF_CS).length <= 255, s.getBytes(UTF_CS).length + " -> seed " + seed); - } - @Test public void testIssue2609() { String s = ""; @@ -138,11 +124,4 @@ public void testIssue2609() { bytes[0] = -25; assertEquals(3, new String(bytes, 0, 1, UTF_CS).getBytes(UTF_CS).length); } - - @Test - public void testCutString() { - String s = Helper.cutStringForKV("Бухарестская улица (http://ru.wikipedia.org/wiki/" + - "%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))"); - assertEquals(250, s.getBytes(UTF_CS).length); - } } From b2c1f5c72f053f4d4fb286f4bebd947c907b9551 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 21 Jul 2022 14:38:46 +0200 Subject: [PATCH 110/389] EdgeKVStorage: no need for cacheSize parameter anymore --- .../java/com/graphhopper/search/EdgeKVStorage.java | 6 +----- .../main/java/com/graphhopper/storage/BaseGraph.java | 2 +- .../java/com/graphhopper/search/EdgeKVStorageTest.java | 10 +++++----- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java index b4db8c8fc1e..3e3e633ade6 100644 --- a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java +++ b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java @@ -82,14 +82,10 @@ public class EdgeKVStorage { private long lastEntryPointer = -1; private List lastEntries; - public EdgeKVStorage(Directory dir) { - this(dir, 1000); - } - /** * Specify a larger cacheSize to reduce disk usage. Note that this increases the memory usage of this object. */ - public EdgeKVStorage(Directory dir, final int cacheSize) { + public EdgeKVStorage(Directory dir) { keys = dir.create("edgekv_keys", 10 * 1024); vals = dir.create("edgekv_vals"); } diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index 67124c80b27..ffeaa135ab3 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -62,7 +62,7 @@ public BaseGraph(Directory dir, int intsForFlags, boolean withElevation, boolean this.dir = dir; this.bitUtil = BitUtil.LITTLE; this.wayGeometry = dir.create("geometry", segmentSize); - this.edgeKVStorage = new EdgeKVStorage(dir, 1000); + this.edgeKVStorage = new EdgeKVStorage(dir); this.store = new BaseGraphNodesAndEdges(dir, intsForFlags, withElevation, withTurnCosts, segmentSize); this.nodeAccess = new GHNodeAccess(store); this.segmentSize = segmentSize; diff --git a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java index f9371cdc811..68eabe43100 100644 --- a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java +++ b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java @@ -21,7 +21,7 @@ public class EdgeKVStorageTest { private final static String location = "./target/edge-kv-storage"; private EdgeKVStorage create() { - return new EdgeKVStorage(new RAMDirectory(), 1000).create(1000); + return new EdgeKVStorage(new RAMDirectory()).create(1000); } List createList(Object... keyValues) { @@ -217,12 +217,12 @@ public void testIntLongDoubleFloat2() { public void testFlush() { Helper.removeDir(new File(location)); - EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create(), 1000); + EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create()); long pointer = index.add(createList("", "test")); index.flush(); index.close(); - index = new EdgeKVStorage(new RAMDirectory(location, true), 1000); + index = new EdgeKVStorage(new RAMDirectory(location, true)); assertTrue(index.loadExisting()); assertEquals("test", index.get(pointer, "", false)); // make sure bytePointer is correctly set after loadExisting @@ -237,7 +237,7 @@ public void testFlush() { public void testLoadKeys() { Helper.removeDir(new File(location)); - EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create(), 1000).create(1000); + EdgeKVStorage index = new EdgeKVStorage(new RAMDirectory(location, true).create()).create(1000); long pointerA = index.add(createList("c", "test value")); assertEquals(2, index.getKeys().size()); long pointerB = index.add(createList("a", "value", "b", "another value")); @@ -246,7 +246,7 @@ public void testLoadKeys() { index.flush(); index.close(); - index = new EdgeKVStorage(new RAMDirectory(location, true), 1000); + index = new EdgeKVStorage(new RAMDirectory(location, true)); assertTrue(index.loadExisting()); assertEquals("[, c, a, b]", index.getKeys().toString()); assertEquals("test value", index.get(pointerA, "c", false)); From cf955a5d8d5257ea693fb451efd4ba948ca17c06 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 22 Jul 2022 13:12:23 +0200 Subject: [PATCH 111/389] Examples: remove incorrect comment --- client-hc/src/test/java/com/graphhopper/api/Examples.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-hc/src/test/java/com/graphhopper/api/Examples.java b/client-hc/src/test/java/com/graphhopper/api/Examples.java index ae4a9f706c0..ca959fcfdfa 100644 --- a/client-hc/src/test/java/com/graphhopper/api/Examples.java +++ b/client-hc/src/test/java/com/graphhopper/api/Examples.java @@ -38,7 +38,7 @@ public void routing() { addPoint(new GHPoint(49.6550, 11.4180)); // Set profile like car, bike, foot, ... req.setProfile("bike"); - // Optionally enable/disable elevation in output PointList, currently bike and foot support elevation, default is false + // Optionally enable/disable elevation in output PointList, default is false req.putHint("elevation", false); // Optionally enable/disable turn instruction information, defaults is true req.putHint("instructions", true); From a2ca5e39c54604d256ec97390be6e64617783e7c Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 24 Jul 2022 14:28:24 +0200 Subject: [PATCH 112/389] fix PathDetails e.g. -1 as default for DecimalDetails doesn't work as a value of the EV could be negative too --- .../util/details/AbstractPathDetailsBuilder.java | 2 +- .../graphhopper/util/details/AverageSpeedDetails.java | 10 ++++------ .../com/graphhopper/util/details/DecimalDetails.java | 4 ++-- .../com/graphhopper/util/details/EdgeIdDetails.java | 3 ++- .../com/graphhopper/util/details/EdgeKeyDetails.java | 3 +-- .../java/com/graphhopper/util/details/EnumDetails.java | 2 +- .../java/com/graphhopper/util/details/IntDetails.java | 4 ++-- .../com/graphhopper/util/details/KVStringDetails.java | 5 ++--- .../com/graphhopper/util/details/StringDetails.java | 4 ++-- .../java/com/graphhopper/util/details/TimeDetails.java | 3 ++- .../com/graphhopper/util/details/WeightDetails.java | 2 +- 11 files changed, 20 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/com/graphhopper/util/details/AbstractPathDetailsBuilder.java b/core/src/main/java/com/graphhopper/util/details/AbstractPathDetailsBuilder.java index 1912eadf88d..ad8f97ee70a 100644 --- a/core/src/main/java/com/graphhopper/util/details/AbstractPathDetailsBuilder.java +++ b/core/src/main/java/com/graphhopper/util/details/AbstractPathDetailsBuilder.java @@ -33,7 +33,7 @@ public abstract class AbstractPathDetailsBuilder implements PathDetailsBuilder { private final String name; private boolean isOpen = false; private PathDetail currentDetail; - private List pathDetails = new ArrayList<>(); + private final List pathDetails = new ArrayList<>(); public AbstractPathDetailsBuilder(String name) { this.name = name; diff --git a/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java b/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java index 25e92bbeef6..7f76fc0d707 100644 --- a/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java @@ -1,6 +1,7 @@ package com.graphhopper.util.details; import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.util.EdgeIterator; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; @@ -12,7 +13,7 @@ public class AverageSpeedDetails extends AbstractPathDetailsBuilder { private final double precision; private Double decimalValue; // will include the turn time penalty - private int prevEdgeId = -1; + private int prevEdgeId = EdgeIterator.NO_EDGE; public AverageSpeedDetails(Weighting weighting) { this(weighting, 0.1); @@ -39,11 +40,8 @@ public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { // even lead to speed=Infinity -> just ignore these cases here, see #1848 and #2620 final double distance = edge.getDistance(); if (distance < 0.01) { - if (decimalValue != null) - return false; - - // in case this is the first edge we have to return some value - decimalValue = null; + if (decimalValue != null) return false; + // in case this is the first edge we return decimalValue=null return true; } diff --git a/core/src/main/java/com/graphhopper/util/details/DecimalDetails.java b/core/src/main/java/com/graphhopper/util/details/DecimalDetails.java index 76ce84e8724..155bf7f7ffd 100644 --- a/core/src/main/java/com/graphhopper/util/details/DecimalDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/DecimalDetails.java @@ -23,7 +23,7 @@ public class DecimalDetails extends AbstractPathDetailsBuilder { private final DecimalEncodedValue ev; - private double decimalValue = -1; + private Double decimalValue; private final String infinityJsonValue; private final double precision; @@ -55,7 +55,7 @@ protected Object getCurrentValue() { @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { double tmpVal = edge.get(ev); - if (Math.abs(tmpVal - decimalValue) >= precision) { + if (decimalValue == null || Math.abs(tmpVal - decimalValue) >= precision) { this.decimalValue = Double.isInfinite(tmpVal) ? tmpVal : Math.round(tmpVal / precision) * precision; return true; } diff --git a/core/src/main/java/com/graphhopper/util/details/EdgeIdDetails.java b/core/src/main/java/com/graphhopper/util/details/EdgeIdDetails.java index 1fff5a16302..220535ba848 100644 --- a/core/src/main/java/com/graphhopper/util/details/EdgeIdDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/EdgeIdDetails.java @@ -18,6 +18,7 @@ package com.graphhopper.util.details; import com.graphhopper.routing.querygraph.VirtualEdgeIteratorState; +import com.graphhopper.util.EdgeIterator; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; @@ -30,7 +31,7 @@ */ public class EdgeIdDetails extends AbstractPathDetailsBuilder { - private int edgeId = -1; + private int edgeId = EdgeIterator.NO_EDGE; public EdgeIdDetails() { super(EDGE_ID); diff --git a/core/src/main/java/com/graphhopper/util/details/EdgeKeyDetails.java b/core/src/main/java/com/graphhopper/util/details/EdgeKeyDetails.java index dd5bf3cfc5b..0c08f4ea854 100644 --- a/core/src/main/java/com/graphhopper/util/details/EdgeKeyDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/EdgeKeyDetails.java @@ -24,11 +24,10 @@ public class EdgeKeyDetails extends AbstractPathDetailsBuilder { - private int edgeKey; + private int edgeKey = -1; public EdgeKeyDetails() { super(EDGE_KEY); - edgeKey = -1; } @Override diff --git a/core/src/main/java/com/graphhopper/util/details/EnumDetails.java b/core/src/main/java/com/graphhopper/util/details/EnumDetails.java index 985efb2e9d4..5b9bc6f6572 100644 --- a/core/src/main/java/com/graphhopper/util/details/EnumDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/EnumDetails.java @@ -23,7 +23,7 @@ public class EnumDetails extends AbstractPathDetailsBuilder { private final EnumEncodedValue ev; - private Enum objVal = null; + private E objVal; public EnumDetails(String name, EnumEncodedValue ev) { super(name); diff --git a/core/src/main/java/com/graphhopper/util/details/IntDetails.java b/core/src/main/java/com/graphhopper/util/details/IntDetails.java index 97665831f3a..dfa29fdb674 100644 --- a/core/src/main/java/com/graphhopper/util/details/IntDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/IntDetails.java @@ -23,7 +23,7 @@ public class IntDetails extends AbstractPathDetailsBuilder { private final IntEncodedValue ev; - private int intVal = -1; + private Integer intVal; public IntDetails(String name, IntEncodedValue ev) { super(name); @@ -38,7 +38,7 @@ protected Object getCurrentValue() { @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { int val = edge.get(ev); - if (val != intVal) { + if (intVal == null || val != intVal) { this.intVal = val; return true; } diff --git a/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java b/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java index 5eb0e48f8db..93dc42bc1eb 100644 --- a/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java @@ -26,8 +26,8 @@ */ public class KVStringDetails extends AbstractPathDetailsBuilder { - private String curString = null; - private String key; + private final String key; + private String curString; public KVStringDetails(String name, String key) { super(name); @@ -37,7 +37,6 @@ public KVStringDetails(String name, String key) { @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { if (curString == null) { - // TODO it might be more efficient if we fetch the Map only once per edge when more than one KVStringDetails are requested curString = (String) edge.getValue(key); return true; } diff --git a/core/src/main/java/com/graphhopper/util/details/StringDetails.java b/core/src/main/java/com/graphhopper/util/details/StringDetails.java index bdeabceacb9..025f40bb4d9 100644 --- a/core/src/main/java/com/graphhopper/util/details/StringDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/StringDetails.java @@ -23,7 +23,7 @@ public class StringDetails extends AbstractPathDetailsBuilder { private final StringEncodedValue ev; - private String currentVal = null; + private String currentVal; public StringDetails(String name, StringEncodedValue ev) { super(name); @@ -39,7 +39,7 @@ protected Object getCurrentValue() { public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { String val = edge.get(ev); // we can use the reference equality here - if (val != currentVal) { + if (!val.equals(currentVal)) { this.currentVal = val; return true; } diff --git a/core/src/main/java/com/graphhopper/util/details/TimeDetails.java b/core/src/main/java/com/graphhopper/util/details/TimeDetails.java index 3dd6e861f1b..59099e4dcc3 100644 --- a/core/src/main/java/com/graphhopper/util/details/TimeDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/TimeDetails.java @@ -18,6 +18,7 @@ package com.graphhopper.util.details; import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.util.EdgeIterator; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.GHUtility; @@ -31,7 +32,7 @@ public class TimeDetails extends AbstractPathDetailsBuilder { private final Weighting weighting; - private int prevEdgeId = -1; + private int prevEdgeId = EdgeIterator.NO_EDGE; // will include the turn time penalty private long time = 0; diff --git a/core/src/main/java/com/graphhopper/util/details/WeightDetails.java b/core/src/main/java/com/graphhopper/util/details/WeightDetails.java index 437afada5ca..1a4980ff950 100644 --- a/core/src/main/java/com/graphhopper/util/details/WeightDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/WeightDetails.java @@ -33,7 +33,7 @@ public class WeightDetails extends AbstractPathDetailsBuilder { private final Weighting weighting; private int edgeId = EdgeIterator.NO_EDGE; - private double weight = Double.NaN; + private Double weight; public WeightDetails(Weighting weighting) { super(WEIGHT); From 0a0264a5fd13c02d93fabc564db18b7666732c13 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 24 Jul 2022 16:01:30 +0200 Subject: [PATCH 113/389] renamed DouglasPeucker to RamerDouglasPeucker --- CHANGELOG.md | 3 +- .../com/graphhopper/reader/osm/OSMReader.java | 2 +- .../graphhopper/routing/OSMReaderConfig.java | 2 +- .../java/com/graphhopper/routing/Router.java | 4 +-- .../com/graphhopper/routing/RouterConfig.java | 2 +- .../java/com/graphhopper/util/PathMerger.java | 10 +++--- .../graphhopper/util/PathSimplification.java | 32 +++++++++---------- ...sPeucker.java => RamerDouglasPeucker.java} | 10 +++--- .../util/PathSimplificationTest.java | 20 ++++++------ ...Test.java => RamerDouglasPeuckerTest.java} | 26 +++++++-------- .../resources/MapMatchingResource.java | 4 +-- 11 files changed, 58 insertions(+), 57 deletions(-) rename core/src/main/java/com/graphhopper/util/{DouglasPeucker.java => RamerDouglasPeucker.java} (95%) rename core/src/test/java/com/graphhopper/util/{DouglasPeuckerTest.java => RamerDouglasPeuckerTest.java} (90%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fe72999978..21521056737 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### 6.0 [not yet released] +- renamed DouglasPeucker to RamerDouglasPeucker - path details at via-points are no longer merged, see #2626 - removed the FlagEncoder interface. for example encoder.getAccessEnc() is now encodingManager.getBooleanEncodedValue( VehicleAccess.key("car")), #2611 @@ -114,7 +115,7 @@ - removed android demo, #1940 - added edge key path detail, #2073 - fixed bug for turn restrictions on bridges/tunnels, #2070 -- improved resolution of elevation profiles, 3D Douglas-Peucker and long edge sampling, #1953 +- improved resolution of elevation profiles, 3D Ramer-Douglas-Peucker and long edge sampling, #1953 ### 1.0 [22 May 2020] diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 95f582fa1db..5fe0f48029d 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -80,7 +80,7 @@ public class OSMReader { private AreaIndex areaIndex; private CountryRuleFactory countryRuleFactory = null; private File osmFile; - private final DouglasPeucker simplifyAlgo = new DouglasPeucker(); + private final RamerDouglasPeucker simplifyAlgo = new RamerDouglasPeucker(); private final IntsRef tempRelFlags; private Date osmDataDate; diff --git a/core/src/main/java/com/graphhopper/routing/OSMReaderConfig.java b/core/src/main/java/com/graphhopper/routing/OSMReaderConfig.java index 26d7a795e05..d5baea728f6 100644 --- a/core/src/main/java/com/graphhopper/routing/OSMReaderConfig.java +++ b/core/src/main/java/com/graphhopper/routing/OSMReaderConfig.java @@ -58,7 +58,7 @@ public double getMaxWayPointDistance() { } /** - * This parameter affects the routine used to simplify the edge geometries (Douglas-Peucker). Higher values mean + * This parameter affects the routine used to simplify the edge geometries (Ramer-Douglas-Peucker). Higher values mean * more details are preserved. The default is 1 (meter). Simplification can be disabled by setting it to 0. */ public OSMReaderConfig setMaxWayPointDistance(double maxWayPointDistance) { diff --git a/core/src/main/java/com/graphhopper/routing/Router.java b/core/src/main/java/com/graphhopper/routing/Router.java index 542b2e91dc7..5332826c65e 100644 --- a/core/src/main/java/com/graphhopper/routing/Router.java +++ b/core/src/main/java/com/graphhopper/routing/Router.java @@ -282,12 +282,12 @@ private PathMerger createPathMerger(GHRequest request, Weighting weighting, Grap double wayPointMaxDistance = request.getHints().getDouble(Parameters.Routing.WAY_POINT_MAX_DISTANCE, 1d); double elevationWayPointMaxDistance = request.getHints().getDouble(ELEVATION_WAY_POINT_MAX_DISTANCE, routerConfig.getElevationWayPointMaxDistance()); - DouglasPeucker peucker = new DouglasPeucker(). + RamerDouglasPeucker peucker = new RamerDouglasPeucker(). setMaxDistance(wayPointMaxDistance). setElevationMaxDistance(elevationWayPointMaxDistance); PathMerger pathMerger = new PathMerger(graph, weighting). setCalcPoints(calcPoints). - setDouglasPeucker(peucker). + setRamerDouglasPeucker(peucker). setEnableInstructions(enableInstructions). setPathDetailsBuilders(pathDetailsBuilderFactory, request.getPathDetails()). setSimplifyResponse(routerConfig.isSimplifyResponse() && wayPointMaxDistance > 0); diff --git a/core/src/main/java/com/graphhopper/routing/RouterConfig.java b/core/src/main/java/com/graphhopper/routing/RouterConfig.java index 0345b00ad23..398b0d05f9b 100644 --- a/core/src/main/java/com/graphhopper/routing/RouterConfig.java +++ b/core/src/main/java/com/graphhopper/routing/RouterConfig.java @@ -83,7 +83,7 @@ public boolean isSimplifyResponse() { } /** - * This method specifies if the returned path should be simplified or not, via douglas-peucker + * This method specifies if the returned path should be simplified or not, via Ramer-Douglas-Peucker * or similar algorithm. */ public void setSimplifyResponse(boolean simplifyResponse) { diff --git a/core/src/main/java/com/graphhopper/util/PathMerger.java b/core/src/main/java/com/graphhopper/util/PathMerger.java index c603943978e..662a759bd9f 100644 --- a/core/src/main/java/com/graphhopper/util/PathMerger.java +++ b/core/src/main/java/com/graphhopper/util/PathMerger.java @@ -45,13 +45,13 @@ * @author Robin Boldt */ public class PathMerger { - private static final DouglasPeucker DP = new DouglasPeucker(); + private static final RamerDouglasPeucker RDP = new RamerDouglasPeucker(); private final Graph graph; private final Weighting weighting; private boolean enableInstructions = true; private boolean simplifyResponse = true; - private DouglasPeucker douglasPeucker = DP; + private RamerDouglasPeucker ramerDouglasPeucker = RDP; private boolean calcPoints = true; private PathDetailsBuilderFactory pathBuilderFactory; private List requestedPathDetails = Collections.emptyList(); @@ -67,8 +67,8 @@ public PathMerger setCalcPoints(boolean calcPoints) { return this; } - public PathMerger setDouglasPeucker(DouglasPeucker douglasPeucker) { - this.douglasPeucker = douglasPeucker; + public PathMerger setRamerDouglasPeucker(RamerDouglasPeucker ramerDouglasPeucker) { + this.ramerDouglasPeucker = ramerDouglasPeucker; return this; } @@ -165,7 +165,7 @@ public ResponsePath doWork(PointList waypoints, List paths, EncodedValueLo setWaypoints(waypoints); if (allFound && simplifyResponse && (calcPoints || enableInstructions)) { - PathSimplification.simplify(responsePath, douglasPeucker, enableInstructions); + PathSimplification.simplify(responsePath, ramerDouglasPeucker, enableInstructions); } return responsePath; } diff --git a/core/src/main/java/com/graphhopper/util/PathSimplification.java b/core/src/main/java/com/graphhopper/util/PathSimplification.java index 393e4e91c28..63c5f5fa43d 100644 --- a/core/src/main/java/com/graphhopper/util/PathSimplification.java +++ b/core/src/main/java/com/graphhopper/util/PathSimplification.java @@ -25,7 +25,7 @@ import java.util.Map; /** - * This class simplifies the path, using {@link DouglasPeucker}, but also considers a given list of partitions of + * This class simplifies the path, using {@link RamerDouglasPeucker}, but also considers a given list of partitions of * the path. Each partition separates the points of the path into non-overlapping intervals and the simplification is * done such that we never simplify across the boundaries of these intervals. This is important, because the points * at the interval boundaries must not be removed, e.g. when they are referenced by instructions. @@ -49,7 +49,7 @@ public class PathSimplification { * @see PathSimplification */ private final List partitions; - private final DouglasPeucker douglasPeucker; + private final RamerDouglasPeucker ramerDouglasPeucker; // temporary variables used when traversing the different partitions private final int numPartitions; @@ -57,14 +57,14 @@ public class PathSimplification { private final int[] currIntervalStart; private final int[] currIntervalEnd; private final boolean[] partitionFinished; - // keep track of how many points were removed by Douglas-Peucker in the current and previous intervals + // keep track of how many points were removed by Ramer-Douglas-Peucker in the current and previous intervals private final int[] removedPointsInCurrInterval; private final int[] removedPointsInPrevIntervals; /** * Convenience method used to obtain the partitions from a calculated path with details and instructions */ - public static PointList simplify(ResponsePath responsePath, DouglasPeucker douglasPeucker, boolean enableInstructions) { + public static PointList simplify(ResponsePath responsePath, RamerDouglasPeucker ramerDouglasPeucker, boolean enableInstructions) { final PointList pointList = responsePath.getPoints(); List partitions = new ArrayList<>(); // todo: maybe this code can be simplified if path details and instructions would be merged, see #1121 @@ -123,21 +123,21 @@ public void setInterval(int index, int start, int end) { }); } - simplify(responsePath.getPoints(), partitions, douglasPeucker); + simplify(responsePath.getPoints(), partitions, ramerDouglasPeucker); assertConsistencyOfPathDetails(responsePath.getPathDetails()); if (enableInstructions) assertConsistencyOfInstructions(responsePath.getInstructions(), responsePath.getPoints().size()); return pointList; } - public static void simplify(PointList pointList, List partitions, DouglasPeucker douglasPeucker) { - new PathSimplification(pointList, partitions, douglasPeucker).simplify(); + public static void simplify(PointList pointList, List partitions, RamerDouglasPeucker ramerDouglasPeucker) { + new PathSimplification(pointList, partitions, ramerDouglasPeucker).simplify(); } - private PathSimplification(PointList pointList, List partitions, DouglasPeucker douglasPeucker) { + private PathSimplification(PointList pointList, List partitions, RamerDouglasPeucker ramerDouglasPeucker) { this.pointList = pointList; this.partitions = partitions; - this.douglasPeucker = douglasPeucker; + this.ramerDouglasPeucker = ramerDouglasPeucker; numPartitions = this.partitions.size(); currIntervalIndex = new int[numPartitions]; currIntervalStart = new int[numPartitions]; @@ -155,19 +155,19 @@ private void simplify() { // no partitions -> no constraints, just simplify the entire point list if (partitions.isEmpty()) { - douglasPeucker.simplify(pointList, 0, pointList.size() - 1); + ramerDouglasPeucker.simplify(pointList, 0, pointList.size() - 1); pointList.makeImmutable(); return; } - // Douglas-Peucker never removes the first/last point of a given interval, so as long as we only run it + // Ramer-Douglas-Peucker never removes the first/last point of a given interval, so as long as we only run it // on each interval we can be sure that the interval boundaries will remain in the point list. // Whenever we remove points from an interval we have to update the interval indices of all partitions. // For example if an interval goes from point 4 to 9 and we remove points 5 and 7 we have to update the interval // to [4,7]. // The basic idea to do this is as follows: We iterate through the point list and whenever we hit an interval - // end (q) in one of the partitions we run Douglas-Peucker for the interval [p,q], where p is the point where the - // last interval ended. We keep track of the number of removed points in the current and previous intervals + // end (q) in one of the partitions we run Ramer-Douglas-Peucker for the interval [p,q], where p is the point where + // the last interval ended. We keep track of the number of removed points in the current and previous intervals // to be able to calculate the updated indices. // prepare for the first interval in each partition @@ -179,7 +179,7 @@ private void simplify() { // iterate the point list and simplify and update the intervals on the go for (int p = 0; p < pointList.size(); p++) { int removed = 0; - // first we check if we hit the end of an interval for one of the partitions and run Douglas-Peucker if we do + // first we check if we hit the end of an interval for one of the partitions and run Ramer-Douglas-Peucker if we do for (int s = 0; s < numPartitions; s++) { if (partitionFinished[s]) { continue; @@ -190,7 +190,7 @@ private void simplify() { // see #1764. Note that since the point list does not get compressed here yet we have to keep track // of the total number of removed points to calculate the new interval boundaries later final boolean compress = false; - removed = douglasPeucker.simplify(pointList, intervalStart, currIntervalEnd[s], compress); + removed = ramerDouglasPeucker.simplify(pointList, intervalStart, currIntervalEnd[s], compress); intervalStart = p; break; } @@ -218,7 +218,7 @@ private void simplify() { // now we finally have to compress the pointList (actually remove the deleted points). note only after this // call the (now shifted) indices in path details and instructions are correct - DouglasPeucker.removeNaN(pointList); + RamerDouglasPeucker.removeNaN(pointList); // Make sure that the instruction references are not broken pointList.makeImmutable(); diff --git a/core/src/main/java/com/graphhopper/util/DouglasPeucker.java b/core/src/main/java/com/graphhopper/util/RamerDouglasPeucker.java similarity index 95% rename from core/src/main/java/com/graphhopper/util/DouglasPeucker.java rename to core/src/main/java/com/graphhopper/util/RamerDouglasPeucker.java index f811f144dff..779848e6f51 100644 --- a/core/src/main/java/com/graphhopper/util/DouglasPeucker.java +++ b/core/src/main/java/com/graphhopper/util/RamerDouglasPeucker.java @@ -26,14 +26,14 @@ * * @author Peter Karich */ -public class DouglasPeucker { +public class RamerDouglasPeucker { private double normedMaxDist; private double elevationMaxDistance; private double maxDistance; private DistanceCalc calc; private boolean approx; - public DouglasPeucker() { + public RamerDouglasPeucker() { setApproximation(true); // 1m setMaxDistance(1); @@ -52,7 +52,7 @@ public void setApproximation(boolean a) { /** * maximum distance of discrepancy (from the normal way) in meter */ - public DouglasPeucker setMaxDistance(double dist) { + public RamerDouglasPeucker setMaxDistance(double dist) { this.normedMaxDist = calc.calcNormalizedDist(dist); this.maxDistance = dist; return this; @@ -61,7 +61,7 @@ public DouglasPeucker setMaxDistance(double dist) { /** * maximum elevation distance of discrepancy (from the normal way) in meters */ - public DouglasPeucker setElevationMaxDistance(double dist) { + public RamerDouglasPeucker setElevationMaxDistance(double dist) { this.elevationMaxDistance = dist; return this; } @@ -69,7 +69,7 @@ public DouglasPeucker setElevationMaxDistance(double dist) { /** * Simplifies the points, from index 0 to size-1. *

- * It is a wrapper method for {@link DouglasPeucker#simplify(PointList, int, int)}. + * It is a wrapper method for {@link RamerDouglasPeucker#simplify(PointList, int, int)}. * * @return The number removed points */ diff --git a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java index 3912e094aeb..20ef9dcaec8 100644 --- a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java +++ b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java @@ -120,11 +120,11 @@ public void testScenario() { int numberOfPoints = p.calcPoints().size(); - DouglasPeucker douglasPeucker = new DouglasPeucker(); + RamerDouglasPeucker ramerDouglasPeucker = new RamerDouglasPeucker(); // Do not simplify anything - douglasPeucker.setMaxDistance(0); + ramerDouglasPeucker.setMaxDistance(0); - PathSimplification.simplify(responsePath, douglasPeucker, true); + PathSimplification.simplify(responsePath, ramerDouglasPeucker, true); assertEquals(numberOfPoints, responsePath.getPoints().size()); @@ -133,8 +133,8 @@ public void testScenario() { responsePath.addPathDetails(details); responsePath.setPoints(p.calcPoints()); - douglasPeucker.setMaxDistance(100000000); - PathSimplification.simplify(responsePath, douglasPeucker, true); + ramerDouglasPeucker.setMaxDistance(100000000); + PathSimplification.simplify(responsePath, ramerDouglasPeucker, true); assertTrue(numberOfPoints > responsePath.getPoints().size()); } @@ -142,7 +142,7 @@ public void testScenario() { @Test public void testSinglePartition() { // points are chosen such that DP will remove those marked with an x - // todo: we could go further and replace DouglasPeucker with some abstract thing that makes this easier to test + // todo: we could go further and replace Ramer-Douglas-Peucker with some abstract thing that makes this easier to test PointList points = new PointList(); points.add(48.89107, 9.33161); // 0 -> 0 points.add(48.89104, 9.33102); // 1 x @@ -163,14 +163,14 @@ public void testSinglePartition() { .add(7, 7); // end List partitions = new ArrayList<>(); partitions.add(partition); - PathSimplification.simplify(points, partitions, new DouglasPeucker()); + PathSimplification.simplify(points, partitions, new RamerDouglasPeucker()); // check points were modified correctly assertEquals(5, points.size()); origPoints.set(1, Double.NaN, Double.NaN, Double.NaN); origPoints.set(2, Double.NaN, Double.NaN, Double.NaN); origPoints.set(5, Double.NaN, Double.NaN, Double.NaN); - DouglasPeucker.removeNaN(origPoints); + RamerDouglasPeucker.removeNaN(origPoints); assertEquals(origPoints, points); // check partition was modified correctly @@ -237,7 +237,7 @@ public void testMultiplePartitions() { partitions.add(partition1); partitions.add(partition2); partitions.add(partition3); - PathSimplification.simplify(points, partitions, new DouglasPeucker()); + PathSimplification.simplify(points, partitions, new RamerDouglasPeucker()); // check points were modified correctly assertEquals(12, points.size()); @@ -245,7 +245,7 @@ public void testMultiplePartitions() { origPoints.set(2, Double.NaN, Double.NaN, Double.NaN); origPoints.set(5, Double.NaN, Double.NaN, Double.NaN); origPoints.set(13, Double.NaN, Double.NaN, Double.NaN); - DouglasPeucker.removeNaN(origPoints); + RamerDouglasPeucker.removeNaN(origPoints); assertEquals(origPoints, points); // check partitions were modified correctly diff --git a/core/src/test/java/com/graphhopper/util/DouglasPeuckerTest.java b/core/src/test/java/com/graphhopper/util/RamerDouglasPeuckerTest.java similarity index 90% rename from core/src/test/java/com/graphhopper/util/DouglasPeuckerTest.java rename to core/src/test/java/com/graphhopper/util/RamerDouglasPeuckerTest.java index 31dd87ca7fa..57e6fa7c31a 100644 --- a/core/src/test/java/com/graphhopper/util/DouglasPeuckerTest.java +++ b/core/src/test/java/com/graphhopper/util/RamerDouglasPeuckerTest.java @@ -29,7 +29,7 @@ /** * @author Peter Karich */ -public class DouglasPeuckerTest { +public class RamerDouglasPeuckerTest { // get some real life points from graphhopper API // http://217.92.216.224:8080/?point=49.945642,11.571436&point=49.946001,11.580706 @@ -57,7 +57,7 @@ public void testPathSimplify() { PointList pointList = new PointList(); pointList.parse2DJSON(points1); assertEquals(32, pointList.size()); - new DouglasPeucker().setMaxDistance(.5).simplify(pointList); + new RamerDouglasPeucker().setMaxDistance(.5).simplify(pointList); // Arrays.asList(2, 4, 6, 7, 8, 9, 12, 14, 15, 17, 18, 19, 20, 22, 24, 27, 28, 29, 31, 33), assertEquals(20, pointList.size()); } @@ -66,7 +66,7 @@ public void testPathSimplify() { public void testSimplifyCheckPointCount() { PointList pointList = new PointList(); pointList.parse2DJSON(points1); - DouglasPeucker dp = new DouglasPeucker().setMaxDistance(.5); + RamerDouglasPeucker dp = new RamerDouglasPeucker().setMaxDistance(.5); assertEquals(32, pointList.size()); dp.simplify(pointList); assertEquals(20, pointList.size()); @@ -93,7 +93,7 @@ public void testSimplifyCheckPointOrder() { PointList pointList = new PointList(); pointList.parse2DJSON(points2); assertEquals(13, pointList.size()); - new DouglasPeucker().setMaxDistance(.5).simplify(pointList); + new RamerDouglasPeucker().setMaxDistance(.5).simplify(pointList); assertEquals(11, pointList.size()); assertFalse(pointList.toString().contains("NaN"), pointList.toString()); assertEquals("(50.203764443183644,9.961074440801317), (50.20318963087774,9.960999562464645), (50.202952888673984,9.96094144793469), (50.20267889356641,9.96223002587773), (50.201853928011374,9.961859918278305), " @@ -123,10 +123,10 @@ public void testRemoveNaN() { pl.add(14, 14, 14); pl.add(Double.NaN, Double.NaN, Double.NaN); - DouglasPeucker.removeNaN(pl); + RamerDouglasPeucker.removeNaN(pl); // doing it again should be no problem - DouglasPeucker.removeNaN(pl); - DouglasPeucker.removeNaN(pl); + RamerDouglasPeucker.removeNaN(pl); + RamerDouglasPeucker.removeNaN(pl); assertEquals(8, pl.size()); List expected = Arrays.asList(1, 5, 6, 7, 8, 9, 10, 14); List given = new ArrayList<>(); @@ -146,7 +146,7 @@ public void test3dPathSimplify() { pointList.add(0.02, 0, 20); // can be removed pointList.add(0.03, 0, 30); // can't be removed pointList.add(0.04, 0, 50); - new DouglasPeucker().setMaxDistance(1).setElevationMaxDistance(1).simplify(pointList); + new RamerDouglasPeucker().setMaxDistance(1).setElevationMaxDistance(1).simplify(pointList); assertEquals("(0.0,0.0,0.0), (0.03,0.0,30.0), (0.04,0.0,50.0)", pointList.toString()); } @@ -156,7 +156,7 @@ public void test3dPathSimplifyElevationDisabled() { pointList.add(0, 0, 0); pointList.add(0.03, 0, 30); // would be kept, if we cared about elevation pointList.add(0.04, 0, 50); - new DouglasPeucker().setMaxDistance(1).setElevationMaxDistance(Double.MAX_VALUE).simplify(pointList); + new RamerDouglasPeucker().setMaxDistance(1).setElevationMaxDistance(Double.MAX_VALUE).simplify(pointList); assertEquals("(0.0,0.0,0.0), (0.04,0.0,50.0)", pointList.toString()); } @@ -168,7 +168,7 @@ public void test3dPathSimplifyElevationMaxDistFive() { pointList.add(0.02, 0, 20); // on straight line, remove pointList.add(0.03, 0, 30); // >5m from straight line, keep pointList.add(0.04, 0, 50); - new DouglasPeucker().setMaxDistance(1).setElevationMaxDistance(5).simplify(pointList); + new RamerDouglasPeucker().setMaxDistance(1).setElevationMaxDistance(5).simplify(pointList); assertEquals("(0.0,0.0,0.0), (0.03,0.0,30.0), (0.04,0.0,50.0)", pointList.toString()); } @@ -179,7 +179,7 @@ public void test3dPathSimplifyWithMissingElevation() { pointList.add(0, 0.5, Double.NaN); // on straight line in 2d space, ignore elevation pointList.add(0, 1, 14); // <5m from straight line (10), remove pointList.add(1, 1, 20); - new DouglasPeucker().setMaxDistance(1).setElevationMaxDistance(1).simplify(pointList); + new RamerDouglasPeucker().setMaxDistance(1).setElevationMaxDistance(1).simplify(pointList); assertEquals("(0.0,0.0,0.0), (0.0,1.0,14.0), (1.0,1.0,20.0)", pointList.toString()); } @@ -189,7 +189,7 @@ public void test3dSimplifyStartEndSame() { pointList.add(0, 0, 0); pointList.add(0.03, 0, 30); pointList.add(0, 0, 0); - new DouglasPeucker().setMaxDistance(1).setElevationMaxDistance(1).simplify(pointList); + new RamerDouglasPeucker().setMaxDistance(1).setElevationMaxDistance(1).simplify(pointList); assertEquals("(0.0,0.0,0.0), (0.03,0.0,30.0), (0.0,0.0,0.0)", pointList.toString()); } @@ -199,7 +199,7 @@ public void test2dSimplifyStartEndSame() { pointList.add(0, 0); pointList.add(0.03, 0); pointList.add(0, 0); - new DouglasPeucker().setMaxDistance(1).setElevationMaxDistance(1).simplify(pointList); + new RamerDouglasPeucker().setMaxDistance(1).setElevationMaxDistance(1).simplify(pointList); assertEquals("(0.0,0.0), (0.03,0.0), (0.0,0.0)", pointList.toString()); } } diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java index 53237ea486c..1dc05c60e9e 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java @@ -136,11 +136,11 @@ public Response match( build(); } else { Translation tr = trMap.getWithFallBack(Helper.getLocale(localeStr)); - DouglasPeucker peucker = new DouglasPeucker().setMaxDistance(minPathPrecision); + RamerDouglasPeucker simplifyAlgo = new RamerDouglasPeucker().setMaxDistance(minPathPrecision); PathMerger pathMerger = new PathMerger(matchResult.getGraph(), matchResult.getWeighting()). setEnableInstructions(instructions). setPathDetailsBuilders(graphHopper.getPathDetailsBuilderFactory(), pathDetails). - setDouglasPeucker(peucker). + setRamerDouglasPeucker(simplifyAlgo). setSimplifyResponse(minPathPrecision > 0); ResponsePath responsePath = pathMerger.doWork(PointList.EMPTY, Collections.singletonList(matchResult.getMergedPath()), graphHopper.getEncodingManager(), tr); From f01743c6d6081e758e8461dce343705ea2e25805 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 25 Jul 2022 11:01:56 +0200 Subject: [PATCH 114/389] client-hc: add examples to get translated ("raw") turn instructions --- client-hc/src/test/java/com/graphhopper/api/Examples.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client-hc/src/test/java/com/graphhopper/api/Examples.java b/client-hc/src/test/java/com/graphhopper/api/Examples.java index ca959fcfdfa..887742d070f 100644 --- a/client-hc/src/test/java/com/graphhopper/api/Examples.java +++ b/client-hc/src/test/java/com/graphhopper/api/Examples.java @@ -75,6 +75,10 @@ public void routing() { InstructionList il = res.getInstructions(); for (Instruction i : il) { // System.out.println(i.getName()); + + // to get the translated turn instructions you call: + // System.out.println(i.getTurnDescription(null)); + // Note, that you can control the language only in via the request setLocale method and cannot change it only the client side } // get path details List pathDetails = res.getPathDetails().get(Parameters.Details.STREET_NAME); From ec122409733a45be995dca88a11d294e48768b92 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 24 Jul 2022 16:24:58 +0200 Subject: [PATCH 115/389] HeightTile: minor correction, DecimalEncodedValueImpl: minor clarification --- core/src/main/java/com/graphhopper/reader/dem/HeightTile.java | 2 +- .../graphhopper/routing/ev/DecimalEncodedValueImplTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/reader/dem/HeightTile.java b/core/src/main/java/com/graphhopper/reader/dem/HeightTile.java index 114469d9378..93b29c682eb 100644 --- a/core/src/main/java/com/graphhopper/reader/dem/HeightTile.java +++ b/core/src/main/java/com/graphhopper/reader/dem/HeightTile.java @@ -81,7 +81,7 @@ void setHeights(DataAccess da) { private short getHeightSample(int x, int y) { // always keep in mind factor 2 because of short value - return heights.getShort(2 * (y * width + x)); + return heights.getShort(2L * ((long) y * width + x)); } private boolean isValidElevation(double elevation) { diff --git a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java index 8400cf2d7e2..869e1cc58c3 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java @@ -53,6 +53,9 @@ public void testNegative() { DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, -6, 0.1, false, false, false, true); testEnc.init(new EncodedValue.InitializerConfig()); IntsRef intsRef = new IntsRef(1); + // a bit ugly: the default is the minimum not 0 + assertEquals(-6, testEnc.getDecimal(false, intsRef), .1); + testEnc.setDecimal(false, intsRef, -5.5); assertEquals(-5.5, testEnc.getDecimal(false, intsRef), .1); assertEquals(-5.5, testEnc.getDecimal(true, intsRef), .1); From 637adb79a00e8761c48912511f758e6daa20baba Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 26 Jul 2022 11:29:49 +0200 Subject: [PATCH 116/389] EdgeKVStorage: allow 32 bits (#2632) * allow 32 bits instead of just 31 for EdgeKVStorage * remove incorrect exception * minor change to wayGeo limit check --- .../java/com/graphhopper/storage/BaseGraph.java | 16 ++++++++-------- .../graphhopper/search/EdgeKVStorageTest.java | 8 ++++++++ .../main/java/com/graphhopper/util/Helper.java | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index ffeaa135ab3..bfd643076ea 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -28,7 +28,6 @@ import java.io.Closeable; import java.util.List; -import java.util.Map; import static com.graphhopper.util.Helper.nf; @@ -44,6 +43,7 @@ * loadExisting, (4) usage, (5) flush, (6) close */ public class BaseGraph implements Graph, Closeable { + final static long MAX_UNSIGNED_INT = 0xFFFF_FFFFL; final BaseGraphNodesAndEdges store; final NodeAccess nodeAccess; final EdgeKVStorage edgeKVStorage; @@ -470,7 +470,7 @@ private void ensureGeometry(long bytePos, int byteLength) { private long nextGeoRef(int arrayLength) { long tmp = maxGeoRef; maxGeoRef += arrayLength + 1L; - if (maxGeoRef >= 0xFFFFffffL) + if (maxGeoRef > MAX_UNSIGNED_INT) throw new IllegalStateException("Geometry too large, does not fit in 32 bits " + maxGeoRef); return tmp; @@ -949,27 +949,27 @@ public int getReverseEdgeKey() { @Override public EdgeIteratorState setKeyValues(List entries) { long pointer = baseGraph.edgeKVStorage.add(entries); - if (pointer > Integer.MAX_VALUE) - throw new IllegalStateException("Too many key value pairs are stored, currently limited to " + Integer.MAX_VALUE + " was " + pointer); - store.setKeyValuesRef(edgePointer, (int) pointer); + if (pointer > MAX_UNSIGNED_INT) + throw new IllegalStateException("Too many key value pairs are stored, currently limited to " + MAX_UNSIGNED_INT + " was " + pointer); + store.setKeyValuesRef(edgePointer, Helper.toSignedInt(pointer)); return this; } @Override public List getKeyValues() { - int kvEntryRef = store.getKeyValuesRef(edgePointer); + long kvEntryRef = Helper.toUnsignedLong(store.getKeyValuesRef(edgePointer)); return baseGraph.edgeKVStorage.getAll(kvEntryRef); } @Override public Object getValue(String key) { - int kvEntryRef = store.getKeyValuesRef(edgePointer); + long kvEntryRef = Helper.toUnsignedLong(store.getKeyValuesRef(edgePointer)); return baseGraph.edgeKVStorage.get(kvEntryRef, key, reverse); } @Override public String getName() { - int kvEntryRef = store.getKeyValuesRef(edgePointer); + long kvEntryRef = Helper.toUnsignedLong(store.getKeyValuesRef(edgePointer)); String name = (String) baseGraph.edgeKVStorage.get(kvEntryRef, "name", reverse); // preserve backward compatibility (returns empty string if name tag missing) return name == null ? "" : name; diff --git a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java index 68eabe43100..ed526933368 100644 --- a/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java +++ b/core/src/test/java/com/graphhopper/search/EdgeKVStorageTest.java @@ -393,4 +393,12 @@ public void testCutString() { "%D0%91%D1%83%D1%85%D0%B0%D1%80%D0%B5%D1%81%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D1%83%D0%BB%D0%B8%D1%86%D0%B0_(%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3))"); assertEquals(250, s.getBytes(UTF_CS).length); } + + @Test + public void testMax() { + long pointer = Integer.MAX_VALUE; + int storedPointer = (int) (pointer + 100); + assertTrue(storedPointer < 0); + assertEquals(pointer + 100, Helper.toUnsignedLong(storedPointer)); + } } \ No newline at end of file diff --git a/web-api/src/main/java/com/graphhopper/util/Helper.java b/web-api/src/main/java/com/graphhopper/util/Helper.java index 7185a0a523b..e168e8a8607 100644 --- a/web-api/src/main/java/com/graphhopper/util/Helper.java +++ b/web-api/src/main/java/com/graphhopper/util/Helper.java @@ -357,7 +357,7 @@ public static DateFormat createFormatter(String str) { * and returns the positive converted long. */ public static long toUnsignedLong(int x) { - return ((long) x) & 0xFFFFffffL; + return ((long) x) & 0xFFFF_FFFFL; } /** From 587ee81a0233fd3d85c2464d1d0acc4a1198977d Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 28 Jul 2022 11:03:43 +0200 Subject: [PATCH 117/389] Maps: Hide gpx export button when custom model box is open, fix #2635 --- .../main/resources/com/graphhopper/maps/js/main-template.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js index e000a00c83d..2a029de39d2 100644 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js +++ b/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js @@ -95,6 +95,9 @@ $(document).ready(function (e) { }; $("#custom-model-button").click(function() { toggleCustomModelBox(true); + // we only show the gpx button when the custom model box is closed, because the gpx export does not work for custom model routes (#2635) + $("#gpxExportButton").toggle(); + $("#gpx_dialog").dialog('close'); }); function showCustomModelExample() { cmEditor.value = From 5da6f30afa986620c48cc60c3a5d29e19dc68a79 Mon Sep 17 00:00:00 2001 From: Alexey Abel Date: Mon, 1 Aug 2022 12:12:11 +0200 Subject: [PATCH 118/389] Add hint about custom_model_file vs. custom_model to exception error message (#2638) --- .../src/main/java/com/graphhopper/http/GraphHopperManaged.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java index 7a84312f877..fc72db0c6be 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java +++ b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java @@ -73,7 +73,8 @@ public static List resolveCustomModelFiles(String customModelFolder, Li newProfiles.add(new CustomProfile(profile).setCustomModel(customModel)); continue; } catch (Exception ex) { - throw new RuntimeException("Cannot load custom_model from " + cm + " for profile " + profile.getName(), ex); + throw new RuntimeException("Cannot load custom_model from " + cm + " for profile " + profile.getName() + + ". If you are trying to load from a file, use 'custom_model_file' instead.", ex); } } String customModelFileName = profile.getHints().getString("custom_model_file", ""); From ed6939dff0638c9266834ec10c562d65f2c493d9 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 2 Aug 2022 16:26:36 +0200 Subject: [PATCH 119/389] Add comma in routing logs --- core/src/main/java/com/graphhopper/routing/ViaRouting.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/routing/ViaRouting.java b/core/src/main/java/com/graphhopper/routing/ViaRouting.java index a718a0065ad..f9e66d6dde6 100644 --- a/core/src/main/java/com/graphhopper/routing/ViaRouting.java +++ b/core/src/main/java/com/graphhopper/routing/ViaRouting.java @@ -149,7 +149,7 @@ public static Result calcPaths(List points, QueryGraph queryGraph, List } result.visitedNodes += pathCalculator.getVisitedNodes(); - result.debug += "visited nodes sum: " + result.visitedNodes; + result.debug += ", visited nodes sum: " + result.visitedNodes; } return result; From e0b9735092bf8026719e5baf9d77948a359af311 Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 4 Aug 2022 18:03:02 +0200 Subject: [PATCH 120/389] Move code that creates EncodingManager from properties to EncodingManager --- .../java/com/graphhopper/GraphHopper.java | 38 +------------------ .../routing/util/EncodingManager.java | 34 +++++++++++++++++ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 3468b7ee46d..38dab49bd55 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -18,13 +18,10 @@ package com.graphhopper; import com.bedatadriven.jackson.datatype.jts.JtsModule; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; -import com.graphhopper.jackson.Jackson; import com.graphhopper.reader.dem.*; import com.graphhopper.reader.osm.OSMReader; import com.graphhopper.reader.osm.conditional.DateRangeParser; @@ -909,8 +906,8 @@ public boolean load() { // the -gh folder exists, but there is no properties file. it might be just empty, so let's act as if // the import did not run yet or is not complete for some reason return false; - loadEncodingManagerFromProperties(properties); - baseGraph = new BaseGraph.Builder(getEncodingManager()) + encodingManager = EncodingManager.fromProperties(properties); + baseGraph = new BaseGraph.Builder(encodingManager) .setDir(directory) .set3D(hasElevation()) .withTurnCosts(encodingManager.needsTurnCostsSupport()) @@ -936,37 +933,6 @@ public boolean load() { } } - private void loadEncodingManagerFromProperties(StorableProperties properties) { - if (properties.containsVersion()) - throw new IllegalStateException("The GraphHopper file format is not compatible with the data you are " + - "trying to load. You either need to use an older version of GraphHopper or run a new import"); - - String versionStr = properties.get("graph.em.version"); - if (versionStr.isEmpty() || !String.valueOf(Constants.VERSION_EM).equals(versionStr)) - throw new IllegalStateException("Incompatible encoding version. You need to use the same GraphHopper version you used to import the graph, or run a new import. " - + " Stored encoding version: " + (versionStr.isEmpty() ? "missing" : versionStr) + ", used encoding version: " + Constants.VERSION_EM); - String encodedValueStr = properties.get("graph.encoded_values"); - ArrayNode evList = deserializeEncodedValueList(encodedValueStr); - LinkedHashMap encodedValues = new LinkedHashMap<>(); - evList.forEach(serializedEV -> { - EncodedValue encodedValue = EncodedValueSerializer.deserializeEncodedValue(serializedEV.textValue()); - if (encodedValues.put(encodedValue.getName(), encodedValue) != null) - throw new IllegalStateException("Duplicate encoded value name: " + encodedValue.getName() + " in: graph.encoded_values=" + encodedValueStr); - }); - - EncodedValue.InitializerConfig edgeConfig = EncodedValueSerializer.deserializeInitializerConfig(properties.get("graph.em.edge_config")); - EncodedValue.InitializerConfig turnCostConfig = EncodedValueSerializer.deserializeInitializerConfig(properties.get("graph.em.turn_cost_config")); - encodingManager = new EncodingManager(encodedValues, edgeConfig, turnCostConfig); - } - - private ArrayNode deserializeEncodedValueList(String encodedValueStr) { - try { - return Jackson.newObjectMapper().readValue(encodedValueStr, ArrayNode.class); - } catch (JsonProcessingException e) { - throw new UncheckedIOException(e); - } - } - private String getProfilesString() { return profilesByName.values().stream().map(p -> p.getName() + "|" + p.getVersion()).collect(Collectors.joining(",")); } diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java index bb587c56f94..7666b82402f 100644 --- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java +++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java @@ -18,9 +18,12 @@ package com.graphhopper.routing.util; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.graphhopper.jackson.Jackson; import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; +import com.graphhopper.storage.StorableProperties; +import com.graphhopper.util.Constants; import com.graphhopper.util.PMap; import java.io.UncheckedIOException; @@ -63,6 +66,37 @@ private static EncodingManager.Builder createBuilder(List encodedValues = new LinkedHashMap<>(); + evList.forEach(serializedEV -> { + EncodedValue encodedValue = EncodedValueSerializer.deserializeEncodedValue(serializedEV.textValue()); + if (encodedValues.put(encodedValue.getName(), encodedValue) != null) + throw new IllegalStateException("Duplicate encoded value name: " + encodedValue.getName() + " in: graph.encoded_values=" + encodedValueStr); + }); + + EncodedValue.InitializerConfig edgeConfig = EncodedValueSerializer.deserializeInitializerConfig(properties.get("graph.em.edge_config")); + EncodedValue.InitializerConfig turnCostConfig = EncodedValueSerializer.deserializeInitializerConfig(properties.get("graph.em.turn_cost_config")); + return new EncodingManager(encodedValues, edgeConfig, turnCostConfig); + } + + private static ArrayNode deserializeEncodedValueList(String encodedValueStr) { + try { + return Jackson.newObjectMapper().readValue(encodedValueStr, ArrayNode.class); + } catch (JsonProcessingException e) { + throw new UncheckedIOException(e); + } + } + /** * Starts the build process of an EncodingManager */ From 513af5721763fd50a028646f695a7747cf0ad930 Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 4 Aug 2022 18:21:12 +0200 Subject: [PATCH 121/389] Return boolean result from BaseGraph#loadExisting --- .../main/java/com/graphhopper/storage/BaseGraph.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index bfd643076ea..0c1a7b92b5c 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -228,23 +228,24 @@ long getMaxGeoRef() { return maxGeoRef; } - public void loadExisting() { + public boolean loadExisting() { checkNotInitialized(); if (!store.loadExisting()) - throw new IllegalStateException("Cannot load edges or nodes. corrupt file or directory? " + dir); + return false; if (!wayGeometry.loadExisting()) - throw new IllegalStateException("Cannot load geometry. corrupt file or directory? " + dir); + return false; if (!edgeKVStorage.loadExisting()) - throw new IllegalStateException("Cannot load name index. corrupt file or directory? " + dir); + return false; if (supportsTurnCosts() && !turnCostStorage.loadExisting()) - throw new IllegalStateException("Cannot load turn cost storage. corrupt file or directory? " + dir); + return false; setInitialized(); loadWayGeometryHeader(); + return true; } /** From 332bbda718d20a70199e644f1ebbec50fba2598c Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 4 Aug 2022 18:26:44 +0200 Subject: [PATCH 122/389] Move code that puts EncodingManager into properties to EncodingManager --- core/src/main/java/com/graphhopper/GraphHopper.java | 5 +---- .../java/com/graphhopper/routing/util/EncodingManager.java | 7 +++++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 38dab49bd55..a716de36cf2 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -823,10 +823,7 @@ protected void createBaseGraphAndProperties() { } protected void writeEncodingManagerToProperties() { - properties.put("graph.em.version", Constants.VERSION_EM); - properties.put("graph.em.edge_config", encodingManager.toEdgeConfigAsString()); - properties.put("graph.em.turn_cost_config", encodingManager.toTurnCostConfigAsString()); - properties.put("graph.encoded_values", encodingManager.toEncodedValuesAsString()); + EncodingManager.putEncodingManagerIntoProperties(encodingManager, properties); } private List readCustomAreas() { diff --git a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java index 7666b82402f..26ab995bd6d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java +++ b/core/src/main/java/com/graphhopper/routing/util/EncodingManager.java @@ -66,6 +66,13 @@ private static EncodingManager.Builder createBuilder(List Date: Sun, 7 Aug 2022 09:40:27 +0200 Subject: [PATCH 123/389] add hgt provider --- .../java/com/graphhopper/GraphHopper.java | 4 +- .../dem/AbstractSRTMElevationProvider.java | 5 +- .../graphhopper/reader/dem/HGTProvider.java | 60 +++++++++++++++++++ .../reader/dem/HGTProviderTest.java | 36 +++++++++++ 4 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/reader/dem/HGTProvider.java create mode 100644 core/src/test/java/com/graphhopper/reader/dem/HGTProviderTest.java diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index a716de36cf2..026ccc4edb0 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -633,7 +633,9 @@ private static ElevationProvider createElevationProvider(GraphHopperConfig ghCon throw new IllegalArgumentException("use graph.elevation.cache_dir not cachedir in configuration"); ElevationProvider elevationProvider = ElevationProvider.NOOP; - if (eleProviderStr.equalsIgnoreCase("srtm")) { + if (eleProviderStr.equalsIgnoreCase("hgt")) { + elevationProvider = new HGTProvider(cacheDirStr); + } else if (eleProviderStr.equalsIgnoreCase("srtm")) { elevationProvider = new SRTMProvider(cacheDirStr); } else if (eleProviderStr.equalsIgnoreCase("cgiar")) { elevationProvider = new CGIARProvider(cacheDirStr); diff --git a/core/src/main/java/com/graphhopper/reader/dem/AbstractSRTMElevationProvider.java b/core/src/main/java/com/graphhopper/reader/dem/AbstractSRTMElevationProvider.java index 9e066730d35..105cf2a6ae1 100644 --- a/core/src/main/java/com/graphhopper/reader/dem/AbstractSRTMElevationProvider.java +++ b/core/src/main/java/com/graphhopper/reader/dem/AbstractSRTMElevationProvider.java @@ -21,11 +21,11 @@ import com.graphhopper.storage.DataAccess; import com.graphhopper.util.BitUtil; import com.graphhopper.util.Downloader; +import com.graphhopper.util.Helper; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; import java.net.SocketTimeoutException; /** @@ -97,7 +97,7 @@ public double getEle(double lat, double lon) { int minLon = down(lon); String fileName = getFileName(lat, lon); - if (fileName == null) + if (fileName == null || (Helper.isEmpty(baseUrl) && !new File(fileName).exists())) return 0; DataAccess heights = getDirectory().create("dem" + intKey); @@ -165,7 +165,6 @@ private void updateHeightsFromFile(double lat, double lon, DataAccess heights) t private byte[] getByteArrayFromFile(double lat, double lon) throws InterruptedException, IOException { String zippedURL = baseUrl + getDownloadURL(lat, lon); File file = new File(cacheDir, new File(zippedURL).getName()); - InputStream is; // get zip file if not already in cacheDir if (!file.exists()) for (int i = 0; i < 3; i++) { diff --git a/core/src/main/java/com/graphhopper/reader/dem/HGTProvider.java b/core/src/main/java/com/graphhopper/reader/dem/HGTProvider.java new file mode 100644 index 00000000000..80e53cf5be2 --- /dev/null +++ b/core/src/main/java/com/graphhopper/reader/dem/HGTProvider.java @@ -0,0 +1,60 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.reader.dem; + +import com.graphhopper.util.Helper; + +import java.io.*; +import java.nio.file.Files; +import java.util.zip.ZipInputStream; + +public class HGTProvider extends AbstractSRTMElevationProvider { + public HGTProvider(String dir) { + super("", dir, "", Integer.MIN_VALUE, Integer.MAX_VALUE, 3601); + } + + @Override + byte[] readFile(File file) throws IOException { + InputStream is = Files.newInputStream(file.toPath()); + ZipInputStream zis = new ZipInputStream(is); + zis.getNextEntry(); + BufferedInputStream buff = new BufferedInputStream(zis); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + byte[] buffer = new byte[0xFFFF]; + int len; + while ((len = buff.read(buffer)) > 0) { + os.write(buffer, 0, len); + } + os.flush(); + Helper.close(buff); + return os.toByteArray(); + } + + @Override + String getFileName(double lat, double lon) { + int latInt = (int) Math.floor(lat); + int lonInt = (int) Math.floor(lon); + return cacheDir + "/" + (lat > 0 ? "N" : "S") + getPaddedLatString(latInt) + (lon > 0 ? "E" : "W") + getPaddedLonString(lonInt) + ".hgt.zip"; + } + + @Override + String getDownloadURL(double lat, double lon) { + return getFileName(lat, lon); + } +} diff --git a/core/src/test/java/com/graphhopper/reader/dem/HGTProviderTest.java b/core/src/test/java/com/graphhopper/reader/dem/HGTProviderTest.java new file mode 100644 index 00000000000..47a6dce57f2 --- /dev/null +++ b/core/src/test/java/com/graphhopper/reader/dem/HGTProviderTest.java @@ -0,0 +1,36 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.reader.dem; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class HGTProviderTest { + + @Disabled + @Test + void getEle() { + HGTProvider hgt = new HGTProvider("/your/path/to/hgt/"); + assertEquals(511, hgt.getEle(49.1, 11.7), 1); + assertEquals(0, hgt.getEle(0.6, 0.6), 1); + } + +} \ No newline at end of file From a72c6c82718a4ce46cc006fc7edea52c089f2a64 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 13 Aug 2022 16:16:30 +0200 Subject: [PATCH 124/389] AbstractTiffElevationProvider: use correct long cast --- .../graphhopper/reader/dem/AbstractTiffElevationProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/dem/AbstractTiffElevationProvider.java b/core/src/main/java/com/graphhopper/reader/dem/AbstractTiffElevationProvider.java index 8bdc8c84973..b7bacd8806b 100644 --- a/core/src/main/java/com/graphhopper/reader/dem/AbstractTiffElevationProvider.java +++ b/core/src/main/java/com/graphhopper/reader/dem/AbstractTiffElevationProvider.java @@ -140,7 +140,7 @@ public double getEle(double lat, double lon) { } // short == 2 bytes - heights.create(2 * WIDTH * HEIGHT); + heights.create(2L * WIDTH * HEIGHT); Raster raster = generateRasterFromFile(file, name + ".tif"); fillDataAccessWithElevationData(raster, heights, WIDTH); @@ -190,7 +190,7 @@ private void fillDataAccessWithElevationData(Raster raster, DataAccess heights, if (val < -1000 || val > 12000) val = Short.MIN_VALUE; - heights.setShort(2 * (y * dataAccessWidth + x), val); + heights.setShort(2 * ((long) y * dataAccessWidth + x), val); } } heights.flush(); From 41f242ee2360bff180752481e24d69a8fecab630 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 14 Aug 2022 21:21:58 +0200 Subject: [PATCH 125/389] pt: hint on how to use multiple files --- reader-gtfs/config-example-pt.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/reader-gtfs/config-example-pt.yml b/reader-gtfs/config-example-pt.yml index e618e2635ec..89fe1f4daa8 100644 --- a/reader-gtfs/config-example-pt.yml +++ b/reader-gtfs/config-example-pt.yml @@ -1,5 +1,6 @@ graphhopper: datareader.file: brandenburg-latest.osm.pbf + # for multiple files you can use: gtfs.file: file1.zip,file2.zip,file3.zip gtfs.file: gtfs-vbb.zip graph.location: graphs/brandenburg-with-transit From 6e531d8ed497d6a836aa8bb73089e47ae8b48fb1 Mon Sep 17 00:00:00 2001 From: easbar Date: Mon, 15 Aug 2022 16:12:35 +0200 Subject: [PATCH 126/389] Add BaseGraph#debugPrint --- core/src/main/java/com/graphhopper/storage/BaseGraph.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index 0c1a7b92b5c..77af892a16c 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -84,6 +84,10 @@ private static boolean isTestingEnabled() { return enableIfAssert; } + public void debugPrint() { + store.debugPrint(); + } + @Override public BaseGraph getBaseGraph() { return this; From 52dd05000144ac117dfc9b0244d3d82a647905c5 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 15 Aug 2022 21:25:59 +0200 Subject: [PATCH 127/389] new edge smoothing: "ramer" (#2634) * initial version of new edge smoothing * improve comments * let's switch the order: first do sampling, then smoothing * use moving_average as name and a few more comments * use same max_elevation like in example config * fix moving_average * again moving_average rename --- config-example.yml | 15 +-- .../java/com/graphhopper/GraphHopper.java | 5 +- .../reader/dem/EdgeElevationSmoothing.java | 127 ++++++++++++++++++ .../reader/dem/GraphElevationSmoothing.java | 62 --------- .../com/graphhopper/reader/osm/OSMReader.java | 18 ++- .../graphhopper/routing/OSMReaderConfig.java | 16 ++- ...t.java => EdgeElevationSmoothingTest.java} | 34 ++++- 7 files changed, 193 insertions(+), 84 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/reader/dem/EdgeElevationSmoothing.java delete mode 100644 core/src/main/java/com/graphhopper/reader/dem/GraphElevationSmoothing.java rename core/src/test/java/com/graphhopper/reader/dem/{GraphElevationSmoothingTest.java => EdgeElevationSmoothingTest.java} (57%) diff --git a/config-example.yml b/config-example.yml index fe466747cbe..444a2d8c862 100644 --- a/config-example.yml +++ b/config-example.yml @@ -5,8 +5,8 @@ graphhopper: # Local folder used by graphhopper to store its data graph.location: graph-cache - ##### Vehicles ##### + ##### Vehicles ##### # More options: foot,hike,bike,bike2,mtb,racingbike,motorcycle,car4wd,wheelchair (comma separated) # bike2 takes elevation data into account (like up-hill is slower than down-hill) and requires enabling graph.elevation.provider below. @@ -81,22 +81,24 @@ graphhopper: ##### Elevation ##### - # To populate your graph with elevation data use SRTM, default is noop (no elevation). Read more about it in docs/core/elevation.md # graph.elevation.provider: srtm - # default location for cache is /tmp/srtm # graph.elevation.cache_dir: ./srtmprovider/ - # If you have a slow disk or plenty of RAM change the default MMAP to: # graph.elevation.dataaccess: RAM_STORE - # To enable bilinear interpolation when sampling elevation at points (default uses nearest neighbor): # graph.elevation.interpolate: bilinear + # Reduce ascend/descend per edge without changing the maximum slope: + # graph.elevation.edge_smoothing: ramer + # removes elevation fluctuations up to max_elevation (in meter) and replaces the elevation with a value based on the average slope + # graph.elevation.edge_smoothing.ramer.max_elevation: 5 + # A potentially bigger reduction of ascend/descend is possible, but maximum slope will often increase (do not use when average_slope or maximum_slope shall be used in a custom_model) + # graph.elevation.edge_smoothing: moving_average # To increase elevation profile resolution, use the following two parameters to tune the extra resolution you need # against the additional storage space used for edge geometries. You should enable bilinear interpolation when using @@ -110,7 +112,6 @@ graphhopper: #### Speed, hybrid and flexible mode #### - # To make CH preparation faster for multiple profiles you can increase the default threads if you have enough RAM. # Change this setting only if you know what you are doing and if the default worked for you. # prepare.ch.threads: 1 @@ -131,7 +132,6 @@ graphhopper: ##### Routing ##### - # You can define the maximum visited nodes when routing. This may result in not found connections if there is no # connection between two points within the given visited nodes. The default is Integer.MAX_VALUE. Useful for flexibility mode # routing.max_visited_nodes: 1000000 @@ -146,7 +146,6 @@ graphhopper: ##### Storage ##### - # configure the memory access, use RAM_STORE for well equipped servers (default and recommended) graph.dataaccess.default_type: RAM_STORE diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 026ccc4edb0..2708c15332e 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -509,7 +509,10 @@ public GraphHopper init(GraphHopperConfig ghConfig) { lockFactory = new NativeFSLockFactory(); // elevation - osmReaderConfig.setSmoothElevation(ghConfig.getBool("graph.elevation.smoothing", osmReaderConfig.isSmoothElevation())); + if (ghConfig.has("graph.elevation.smoothing")) + throw new IllegalArgumentException("Use 'graph.elevation.edge_smoothing: moving_average' or the new 'graph.elevation.edge_smoothing: ramer'. See #2634."); + osmReaderConfig.setElevationSmoothing(ghConfig.getString("graph.elevation.edge_smoothing", osmReaderConfig.getElevationSmoothing())); + osmReaderConfig.setElevationSmoothingRamerMax(ghConfig.getInt("graph.elevation.edge_smoothing.ramer.max_elevation", osmReaderConfig.getElevationSmoothingRamerMax())); osmReaderConfig.setLongEdgeSamplingDistance(ghConfig.getDouble("graph.elevation.long_edge_sampling_distance", osmReaderConfig.getLongEdgeSamplingDistance())); osmReaderConfig.setElevationMaxWayPointDistance(ghConfig.getDouble("graph.elevation.way_point_max_distance", osmReaderConfig.getElevationMaxWayPointDistance())); routerConfig.setElevationWayPointMaxDistance(ghConfig.getDouble("graph.elevation.way_point_max_distance", routerConfig.getElevationWayPointMaxDistance())); diff --git a/core/src/main/java/com/graphhopper/reader/dem/EdgeElevationSmoothing.java b/core/src/main/java/com/graphhopper/reader/dem/EdgeElevationSmoothing.java new file mode 100644 index 00000000000..276e27d189b --- /dev/null +++ b/core/src/main/java/com/graphhopper/reader/dem/EdgeElevationSmoothing.java @@ -0,0 +1,127 @@ +package com.graphhopper.reader.dem; + +import com.graphhopper.util.DistanceCalcEarth; +import com.graphhopper.util.DistancePlaneProjection; +import com.graphhopper.util.PointList; + +/** + * The ElevationData is read from rectangular tiles. Especially when going along a cliff, + * valley, or pass, it can happen that a small part of the road contains incorrect elevation data. + * This is because the elevation data is coarse and sometimes contains errors. + * + * @author Robin Boldt + */ +public class EdgeElevationSmoothing { + + // If the point is farther then this, we stop averaging + private final static int MAX_SEARCH_DISTANCE = 150; + + /** + * This method smooths the elevation data of a PointList by calculating the average elevation over + * multiple points of that PointList. + */ + public static void smoothMovingAverage(PointList geometry) { + for (int i = 1; i < geometry.size() - 1; i++) { + + int start = i; + for (int j = i - 1; j >= 0; j--) { + if (MAX_SEARCH_DISTANCE > DistancePlaneProjection.DIST_PLANE.calcDist(geometry.getLat(i), geometry.getLon(i), geometry.getLat(j), geometry.getLon(j))) { + start = j; + } else { + break; + } + } + + int end = i; + for (int j = i + 1; j < geometry.size(); j++) { + if (MAX_SEARCH_DISTANCE > DistancePlaneProjection.DIST_PLANE.calcDist(geometry.getLat(i), geometry.getLon(i), geometry.getLat(j), geometry.getLon(j))) { + // +1 because the end is exclusive + end = j + 1; + } else { + break; + } + } + + // In this case we cannot find any points within the max search distance, so we simply skip this point + if (start == end) + continue; + + double sum = 0; + for (int j = start; j < end; j++) { + // We skip points that are too far away, important for motorways + if (MAX_SEARCH_DISTANCE > DistancePlaneProjection.DIST_PLANE.calcDist(geometry.getLat(i), geometry.getLon(i), geometry.getLat(j), geometry.getLon(j))) { + sum += geometry.getEle(j); + } + } + double smoothed = sum / (end - start); + geometry.setElevation(i, smoothed); + } + } + + /** + * This method removes elevation fluctuations up to maxElevationDelta. Compared to the smoothMovingAverage function + * this method has the advantage that the maximum slope of a PointList never increases (max(abs(slope_i))). + * The disadvantage is that the appearance might be still more spiky (at tower nodes) as a result when a bigger + * positive slope changes to a bigger negative slope. + *

+ * The underlying algorithm is an adapted Ramer-Douglas-Peucker algorithm (see #2634) with a maximum elevation change and: + * 1. only elevation changes are considered and any lat,lon difference is ignored + * 2. instead of removing the point the elevation will be calculated from the average slope of the first and last + * point of the specified pointList + */ + public static void smoothRamer(PointList pointList, double maxElevationDelta) { + internSmoothRamer(pointList, 0, pointList.size() - 1, maxElevationDelta); + } + + static void internSmoothRamer(PointList pointList, int fromIndex, int lastIndex, double maxElevationDelta) { + if (lastIndex - fromIndex < 2) + return; + + double prevLat = pointList.getLat(fromIndex); + double prevLon = pointList.getLon(fromIndex); + double dist2D = DistanceCalcEarth.DIST_EARTH.calcDist(prevLat, prevLon, pointList.getLat(lastIndex), pointList.getLon(lastIndex)); + double averageSlope = (pointList.getEle(lastIndex) - pointList.getEle(fromIndex)) / dist2D; + double prevAverageSlopeEle = pointList.getEle(fromIndex); + double maxEleDelta = -1; + int indexWithMaxDelta = -1; + for (int i = fromIndex + 1; i < lastIndex; i++) { + double lat = pointList.getLat(i); + double lon = pointList.getLon(i); + double ele = pointList.getEle(i); + double tmpDist2D = DistanceCalcEarth.DIST_EARTH.calcDist(prevLat, prevLon, lat, lon); + double eleFromAverageSlope = averageSlope * tmpDist2D + prevAverageSlopeEle; + double tmpEleDelta = Math.abs(ele - eleFromAverageSlope); + if (maxEleDelta < tmpEleDelta) { + indexWithMaxDelta = i; + maxEleDelta = tmpEleDelta; + } + prevAverageSlopeEle = eleFromAverageSlope; + prevLat = lat; + prevLon = lon; + } + + if (indexWithMaxDelta < 0) + throw new IllegalStateException("maximum not found in [" + fromIndex + "," + lastIndex + "] " + pointList); + + // the maximum elevation change limit filters away especially the smaller high frequent elevation changes, + // which is likely the "noise" that we want to remove. + if (maxElevationDelta > maxEleDelta) { + prevLat = pointList.getLat(fromIndex); + prevLon = pointList.getLon(fromIndex); + prevAverageSlopeEle = pointList.getEle(fromIndex); + for (int i = fromIndex + 1; i < lastIndex; i++) { + double lat = pointList.getLat(i); + double lon = pointList.getLon(i); + double tmpDist2D = DistanceCalcEarth.DIST_EARTH.calcDist(prevLat, prevLon, lat, lon); + double eleFromAverageSlope = averageSlope * tmpDist2D + prevAverageSlopeEle; + pointList.setElevation(i, eleFromAverageSlope); + prevAverageSlopeEle = eleFromAverageSlope; + prevLat = lat; + prevLon = lon; + } + } else { + internSmoothRamer(pointList, fromIndex, indexWithMaxDelta, maxElevationDelta); + internSmoothRamer(pointList, indexWithMaxDelta, lastIndex, maxElevationDelta); + } + } +} diff --git a/core/src/main/java/com/graphhopper/reader/dem/GraphElevationSmoothing.java b/core/src/main/java/com/graphhopper/reader/dem/GraphElevationSmoothing.java deleted file mode 100644 index 45c4db2ca45..00000000000 --- a/core/src/main/java/com/graphhopper/reader/dem/GraphElevationSmoothing.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.graphhopper.reader.dem; - -import com.graphhopper.util.DistancePlaneProjection; -import com.graphhopper.util.PointList; - -/** - * This class smooths the elevation data of a PointList by calculating the average elevation over - * multiple points of that PointList. - *

- * The ElevationData is read from rectangular tiles. Especially when going along a cliff, - * valley, or pass, it can happen that a small part of the road contains incorrect elevation data. - * This is because the elevation data is coarse and sometimes contains errors. - *

- * This can lead to incorrect ascend, descend, and distance calculation of a route. - * - * @author Robin Boldt - */ -public class GraphElevationSmoothing { - - // If the point is farther then this, we stop averaging - private final static int MAX_SEARCH_DISTANCE = 150; - - public static PointList smoothElevation(PointList geometry) { - for (int i = 1; i < geometry.size() - 1; i++) { - - int start = i; - for (int j = i-1; j >= 0 ; j--) { - if (MAX_SEARCH_DISTANCE > DistancePlaneProjection.DIST_PLANE.calcDist(geometry.getLat(i), geometry.getLon(i), geometry.getLat(j), geometry.getLon(j))) { - start = j; - }else{ - break; - } - } - - int end = i; - for (int j = i+1; j < geometry.size(); j++) { - if (MAX_SEARCH_DISTANCE > DistancePlaneProjection.DIST_PLANE.calcDist(geometry.getLat(i), geometry.getLon(i), geometry.getLat(j), geometry.getLon(j))) { - // +1 because the end is exclusive - end = j+1; - }else{ - break; - } - } - - // In this case we cannot find any points within the max search distance, so we simply skip this point - if(start == end) - continue; - - double sum = 0; - for (int j = start; j < end; j++) { - // We skip points that are too far away, important for motorways - if (MAX_SEARCH_DISTANCE > DistancePlaneProjection.DIST_PLANE.calcDist(geometry.getLat(i), geometry.getLon(i), geometry.getLat(j), geometry.getLon(j))) { - sum += geometry.getEle(j); - } - } - double smoothed = sum / (end-start); - geometry.setElevation(i, smoothed); - } - return geometry; - } - -} diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 5fe0f48029d..126acf46e28 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -23,9 +23,9 @@ import com.graphhopper.coll.GHLongHashSet; import com.graphhopper.coll.GHLongLongHashMap; import com.graphhopper.reader.*; +import com.graphhopper.reader.dem.EdgeElevationSmoothing; import com.graphhopper.reader.dem.EdgeSampling; import com.graphhopper.reader.dem.ElevationProvider; -import com.graphhopper.reader.dem.GraphElevationSmoothing; import com.graphhopper.routing.OSMReaderConfig; import com.graphhopper.routing.ev.Country; import com.graphhopper.routing.util.AreaIndex; @@ -292,13 +292,17 @@ protected void addEdge(int fromIndex, int toIndex, PointList pointList, ReaderWa // to do some kind of elevation processing (bridge+tunnel interpolation in GraphHopper class, maybe this can // go together - // Smooth the elevation before calculating the distance because the distance will be incorrect if calculated afterwards - if (config.isSmoothElevation()) - GraphElevationSmoothing.smoothElevation(pointList); + if (pointList.is3D()) { + // sample points along long edges + if (config.getLongEdgeSamplingDistance() < Double.MAX_VALUE) + pointList = EdgeSampling.sample(pointList, config.getLongEdgeSamplingDistance(), distCalc, eleProvider); - // sample points along long edges - if (config.getLongEdgeSamplingDistance() < Double.MAX_VALUE && pointList.is3D()) - pointList = EdgeSampling.sample(pointList, config.getLongEdgeSamplingDistance(), distCalc, eleProvider); + // smooth the elevation before calculating the distance because the distance will be incorrect if calculated afterwards + if (config.getElevationSmoothing().equals("ramer")) + EdgeElevationSmoothing.smoothRamer(pointList, config.getElevationSmoothingRamerMax()); + else if (config.getElevationSmoothing().equals("moving_average")) + EdgeElevationSmoothing.smoothMovingAverage(pointList); + } if (config.getMaxWayPointDistance() > 0 && pointList.size() > 2) simplifyAlgo.simplify(pointList); diff --git a/core/src/main/java/com/graphhopper/routing/OSMReaderConfig.java b/core/src/main/java/com/graphhopper/routing/OSMReaderConfig.java index d5baea728f6..1f196c9b06d 100644 --- a/core/src/main/java/com/graphhopper/routing/OSMReaderConfig.java +++ b/core/src/main/java/com/graphhopper/routing/OSMReaderConfig.java @@ -23,7 +23,8 @@ public class OSMReaderConfig { private String preferredLanguage = ""; private double maxWayPointDistance = 1; private double elevationMaxWayPointDistance = Double.MAX_VALUE; - private boolean smoothElevation = false; + private String smoothElevation = ""; + private int ramerElevationSmoothingMax = 5; private double longEdgeSamplingDistance = Double.MAX_VALUE; private int workerThreads = 2; @@ -78,18 +79,27 @@ public OSMReaderConfig setElevationMaxWayPointDistance(double elevationMaxWayPoi return this; } - public boolean isSmoothElevation() { + public String getElevationSmoothing() { return smoothElevation; } /** * Enables/disables elevation smoothing */ - public OSMReaderConfig setSmoothElevation(boolean smoothElevation) { + public OSMReaderConfig setElevationSmoothing(String smoothElevation) { this.smoothElevation = smoothElevation; return this; } + public int getElevationSmoothingRamerMax() { + return ramerElevationSmoothingMax; + } + + public OSMReaderConfig setElevationSmoothingRamerMax(int max) { + this.ramerElevationSmoothingMax = max; + return this; + } + public double getLongEdgeSamplingDistance() { return longEdgeSamplingDistance; } diff --git a/core/src/test/java/com/graphhopper/reader/dem/GraphElevationSmoothingTest.java b/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationSmoothingTest.java similarity index 57% rename from core/src/test/java/com/graphhopper/reader/dem/GraphElevationSmoothingTest.java rename to core/src/test/java/com/graphhopper/reader/dem/EdgeElevationSmoothingTest.java index d2a75f5018c..7593ddf6d15 100644 --- a/core/src/test/java/com/graphhopper/reader/dem/GraphElevationSmoothingTest.java +++ b/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationSmoothingTest.java @@ -25,7 +25,7 @@ /** * @author Robin Boldt */ -public class GraphElevationSmoothingTest { +public class EdgeElevationSmoothingTest { @Test public void interpolatesElevationOfPillarNodes() { @@ -34,7 +34,7 @@ public void interpolatesElevationOfPillarNodes() { pl1.add(0, 0, 0); pl1.add(0.0005, 0.0005, 100); pl1.add(0.001, 0.001, 50); - GraphElevationSmoothing.smoothElevation(pl1); + EdgeElevationSmoothing.smoothMovingAverage(pl1); assertEquals(3, pl1.size()); assertEquals(50, pl1.getEle(1), .1); @@ -44,7 +44,7 @@ public void interpolatesElevationOfPillarNodes() { pl2.add(0.0016, 0.0015, 150); pl2.add(0.0017, 0.0015, 220); pl2.add(0.002, 0.002, 20); - GraphElevationSmoothing.smoothElevation(pl2); + EdgeElevationSmoothing.smoothMovingAverage(pl2); assertEquals(5, pl2.size()); assertEquals(120, pl2.getEle(1), .1); // This is not 120 anymore, as the point at index 1 was smoothed from 160=>120 @@ -53,4 +53,32 @@ public void interpolatesElevationOfPillarNodes() { assertEquals(50, pl2.getEle(0), .1); } + @Test + public void interpolateViaDouglasPeucker() { + PointList pl1 = new PointList(3, true); + pl1.add(0, 0, 0); + pl1.add(0.0005, 0.0005, 100); + pl1.add(0.001, 0.001, 50); + EdgeElevationSmoothing.smoothRamer(pl1, 70); + assertEquals(3, pl1.size()); + assertEquals(100, pl1.getEle(1), .1); + EdgeElevationSmoothing.smoothRamer(pl1, 75); + assertEquals(3, pl1.size()); + assertEquals(25, pl1.getEle(1), .1); + } + + @Test + public void interpolateViaDouglasPeucker2() { + PointList pl2 = new PointList(3, true); + pl2.add(0.001, 0.001, 50); + pl2.add(0.0015, 0.0015, 160); + pl2.add(0.0016, 0.0015, 150); + pl2.add(0.0017, 0.0015, 220); + pl2.add(0.002, 0.002, 20); + EdgeElevationSmoothing.smoothRamer(pl2, 100); + assertEquals(5, pl2.size()); + assertEquals(190, pl2.getEle(1), 1); // modify as too small in interval [0,4] + assertEquals(210, pl2.getEle(2), 1); // modify as too small in interval [0,4] + assertEquals(220, pl2.getEle(3), .1); // keep as it is bigger than maxElevationDelta in interval [0,4] + } } From c8a71fc9396c9838a9ce72c9f5b6cc3b2b07d9b5 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 16 Aug 2022 08:49:02 +0200 Subject: [PATCH 128/389] New average_slope EV (#2645) * initial version of new edge smoothing * improve comments * let's switch the order: first do sampling, then smoothing * encoded values for elevation-aware routing: average_slope and max_slope * for tunnels and bridges ignore elevation changes for pillar nodes * SlopeSetter -> SlopeCalculator --- .../java/com/graphhopper/GraphHopper.java | 2 + .../graphhopper/reader/dem/HeightTile.java | 1 - .../graphhopper/routing/ev/AverageSlope.java | 13 +++ .../ev/DefaultEncodedValueFactory.java | 4 + .../com/graphhopper/routing/ev/MaxSlope.java | 12 +++ .../routing/util/parsers/SlopeCalculator.java | 82 +++++++++++++++++++ .../graphhopper/util/DistanceCalcEarth.java | 22 +++-- .../util/parsers/SlopeCalculatorTest.java | 78 ++++++++++++++++++ 8 files changed, 206 insertions(+), 8 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/ev/AverageSlope.java create mode 100644 core/src/main/java/com/graphhopper/routing/ev/MaxSlope.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java create mode 100644 core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 2708c15332e..21a810bdbad 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -605,6 +605,8 @@ private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String en osmParsers.addWayTagParser(new OSMMaxSpeedParser(encodingManager.getDecimalEncodedValue(MaxSpeed.KEY))); if (!encodedValueStrings.contains(RoadAccess.KEY)) osmParsers.addWayTagParser(new OSMRoadAccessParser(encodingManager.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR))); + if (encodingManager.hasEncodedValue(AverageSlope.KEY) || encodingManager.hasEncodedValue(MaxSlope.KEY)) + osmParsers.addWayTagParser(new SlopeCalculator(encodingManager.getDecimalEncodedValue(MaxSlope.KEY), encodingManager.getDecimalEncodedValue(AverageSlope.KEY))); DateRangeParser dateRangeParser = DateRangeParser.createInstance(dateRangeParserString); flagEncodersMap.forEach((name, encoderStr) -> { diff --git a/core/src/main/java/com/graphhopper/reader/dem/HeightTile.java b/core/src/main/java/com/graphhopper/reader/dem/HeightTile.java index 93b29c682eb..61b0a2723cd 100644 --- a/core/src/main/java/com/graphhopper/reader/dem/HeightTile.java +++ b/core/src/main/java/com/graphhopper/reader/dem/HeightTile.java @@ -24,7 +24,6 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; -import java.util.concurrent.atomic.AtomicInteger; /** * One rectangle of height data from Shuttle Radar Topography Mission. diff --git a/core/src/main/java/com/graphhopper/routing/ev/AverageSlope.java b/core/src/main/java/com/graphhopper/routing/ev/AverageSlope.java new file mode 100644 index 00000000000..38eb4c870d8 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/AverageSlope.java @@ -0,0 +1,13 @@ +package com.graphhopper.routing.ev; + +/** + * Average elevation. Will be negated in reverse direction. + */ +public class AverageSlope { + public static final String KEY = "average_slope"; + + public static DecimalEncodedValue create() { + return new DecimalEncodedValueImpl(KEY, 5, 0, 1, false, + true, false, false); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java index 5cb66e4c713..502891f6ab4 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java @@ -82,6 +82,10 @@ public EncodedValue create(String string) { enc = Country.create(); } else if (name.endsWith(Subnetwork.key(""))) { enc = new SimpleBooleanEncodedValue(name); + } else if (MaxSlope.KEY.equals(name)) { + enc = MaxSlope.create(); + } else if (AverageSlope.KEY.equals(name)) { + enc = AverageSlope.create(); } else { throw new IllegalArgumentException("DefaultEncodedValueFactory cannot find EncodedValue " + name); } diff --git a/core/src/main/java/com/graphhopper/routing/ev/MaxSlope.java b/core/src/main/java/com/graphhopper/routing/ev/MaxSlope.java new file mode 100644 index 00000000000..bbb64e343e9 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/MaxSlope.java @@ -0,0 +1,12 @@ +package com.graphhopper.routing.ev; + +/** + * Maximum elevation change in m/100m. + */ +public class MaxSlope { + public static final String KEY = "max_slope"; + + public static DecimalEncodedValue create() { + return new DecimalEncodedValueImpl(KEY, 5, 1, false, false); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java b/core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java new file mode 100644 index 00000000000..b551454d15d --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java @@ -0,0 +1,82 @@ +package com.graphhopper.routing.util.parsers; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.DistanceCalcEarth; +import com.graphhopper.util.PointList; + +public class SlopeCalculator implements TagParser { + private final DecimalEncodedValue maxSlopeEnc; + private final DecimalEncodedValue averageSlopeEnc; + // the elevation data fluctuates a lot and so the slope is not that precise for short edges. + private static final double MIN_LENGTH = 8; + + public SlopeCalculator(DecimalEncodedValue max, DecimalEncodedValue averageEnc) { + this.maxSlopeEnc = max; + this.averageSlopeEnc = averageEnc; + } + + @Override + public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + PointList pointList = way.getTag("point_list", null); + if (pointList != null && pointList.size() > 1) { + // Calculate 2d distance, although pointList might be 3D. + // This calculation is a bit expensive and edge_distance is available already, but this would be in 3D + double distance2D = DistanceCalcEarth.calcDistance(pointList, false); + + if (distance2D < MIN_LENGTH) { + // default is minimum of average_slope is negative so we have to explicitly set it to 0 + if (averageSlopeEnc != null) + averageSlopeEnc.setDecimal(false, edgeFlags, 0); + return edgeFlags; + } + + double towerNodeSlope = calcSlope(pointList.getEle(pointList.size() - 1) - pointList.getEle(0), distance2D); + if (Double.isNaN(towerNodeSlope)) + throw new IllegalArgumentException("average_slope was NaN for OSM way ID " + way.getId()); + + if (averageSlopeEnc != null) { + if (towerNodeSlope >= 0) + averageSlopeEnc.setDecimal(false, edgeFlags, Math.min(towerNodeSlope, averageSlopeEnc.getMaxStorableDecimal())); + else + averageSlopeEnc.setDecimal(true, edgeFlags, Math.min(Math.abs(towerNodeSlope), averageSlopeEnc.getMaxStorableDecimal())); + } + + // max_slope is more error-prone as the shorter distances increase the fluctuation + // so apply some more filtering (here we use the average elevation delta of the previous two points) + double maxSlope = 0, prevDist = 0, prevLat = pointList.getLat(0), prevLon = pointList.getLon(0); + for (int i = 1; i < pointList.size(); i++) { + double pillarDistance2D = DistanceCalcEarth.DIST_EARTH.calcDist(prevLat, prevLon, pointList.getLat(i), pointList.getLon(i)); + if (i > 1 && prevDist > MIN_LENGTH) { + double averagedPrevEle = (pointList.getEle(i - 1) + pointList.getEle(i - 2)) / 2; + double tmpSlope = calcSlope(pointList.getEle(i) - averagedPrevEle, pillarDistance2D + prevDist / 2); + maxSlope = Math.max(maxSlope, Math.abs(tmpSlope)); + } + prevDist = pillarDistance2D; + prevLat = pointList.getLat(i); + prevLon = pointList.getLon(i); + } + + // For tunnels and bridges we cannot trust the pillar node elevation and ignore all changes. + // Probably we should somehow recalculate even the average_slope after elevation interpolation? See EdgeElevationInterpolator + if (way.hasTag("tunnel", "yes") || way.hasTag("bridge", "yes") || way.hasTag("highway", "steps")) + maxSlope = Math.abs(towerNodeSlope); + else + maxSlope = Math.max(Math.abs(towerNodeSlope), maxSlope); + + if (Double.isNaN(maxSlope)) + throw new IllegalArgumentException("max_slope was NaN for OSM way ID " + way.getId()); + + // TODO Use two independent values for both directions to store if it is a gain or loss and not just the absolute change. + // TODO To save space then it would be nice to have an encoded value that can store two different values which are swapped when the reverse direction is used + if (maxSlopeEnc != null) + maxSlopeEnc.setDecimal(false, edgeFlags, Math.min(maxSlope, maxSlopeEnc.getMaxStorableDecimal())); + } + return edgeFlags; + } + + static double calcSlope(double eleDelta, double distance2D) { + return eleDelta * 100 / distance2D; + } +} diff --git a/core/src/main/java/com/graphhopper/util/DistanceCalcEarth.java b/core/src/main/java/com/graphhopper/util/DistanceCalcEarth.java index 040f2c3590f..8ea8bfb08ec 100644 --- a/core/src/main/java/com/graphhopper/util/DistanceCalcEarth.java +++ b/core/src/main/java/com/graphhopper/util/DistanceCalcEarth.java @@ -40,7 +40,7 @@ public class DistanceCalcEarth implements DistanceCalc { public final static double C = 2 * PI * R; public final static double KM_MILE = 1.609344; public final static double METERS_PER_DEGREE = C / 360.0; - public static final DistanceCalc DIST_EARTH = new DistanceCalcEarth(); + public static final DistanceCalcEarth DIST_EARTH = new DistanceCalcEarth(); /** * Calculates distance of (from, to) in meter. @@ -298,33 +298,41 @@ public GHPoint intermediatePoint(double f, double lat1, double lon1, double lat2 double sinHalfDeltaLon = sin(deltaLon / 2); double a = sinHalfDeltaLat * sinHalfDeltaLat + cosLat1 * cosLat2 * sinHalfDeltaLon * sinHalfDeltaLon; - double angularDistance = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + double angularDistance = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); double sinDistance = sin(angularDistance); if (angularDistance == 0) return new GHPoint(lat1, lon1); - double A = Math.sin((1-f)*angularDistance) / sinDistance; - double B = Math.sin(f*angularDistance) / sinDistance; + double A = Math.sin((1 - f) * angularDistance) / sinDistance; + double B = Math.sin(f * angularDistance) / sinDistance; double x = A * cosLat1 * cos(lon1radians) + B * cosLat2 * cos(lon2radians); double y = A * cosLat1 * sin(lon1radians) + B * cosLat2 * sin(lon2radians); double z = A * sin(lat1radians) + B * sin(lat2radians); - double midLat = Math.toDegrees(Math.atan2(z, Math.sqrt(x*x + y*y))); + double midLat = Math.toDegrees(Math.atan2(z, Math.sqrt(x * x + y * y))); double midLon = Math.toDegrees(Math.atan2(y, x)); return new GHPoint(midLat, midLon); } @Override - public final double calcDistance(PointList pointList) { + public double calcDistance(PointList pointList) { + return internCalcDistance(pointList, pointList.is3D()); + } + + public static double calcDistance(PointList pointList, boolean is3d) { + return DistanceCalcEarth.DIST_EARTH.internCalcDistance(pointList, is3d); + } + + private double internCalcDistance(PointList pointList, boolean is3d) { double prevLat = Double.NaN; double prevLon = Double.NaN; double prevEle = Double.NaN; double dist = 0; for (int i = 0; i < pointList.size(); i++) { if (i > 0) { - if (pointList.is3D()) + if (is3d) dist += calcDist3D(prevLat, prevLon, prevEle, pointList.getLat(i), pointList.getLon(i), pointList.getEle(i)); else dist += calcDist(prevLat, prevLon, pointList.getLat(i), pointList.getLon(i)); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java new file mode 100644 index 00000000000..6a154e26184 --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java @@ -0,0 +1,78 @@ +package com.graphhopper.routing.util.parsers; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.AverageSlope; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.ev.MaxSlope; +import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.PointList; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class SlopeCalculatorTest { + + @Test + void simpleElevation() { + DecimalEncodedValue averageEnc = AverageSlope.create(); + DecimalEncodedValue maxEnc = MaxSlope.create(); + new EncodingManager.Builder().add(averageEnc).add(maxEnc).build(); + SlopeCalculator creator = new SlopeCalculator(maxEnc, averageEnc); + IntsRef edgeRef = new IntsRef(1); + ReaderWay way = new ReaderWay(1L); + PointList pointList = new PointList(5, true); + pointList.add(51.0, 12.001, 0); + pointList.add(51.0, 12.002, 3.5); // ~70m + pointList.add(51.0, 12.003, 4); // ~140m + pointList.add(51.0, 12.004, 2); // ~210m + way.setTag("point_list", pointList); + creator.handleWayTags(edgeRef, way, IntsRef.EMPTY); + + assertEquals(Math.round(2.0 / 210 * 100), averageEnc.getDecimal(false, edgeRef), 1e-3); + assertEquals(-Math.round(2.0 / 210 * 100), averageEnc.getDecimal(true, edgeRef), 1e-3); + + assertEquals(Math.round(1.75 / 105 * 100), maxEnc.getDecimal(false, edgeRef), 1e-3); + assertEquals(Math.round(1.75 / 105 * 100), maxEnc.getDecimal(true, edgeRef), 1e-3); + } + + @Test + public void testAveragingOfMaxSlope() { + // point=49.977518%2C11.564285&point=49.979878%2C11.563663&profile=bike + DecimalEncodedValue averageEnc = AverageSlope.create(); + DecimalEncodedValue maxEnc = MaxSlope.create(); + new EncodingManager.Builder().add(averageEnc).add(maxEnc).build(); + SlopeCalculator creator = new SlopeCalculator(maxEnc, averageEnc); + IntsRef edgeRef = new IntsRef(1); + ReaderWay way = new ReaderWay(1L); + PointList pointList = new PointList(5, true); + pointList.add(51.0, 12.0010, 10); + pointList.add(51.0, 12.0014, 8); // 28m + pointList.add(51.0, 12.0034, 8); // 140m + pointList.add(51.0, 12.0054, 0); // 140m + pointList.add(51.0, 12.0070, 7); // 112m + way.setTag("point_list", pointList); + creator.handleWayTags(edgeRef, way, IntsRef.EMPTY); + + assertEquals(Math.round(8.0 / 210 * 100), maxEnc.getDecimal(false, edgeRef), 1e-3); + assertEquals(Math.round(8.0 / 210 * 100), maxEnc.getDecimal(true, edgeRef), 1e-3); + } + + @Test + public void test2() { + PointList pointList = new PointList(5, true); + pointList.add(47.7281561, 11.9993135, 1163.0); + pointList.add(47.7282782, 11.9991944, 1163.0); + pointList.add(47.7283135, 11.9991135, 1178.0); + ReaderWay way = new ReaderWay(1); + way.setTag("point_list", pointList); + IntsRef edgeRef = new IntsRef(1); + DecimalEncodedValue averageEnc = AverageSlope.create(); + DecimalEncodedValue maxEnc = MaxSlope.create(); + new EncodingManager.Builder().add(averageEnc).add(maxEnc).build(); + SlopeCalculator creator = new SlopeCalculator(maxEnc, averageEnc); + creator.handleWayTags(edgeRef, way, IntsRef.EMPTY); + assertEquals(31, maxEnc.getDecimal(false, edgeRef), 1e-3); + assertEquals(31, averageEnc.getDecimal(false, edgeRef), 1e-3); + } +} From 4c13a98ec2ee9f3e13ac667a2fd03f99c7d07c83 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 18 Aug 2022 10:22:47 +0200 Subject: [PATCH 129/389] fix link for GTFS demo file for #2639 --- reader-gtfs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reader-gtfs/README.md b/reader-gtfs/README.md index dc01f957dd9..276b637824a 100644 --- a/reader-gtfs/README.md +++ b/reader-gtfs/README.md @@ -12,7 +12,7 @@ git clone https://github.com/graphhopper/graphhopper cd graphhopper # download GTFS from Berlin & Brandenburg in Germany (VBB) and the 'surrounding' OpenStreetMap data for the walk network -wget -O gtfs-vbb.zip https://www.vbb.de/fileadmin/user_upload/VBB/Dokumente/API-Datensaetze/GTFS.zip +wget -O gtfs-vbb.zip https://www.vbb.de/fileadmin/user_upload/VBB/Dokumente/API-Datensaetze/gtfs-mastscharf/GTFS.zip wget http://download.geofabrik.de/europe/germany/brandenburg-latest.osm.pbf mvn clean package -DskipTests From 1bee4d96e2b339f19bcbc60c617b027e1c5b84c5 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 18 Aug 2022 11:35:52 +0200 Subject: [PATCH 130/389] removed defaultIsInfinity and fix bug in DecimalEncodedValueImpl (#2646) * removed defaultIsInfinity and fix bug in DecimalEncodedValueImpl * changelog: fix issue number * for useMaximumAsInfinity: also throw an exception if value is too big, but not for infinity * fix merge of master * Revert "for useMaximumAsInfinity: also throw an exception if value is too big, but not for infinity" This reverts commit e3d882616dca6937c54d76846c1b944325fb3015. * print warning if max_width, max_weight etc values are too large * fix link for GTFS demo file for #2639 * Revert "fix link for GTFS demo file for #2639" This reverts commit d9bb4b9a9e1adfe42a415dfc27d5b61a09ab9aee. --- CHANGELOG.md | 2 + .../graphhopper/routing/ev/AverageSlope.java | 2 +- .../routing/ev/DecimalEncodedValueImpl.java | 44 +++++-------- .../graphhopper/routing/ev/MaxAxleLoad.java | 2 +- .../com/graphhopper/routing/ev/MaxHeight.java | 2 +- .../com/graphhopper/routing/ev/MaxLength.java | 2 +- .../com/graphhopper/routing/ev/MaxSlope.java | 2 +- .../com/graphhopper/routing/ev/MaxSpeed.java | 2 +- .../com/graphhopper/routing/ev/MaxWeight.java | 2 +- .../com/graphhopper/routing/ev/MaxWidth.java | 2 +- .../com/graphhopper/routing/ev/TurnCost.java | 2 +- .../parsers/helpers/OSMValueExtractor.java | 37 ++++++----- .../ev/DecimalEncodedValueImplTest.java | 64 +++++++++---------- .../ev/EncodedValueSerializerTest.java | 2 +- .../PrepareRoutingSubnetworksTest.java | 6 +- .../parsers/OSMMaxAxleLoadParserTest.java | 2 +- .../util/parsers/OSMMaxWeightParserTest.java | 2 +- 17 files changed, 80 insertions(+), 97 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21521056737..f2bfdef7ab3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ ### 6.0 [not yet released] +- When using a DecimalEncodedValue with useMaximumAsInfinity=true and a single bit of space make sure you always use + Double.POSITIVE_INFINITY to set the value, see #2646 - renamed DouglasPeucker to RamerDouglasPeucker - path details at via-points are no longer merged, see #2626 - removed the FlagEncoder interface. for example encoder.getAccessEnc() is now encodingManager.getBooleanEncodedValue( diff --git a/core/src/main/java/com/graphhopper/routing/ev/AverageSlope.java b/core/src/main/java/com/graphhopper/routing/ev/AverageSlope.java index 38eb4c870d8..236f4630cf1 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/AverageSlope.java +++ b/core/src/main/java/com/graphhopper/routing/ev/AverageSlope.java @@ -7,7 +7,7 @@ public class AverageSlope { public static final String KEY = "average_slope"; public static DecimalEncodedValue create() { - return new DecimalEncodedValueImpl(KEY, 5, 0, 1, false, + return new DecimalEncodedValueImpl(KEY, 5, 0, 1, true, false, false); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java index 72a33341030..18616dc64fe 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java @@ -27,21 +27,13 @@ */ public final class DecimalEncodedValueImpl extends IntEncodedValueImpl implements DecimalEncodedValue { private final double factor; - private final boolean defaultIsInfinity; private final boolean useMaximumAsInfinity; /** - * @see #DecimalEncodedValueImpl(String, int, double, double, boolean, boolean, boolean, boolean) + * @see #DecimalEncodedValueImpl(String, int, double, double, boolean, boolean, boolean) */ public DecimalEncodedValueImpl(String name, int bits, double factor, boolean storeTwoDirections) { - this(name, bits, factor, false, storeTwoDirections); - } - - /** - * @see #DecimalEncodedValueImpl(String, int, double, double, boolean, boolean, boolean, boolean) - */ - public DecimalEncodedValueImpl(String name, int bits, double factor, boolean defaultIsInfinity, boolean storeTwoDirections) { - this(name, bits, 0, factor, defaultIsInfinity, false, storeTwoDirections, false); + this(name, bits, 0, factor, false, storeTwoDirections, false); } /** @@ -50,24 +42,18 @@ public DecimalEncodedValueImpl(String name, int bits, double factor, boolean def * maximum value. * @param minStorableValue the minimum storable value. Use e.g. 0 if no negative values are needed. * @param factor the precision factor, i.e. store = (int) Math.round(value / factor) - * @param defaultIsInfinity true if default should be Double.Infinity. False if 0 should be default. * @param negateReverseDirection true if the reverse direction should be always negative of the forward direction. * This is used to reduce space and store the value only once. * @param storeTwoDirections true if forward and backward direction of the edge should get two independent values. * @param useMaximumAsInfinity true if the maximum value should be treated as Double.Infinity */ - public DecimalEncodedValueImpl(String name, int bits, double minStorableValue, double factor, boolean defaultIsInfinity, + public DecimalEncodedValueImpl(String name, int bits, double minStorableValue, double factor, boolean negateReverseDirection, boolean storeTwoDirections, boolean useMaximumAsInfinity) { super(name, bits, (int) Math.round(minStorableValue / factor), negateReverseDirection, storeTwoDirections); if (!negateReverseDirection && super.minStorableValue * factor != minStorableValue) throw new IllegalArgumentException("minStorableValue " + minStorableValue + " is not a multiple of the specified factor " + factor); this.factor = factor; - this.defaultIsInfinity = defaultIsInfinity; this.useMaximumAsInfinity = useMaximumAsInfinity; - if (useMaximumAsInfinity && defaultIsInfinity) - throw new IllegalArgumentException("defaultIsInfinity and useMaximumAsInfinity cannot be both true"); - if (defaultIsInfinity && minStorableValue < 0) - throw new IllegalArgumentException("defaultIsInfinity cannot be true when minStorableValue is negative"); } @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) @@ -85,12 +71,10 @@ public DecimalEncodedValueImpl(String name, int bits, double minStorableValue, d @JsonProperty("fwd_mask") int fwdMask, @JsonProperty("bwd_mask") int bwdMask, @JsonProperty("factor") double factor, - @JsonProperty("default_is_infinity") boolean defaultIsInfinity, @JsonProperty("use_maximum_as_infinity") boolean useMaximumAsInfinity) { // we need this constructor for Jackson super(name, bits, minStorableValue, maxStorableValue, maxValue, negateReverseDirection, storeTwoDirections, fwdDataIndex, bwdDataIndex, fwdShift, bwdShift, fwdMask, bwdMask); this.factor = factor; - this.defaultIsInfinity = defaultIsInfinity; this.useMaximumAsInfinity = useMaximumAsInfinity; } @@ -98,16 +82,17 @@ public DecimalEncodedValueImpl(String name, int bits, double minStorableValue, d public void setDecimal(boolean reverse, IntsRef ref, double value) { if (!isInitialized()) throw new IllegalStateException("Call init before using EncodedValue " + getName()); - if (Double.isInfinite(value)) { - if (useMaximumAsInfinity) { + if (useMaximumAsInfinity) { + if (Double.isInfinite(value)) { super.setInt(reverse, ref, maxStorableValue); return; - } else if (defaultIsInfinity) { - super.setInt(reverse, ref, 0); + } else if (value >= maxStorableValue * factor) { // equality is important as maxStorableValue is reserved for infinity + super.uncheckedSet(reverse, ref, maxStorableValue - 1); return; } + } else if (Double.isInfinite(value)) throw new IllegalArgumentException("Value cannot be infinite if useMaximumAsInfinity is false"); - } + if (Double.isNaN(value)) throw new IllegalArgumentException("NaN value for " + getName() + " not allowed!"); @@ -123,7 +108,7 @@ public void setDecimal(boolean reverse, IntsRef ref, double value) { @Override public double getDecimal(boolean reverse, IntsRef ref) { int value = getInt(reverse, ref); - if (useMaximumAsInfinity && value == maxStorableValue || defaultIsInfinity && value == 0) + if (useMaximumAsInfinity && value == maxStorableValue) return Double.POSITIVE_INFINITY; return value * factor; } @@ -132,7 +117,7 @@ public double getDecimal(boolean reverse, IntsRef ref) { public double getNextStorableValue(double value) { if (!useMaximumAsInfinity && value > getMaxStorableDecimal()) throw new IllegalArgumentException(getName() + ": There is no next storable value for " + value + ". max:" + getMaxStorableDecimal()); - else if (useMaximumAsInfinity && value > getMaxStorableDecimal()) + else if (useMaximumAsInfinity && value > (maxStorableValue - 1) * factor) return Double.POSITIVE_INFINITY; else return (factor * (int) Math.ceil(value / factor)); @@ -147,6 +132,7 @@ public double getSmallestNonZeroValue() { @Override public double getMaxStorableDecimal() { + if (useMaximumAsInfinity) return Double.POSITIVE_INFINITY; return maxStorableValue * factor; } @@ -157,8 +143,8 @@ public double getMinStorableDecimal() { @Override public double getMaxOrMaxStorableDecimal() { - if (useMaximumAsInfinity || defaultIsInfinity) - throw new IllegalStateException("getMaxOrMaxStorableDecimal() is not implemented for useMaximumAsInfinity or defaultIsInfinity"); - return getMaxOrMaxStorableInt() * factor; + int maxOrMaxStorable = getMaxOrMaxStorableInt(); + if (useMaximumAsInfinity && maxOrMaxStorable == maxStorableValue) return Double.POSITIVE_INFINITY; + return maxOrMaxStorable * factor; } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/MaxAxleLoad.java b/core/src/main/java/com/graphhopper/routing/ev/MaxAxleLoad.java index 6279960a8d4..5b7e3631dcb 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/MaxAxleLoad.java +++ b/core/src/main/java/com/graphhopper/routing/ev/MaxAxleLoad.java @@ -29,6 +29,6 @@ public class MaxAxleLoad { * it was done with the MappedDecimalEncodedValue still handling (or rounding) of unknown values is unclear. */ public static DecimalEncodedValue create() { - return new DecimalEncodedValueImpl(KEY, 7, 0.5, true, false); + return new DecimalEncodedValueImpl(KEY, 7, 0, 0.5, false, false, true); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/MaxHeight.java b/core/src/main/java/com/graphhopper/routing/ev/MaxHeight.java index 7fe15711e6a..6ac26936238 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/MaxHeight.java +++ b/core/src/main/java/com/graphhopper/routing/ev/MaxHeight.java @@ -32,6 +32,6 @@ public class MaxHeight { * it is assumed to use the maximum value. */ public static DecimalEncodedValue create() { - return new DecimalEncodedValueImpl(KEY, 7, 0.1, true, false); + return new DecimalEncodedValueImpl(KEY, 7, 0, 0.1, false, false, true); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/MaxLength.java b/core/src/main/java/com/graphhopper/routing/ev/MaxLength.java index 03b52d8176b..5848d239ea2 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/MaxLength.java +++ b/core/src/main/java/com/graphhopper/routing/ev/MaxLength.java @@ -32,6 +32,6 @@ public class MaxLength { * between the maximum and infinity it is assumed to use the maximum value. */ public static DecimalEncodedValue create() { - return new DecimalEncodedValueImpl(KEY, 7, 0.1, true, false); + return new DecimalEncodedValueImpl(KEY, 7, 0, 0.1, false, false, true); } } \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/routing/ev/MaxSlope.java b/core/src/main/java/com/graphhopper/routing/ev/MaxSlope.java index bbb64e343e9..26282b45704 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/MaxSlope.java +++ b/core/src/main/java/com/graphhopper/routing/ev/MaxSlope.java @@ -7,6 +7,6 @@ public class MaxSlope { public static final String KEY = "max_slope"; public static DecimalEncodedValue create() { - return new DecimalEncodedValueImpl(KEY, 5, 1, false, false); + return new DecimalEncodedValueImpl(KEY, 5, 1, false); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/MaxSpeed.java b/core/src/main/java/com/graphhopper/routing/ev/MaxSpeed.java index ec2e970385e..f0343e412ac 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/MaxSpeed.java +++ b/core/src/main/java/com/graphhopper/routing/ev/MaxSpeed.java @@ -35,6 +35,6 @@ public class MaxSpeed { public static final double UNSET_SPEED = Double.POSITIVE_INFINITY; public static DecimalEncodedValue create() { - return new DecimalEncodedValueImpl(KEY, 5, 5, true, true); + return new DecimalEncodedValueImpl(KEY, 5, 0, 5, false, true, true); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/MaxWeight.java b/core/src/main/java/com/graphhopper/routing/ev/MaxWeight.java index 9a77e191e20..5f0cca0a205 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/MaxWeight.java +++ b/core/src/main/java/com/graphhopper/routing/ev/MaxWeight.java @@ -33,6 +33,6 @@ public class MaxWeight { * it was done with the MappedDecimalEncodedValue still handling (or rounding) of unknown values is unclear. */ public static DecimalEncodedValue create() { - return new DecimalEncodedValueImpl(KEY, 8, 0.1, true, false); + return new DecimalEncodedValueImpl(KEY, 8, 0, 0.1, false, false, true); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/MaxWidth.java b/core/src/main/java/com/graphhopper/routing/ev/MaxWidth.java index 172c94a2829..a7a16d86256 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/MaxWidth.java +++ b/core/src/main/java/com/graphhopper/routing/ev/MaxWidth.java @@ -32,6 +32,6 @@ public class MaxWidth { * it is assumed to use the maximum value. */ public static DecimalEncodedValue create() { - return new DecimalEncodedValueImpl(KEY, 7, 0.1, true, false); + return new DecimalEncodedValueImpl(KEY, 7, 0, 0.1, false, false, true); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/TurnCost.java b/core/src/main/java/com/graphhopper/routing/ev/TurnCost.java index e480f2624b7..49df15bd817 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/TurnCost.java +++ b/core/src/main/java/com/graphhopper/routing/ev/TurnCost.java @@ -16,7 +16,7 @@ public static String key(String prefix) { */ public static DecimalEncodedValue create(String name, int maxTurnCosts) { int turnBits = Helper.countBitValue(maxTurnCosts); - return new DecimalEncodedValueImpl(key(name), turnBits, 0, 1, false, false, false, true); + return new DecimalEncodedValueImpl(key(name), turnBits, 0, 1, false, false, true); } public static IntsRef createFlags() { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java b/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java index 325dd5ba0e1..2067852c7c0 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java @@ -6,6 +6,8 @@ import com.graphhopper.storage.IntsRef; import com.graphhopper.util.DistanceCalcEarth; import com.graphhopper.util.Helper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; import java.util.regex.Pattern; @@ -21,6 +23,7 @@ public class OSMValueExtractor { private static final Pattern INCH_PATTERN = Pattern.compile("\"|\'\'"); private static final Pattern FEET_PATTERN = Pattern.compile("\'|feet"); private static final Pattern APPROX_PATTERN = Pattern.compile("~|approx"); + private static final Logger logger = LoggerFactory.getLogger(OSMValueExtractor.class); private OSMValueExtractor() { // utility class @@ -30,13 +33,11 @@ public static void extractTons(IntsRef edgeFlags, ReaderWay way, DecimalEncodedV final String rawValue = way.getFirstPriorityTag(keys); double value = stringToTons(rawValue); - if (Double.isNaN(value)) { - return; - } + if (Double.isNaN(value)) value = Double.POSITIVE_INFINITY; - if (value > valueEncoder.getMaxStorableDecimal()) - value = valueEncoder.getMaxStorableDecimal(); valueEncoder.setDecimal(false, edgeFlags, value); + if (value - valueEncoder.getDecimal(false, edgeFlags) > 2) + logger.warn("Value " + value + " for " + valueEncoder.getName() + " was too large and truncated to " + valueEncoder.getDecimal(false, edgeFlags)); } public static double stringToTons(String value) { @@ -70,13 +71,11 @@ public static void extractMeter(IntsRef edgeFlags, ReaderWay way, DecimalEncoded final String rawValue = way.getFirstPriorityTag(keys); double value = stringToMeter(rawValue); - if (Double.isNaN(value)) { - return; - } + if (Double.isNaN(value)) value = Double.POSITIVE_INFINITY; - if (value > valueEncoder.getMaxStorableDecimal()) - value = valueEncoder.getMaxStorableDecimal(); valueEncoder.setDecimal(false, edgeFlags, value); + if (value - valueEncoder.getDecimal(false, edgeFlags) > 2) + logger.warn("Value " + value + " for " + valueEncoder.getName() + " was too large and truncated to " + valueEncoder.getDecimal(false, edgeFlags)); } public static double stringToMeter(String value) { @@ -124,7 +123,7 @@ public static double stringToMeter(String value) { if (value.isEmpty()) { return offset; } - + try { return Double.parseDouble(value) * factor + offset; } catch (NumberFormatException e) { @@ -149,20 +148,20 @@ public static boolean isInvalidValue(String value) { public static double stringToKmh(String str) { if (Helper.isEmpty(str)) return Double.NaN; - + // on some German autobahns and a very few other places if ("none".equals(str)) return MaxSpeed.UNLIMITED_SIGN_SPEED; - + if (str.endsWith(":rural") || str.endsWith(":trunk")) return 80; - + if (str.endsWith(":urban")) return 50; - + if (str.equals("walk") || str.endsWith(":living_street")) return 6; - + int mpInteger = str.indexOf("mp"); int knotInteger = str.indexOf("knots"); int kmInteger = str.indexOf("km"); @@ -183,18 +182,18 @@ public static double stringToKmh(String str) { } factor = 1; } - + double value; try { value = Integer.parseInt(str) * factor; } catch (Exception ex) { return Double.NaN; } - + if (value <= 0) { return Double.NaN; } - + return value; } } \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java index 869e1cc58c3..1ecf8ad7924 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java @@ -11,7 +11,7 @@ public class DecimalEncodedValueImplTest { @Test public void getDecimal() { - DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, 1, false, false); + DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, 1, false); testEnc.init(new EncodedValue.InitializerConfig()); IntsRef intsRef = new IntsRef(1); @@ -21,36 +21,33 @@ public void getDecimal() { assertEquals(7, testEnc.getDecimal(false, intsRef), .1); } - @Test - public void testInfinityDefault() { - IntsRef intsRef = new IntsRef(1); - DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, 1, true, false); - testEnc.init(new EncodedValue.InitializerConfig()); - assertTrue(Double.isInfinite(testEnc.getDecimal(false, intsRef))); - - // set the default which maps to infinity (see discussion in #2473) - testEnc.setDecimal(false, intsRef, 0); - assertTrue(Double.isInfinite(testEnc.getDecimal(false, intsRef))); - - assertTrue(Double.MAX_VALUE < testEnc.getDecimal(false, intsRef)); - testEnc.setDecimal(false, intsRef, Double.POSITIVE_INFINITY); - assertTrue(Double.isInfinite(testEnc.getDecimal(false, intsRef))); - } - @Test public void setMaxToInfinity() { - DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, 0, 1, false, false, false, true); + DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, 0, 1, false, false, true); testEnc.init(new EncodedValue.InitializerConfig()); IntsRef intsRef = new IntsRef(1); assertEquals(0, testEnc.getDecimal(false, intsRef), .1); + assertTrue(Double.isInfinite(testEnc.getMaxOrMaxStorableDecimal())); + assertTrue(Double.isInfinite(testEnc.getMaxStorableDecimal())); + assertTrue(Double.isInfinite(testEnc.getNextStorableValue(7))); + assertEquals(6, testEnc.getNextStorableValue(6)); + + testEnc.setDecimal(false, intsRef, 5); + assertEquals(5, testEnc.getDecimal(false, intsRef), .1); + + assertEquals(5, testEnc.getMaxOrMaxStorableDecimal()); + assertTrue(Double.isInfinite(testEnc.getMaxStorableDecimal())); + testEnc.setDecimal(false, intsRef, Double.POSITIVE_INFINITY); assertEquals(Double.POSITIVE_INFINITY, testEnc.getDecimal(false, intsRef), .1); + assertTrue(Double.isInfinite(testEnc.getMaxOrMaxStorableDecimal())); + assertTrue(Double.isInfinite(testEnc.getMaxStorableDecimal())); } @Test public void testNegative() { - DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, -6, 0.1, false, false, false, true); + DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, -6, 0.1, false, false, true); testEnc.init(new EncodedValue.InitializerConfig()); IntsRef intsRef = new IntsRef(1); // a bit ugly: the default is the minimum not 0 @@ -61,14 +58,14 @@ public void testNegative() { assertEquals(-5.5, testEnc.getDecimal(true, intsRef), .1); Exception e = assertThrows(IllegalArgumentException.class, () -> { - new DecimalEncodedValueImpl("test", 3, -6, 0.11, false, false, false, true); + new DecimalEncodedValueImpl("test", 3, -6, 0.11, false, false, true); }); assertTrue(e.getMessage().contains("minStorableValue -6.0 is not a multiple of the specified factor"), e.getMessage()); } @Test public void testInfinityWithMinValue() { - DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, -6, 0.1, false, false, false, true); + DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 3, -6, 0.1, false, false, true); testEnc.init(new EncodedValue.InitializerConfig()); IntsRef intsRef = new IntsRef(1); testEnc.setDecimal(false, intsRef, Double.POSITIVE_INFINITY); @@ -77,7 +74,7 @@ public void testInfinityWithMinValue() { @Test public void testNegateReverse() { - DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 4, 0, 0.5, false, true, false, false); + DecimalEncodedValueImpl testEnc = new DecimalEncodedValueImpl("test", 4, 0, 0.5, true, false, false); testEnc.init(new EncodedValue.InitializerConfig()); IntsRef intsRef = new IntsRef(1); testEnc.setDecimal(false, intsRef, 5.5); @@ -85,9 +82,8 @@ public void testNegateReverse() { assertEquals(-5.5, testEnc.getDecimal(true, intsRef), .1); EncodedValue.InitializerConfig config = new EncodedValue.InitializerConfig(); - new DecimalEncodedValueImpl("tmp1", 5, 1, false, false).init(config); - testEnc = new DecimalEncodedValueImpl("tmp2", 5, 0, 1, false, - true, false, false); + new DecimalEncodedValueImpl("tmp1", 5, 1, false).init(config); + testEnc = new DecimalEncodedValueImpl("tmp2", 5, 0, 1, true, false, false); testEnc.init(config); intsRef = new IntsRef(1); testEnc.setDecimal(false, intsRef, 2.6); @@ -143,7 +139,7 @@ public void smallestNonZeroValue() { assertSmallestNonZeroValue(new DecimalEncodedValueImpl("test", 5, 0.1, true), 0.1); assertTrue(assertThrows(IllegalStateException.class, - () -> new DecimalEncodedValueImpl("test", 5, 0, 5, false, true, false, false).getSmallestNonZeroValue()) + () -> new DecimalEncodedValueImpl("test", 5, 0, 5, true, false, false).getSmallestNonZeroValue()) .getMessage().contains("getting the smallest non-zero value is not possible")); } @@ -159,23 +155,25 @@ private void assertSmallestNonZeroValue(DecimalEncodedValueImpl enc, double expe @Test public void testNextStorableValue_maxInfinity() { - DecimalEncodedValueImpl enc = new DecimalEncodedValueImpl("test", 4, 0, 3, false, false, false, true); + DecimalEncodedValueImpl enc = new DecimalEncodedValueImpl("test", 4, 0, 3, false, false, true); enc.init(new EncodedValue.InitializerConfig()); assertEquals(12, enc.getNextStorableValue(11.2)); - assertEquals(45, enc.getNextStorableValue(44.3)); - assertEquals(45, enc.getNextStorableValue(45)); + assertEquals(42, enc.getNextStorableValue(41.3)); + assertEquals(42, enc.getNextStorableValue(42)); + assertEquals(Double.POSITIVE_INFINITY, enc.getNextStorableValue(42.1)); + assertEquals(Double.POSITIVE_INFINITY, enc.getNextStorableValue(45)); assertEquals(Double.POSITIVE_INFINITY, enc.getNextStorableValue(45.1)); - assertEquals(Double.POSITIVE_INFINITY, enc.getNextStorableValue(48)); - assertEquals(Double.POSITIVE_INFINITY, enc.getNextStorableValue(48.1)); IntsRef intsRef = new IntsRef(1); - assertThrows(IllegalArgumentException.class, () -> enc.setDecimal(false, intsRef, 48)); + enc.setDecimal(false, intsRef, 45); + assertEquals(42, enc.getDecimal(false, intsRef)); + enc.setDecimal(false, intsRef, Double.POSITIVE_INFINITY); assertEquals(Double.POSITIVE_INFINITY, enc.getDecimal(false, intsRef)); } @Test public void lowestUpperBound_with_negateReverseDirection() { - DecimalEncodedValueImpl enc = new DecimalEncodedValueImpl("test", 4, 0, 3, false, true, false, false); + DecimalEncodedValueImpl enc = new DecimalEncodedValueImpl("test", 4, 0, 3, true, false, false); enc.init(new EncodedValue.InitializerConfig()); assertEquals(15 * 3, enc.getMaxOrMaxStorableDecimal()); IntsRef ints = new IntsRef(1); diff --git a/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java b/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java index d2c2b485ced..31d457efd8f 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/EncodedValueSerializerTest.java @@ -78,7 +78,7 @@ void explicitString() { assertEquals("{\"className\":\"com.graphhopper.routing.ev.DecimalEncodedValueImpl\",\"name\":\"max_width\",\"bits\":7," + "\"min_storable_value\":0,\"max_storable_value\":127,\"max_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false," + "\"fwd_data_index\":0,\"bwd_data_index\":0,\"fwd_shift\":3,\"bwd_shift\":-1,\"fwd_mask\":1016,\"bwd_mask\":0," + - "\"factor\":0.1,\"default_is_infinity\":true,\"use_maximum_as_infinity\":false}", serialized.get(1)); + "\"factor\":0.1,\"use_maximum_as_infinity\":true}", serialized.get(1)); assertEquals("{\"className\":\"com.graphhopper.routing.ev.SimpleBooleanEncodedValue\",\"name\":\"get_off_bike\",\"bits\":1," + "\"min_storable_value\":0,\"max_storable_value\":1,\"max_value\":-2147483648,\"negate_reverse_direction\":false,\"store_two_directions\":false,\"fwd_data_index\":0," + "\"bwd_data_index\":0,\"fwd_shift\":10,\"bwd_shift\":-1,\"fwd_mask\":1024,\"bwd_mask\":0}", serialized.get(2)); diff --git a/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java b/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java index 538901fd031..793cc1b45bd 100644 --- a/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java +++ b/core/src/test/java/com/graphhopper/routing/subnetwork/PrepareRoutingSubnetworksTest.java @@ -169,17 +169,15 @@ public void testPrepareSubnetwork_withTurnCosts() { g = createSubnetworkTestStorage(em, accessEnc, speedEnc, null, null); edge = GHUtility.getEdge(g, 3, 4); GHUtility.setSpeed(10, true, true, accessEnc, speedEnc, edge); - g.getTurnCostStorage().set(turnCostEnc, 0, 4, 7, 1); - g.getTurnCostStorage().set(turnCostEnc, 0, 4, 9, 1); + g.getTurnCostStorage().set(turnCostEnc, 0, 4, 7, Double.POSITIVE_INFINITY); + g.getTurnCostStorage().set(turnCostEnc, 0, 4, 9, Double.POSITIVE_INFINITY); instance = new PrepareRoutingSubnetworks(g, Collections.singletonList( createJob(subnetworkEnc, accessEnc, speedEnc, new DefaultTurnCostProvider(turnCostEnc, g.getTurnCostStorage(), 0)))); instance.setMinNetworkSize(4); assertEquals(3, instance.doWork()); assertEquals(IntArrayList.from(7, 8, 9), getSubnetworkEdges(g, subnetworkEnc)); - } - private BaseGraph createSubnetworkTestStorageWithOneWays(EncodingManager em, BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc) { BaseGraph g = new BaseGraph.Builder(em).create(); // 0 - 1 - 2 - 3 - 4 <- 5 - 6 diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java index 380345e5a28..4bff4038e10 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxAxleLoadParserTest.java @@ -35,7 +35,7 @@ public void testSimpleTags() { intsRef = new IntsRef(1); readerWay.setTag("maxaxleload", "80"); parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(malEnc.getMaxStorableDecimal(), malEnc.getDecimal(false, intsRef), .01); + assertEquals(63.0, malEnc.getDecimal(false, intsRef), .01); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java index 759f73aa3e4..1d3d29ad0a5 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMMaxWeightParserTest.java @@ -36,6 +36,6 @@ public void testSimpleTags() { intsRef = new IntsRef(1); readerWay.setTag("maxweight", "50"); parser.handleWayTags(intsRef, readerWay, relFlags); - assertEquals(mwEnc.getMaxStorableDecimal(), mwEnc.getDecimal(false, intsRef), .01); + assertEquals(25.4, mwEnc.getDecimal(false, intsRef), .01); } } \ No newline at end of file From 5dfff5b68d27c81e6466edd12b8f811abaee2d9c Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 18 Aug 2022 11:52:54 +0200 Subject: [PATCH 131/389] NOTICE: updated dependencies and copyright --- NOTICE.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/NOTICE.md b/NOTICE.md index c3689edbf7c..eabb54fb772 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -2,9 +2,9 @@ GraphHopper licensed under the Apache license, Version 2.0 -Copyright 2012 - 2021 GraphHopper GmbH +Copyright 2012 - 2022 GraphHopper GmbH -The core module includes the following software: +The core module includes the following additional software: * slf4j.org - SLF4J distributed under the MIT license. * com.carrotsearch:hppc (Apache license) @@ -14,32 +14,36 @@ The core module includes the following software: * Apache Commons Lang - we copied the implementation of the Levenshtein Distance (Apache License) * Apache Commons Collections - we copied parts of the BinaryHeap (Apache License) * java-string-similarity - we copied the implementation of JaroWinkler (MIT license) - * com.fasterxml.jackson.core:jackson-annotations (Apache License) + * Jackson (Apache License) * org.locationtech:jts (EDL), see #1039 * AngleCalc.atan2 from Jim Shima, 1999 (public domain) - * list of Java keywords in EncodingManager from janino compiler (BSD-3-Clause license) + * janino compiler (BSD-3-Clause license) * protobuf - New BSD license * OSM-binary - LGPL license - * Osmosis - public domain, see osmosis-copying.txt under core/files + * Osmosis - public domain, see their github under package/copying.txt reader-gtfs: * some files from com.conveyal:gtfs-lib (BSD 2-clause license) * com.google.transit:gtfs-realtime-bindings (Apache license) - -reader-shp: - - * org.geotools:gt-shapefile (LGPL) + * com.google.guava:guava (Apache license) + * net.sourceforge.javacsv:javacsv (LGPL license) + * commons-io:commons-io (Apache license) + * org.mapdb:mapdb (Apache license) tools: * uses Apache Compress (Apache license) +client-hc: + + * okhttp (Apache license) + web: * org.eclipse.jetty:jetty-server (Apache License) - * com.fasterxml.jackson.core:jackson-databind (Apache license) - * com.google.inject (Apache license) + * Dropwizard and dependencies (Apache license) + * com.wdtinc:mapbox-vector-tile (Apache license) * some images from mapbox https://www.mapbox.com/maki/, BSD License, see core/files ## Data From cf2069667c4a84ccc1a109c98d2786820a0fe718 Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 20 Aug 2022 11:20:51 +0200 Subject: [PATCH 132/389] make ramer edge smoothing more robust, #2634 --- .../reader/dem/EdgeElevationSmoothing.java | 9 ++++----- .../reader/dem/EdgeElevationSmoothingTest.java | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/dem/EdgeElevationSmoothing.java b/core/src/main/java/com/graphhopper/reader/dem/EdgeElevationSmoothing.java index 276e27d189b..924402126a6 100644 --- a/core/src/main/java/com/graphhopper/reader/dem/EdgeElevationSmoothing.java +++ b/core/src/main/java/com/graphhopper/reader/dem/EdgeElevationSmoothing.java @@ -80,7 +80,9 @@ static void internSmoothRamer(PointList pointList, int fromIndex, int lastIndex, double prevLat = pointList.getLat(fromIndex); double prevLon = pointList.getLon(fromIndex); double dist2D = DistanceCalcEarth.DIST_EARTH.calcDist(prevLat, prevLon, pointList.getLat(lastIndex), pointList.getLon(lastIndex)); - double averageSlope = (pointList.getEle(lastIndex) - pointList.getEle(fromIndex)) / dist2D; + + // in rare cases the first point can be identical to the last for e.g. areas (or for things like man_made=pier which are not explicitly excluded from adding edges) + double averageSlope = dist2D == 0 ? 0 : (pointList.getEle(lastIndex) - pointList.getEle(fromIndex)) / dist2D; double prevAverageSlopeEle = pointList.getEle(fromIndex); double maxEleDelta = -1; int indexWithMaxDelta = -1; @@ -100,12 +102,9 @@ static void internSmoothRamer(PointList pointList, int fromIndex, int lastIndex, prevLon = lon; } - if (indexWithMaxDelta < 0) - throw new IllegalStateException("maximum not found in [" + fromIndex + "," + lastIndex + "] " + pointList); - // the maximum elevation change limit filters away especially the smaller high frequent elevation changes, // which is likely the "noise" that we want to remove. - if (maxElevationDelta > maxEleDelta) { + if (indexWithMaxDelta < 0 || maxElevationDelta > maxEleDelta) { prevLat = pointList.getLat(fromIndex); prevLon = pointList.getLon(fromIndex); prevAverageSlopeEle = pointList.getEle(fromIndex); diff --git a/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationSmoothingTest.java b/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationSmoothingTest.java index 7593ddf6d15..69d8a03379c 100644 --- a/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationSmoothingTest.java +++ b/core/src/test/java/com/graphhopper/reader/dem/EdgeElevationSmoothingTest.java @@ -54,7 +54,7 @@ public void interpolatesElevationOfPillarNodes() { } @Test - public void interpolateViaDouglasPeucker() { + public void smoothRamer() { PointList pl1 = new PointList(3, true); pl1.add(0, 0, 0); pl1.add(0.0005, 0.0005, 100); @@ -68,7 +68,7 @@ public void interpolateViaDouglasPeucker() { } @Test - public void interpolateViaDouglasPeucker2() { + public void smoothRamer2() { PointList pl2 = new PointList(3, true); pl2.add(0.001, 0.001, 50); pl2.add(0.0015, 0.0015, 160); @@ -81,4 +81,17 @@ public void interpolateViaDouglasPeucker2() { assertEquals(210, pl2.getEle(2), 1); // modify as too small in interval [0,4] assertEquals(220, pl2.getEle(3), .1); // keep as it is bigger than maxElevationDelta in interval [0,4] } + + @Test + public void smoothRamerNoMaximumFound() { + PointList pl2 = new PointList(3, true); + pl2.add(60.03307, 20.82262, 5.35); + pl2.add(60.03309, 20.82269, 5.42); + pl2.add(60.03307, 20.82262, 5.35); + EdgeElevationSmoothing.smoothRamer(pl2, 10); + assertEquals(3, pl2.size()); + assertEquals(5.35, pl2.getEle(0), 0.01); + assertEquals(5.35, pl2.getEle(1), 0.01); + assertEquals(5.35, pl2.getEle(2), 0.01); + } } From 0c7c7a57fc00e873ebe99c2766f55f98949cb145 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 22 Aug 2022 15:17:46 +0200 Subject: [PATCH 133/389] TurnCostParser: no need for method createTurnCostEncodedValues --- .../routing/util/parsers/OSMTurnRelationParser.java | 5 ----- .../com/graphhopper/routing/util/parsers/TurnCostParser.java | 2 -- 2 files changed, 7 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java index 9ad3418d6a9..d42496acdf0 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java @@ -47,11 +47,6 @@ public OSMTurnRelationParser(BooleanEncodedValue accessEnc, DecimalEncodedValue this.restrictions = restrictions; } - @Override - public void createTurnCostEncodedValues(EncodedValueLookup lookup, List registerNewEncodedValue) { - registerNewEncodedValue.add(turnCostEnc); - } - @Override public void handleTurnRelationTags(OSMTurnRelation turnRelation, ExternalInternalMap map, Graph graph) { if (!turnRelation.isVehicleTypeConcernedByTurnRestriction(restrictions)) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java index cd9e4035f1b..42102b792e0 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java @@ -31,8 +31,6 @@ public interface TurnCostParser { String getName(); - void createTurnCostEncodedValues(EncodedValueLookup lookup, List registerNewEncodedValue); - void handleTurnRelationTags(OSMTurnRelation turnRelation, ExternalInternalMap map, Graph graph); /** From f150cc20abbf43d0ff4511856169ea2f83af82a3 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 22 Aug 2022 21:31:03 +0200 Subject: [PATCH 134/389] improvements for bike (#2631) * lower speed for bad smoothness and steps; avoid hazmat; faster if paving_stones * clean up of smoothness handling * revert to 4kmh pushing section speed and tweak speed for certain surfaces * mtb+racing: do not overwrite highway and surface speed if identical in subclass --- .../routing/util/Bike2WeightTagParser.java | 4 +- .../routing/util/BikeCommonTagParser.java | 64 ++++++++++--------- .../routing/util/BikeTagParser.java | 10 --- .../routing/util/MountainBikeTagParser.java | 41 ++---------- .../routing/util/RacingBikeTagParser.java | 52 ++++++--------- .../java/com/graphhopper/GraphHopperTest.java | 22 +++---- .../routing/RoutingAlgorithmWithOSMTest.java | 5 +- .../util/AbstractBikeTagParserTester.java | 4 +- .../routing/util/BikeTagParserTest.java | 24 ++++--- .../util/MountainBikeTagParserTest.java | 11 ++-- .../routing/util/RacingBikeTagParserTest.java | 27 ++++---- .../routing/util/TagParsingTest.java | 2 +- 12 files changed, 112 insertions(+), 154 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java b/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java index 6bc34b1f49e..8797bf1ac6d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java @@ -105,7 +105,7 @@ public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { double fwdSlower = 1 - 5 * keepIn(fwdIncline, 0, 0.2); fwdSlower = fwdSlower * fwdSlower; speed = speed * (fwdSlower * incDist2DSum + fwdFaster * decDist2DSum + 1 * restDist2D) / fullDist2D; - setSpeed(false, intsRef, keepIn(speed, PUSHING_SECTION_SPEED / 2.0, maxSpeed)); + setSpeed(false, intsRef, keepIn(speed, MIN_SPEED, maxSpeed)); } if (accessEnc.getBool(true, intsRef)) { @@ -115,7 +115,7 @@ public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { double bwSlower = 1 - 5 * keepIn(fwdDecline, 0, 0.2); bwSlower = bwSlower * bwSlower; speedReverse = speedReverse * (bwFaster * incDist2DSum + bwSlower * decDist2DSum + 1 * restDist2D) / fullDist2D; - setSpeed(true, intsRef, keepIn(speedReverse, PUSHING_SECTION_SPEED / 2.0, maxSpeed)); + setSpeed(true, intsRef, keepIn(speedReverse, MIN_SPEED, maxSpeed)); } edge.setFlags(intsRef); } diff --git a/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java b/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java index 68347599f12..bf82f5fcd48 100644 --- a/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/BikeCommonTagParser.java @@ -36,9 +36,9 @@ */ abstract public class BikeCommonTagParser extends VehicleTagParser { - public static double BIKE_MAX_SPEED = 30; - + public static double MAX_SPEED = 30; protected static final int PUSHING_SECTION_SPEED = 4; + protected static final int MIN_SPEED = 2; // Pushing section highways are parts where you need to get off your bike and push it (German: Schiebestrecke) protected final HashSet pushingSectionsHighways = new HashSet<>(); protected final HashSet oppositeLanes = new HashSet<>(); @@ -47,7 +47,6 @@ abstract public class BikeCommonTagParser extends VehicleTagParser { protected final Set unpavedSurfaceTags = new HashSet<>(); private final Map trackTypeSpeeds = new HashMap<>(); private final Map surfaceSpeeds = new HashMap<>(); - protected static final double smoothnessFactorPushingSectionThreshold = 0.3d; private final Map smoothnessFactor = new HashMap<>(); private final Map highwaySpeeds = new HashMap<>(); protected final DecimalEncodedValue priorityEnc; @@ -63,7 +62,7 @@ abstract public class BikeCommonTagParser extends VehicleTagParser { protected BikeCommonTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, EnumEncodedValue bikeRouteEnc, EnumEncodedValue smoothnessEnc, String name, BooleanEncodedValue roundaboutEnc, DecimalEncodedValue turnCostEnc) { - super(accessEnc, speedEnc, name, roundaboutEnc, turnCostEnc, TransportationMode.BIKE, speedEnc.getNextStorableValue(BIKE_MAX_SPEED)); + super(accessEnc, speedEnc, name, roundaboutEnc, turnCostEnc, TransportationMode.BIKE, speedEnc.getNextStorableValue(MAX_SPEED)); this.bikeRouteEnc = bikeRouteEnc; this.smoothnessEnc = smoothnessEnc; this.priorityEnc = priorityEnc; @@ -117,10 +116,10 @@ protected BikeCommonTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue setSurfaceSpeed("concrete", 18); setSurfaceSpeed("concrete:lanes", 16); setSurfaceSpeed("concrete:plates", 16); - setSurfaceSpeed("paving_stones", 12); - setSurfaceSpeed("paving_stones:30", 12); - setSurfaceSpeed("unpaved", 14); - setSurfaceSpeed("compacted", 16); + setSurfaceSpeed("paving_stones", 14); + setSurfaceSpeed("paving_stones:30", 14); + setSurfaceSpeed("unpaved", 12); + setSurfaceSpeed("compacted", 14); setSurfaceSpeed("dirt", 10); setSurfaceSpeed("earth", 12); setSurfaceSpeed("fine_gravel", 18); @@ -128,24 +127,24 @@ protected BikeCommonTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue setSurfaceSpeed("grass_paver", 8); setSurfaceSpeed("gravel", 12); setSurfaceSpeed("ground", 12); - setSurfaceSpeed("ice", PUSHING_SECTION_SPEED / 2); + setSurfaceSpeed("ice", MIN_SPEED); setSurfaceSpeed("metal", 10); setSurfaceSpeed("mud", 10); - setSurfaceSpeed("pebblestone", 16); - setSurfaceSpeed("salt", 6); - setSurfaceSpeed("sand", 6); - setSurfaceSpeed("wood", 6); + setSurfaceSpeed("pebblestone", 14); + setSurfaceSpeed("salt", PUSHING_SECTION_SPEED); + setSurfaceSpeed("sand", PUSHING_SECTION_SPEED); + setSurfaceSpeed("wood", PUSHING_SECTION_SPEED); - setHighwaySpeed("living_street", 6); - setHighwaySpeed("steps", PUSHING_SECTION_SPEED / 2); + setHighwaySpeed("living_street", PUSHING_SECTION_SPEED); + setHighwaySpeed("steps", MIN_SPEED); avoidHighwayTags.add("steps"); final int CYCLEWAY_SPEED = 18; // Make sure cycleway and path use same speed value, see #634 setHighwaySpeed("cycleway", CYCLEWAY_SPEED); setHighwaySpeed("path", 10); setHighwaySpeed("footway", 6); - setHighwaySpeed("platform", 6); - setHighwaySpeed("pedestrian", 6); + setHighwaySpeed("platform", PUSHING_SECTION_SPEED); + setHighwaySpeed("pedestrian", PUSHING_SECTION_SPEED); setHighwaySpeed("track", 12); setHighwaySpeed("service", 14); setHighwaySpeed("residential", 18); @@ -169,7 +168,7 @@ protected BikeCommonTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue avoidHighwayTags.add("motorway"); avoidHighwayTags.add("motorway_link"); - setHighwaySpeed("bridleway", 6); + setHighwaySpeed("bridleway", PUSHING_SECTION_SPEED); avoidHighwayTags.add("bridleway"); routeMap.put(INTERNATIONAL, BEST.getValue()); @@ -177,8 +176,17 @@ protected BikeCommonTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue routeMap.put(REGIONAL, VERY_NICE.getValue()); routeMap.put(LOCAL, PREFER.getValue()); + // note that this factor reduces the speed but only until MIN_SPEED setSmoothnessSpeedFactor(Smoothness.MISSING, 1.0d); setSmoothnessSpeedFactor(Smoothness.OTHER, 0.7d); + setSmoothnessSpeedFactor(Smoothness.EXCELLENT, 1.1d); + setSmoothnessSpeedFactor(Smoothness.GOOD, 1.0d); + setSmoothnessSpeedFactor(Smoothness.INTERMEDIATE, 0.9d); + setSmoothnessSpeedFactor(Smoothness.BAD, 0.7d); + setSmoothnessSpeedFactor(Smoothness.VERY_BAD, 0.4d); + setSmoothnessSpeedFactor(Smoothness.HORRIBLE, 0.3d); + setSmoothnessSpeedFactor(Smoothness.VERY_HORRIBLE, 0.1d); + setSmoothnessSpeedFactor(Smoothness.IMPASSABLE, 0); setAvoidSpeedLimit(71); } @@ -280,12 +288,8 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { if (!access.isFerry()) { wayTypeSpeed = applyMaxSpeed(way, wayTypeSpeed); Smoothness smoothness = smoothnessEnc.getEnum(false, edgeFlags); - if (smoothness != Smoothness.MISSING) { - // smoothness handling: Multiply speed with smoothnessFactor - double smoothnessSpeedFactor = smoothnessFactor.get(smoothness); - wayTypeSpeed = (smoothnessSpeedFactor <= smoothnessFactorPushingSectionThreshold) ? - PUSHING_SECTION_SPEED : Math.round(smoothnessSpeedFactor * wayTypeSpeed); - } + wayTypeSpeed = Math.max(MIN_SPEED, smoothnessFactor.get(smoothness) * wayTypeSpeed); + avgSpeedEnc.setDecimal(false, edgeFlags, wayTypeSpeed); if (avgSpeedEnc.isStoreTwoDirections()) avgSpeedEnc.setDecimal(true, edgeFlags, wayTypeSpeed); @@ -349,7 +353,7 @@ int getSpeed(ReaderWay way) { && (way.hasTag("highway", pushingSectionsHighways) || way.hasTag("bicycle", "dismount"))) { if (!way.hasTag("bicycle", intendedValues)) { // Here we set the speed for pushing sections and set speed for steps as even lower: - speed = way.hasTag("highway", "steps") ? PUSHING_SECTION_SPEED / 2 : PUSHING_SECTION_SPEED; + speed = way.hasTag("highway", "steps") ? MIN_SPEED : PUSHING_SECTION_SPEED; } else if (way.hasTag("bicycle", "designated") || way.hasTag("bicycle", "official") || way.hasTag("segregated", "yes") || way.hasTag("bicycle", "yes")) { // Here we handle the cases where the OSM tagging results in something similar to "highway=cycleway" @@ -358,9 +362,9 @@ int getSpeed(ReaderWay way) { else speed = way.hasTag("bicycle", "yes") ? 10 : highwaySpeeds.get("cycleway"); - // overwrite our speed again in case we have a valid surface speed and if it is smaller as computed so far - if ((surfaceSpeed > 0) && (surfaceSpeed < speed)) - speed = surfaceSpeed; + // valid surface speed? + if (surfaceSpeed > 0) + speed = Math.min(speed, surfaceSpeed); } } return speed; @@ -445,8 +449,8 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap weight } else if (avoidHighwayTags.contains(highway) || isValidSpeed(maxSpeed) && maxSpeed >= avoidSpeedLimit && !"track".equals(highway)) { weightToPrioMap.put(50d, AVOID.getValue()); - if (way.hasTag("tunnel", intendedValues)) - weightToPrioMap.put(50d, AVOID_MORE.getValue()); + if (way.hasTag("tunnel", intendedValues) || way.hasTag("hazmat", intendedValues)) + weightToPrioMap.put(50d, BAD.getValue()); } String cycleway = way.getFirstPriorityTag(Arrays.asList("cycleway", "cycleway:left", "cycleway:right")); diff --git a/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java index accd01b3c85..05fcf491c2c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/BikeTagParser.java @@ -69,16 +69,6 @@ public BikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc preferHighwayTags.add("residential"); preferHighwayTags.add("unclassified"); - setSmoothnessSpeedFactor(EXCELLENT, 1.1d); - setSmoothnessSpeedFactor(GOOD, 1.0d); - setSmoothnessSpeedFactor(INTERMEDIATE, 0.9d); - setSmoothnessSpeedFactor(BAD, 0.7d); - setSmoothnessSpeedFactor(VERY_BAD, 0.6d); - setSmoothnessSpeedFactor(HORRIBLE, 0.5d); - setSmoothnessSpeedFactor(VERY_HORRIBLE, 0.4d); - // SmoothnessSpeed <= smoothnessFactorPushingSectionThreshold gets mapped to speed PUSHING_SECTION_SPEED - setSmoothnessSpeedFactor(IMPASSABLE, smoothnessFactorPushingSectionThreshold); - barriers.add("kissing_gate"); barriers.add("stile"); barriers.add("turnstile"); diff --git a/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java index 467d64a658d..ef38bec1c33 100644 --- a/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/MountainBikeTagParser.java @@ -60,18 +60,9 @@ protected MountainBikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedVal setTrackTypeSpeed("grade4", 8); setTrackTypeSpeed("grade5", 6); // like sand/grass - setSurfaceSpeed("paved", 18); - setSurfaceSpeed("asphalt", 18); - setSurfaceSpeed("cobblestone", 10); - setSurfaceSpeed("cobblestone:flattened", 10); - setSurfaceSpeed("sett", 10); setSurfaceSpeed("concrete", 14); setSurfaceSpeed("concrete:lanes", 16); setSurfaceSpeed("concrete:plates", 16); - setSurfaceSpeed("paving_stones", 16); - setSurfaceSpeed("paving_stones:30", 16); - setSurfaceSpeed("unpaved", 14); - setSurfaceSpeed("compacted", 14); setSurfaceSpeed("dirt", 14); setSurfaceSpeed("earth", 14); setSurfaceSpeed("fine_gravel", 18); @@ -79,36 +70,22 @@ protected MountainBikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedVal setSurfaceSpeed("grass_paver", 14); setSurfaceSpeed("gravel", 16); setSurfaceSpeed("ground", 16); - setSurfaceSpeed("ice", PUSHING_SECTION_SPEED / 2); + setSurfaceSpeed("ice", MIN_SPEED); setSurfaceSpeed("metal", 10); setSurfaceSpeed("mud", 12); - setSurfaceSpeed("pebblestone", 12); setSurfaceSpeed("salt", 12); setSurfaceSpeed("sand", 10); setSurfaceSpeed("wood", 10); - setHighwaySpeed("living_street", 6); + setHighwaySpeed("living_street", PUSHING_SECTION_SPEED); setHighwaySpeed("steps", PUSHING_SECTION_SPEED); - setHighwaySpeed("cycleway", 18); setHighwaySpeed("path", 18); - setHighwaySpeed("footway", 6); - setHighwaySpeed("pedestrian", 6); - setHighwaySpeed("road", 12); + setHighwaySpeed("footway", PUSHING_SECTION_SPEED); + setHighwaySpeed("pedestrian", PUSHING_SECTION_SPEED); setHighwaySpeed("track", 18); - setHighwaySpeed("service", 14); - setHighwaySpeed("unclassified", 16); setHighwaySpeed("residential", 16); - setHighwaySpeed("trunk", 18); - setHighwaySpeed("trunk_link", 18); - setHighwaySpeed("primary", 18); - setHighwaySpeed("primary_link", 18); - setHighwaySpeed("secondary", 18); - setHighwaySpeed("secondary_link", 18); - setHighwaySpeed("tertiary", 18); - setHighwaySpeed("tertiary_link", 18); - addPushingSection("footway"); addPushingSection("platform"); addPushingSection("pedestrian"); @@ -133,16 +110,6 @@ protected MountainBikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedVal preferHighwayTags.add("residential"); preferHighwayTags.add("unclassified"); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.EXCELLENT, 1.1d); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.GOOD, 1.0d); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.INTERMEDIATE, 0.9d); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.BAD, 0.7d); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.VERY_BAD, 0.6d); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.HORRIBLE, 0.5d); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.VERY_HORRIBLE, 0.4d); - // SmoothnessSpeed <= smoothnessFactorPushingSectionThreshold gets mapped to speed PUSHING_SECTION_SPEED - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.IMPASSABLE, smoothnessFactorPushingSectionThreshold); - setSpecificClassBicycle("mtb"); } diff --git a/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java index 374650b0182..63097b67bb1 100644 --- a/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/RacingBikeTagParser.java @@ -67,37 +67,30 @@ protected RacingBikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue setSurfaceSpeed("paved", 20); setSurfaceSpeed("asphalt", 20); - setSurfaceSpeed("cobblestone", 10); - setSurfaceSpeed("cobblestone:flattened", 10); - setSurfaceSpeed("sett", 10); setSurfaceSpeed("concrete", 20); setSurfaceSpeed("concrete:lanes", 16); setSurfaceSpeed("concrete:plates", 16); - setSurfaceSpeed("paving_stones", 10); - setSurfaceSpeed("paving_stones:30", 10); - setSurfaceSpeed("unpaved", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("compacted", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("dirt", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("earth", PUSHING_SECTION_SPEED / 2); + setSurfaceSpeed("unpaved", MIN_SPEED); + setSurfaceSpeed("compacted", MIN_SPEED); + setSurfaceSpeed("dirt", MIN_SPEED); + setSurfaceSpeed("earth", MIN_SPEED); setSurfaceSpeed("fine_gravel", PUSHING_SECTION_SPEED); - setSurfaceSpeed("grass", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("grass_paver", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("gravel", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("ground", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("ice", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("metal", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("mud", PUSHING_SECTION_SPEED / 2); + setSurfaceSpeed("grass", MIN_SPEED); + setSurfaceSpeed("grass_paver", MIN_SPEED); + setSurfaceSpeed("gravel", MIN_SPEED); + setSurfaceSpeed("ground", MIN_SPEED); + setSurfaceSpeed("ice", MIN_SPEED); + setSurfaceSpeed("metal", MIN_SPEED); + setSurfaceSpeed("mud", MIN_SPEED); setSurfaceSpeed("pebblestone", PUSHING_SECTION_SPEED); - setSurfaceSpeed("salt", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("sand", PUSHING_SECTION_SPEED / 2); - setSurfaceSpeed("wood", PUSHING_SECTION_SPEED / 2); + setSurfaceSpeed("salt", MIN_SPEED); + setSurfaceSpeed("sand", MIN_SPEED); + setSurfaceSpeed("wood", MIN_SPEED); - setHighwaySpeed("cycleway", 18); setHighwaySpeed("path", 8); - setHighwaySpeed("footway", 6); - setHighwaySpeed("pedestrian", 6); - setHighwaySpeed("road", 12); - setHighwaySpeed("track", PUSHING_SECTION_SPEED / 2); // assume unpaved + setHighwaySpeed("footway", PUSHING_SECTION_SPEED); + setHighwaySpeed("pedestrian", PUSHING_SECTION_SPEED); + setHighwaySpeed("track", MIN_SPEED); // assume unpaved setHighwaySpeed("service", 12); setHighwaySpeed("unclassified", 16); setHighwaySpeed("residential", 16); @@ -117,14 +110,11 @@ protected RacingBikeTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue addPushingSection("pedestrian"); addPushingSection("steps"); + // overwite map from BikeCommon setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.EXCELLENT, 1.2d); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.GOOD, 1.0d); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.INTERMEDIATE, 0.9d); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.BAD, 0.7d); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.VERY_BAD, smoothnessFactorPushingSectionThreshold); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.HORRIBLE, smoothnessFactorPushingSectionThreshold); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.VERY_HORRIBLE, smoothnessFactorPushingSectionThreshold); - setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.IMPASSABLE, smoothnessFactorPushingSectionThreshold); + setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.VERY_BAD, 0.1); + setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.HORRIBLE, 0.1); + setSmoothnessSpeedFactor(com.graphhopper.routing.ev.Smoothness.VERY_HORRIBLE, 0.1); routeMap.put(INTERNATIONAL, BEST.getValue()); routeMap.put(NATIONAL, BEST.getValue()); diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 5554cf90b50..68d6ce0a71f 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -1343,14 +1343,12 @@ public void testCircularJunctionInstructionsWithCH() { @Test public void testMultipleVehiclesWithCH() { - final String profile1 = "profile1"; - final String profile2 = "profile2"; - final String vehicle1 = "bike"; - final String vehicle2 = "car"; + final String bikeProfile = "bike_profile"; + final String carProfile = "car_profile"; final String weighting = "fastest"; List profiles = asList( - new Profile(profile1).setVehicle(vehicle1).setWeighting(weighting), - new Profile(profile2).setVehicle(vehicle2).setWeighting(weighting) + new Profile(bikeProfile).setVehicle("bike").setWeighting(weighting), + new Profile(carProfile).setVehicle("car").setWeighting(weighting) ); GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). @@ -1358,19 +1356,19 @@ public void testMultipleVehiclesWithCH() { setProfiles(profiles). setStoreOnFlush(true); hopper.getCHPreparationHandler().setCHProfiles( - new CHProfile(profile1), - new CHProfile(profile2) + new CHProfile(bikeProfile), + new CHProfile(carProfile) ); hopper.importOrLoad(); GHResponse rsp = hopper.route(new GHRequest(43.73005, 7.415707, 43.741522, 7.42826) - .setProfile("profile2")); + .setProfile(carProfile)); ResponsePath res = rsp.getBest(); assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); assertEquals(207, res.getTime() / 1000f, 1); assertEquals(2837, res.getDistance(), 1); rsp = hopper.route(new GHRequest(43.73005, 7.415707, 43.741522, 7.42826) - .setProfile("profile1")); + .setProfile(bikeProfile)); res = rsp.getBest(); assertFalse(rsp.hasErrors(), rsp.getErrors().toString()); assertEquals(511, res.getTime() / 1000f, 1); @@ -1378,13 +1376,13 @@ public void testMultipleVehiclesWithCH() { rsp = hopper.route(new GHRequest(43.73005, 7.415707, 43.741522, 7.42826) .setProfile("profile3")); - assertTrue(rsp.hasErrors(), "only profile1 and profile2 exist, request for profile3 should fail"); + assertTrue(rsp.hasErrors(), "only car_profile and bike_profile exist, request for profile3 should fail"); GHRequest req = new GHRequest(). addPoint(new GHPoint(43.741069, 7.426854)). addPoint(new GHPoint(43.744445, 7.429483)). setHeadings(Arrays.asList(0., 190.)). - setProfile("profile1"); + setProfile(bikeProfile); rsp = hopper.route(req); assertTrue(rsp.hasErrors(), "heading not allowed for CH enabled graph"); diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index a46dbb2088d..3e9e1e9131c 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -335,7 +335,7 @@ public void testMonacoBike3D_twoSpeedsPerEdge() { // 1. queries.add(new Query(43.727687, 7.418737, 43.730864, 7.420771, 2599, 115)); queries.add(new Query(43.74958, 7.436566, 43.728499, 7.417907, 4180, 165)); - queries.add(new Query(43.739213, 7.427806, 43.728677, 7.41016, 3244, 179)); + queries.add(new Query(43.739213, 7.427806, 43.728677, 7.41016, 2805, 145)); // 4. avoid tunnel(s)! queries.add(new Query(43.739662, 7.424355, 43.733802, 7.413433, 2436, 112)); GraphHopper hopper = createHopper(MONACO, new Profile("bike2").setVehicle("bike2").setWeighting("fastest")); @@ -387,7 +387,8 @@ public void testMonacoBike() { @Test public void testMonacoMountainBike() { List queries = new ArrayList<>(); - queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2593, 110)); + // for mtb it is also ok to go over steps (43.7318,7.423) -> 1900m vs 2600m (in latest OSM data all bikes are forbidden and steps aren't taken) + queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2594, 111)); queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3655, 176)); queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2331, 121)); // hard to select between secondary and primary (both are AVOID for mtb) diff --git a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java index 6a7b12f7261..743103d611b 100644 --- a/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java +++ b/core/src/test/java/com/graphhopper/routing/util/AbstractBikeTagParserTester.java @@ -305,7 +305,7 @@ public void testAvoidTunnel() { osmWay.setTag("highway", "secondary"); osmWay.setTag("tunnel", "yes"); - assertPriority(AVOID_MORE.getValue(), osmWay); + assertPriority(BAD.getValue(), osmWay); osmWay.setTag("bicycle", "designated"); assertPriority(PREFER.getValue(), osmWay); @@ -331,7 +331,7 @@ public void testService() { assertPriorityAndSpeed(PREFER.getValue(), 14, way); way.setTag("service", "parking_aisle"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 6, way); + assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 4, way); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java index 96274c7daaa..f705e783e71 100644 --- a/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/BikeTagParserTest.java @@ -31,6 +31,7 @@ import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; +import static com.graphhopper.routing.util.BikeCommonTagParser.MIN_SPEED; import static com.graphhopper.routing.util.BikeCommonTagParser.PUSHING_SECTION_SPEED; import static com.graphhopper.routing.util.PriorityCode.*; import static org.junit.jupiter.api.Assertions.*; @@ -88,6 +89,11 @@ public void testSpeedAndPriority() { way.setTag("bicycle", "dismount"); assertPriorityAndSpeed(AVOID.getValue(), PUSHING_SECTION_SPEED, way); + way.clearTags(); + way.setTag("highway", "secondary"); + way.setTag("hazmat", "designated"); + assertPriorityAndSpeed(BAD.getValue(), 18, way); + way.clearTags(); way.setTag("highway", "footway"); way.setTag("bicycle", "yes"); @@ -151,7 +157,7 @@ public void testSpeedAndPriority() { assertPriorityAndSpeed(PREFER.getValue(), cyclewaySpeed, way); way.setTag("surface", "unpaved"); - assertPriorityAndSpeed(PREFER.getValue(), 14, way); + assertPriorityAndSpeed(PREFER.getValue(), 12, way); way.setTag("surface", "paved"); assertPriorityAndSpeed(PREFER.getValue(), 18, way); @@ -216,9 +222,9 @@ public void testSpeedAndPriority() { way.clearTags(); way.setTag("highway", "steps"); way.setTag("surface", "wood"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED / 2.0, way); + assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), MIN_SPEED, way); way.setTag("maxspeed", "20"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED / 2.0, way); + assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), MIN_SPEED, way); way.clearTags(); way.setTag("highway", "track"); @@ -278,13 +284,13 @@ public void testSmoothness() { assertEquals(20, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "bad"); - assertEquals(14, getSpeedFromFlags(way), 0.01); + assertEquals(12, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "impassable"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(MIN_SPEED, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "unknown"); - assertEquals(14, getSpeedFromFlags(way), 0.01); + assertEquals(12, getSpeedFromFlags(way), 0.01); way.clearTags(); way.setTag("highway", "residential"); @@ -297,13 +303,13 @@ public void testSmoothness() { way.clearTags(); way.setTag("highway", "track"); way.setTag("tracktype", "grade5"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(4, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "bad"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(2, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "impassable"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(MIN_SPEED, getSpeedFromFlags(way), 0.01); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java index e366ee00edf..5bd6d6a272a 100644 --- a/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/MountainBikeTagParserTest.java @@ -30,6 +30,7 @@ import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; +import static com.graphhopper.routing.util.BikeCommonTagParser.MIN_SPEED; import static com.graphhopper.routing.util.BikeCommonTagParser.PUSHING_SECTION_SPEED; import static com.graphhopper.routing.util.PriorityCode.*; import static org.junit.jupiter.api.Assertions.*; @@ -66,13 +67,13 @@ public void testSpeedAndPriority() { // Test pushing section speeds way.setTag("highway", "footway"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 4, way); + assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); way.setTag("highway", "track"); assertPriorityAndSpeed(PREFER.getValue(), 18, way); way.setTag("highway", "steps"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 4, way); + assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), PUSHING_SECTION_SPEED, way); way.clearTags(); // test speed for allowed pushing section types @@ -105,7 +106,7 @@ public void testSmoothness() { assertEquals(12, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "impassable"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(MIN_SPEED, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "unknown"); assertEquals(12, getSpeedFromFlags(way), 0.01); @@ -124,10 +125,10 @@ public void testSmoothness() { assertEquals(6, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "bad"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(4, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "impassable"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(MIN_SPEED, getSpeedFromFlags(way), 0.01); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java index 71c321f7838..e36f71772cb 100644 --- a/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/RacingBikeTagParserTest.java @@ -27,6 +27,7 @@ import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; +import static com.graphhopper.routing.util.BikeCommonTagParser.MIN_SPEED; import static com.graphhopper.routing.util.BikeCommonTagParser.PUSHING_SECTION_SPEED; import static com.graphhopper.routing.util.PriorityCode.*; import static com.graphhopper.routing.util.WayAccess.WAY; @@ -83,7 +84,7 @@ public void testService() { assertPriorityAndSpeed(UNCHANGED.getValue(), 12, way); way.setTag("service", "parking_aisle"); - assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 6, way); + assertPriorityAndSpeed(SLIGHT_AVOID.getValue(), 4, way); } @Test @@ -151,7 +152,7 @@ public void testSmoothness() { assertEquals(12, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "impassable"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(MIN_SPEED, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "unknown"); assertEquals(12, getSpeedFromFlags(way), 0.01); @@ -159,28 +160,28 @@ public void testSmoothness() { way.clearTags(); way.setTag("highway", "residential"); way.setTag("surface", "ground"); - assertEquals(2, getSpeedFromFlags(way), 0.01); + assertEquals(MIN_SPEED, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "bad"); - assertEquals(2, getSpeedFromFlags(way), 0.01); + assertEquals(MIN_SPEED, getSpeedFromFlags(way), 0.01); way.clearTags(); way.setTag("highway", "track"); way.setTag("tracktype", "grade5"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(4, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "bad"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(2, getSpeedFromFlags(way), 0.01); way.setTag("smoothness", "impassable"); - assertEquals(PUSHING_SECTION_SPEED, getSpeedFromFlags(way), 0.01); + assertEquals(MIN_SPEED, getSpeedFromFlags(way), 0.01); } @Test public void testHandleWayTagsInfluencedByRelation() { ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "track"); - assertEquals(PUSHING_SECTION_SPEED / 2, getSpeedFromFlags(osmWay), 1e-1); + assertEquals(MIN_SPEED, getSpeedFromFlags(osmWay), 1e-1); // relation code is PREFER ReaderRelation osmRel = new ReaderRelation(1); @@ -255,30 +256,30 @@ public WayAccess getAccess(ReaderWay way) { assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, AVOID.getValue(), 18, osmWay); osmWay.setTag("tunnel", "yes"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, AVOID_MORE.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, BAD.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "motorway"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "80"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, AVOID_MORE.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, BAD.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "motorway"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, AVOID_MORE.getValue(), 18, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, BAD.getValue(), 18, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "notdefined"); osmWay.setTag("tunnel", "yes"); osmWay.setTag("maxspeed", "120"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, AVOID_MORE.getValue(), 4, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, BAD.getValue(), PUSHING_SECTION_SPEED, osmWay); osmWay.clearTags(); osmWay.setTag("highway", "notdefined"); osmWay.setTag("maxspeed", "50"); - assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, UNCHANGED.getValue(), 4, osmWay); + assertPriorityAndSpeed(encodingManager, priorityEnc, speedEnc, parser, UNCHANGED.getValue(), PUSHING_SECTION_SPEED, osmWay); } private void assertPriorityAndSpeed(EncodingManager encodingManager, DecimalEncodedValue priorityEnc, DecimalEncodedValue speedEnc, VehicleTagParser parser, int expectedPrio, double expectedSpeed, ReaderWay way) { diff --git a/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java b/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java index 78636f71f89..2d6f0b6d552 100644 --- a/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java @@ -139,7 +139,7 @@ public void testCompatibilityBug() { parser.init(new DateRangeParser()); IntsRef flags = parser.handleWayTags(manager2.createEdgeFlags(), osmWay); double singleSpeed = parser.avgSpeedEnc.getDecimal(false, flags); - assertEquals(4, singleSpeed, 1e-3); + assertEquals(BikeCommonTagParser.PUSHING_SECTION_SPEED, singleSpeed, 1e-3); assertEquals(singleSpeed, parser.avgSpeedEnc.getDecimal(true, flags), 1e-3); EncodingManager manager = EncodingManager.create("bike2,bike,foot"); From d1ef18cc13071687ec8b6edd49f58a45c5fca4b9 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 22 Aug 2022 21:31:24 +0200 Subject: [PATCH 135/389] consider multiple from members for no_entry (#2648) --- .../com/graphhopper/reader/osm/OSMReader.java | 46 +++++++++---------- .../util/parsers/OSMTurnRelationParser.java | 5 +- .../graphhopper/reader/osm/OSMReaderTest.java | 23 ++++++++++ 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 126acf46e28..759512a3781 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -576,10 +576,8 @@ static List createTurnRelations(ReaderRelation relation) { } } if (relation.hasTag("restriction")) { - OSMTurnRelation osmTurnRelation = createTurnRelation(relation, relation.getTag("restriction"), vehicleTypeRestricted, vehicleTypesExcept); - if (osmTurnRelation != null) { - osmTurnRelations.add(osmTurnRelation); - } + osmTurnRelations.addAll(createTurnRelations(relation, relation.getTag("restriction"), + vehicleTypeRestricted, vehicleTypesExcept)); return osmTurnRelations; } if (relation.hasTagWithKeyPrefix("restriction:")) { @@ -587,42 +585,40 @@ static List createTurnRelations(ReaderRelation relation) { for (String vehicleType : vehicleTypesRestricted) { String restrictionType = relation.getTag(vehicleType); vehicleTypeRestricted = vehicleType.replace("restriction:", "").trim(); - OSMTurnRelation osmTurnRelation = createTurnRelation(relation, restrictionType, vehicleTypeRestricted, vehicleTypesExcept); - if (osmTurnRelation != null) { - osmTurnRelations.add(osmTurnRelation); - } + osmTurnRelations.addAll(createTurnRelations(relation, restrictionType, vehicleTypeRestricted, + vehicleTypesExcept)); } } return osmTurnRelations; } - static OSMTurnRelation createTurnRelation(ReaderRelation relation, String restrictionType, String - vehicleTypeRestricted, List vehicleTypesExcept) { + static List createTurnRelations(ReaderRelation relation, String restrictionType, + String vehicleTypeRestricted, List vehicleTypesExcept) { OSMTurnRelation.Type type = OSMTurnRelation.Type.getRestrictionType(restrictionType); if (type != OSMTurnRelation.Type.UNSUPPORTED) { - long fromWayID = -1; long viaNodeID = -1; long toWayID = -1; for (ReaderRelation.Member member : relation.getMembers()) { - if (ReaderElement.WAY == member.getType()) { - if ("from".equals(member.getRole())) { - fromWayID = member.getRef(); - } else if ("to".equals(member.getRole())) { - toWayID = member.getRef(); - } - } else if (ReaderElement.NODE == member.getType() && "via".equals(member.getRole())) { + if (ReaderElement.WAY == member.getType() && "to".equals(member.getRole())) + toWayID = member.getRef(); + else if (ReaderElement.NODE == member.getType() && "via".equals(member.getRole())) viaNodeID = member.getRef(); - } } - if (fromWayID >= 0 && toWayID >= 0 && viaNodeID >= 0) { - OSMTurnRelation osmTurnRelation = new OSMTurnRelation(fromWayID, viaNodeID, toWayID, type); - osmTurnRelation.setVehicleTypeRestricted(vehicleTypeRestricted); - osmTurnRelation.setVehicleTypesExcept(vehicleTypesExcept); - return osmTurnRelation; + if (toWayID >= 0 && viaNodeID >= 0) { + List res = new ArrayList<>(2); + for (ReaderRelation.Member member : relation.getMembers()) { + if (ReaderElement.WAY == member.getType() && "from".equals(member.getRole())) { + OSMTurnRelation osmTurnRelation = new OSMTurnRelation(member.getRef(), viaNodeID, toWayID, type); + osmTurnRelation.setVehicleTypeRestricted(vehicleTypeRestricted); + osmTurnRelation.setVehicleTypesExcept(vehicleTypesExcept); + res.add(osmTurnRelation); + } + } + return res; } } - return null; + return Collections.emptyList(); } private void finishedReading() { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java index d42496acdf0..fc3a5cfc0b6 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java @@ -20,8 +20,6 @@ import com.graphhopper.reader.OSMTurnRelation; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.util.AccessFilter; import com.graphhopper.storage.Graph; import com.graphhopper.storage.TurnCostStorage; @@ -66,8 +64,7 @@ private EdgeExplorer getOutExplorer(Graph graph) { /** * Add the specified relation to the TurnCostStorage */ - void addRelationToTCStorage(OSMTurnRelation osmTurnRelation, - ExternalInternalMap map, Graph graph) { + void addRelationToTCStorage(OSMTurnRelation osmTurnRelation, ExternalInternalMap map, Graph graph) { TurnCostStorage tcs = graph.getTurnCostStorage(); int viaNode = map.getInternalNodeIdOfOsmNode(osmTurnRelation.getViaOsmNodeId()); EdgeExplorer edgeOutExplorer = getOutExplorer(graph), edgeInExplorer = getInExplorer(graph); diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 670a7145fcc..c942229ff3e 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -22,6 +22,7 @@ import com.graphhopper.GraphHopper; import com.graphhopper.GraphHopperTest; import com.graphhopper.config.Profile; +import com.graphhopper.reader.OSMTurnRelation; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.dem.ElevationProvider; import com.graphhopper.reader.dem.SRTMProvider; @@ -592,6 +593,28 @@ public void testTurnRestrictions() { assertTrue(tcStorage.get(bikeTCEnc, edge10_11, n11, edge11_14) > 0); } + @Test + public void testMultipleFromForNoEntry() { + ReaderRelation rel = new ReaderRelation(1L); + + rel.setTag("restriction", "no_entry"); + rel.add(new ReaderRelation.Member(ReaderRelation.Member.WAY, 1L, "from")); + rel.add(new ReaderRelation.Member(ReaderRelation.Member.WAY, 2L, "from")); + rel.add(new ReaderRelation.Member(ReaderRelation.Member.NODE, 3L, "via")); + rel.add(new ReaderRelation.Member(ReaderRelation.Member.WAY, 4L, "to")); + + List osmRel = OSMReader.createTurnRelations(rel); + assertEquals(2, osmRel.size()); + + assertEquals(1, osmRel.get(0).getOsmIdFrom()); + assertEquals(4, osmRel.get(0).getOsmIdTo()); + assertEquals(OSMTurnRelation.Type.NOT, osmRel.get(0).getRestriction()); + + assertEquals(2, osmRel.get(1).getOsmIdFrom()); + assertEquals(4, osmRel.get(1).getOsmIdTo()); + assertEquals(OSMTurnRelation.Type.NOT, osmRel.get(1).getRestriction()); + } + @Test public void testRoadAttributes() { String fileRoadAttributes = "test-road-attributes.xml"; From a15de6c5096f7c2b03097b291b7b7486de74e2e6 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 25 Aug 2022 13:15:29 +0200 Subject: [PATCH 136/389] allow configuring turn costs and TransportationMode for RoadsTagParser, related to #2460 --- .../routing/util/DefaultVehicleTagParserFactory.java | 2 +- .../com/graphhopper/routing/util/RoadsTagParser.java | 12 +++++++++--- .../graphhopper/routing/util/RoadsTagParserTest.java | 11 ++++++++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java index 4a395fbd09c..b704d3793eb 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java @@ -26,7 +26,7 @@ public class DefaultVehicleTagParserFactory implements VehicleTagParserFactory { public VehicleTagParser createParser(EncodedValueLookup lookup, String name, PMap configuration) { if (name.equals(ROADS)) - return new RoadsTagParser(lookup); + return new RoadsTagParser(lookup, configuration); if (name.equals(CAR)) return new CarTagParser(lookup, configuration); if (name.equals(CAR4WD)) diff --git a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java index 94db9124c11..f21b150fbb5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java @@ -3,16 +3,22 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.Helper; +import com.graphhopper.util.PMap; public class RoadsTagParser extends VehicleTagParser { public static final double ROADS_MAX_SPEED = 254; - public RoadsTagParser(EncodedValueLookup lookup) { - this( + public RoadsTagParser(EncodedValueLookup lookup, PMap properties) { + super( lookup.getBooleanEncodedValue(VehicleAccess.key("roads")), lookup.getDecimalEncodedValue(VehicleSpeed.key("roads")), - lookup.getDecimalEncodedValue(TurnCost.key("roads")) + "roads", + lookup.getBooleanEncodedValue(Roundabout.KEY), + lookup.hasEncodedValue(TurnCost.key("roads")) ? lookup.getDecimalEncodedValue(TurnCost.key("roads")) : null, + TransportationMode.valueOf(properties.getString("transportation_mode", "VEHICLE")), + lookup.getDecimalEncodedValue(VehicleSpeed.key("roads")).getNextStorableValue(ROADS_MAX_SPEED) ); } diff --git a/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java index ac9d0c4c21d..07836bef6e2 100644 --- a/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/RoadsTagParserTest.java @@ -3,8 +3,10 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.PMap; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; class RoadsTagParserTest { @@ -13,7 +15,7 @@ class RoadsTagParserTest { private final RoadsTagParser parser; public RoadsTagParserTest() { - parser = new RoadsTagParser(encodingManager); + parser = new RoadsTagParser(encodingManager, new PMap()); parser.init(new DateRangeParser()); } @@ -35,4 +37,11 @@ public void testSpeed() { assertTrue(parser.getAverageSpeedEnc().getDecimal(false, flags) > 200); } + @Test + public void testHGV() { + RoadsTagParser hgvParser = new RoadsTagParser(EncodingManager.create("roads"), new PMap("transportation_mode=HGV")); + hgvParser.init(new DateRangeParser()); + + assertEquals("[hgv, motor_vehicle, vehicle, access]", hgvParser.getRestrictions().toString()); + } } \ No newline at end of file From 4df82f526d666e7e58ecbd729e33ebdf15b8ed8a Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 25 Aug 2022 14:29:37 +0200 Subject: [PATCH 137/389] add hgv enum to make truck access configurable --- config-example.yml | 2 +- .../ev/DefaultEncodedValueFactory.java | 2 + .../java/com/graphhopper/routing/ev/Hgv.java | 53 +++++++++++++++++++ .../util/parsers/DefaultTagParserFactory.java | 2 + .../routing/util/parsers/OSMHgvParser.java | 20 +++++++ 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/com/graphhopper/routing/ev/Hgv.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java diff --git a/config-example.yml b/config-example.yml index 444a2d8c862..299b78062fe 100644 --- a/config-example.yml +++ b/config-example.yml @@ -17,7 +17,7 @@ graphhopper: # Add additional information to every edge. Used for path details (#1548), better instructions (#1844) and tunnel/bridge interpolation (#798). # Default values are: road_class,road_class_link,road_environment,max_speed,road_access (since #1805) - # More are: surface,smoothness,max_width,max_height,max_weight,max_axle_load,max_length,hazmat,hazmat_tunnel,hazmat_water,toll,track_type, + # More are: surface,smoothness,max_width,max_height,max_weight,hgv,max_axle_load,max_length,hazmat,hazmat_tunnel,hazmat_water,toll,track_type, # mtb_rating, hike_rating,horse_rating,lanes # graph.encoded_values: surface,toll,track_type diff --git a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java index 502891f6ab4..ff8430563a8 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java @@ -54,6 +54,8 @@ public EncodedValue create(String string) { enc = MaxAxleLoad.create(); } else if (MaxLength.KEY.equals(name)) { enc = MaxLength.create(); + } else if (Hgv.KEY.equals(name)) { + enc = new EnumEncodedValue<>(Hgv.KEY, Hgv.class); } else if (Surface.KEY.equals(name)) { enc = new EnumEncodedValue<>(Surface.KEY, Surface.class); } else if (Smoothness.KEY.equals(name)) { diff --git a/core/src/main/java/com/graphhopper/routing/ev/Hgv.java b/core/src/main/java/com/graphhopper/routing/ev/Hgv.java new file mode 100644 index 00000000000..7adcd3a31d2 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/Hgv.java @@ -0,0 +1,53 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.routing.ev; + +import com.graphhopper.util.Helper; + +/** + * This enum defines the road access of an edge. Most edges are accessible from everyone and so the default value is + * YES. But some have restrictions like "accessible only for customers" or when delivering. Unknown tags will get the + * value OTHER. The NO value does not permit any access. + */ +public enum Hgv { + MISSING("missing"), YES("yes"), DESIGNATED("designated"), DESTINATION("destination"), + DELIVERY("delivery"), DISCOURAGED("discouraged"), AGRICULTURAL("agricultural"), NO("no"); + + public static final String KEY = "hgv"; + + private final String name; + + Hgv(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + + public static Hgv find(String name) { + if (name == null) + return MISSING; + try { + return Hgv.valueOf(Helper.toUpperCase(name)); + } catch (IllegalArgumentException ex) { + return MISSING; + } + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java index b9f023818f2..df8e7f09ea6 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/DefaultTagParserFactory.java @@ -59,6 +59,8 @@ else if (name.equals(Toll.KEY)) return new OSMTollParser(lookup.getEnumEncodedValue(Toll.KEY, Toll.class)); else if (name.equals(TrackType.KEY)) return new OSMTrackTypeParser(lookup.getEnumEncodedValue(TrackType.KEY, TrackType.class)); + else if (name.equals(Hgv.KEY)) + return new OSMHgvParser(lookup.getEnumEncodedValue(Hgv.KEY, Hgv.class)); else if (name.equals(Hazmat.KEY)) return new OSMHazmatParser(lookup.getEnumEncodedValue(Hazmat.KEY, Hazmat.class)); else if (name.equals(HazmatTunnel.KEY)) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java new file mode 100644 index 00000000000..f5f988d3e11 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMHgvParser.java @@ -0,0 +1,20 @@ +package com.graphhopper.routing.util.parsers; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.Hgv; +import com.graphhopper.storage.IntsRef; + +public class OSMHgvParser implements TagParser { + EnumEncodedValue hgvEnc; + + public OSMHgvParser(EnumEncodedValue hgvEnc) { + this.hgvEnc = hgvEnc; + } + + @Override + public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + hgvEnc.setEnum(false, edgeFlags, Hgv.find(way.getTag("hgv"))); + return edgeFlags; + } +} From bb9c4ac7a31f5d5132d06e3374a301380f092f44 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 25 Aug 2022 14:38:52 +0200 Subject: [PATCH 138/389] add test for hgv encoded value --- .../resources/RouteResourceCustomModelTest.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java index ee0f8478bfb..a641d7ac79f 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java @@ -63,7 +63,7 @@ private static GraphHopperServerConfiguration createConfig() { putObject("prepare.min_network_size", 200). putObject("datareader.file", "../core/files/north-bayreuth.osm.gz"). putObject("graph.location", DIR). - putObject("graph.encoded_values", "max_height,max_weight,max_width,hazmat,toll,surface,track_type"). + putObject("graph.encoded_values", "max_height,max_weight,max_width,hazmat,toll,surface,track_type,hgv"). putObject("custom_model_folder", "./src/test/resources/com/graphhopper/application/resources"). setProfiles(Arrays.asList( new Profile("wheelchair"), @@ -351,6 +351,17 @@ public void wheelchair() { assertEquals(1500, path.get("distance").asDouble(), 10); } + @Test + public void testHgv() { + String body = "{\"points\": [[11.603998, 50.014554], [11.594095, 50.023334]], \"profile\": \"roads\", \"ch.disable\":true," + + "\"custom_model\": {" + + " \"speed\": [{\"if\":\"true\", \"limit_to\":\"car_average_speed * 0.9\"}], \n" + + " \"priority\": [{\"if\": \"car_access == false || hgv == NO || max_width < 3 || max_height < 4\", \"multiply_by\": \"0\"}]}}"; + JsonNode path = getPath(body); + assertEquals(7314, path.get("distance").asDouble(), 10); + assertEquals(957 * 1000, path.get("time").asLong(), 1_000); + } + private void assertMessageStartsWith(JsonNode jsonNode, String message) { assertNotNull(jsonNode.get("message")); assertTrue(jsonNode.get("message").asText().startsWith(message), "Expected error message to start with:\n" + From f7dd2e9d566bafaec4a40f581e7e967220e50f7b Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 26 Aug 2022 11:11:00 +0200 Subject: [PATCH 139/389] for now do not log as too many warnings, #2646 --- .../util/parsers/helpers/OSMValueExtractor.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java b/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java index 2067852c7c0..ac8ae968108 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/helpers/OSMValueExtractor.java @@ -36,8 +36,9 @@ public static void extractTons(IntsRef edgeFlags, ReaderWay way, DecimalEncodedV if (Double.isNaN(value)) value = Double.POSITIVE_INFINITY; valueEncoder.setDecimal(false, edgeFlags, value); - if (value - valueEncoder.getDecimal(false, edgeFlags) > 2) - logger.warn("Value " + value + " for " + valueEncoder.getName() + " was too large and truncated to " + valueEncoder.getDecimal(false, edgeFlags)); + // too many +// if (value - valueEncoder.getDecimal(false, edgeFlags) > 2) +// logger.warn("Value " + value + " for " + valueEncoder.getName() + " was too large and truncated to " + valueEncoder.getDecimal(false, edgeFlags)); } public static double stringToTons(String value) { @@ -74,8 +75,9 @@ public static void extractMeter(IntsRef edgeFlags, ReaderWay way, DecimalEncoded if (Double.isNaN(value)) value = Double.POSITIVE_INFINITY; valueEncoder.setDecimal(false, edgeFlags, value); - if (value - valueEncoder.getDecimal(false, edgeFlags) > 2) - logger.warn("Value " + value + " for " + valueEncoder.getName() + " was too large and truncated to " + valueEncoder.getDecimal(false, edgeFlags)); + // too many +// if (value - valueEncoder.getDecimal(false, edgeFlags) > 2) +// logger.warn("Value " + value + " for " + valueEncoder.getName() + " was too large and truncated to " + valueEncoder.getDecimal(false, edgeFlags)); } public static double stringToMeter(String value) { From 1c0409a7d53f1059e44b7a4d0ebdebf3b4742343 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 26 Aug 2022 11:32:44 +0200 Subject: [PATCH 140/389] SlopeCalculator: skip calculation if PointList is empty or 2D only --- .../routing/util/parsers/SlopeCalculator.java | 9 ++++++--- .../util/parsers/SlopeCalculatorTest.java | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java b/core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java index b551454d15d..90eb3d241e3 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java @@ -20,15 +20,18 @@ public SlopeCalculator(DecimalEncodedValue max, DecimalEncodedValue averageEnc) @Override public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { PointList pointList = way.getTag("point_list", null); - if (pointList != null && pointList.size() > 1) { + if (pointList != null) { + if (pointList.isEmpty() || !pointList.is3D()) { + if (averageSlopeEnc != null) averageSlopeEnc.setDecimal(false, edgeFlags, 0); + return edgeFlags; + } // Calculate 2d distance, although pointList might be 3D. // This calculation is a bit expensive and edge_distance is available already, but this would be in 3D double distance2D = DistanceCalcEarth.calcDistance(pointList, false); if (distance2D < MIN_LENGTH) { // default is minimum of average_slope is negative so we have to explicitly set it to 0 - if (averageSlopeEnc != null) - averageSlopeEnc.setDecimal(false, edgeFlags, 0); + if (averageSlopeEnc != null) averageSlopeEnc.setDecimal(false, edgeFlags, 0); return edgeFlags; } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java index 6a154e26184..ce732a8ab54 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java @@ -75,4 +75,21 @@ public void test2() { assertEquals(31, maxEnc.getDecimal(false, edgeRef), 1e-3); assertEquals(31, averageEnc.getDecimal(false, edgeRef), 1e-3); } + + @Test + public void test2D() { + IntsRef edgeRef = new IntsRef(1); + PointList pointList = new PointList(5, false); + pointList.add(47.7283135, 11.9991135); + ReaderWay way = new ReaderWay(1); + way.setTag("point_list", pointList); + DecimalEncodedValue averageEnc = AverageSlope.create(); + DecimalEncodedValue maxEnc = MaxSlope.create(); + new EncodingManager.Builder().add(averageEnc).add(maxEnc).build(); + + SlopeCalculator creator = new SlopeCalculator(maxEnc, averageEnc); + creator.handleWayTags(edgeRef, way, IntsRef.EMPTY); + assertEquals(0, maxEnc.getDecimal(false, edgeRef), 1e-3); + assertEquals(0, averageEnc.getDecimal(false, edgeRef), 1e-3); + } } From 93f1638fc3846bdf199d14237f02aefa6eed5801 Mon Sep 17 00:00:00 2001 From: easbar Date: Sat, 27 Aug 2022 09:01:33 +0200 Subject: [PATCH 141/389] Do not get elevations for nodes we don't need while parsing OSM --- .../main/java/com/graphhopper/reader/osm/OSMNodeData.java | 7 ++++--- .../java/com/graphhopper/reader/osm/WaySegmentParser.java | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java index b00129d9fa3..154c5bbfbdf 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.function.DoubleSupplier; import java.util.function.IntUnaryOperator; import static java.util.Collections.emptyMap; @@ -145,14 +146,14 @@ public long getTaggedNodeCount() { * * @return the node type this OSM node was associated with before this method was called */ - public int addCoordinatesIfMapped(long osmNodeId, double lat, double lon, double ele) { + public int addCoordinatesIfMapped(long osmNodeId, double lat, double lon, DoubleSupplier getEle) { int nodeType = idsByOsmNodeIds.get(osmNodeId); if (nodeType == EMPTY_NODE) return nodeType; else if (nodeType == JUNCTION_NODE || nodeType == CONNECTION_NODE) - addTowerNode(osmNodeId, lat, lon, ele); + addTowerNode(osmNodeId, lat, lon, getEle.getAsDouble()); else if (nodeType == INTERMEDIATE_NODE || nodeType == END_NODE) - addPillarNode(osmNodeId, lat, lon, ele); + addPillarNode(osmNodeId, lat, lon, getEle.getAsDouble()); else throw new IllegalStateException("Unknown node type: " + nodeType + ", or coordinates already set. Possibly duplicate OSM node ID: " + osmNodeId); return nodeType; diff --git a/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java b/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java index 93daa67d328..b1efdcc80eb 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java +++ b/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java @@ -218,7 +218,7 @@ public void handleNode(ReaderNode node) { LOGGER.info("pass2 - processed nodes: " + nf(nodeCounter) + ", accepted nodes: " + nf(acceptedNodes) + ", " + Helper.getMemInfo()); - int nodeType = nodeData.addCoordinatesIfMapped(node.getId(), node.getLat(), node.getLon(), eleProvider.getEle(node)); + int nodeType = nodeData.addCoordinatesIfMapped(node.getId(), node.getLat(), node.getLon(), () -> eleProvider.getEle(node)); if (nodeType == EMPTY_NODE) return; From 4b6020a8772276b8538b6e022464c2e28ee49077 Mon Sep 17 00:00:00 2001 From: easbar Date: Mon, 29 Aug 2022 09:25:59 +0200 Subject: [PATCH 142/389] Custom weighting calcEdgeMillis truncate instead of round * just for consistency and easier migration with/from FastestWeighting --- .../graphhopper/routing/weighting/custom/CustomWeighting.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java index c7759f7c6e5..31a568c7532 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java @@ -140,7 +140,8 @@ public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { @Override public long calcEdgeMillis(EdgeIteratorState edgeState, boolean reverse) { - return Math.round(calcSeconds(edgeState.getDistance(), edgeState, reverse) * 1000); + // we truncate to long here instead of rounding to make it consistent with FastestWeighting, maybe change to rounding later + return (long) (calcSeconds(edgeState.getDistance(), edgeState, reverse) * 1000); } @Override From ce461d2dcc6c1f3551ccdb50b89fd483bf8889da Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 29 Aug 2022 13:56:26 +0200 Subject: [PATCH 143/389] CustomWeighting: handle special case for barrier edges with distance==0 and average_speed>0 --- .../routing/weighting/custom/CustomWeighting.java | 8 ++++---- .../routing/weighting/custom/CustomWeightingTest.java | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java index 31a568c7532..f7b0c43fad0 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java @@ -107,12 +107,12 @@ public double getMinWeight(double distance) { public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { final double distance = edgeState.getDistance(); double seconds = calcSeconds(distance, edgeState, reverse); - if (Double.isInfinite(seconds)) - return Double.POSITIVE_INFINITY; + if (Double.isInfinite(seconds)) return Double.POSITIVE_INFINITY; double distanceCosts = distance * distanceInfluence; - if (Double.isInfinite(distanceCosts)) - return Double.POSITIVE_INFINITY; + if (Double.isInfinite(distanceCosts)) return Double.POSITIVE_INFINITY; double priority = edgeToPriorityMapping.get(edgeState, reverse); + // special case to avoid NaN for barrier edges (where time is often 0s) + if (priority == 0 && seconds == 0) return Double.POSITIVE_INFINITY; return seconds / priority + distanceCosts; } diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index ccc987fa140..9a011f111aa 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -307,6 +307,17 @@ public void maxSpeedViolated_bug_2307() { assertEquals(10 / (80 * 0.7 / 3.6) * 1000, weighting.calcEdgeMillis(motorway, false), 1); } + @Test + public void bugWithNaNForBarrierEdges() { + EdgeIteratorState motorway = graph.edge(0, 1).setDistance(0). + set(roadClassEnc, MOTORWAY).set(avSpeedEnc, 80).set(accessEnc, true, true); + CustomModel customModel = new CustomModel() + .addToPriority(Statement.If("road_class == MOTORWAY", Statement.Op.MULTIPLY, "0")); + Weighting weighting = createWeighting(customModel); + assertFalse(Double.isNaN(weighting.calcEdgeWeight(motorway, false))); + assertTrue(Double.isInfinite(weighting.calcEdgeWeight(motorway, false))); + } + private Weighting createWeighting(CustomModel vehicleModel) { return CustomModelParser.createWeighting(accessEnc, avSpeedEnc, null, encodingManager, NO_TURN_COST_PROVIDER, vehicleModel); } From 35a8c6bb9447e12aa55e813656bdbf535298f132 Mon Sep 17 00:00:00 2001 From: Andi Date: Mon, 29 Aug 2022 14:23:09 +0200 Subject: [PATCH 144/389] Maps: Add slope detail to elevation diagram (#2654) --- .../resources/com/graphhopper/maps/js/map.js | 116 +++++++++++++++++- 1 file changed, 110 insertions(+), 6 deletions(-) diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/map.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/map.js index 33094713c14..707a86bca9c 100644 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/map.js +++ b/web-bundle/src/main/resources/com/graphhopper/maps/js/map.js @@ -304,13 +304,10 @@ module.exports.addElevation = function (geoJsonFeature, details, selectedDetail, selectedDetailIdx = detailIdx; GHFeatureCollection.push(sliceFeatureCollection(details[detailKey], detailKey, geoJsonFeature)); options.mappings[detailKey] = getColorMapping(details[detailKey]); - } - if (selectedDetailIdx >= 0) - options.selectedAttributeIdx = selectedDetailIdx; - if(GHFeatureCollection.length === 0) { - // No Path Details => Show only elevation + // always show elevation and slope + { geoJsonFeature.properties.attributeType = "elevation"; var elevationCollection = { "type": "FeatureCollection", @@ -321,11 +318,99 @@ module.exports.addElevation = function (geoJsonFeature, details, selectedDetail, "summary": "Elevation" } }; + detailIdx++; + if (selectedDetail === 'Elevation') + selectedDetailIdx = detailIdx; GHFeatureCollection.push(elevationCollection); // Use a fixed color for elevation - options.mappings = { Elevation: {'elevation': {text: 'Elevation [m]', color: '#27ce49'}}}; + options.mappings['Elevation'] = {'elevation': {text: 'Elevation [m]', color: '#27ce49'}}; + + var slopeFeatures = []; + for (var i = 0; i < geoJsonFeature.geometry.coordinates.length - 1; i++) { + var from = geoJsonFeature.geometry.coordinates[i]; + var to = geoJsonFeature.geometry.coordinates[i + 1]; + var distance = getDist(from, to); + var slope = 100.0 * (to[2] - from[2]) / distance; + slopeFeatures.push({ + "type": "Feature", + "geometry": { + "type": "LineString", + "coordinates": [from, to] + }, + "properties": { + "attributeType": slope + } + }) + } + var slopeCollection = { + "type": "FeatureCollection", + "features": slopeFeatures, + "properties": { + "records": slopeFeatures.length, + "summary": "Slope" + } + }; + detailIdx++; + if (selectedDetail === 'Slope') + selectedDetailIdx = detailIdx; + GHFeatureCollection.push(slopeCollection); + options.mappings["Slope"] = slope2color; + + // tower slope: slope between tower nodes: use edge_id detail to find tower nodes + if (details['edge_id']) { + var detail = details['edge_id']; + var towerSlopeFeatures = []; + var points = geoJsonFeature.geometry.coordinates; + for (var i = 0; i < detail.length; i++) { + var featurePoints = points.slice(detail[i][0], detail[i][1] + 1); + var from = featurePoints[0]; + var to = featurePoints[featurePoints.length - 1]; + var distance = getDist(from, to); + var slope = 100.0 * (to[2] - from[2]) / distance; + // for the elevations in tower slope diagram we do linear interpolation between the tower nodes. note that + // we cannot simply leave out the pillar nodes, because otherwise the total distance would change + var tmpDistance = 0; + for (var j = 0; j < featurePoints.length; j++) { + var factor = tmpDistance / distance; + var ele = from[2] + factor * (to[2] - from[2]); + if (j === featurePoints.length - 1) + // there seem to be some small rounding errors which lead to ugly little spikes in the diagram, + // so for the last point use the elevation of the to point directly + ele = to[2]; + featurePoints[j] = [featurePoints[j][0], featurePoints[j][1], ele]; + if (j < featurePoints.length - 1) + tmpDistance += getDist(featurePoints[j], featurePoints[j + 1]); + } + towerSlopeFeatures.push({ + "type": "Feature", + "geometry": { + "type": "LineString", + "coordinates": featurePoints + }, + "properties": { + "attributeType": slope + } + }); + } + var towerSlopeCollection = { + "type": "FeatureCollection", + "features": towerSlopeFeatures, + "properties": { + "records": towerSlopeFeatures.length, + "summary": "Towerslope" + } + }; + detailIdx++; + if (selectedDetail === 'Towerslope') + selectedDetailIdx = detailIdx; + GHFeatureCollection.push(towerSlopeCollection); + options.mappings["Towerslope"] = slope2color; + } } + if (selectedDetailIdx >= 0) + options.selectedAttributeIdx = selectedDetailIdx; + if (elevationControl === null) { elevationControl = L.control.heightgraph(options); elevationControl.addTo(map); @@ -334,6 +419,25 @@ module.exports.addElevation = function (geoJsonFeature, details, selectedDetail, elevationControl.addData(GHFeatureCollection); }; +function getDist(p, q) { + return L.latLng(p[1], p[0]).distanceTo(L.latLng(q[1], q[0])); +} + +function slope2color(slope) { + var colorMin = [0, 153, 247]; + var colorMax = [241, 23, 18]; + var absSlope = Math.abs(slope); + absSlope = Math.min(25, absSlope); + var factor = absSlope / 25; + var color = []; + for (var i = 0; i < 3; i++) + color.push(colorMin[i] + factor * (colorMax[i] - colorMin[i])); + return { + text: slope.toFixed(2), + color: 'rgb(' + color[0] + ', ' + color[1] + ', ' + color[2] + ')' + } +} + function getColorMapping(detail) { var detailInfo = analyzeDetail(detail); if (detailInfo.numeric === true && detailInfo.minVal !== detailInfo.maxVal) { From b5a5b666844a0600ec47f5402dcfcb97138840ad Mon Sep 17 00:00:00 2001 From: easbar Date: Mon, 29 Aug 2022 22:21:38 +0200 Subject: [PATCH 145/389] Custom and fastest weighting calcEdgeMillis round instead of truncate * otherwise they are not always the same, because one multiplies by 3600 and the other by 3.6*1000 ... --- .../routing/weighting/AbstractWeighting.java | 2 +- .../weighting/custom/CustomWeighting.java | 2 +- .../java/com/graphhopper/GraphHopperTest.java | 8 ++++---- .../routing/DijkstraBidirectionCHTest.java | 2 +- .../routing/RoutingAlgorithmTest.java | 6 +++--- .../routing/ch/CHTurnCostTest.java | 2 +- .../weighting/custom/CustomWeightingTest.java | 19 +++++++++++++++++++ .../graphhopper/gpx/GpxConversionsTest.java | 2 +- .../resources/RouteResourceTest.java | 2 +- .../resources/SPTResourceTest.java | 2 +- 10 files changed, 33 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java index 158ed8af145..6f4c8402dd4 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java @@ -71,7 +71,7 @@ public long calcEdgeMillis(EdgeIteratorState edgeState, boolean reverse) { if (speed == 0) throw new IllegalStateException("Speed cannot be 0 for unblocked edge, use access properties to mark edge blocked! Should only occur for shortest path calculation. See #242."); - return (long) (edgeState.getDistance() * 3600 / speed); + return Math.round(edgeState.getDistance() * 3600 / speed); } @Override diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java index f7b0c43fad0..808aab7a926 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomWeighting.java @@ -141,7 +141,7 @@ public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { @Override public long calcEdgeMillis(EdgeIteratorState edgeState, boolean reverse) { // we truncate to long here instead of rounding to make it consistent with FastestWeighting, maybe change to rounding later - return (long) (calcSeconds(edgeState.getDistance(), edgeState, reverse) * 1000); + return Math.round(calcSeconds(edgeState.getDistance(), edgeState, reverse) * 1000); } @Override diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 68d6ce0a71f..9d1d614bc50 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -126,7 +126,7 @@ public void testMonacoDifferentAlgorithms(String algo, boolean withCH, int expec ResponsePath res = rsp.getBest(); assertEquals(3586.9, res.getDistance(), .1); - assertEquals(277112, res.getTime(), 10); + assertEquals(277115, res.getTime(), 10); assertEquals(91, res.getPoints().size()); assertEquals(43.7276852, res.getWaypoints().getLat(0), 1e-7); @@ -1867,9 +1867,9 @@ public void testIssue1960() { assertEquals(1995.38, pathLM.getDistance(), 0.1); assertEquals(1995.38, path.getDistance(), 0.1); - assertEquals(149497, pathCH.getTime()); - assertEquals(149497, pathLM.getTime()); - assertEquals(149497, path.getTime()); + assertEquals(149504, pathCH.getTime()); + assertEquals(149504, pathLM.getTime()); + assertEquals(149504, path.getTime()); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java index aa59b8e0c7f..0810d958ab9 100644 --- a/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java +++ b/core/src/test/java/com/graphhopper/routing/DijkstraBidirectionCHTest.java @@ -80,7 +80,7 @@ public void testBaseGraph() { Path p1 = new RoutingAlgorithmFactorySimple().createAlgo(graph, weighting, new AlgorithmOptions()).calcPath(0, 3); assertEquals(IntArrayList.from(0, 1, 5, 2, 3), p1.calcNodes()); assertEquals(402.30, p1.getDistance(), 1e-2, p1.toString()); - assertEquals(144829, p1.getTime(), p1.toString()); + assertEquals(144830, p1.getTime(), p1.toString()); } @Test diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java index aeafcf8bf19..865446d7ebd 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmTest.java @@ -295,12 +295,12 @@ public void testCalcFastestPath(Fixture f) { Path p1 = f.calcPath(graph, f.defaultWeighting, 0, 3); assertEquals(nodes(0, 1, 5, 2, 3), p1.calcNodes()); assertEquals(402.3, p1.getDistance(), .1, p1.toString()); - assertEquals(144829, p1.getTime(), p1.toString()); + assertEquals(144830, p1.getTime(), p1.toString()); Path p2 = f.calcPath(graph, fastestWeighting, 0, 3); assertEquals(nodes(0, 4, 6, 7, 5, 3), p2.calcNodes()); assertEquals(1261.7, p2.getDistance(), 0.1, p2.toString()); - assertEquals(111439, p2.getTime(), p2.toString()); + assertEquals(111441, p2.getTime(), p2.toString()); } // 0-1-2-3 @@ -996,7 +996,7 @@ public String toString() { initEleGraph(graph, 60, f.carAccessEnc, f.carSpeedEnc); p = f.calcPath(graph, fakeWeighting, 3, 0, 10, 9); assertEquals(nodes(12, 0, 1, 2, 11, 7, 10, 13), p.calcNodes()); - assertEquals(37009621, p.getTime()); + assertEquals(37009625, p.getTime()); assertEquals(616827, p.getDistance(), 1); assertEquals(493462, p.getWeight(), 1); } diff --git a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java index edd12db6bd7..d6d28e18429 100644 --- a/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java +++ b/core/src/test/java/com/graphhopper/routing/ch/CHTurnCostTest.java @@ -1078,7 +1078,7 @@ public void testFiniteUTurnCost_virtualViaNode(String algo) { assertEquals(IntArrayList.from(4, 3, 2, 1, 7, 0, 7, 1, 5, 6), dijkstraPath.calcNodes()); assertEquals(dijkstraPath.getWeight(), path.getWeight(), 1.e-2); assertEquals(dijkstraPath.getDistance(), path.getDistance(), 1.e-2); - assertEquals(dijkstraPath.getTime(), path.getTime()); + assertEquals(dijkstraPath.getTime(), path.getTime(), 5); } @ParameterizedTest diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index 9a011f111aa..a8a92603c8c 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -15,6 +15,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.Random; + import static com.graphhopper.json.Statement.*; import static com.graphhopper.json.Statement.Op.LIMIT; import static com.graphhopper.json.Statement.Op.MULTIPLY; @@ -318,6 +320,23 @@ public void bugWithNaNForBarrierEdges() { assertTrue(Double.isInfinite(weighting.calcEdgeWeight(motorway, false))); } + @Test + void sameTimeAsFastestWeighting() { + // we make sure the returned times are the same, so we can check for regressions more easily when we migrate from fastest to custom + FastestWeighting fastestWeighting = new FastestWeighting(accessEnc, avSpeedEnc); + Weighting customWeighting = createWeighting(new CustomModel().setDistanceInfluence(0)); + Random rnd = new Random(); + for (int i = 0; i < 100; i++) { + double speed = 5 + rnd.nextDouble() * 100; + double distance = rnd.nextDouble() * 1000; + EdgeIteratorState edge = graph.edge(0, 1).setDistance(distance); + GHUtility.setSpeed(speed, speed, accessEnc, avSpeedEnc, edge); + long fastestMillis = fastestWeighting.calcEdgeMillis(edge, false); + long customMillis = customWeighting.calcEdgeMillis(edge, false); + assertEquals(fastestMillis, customMillis); + } + } + private Weighting createWeighting(CustomModel vehicleModel) { return CustomModelParser.createWeighting(accessEnc, avSpeedEnc, null, encodingManager, NO_TURN_COST_PROVIDER, vehicleModel); } diff --git a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java index 3be8c4b2e96..7b4e387cc23 100644 --- a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java +++ b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java @@ -97,7 +97,7 @@ public void testInstructionsWithTimeAndPlace() { assertEquals(34000, p.getDistance(), 1e-1); assertEquals(34000, sumDistances(wayList), 1e-1); assertEquals(5, points.size()); - assertEquals(1604120, p.getTime()); + assertEquals(1604121, p.getTime()); assertEquals(Instruction.CONTINUE_ON_STREET, wayList.get(0).getSign()); assertEquals(15, wayList.get(0).getPoints().getLat(0), 1e-3); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java index 82b52cc222e..11426692e1a 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java @@ -287,7 +287,7 @@ public void testPathDetails() { assertTrue(pathDetails.containsKey("edge_id")); assertTrue(pathDetails.containsKey("time")); List averageSpeedList = pathDetails.get("average_speed"); - assertEquals(13, averageSpeedList.size()); + assertEquals(11, averageSpeedList.size()); assertEquals(30.0, averageSpeedList.get(0).getValue()); assertEquals(14, averageSpeedList.get(0).getLength()); assertEquals(60.0, averageSpeedList.get(1).getValue()); diff --git a/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java index 18e82924848..a2fdc62a471 100644 --- a/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java @@ -98,7 +98,7 @@ public void requestSPTEdgeBased() { assertEquals("prev_node_id,edge_id,node_id,time,distance", lines[0]); assertEquals("-1,-1,1948,0,0", lines[1]); assertEquals("1948,2277,1324,3817,74", lines[2]); - assertEquals("1948,2276,263,13495,262", lines[3]); + assertEquals("1948,2276,263,13496,262", lines[3]); } @Test From ffcbe9b85a4f5a5b1fc7ee37ac7eedf449d4dddf Mon Sep 17 00:00:00 2001 From: easbar Date: Mon, 29 Aug 2022 22:58:52 +0200 Subject: [PATCH 146/389] Fix pt tests --- .../src/test/java/com/graphhopper/AnotherAgencyIT.java | 4 ++-- .../src/test/java/com/graphhopper/FreeWalkIT.java | 2 +- .../java/com/graphhopper/GraphHopperMultimodalIT.java | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java b/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java index 13b3ac4f19d..0624c536f2b 100644 --- a/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java +++ b/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java @@ -171,7 +171,7 @@ public void testWalkTransferBetweenFeeds() { assertEquals("10:00", LocalDateTime.ofInstant(walkDepartureTime, zoneId).toLocalTime().toString()); assertEquals(readWktLineString("LINESTRING (-116.76164 36.906093, -116.761812 36.905928, -116.76217 36.905659)"), transitSolution.getLegs().get(1).geometry); Instant walkArrivalTime = Instant.ofEpochMilli(transitSolution.getLegs().get(1).getArrivalTime().getTime()); - assertEquals("10:08:06.660", LocalDateTime.ofInstant(walkArrivalTime, zoneId).toLocalTime().toString()); + assertEquals("10:08:06.670", LocalDateTime.ofInstant(walkArrivalTime, zoneId).toLocalTime().toString()); assertEquals("EMSI,DADAN", ((Trip.PtLeg) transitSolution.getLegs().get(2)).stops.stream().map(s -> s.stop_id).collect(Collectors.joining(","))); } @@ -189,7 +189,7 @@ public void testMuseumToEmsi() { GHResponse route = ptRouter.route(ghRequest); ResponsePath walkRoute = route.getBest(); assertEquals(1, walkRoute.getLegs().size()); - assertEquals(486660, walkRoute.getTime()); // < 10 min, so the transfer in test above works ^^ + assertEquals(486670, walkRoute.getTime()); // < 10 min, so the transfer in test above works ^^ assertEquals(readWktLineString("LINESTRING (-116.76164 36.906093, -116.761812 36.905928, -116.76217 36.905659)"), walkRoute.getLegs().get(0).geometry); assertFalse(route.hasErrors()); } diff --git a/reader-gtfs/src/test/java/com/graphhopper/FreeWalkIT.java b/reader-gtfs/src/test/java/com/graphhopper/FreeWalkIT.java index b1f2f03ffcf..88455f09971 100644 --- a/reader-gtfs/src/test/java/com/graphhopper/FreeWalkIT.java +++ b/reader-gtfs/src/test/java/com/graphhopper/FreeWalkIT.java @@ -97,7 +97,7 @@ public void testWalkTransferBetweenFeeds() { assertEquals("JUSTICE_COURT,MUSEUM", firstLeg.stops.stream().map(s -> s.stop_id).collect(Collectors.joining(","))); assertEquals("EMSI,DADAN", secondLeg.stops.stream().map(s -> s.stop_id).collect(Collectors.joining(","))); assertEquals(LocalDateTime.parse("2007-01-01T10:00:00").atZone(zoneId).toInstant(), transferLeg.getDepartureTime().toInstant()); - assertEquals(LocalDateTime.parse("2007-01-01T10:08:06.660").atZone(zoneId).toInstant(), transferLeg.getArrivalTime().toInstant()); + assertEquals(LocalDateTime.parse("2007-01-01T10:08:06.670").atZone(zoneId).toInstant(), transferLeg.getArrivalTime().toInstant()); assertEquals(readWktLineString("LINESTRING (-116.76164 36.906093, -116.761812 36.905928, -116.76217 36.905659)"), transitSolution.getLegs().get(1).geometry); diff --git a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java index f4b4c2a4d80..7c7354cbfb9 100644 --- a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java +++ b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java @@ -93,11 +93,11 @@ public void testDepartureTimeOfAccessLegInProfileQuery() { ResponsePath firstTransitSolution = response.getAll().stream().filter(p -> p.getLegs().size() > 1).findFirst().get(); assertThat(firstTransitSolution.getLegs().get(0).getDepartureTime().toInstant().atZone(zoneId).toLocalTime()) - .isEqualTo(LocalTime.parse("06:41:04.827")); + .isEqualTo(LocalTime.parse("06:41:04.826")); assertThat(firstTransitSolution.getLegs().get(0).getArrivalTime().toInstant()) .isEqualTo(firstTransitSolution.getLegs().get(1).getDepartureTime().toInstant()); assertThat(firstTransitSolution.getLegs().get(2).getArrivalTime().toInstant().atZone(zoneId).toLocalTime()) - .isEqualTo(LocalTime.parse("06:52:02.640")); + .isEqualTo(LocalTime.parse("06:52:02.641")); // I like walking exactly as I like riding a bus (per travel time unit) // Now we get a walk solution which arrives earlier than the transit solutions. @@ -129,11 +129,11 @@ public void testDepartureTimeOfAccessLeg() { ResponsePath firstTransitSolution = response.getAll().stream().filter(p -> p.getLegs().size() > 1).findFirst().get(); // There can be a walk-only trip. assertThat(firstTransitSolution.getLegs().get(0).getDepartureTime().toInstant().atZone(zoneId).toLocalTime()) - .isEqualTo(LocalTime.parse("06:41:04.827")); + .isEqualTo(LocalTime.parse("06:41:04.826")); assertThat(firstTransitSolution.getLegs().get(0).getArrivalTime().toInstant()) .isEqualTo(firstTransitSolution.getLegs().get(1).getDepartureTime().toInstant()); assertThat(firstTransitSolution.getLegs().get(2).getArrivalTime().toInstant().atZone(zoneId).toLocalTime()) - .isEqualTo(LocalTime.parse("06:52:02.640")); + .isEqualTo(LocalTime.parse("06:52:02.641")); double EXPECTED_TOTAL_WALKING_DISTANCE = 496.96631386761055; assertThat(firstTransitSolution.getLegs().get(0).distance + firstTransitSolution.getLegs().get(2).distance) @@ -158,7 +158,7 @@ public void testDepartureTimeOfAccessLeg() { // In principle, this would dominate the transit solution, since it's faster, but // walking gets a penalty. assertThat(walkSolution.getLegs().get(0).getArrivalTime().toInstant().atZone(zoneId).toLocalTime()) - .isEqualTo(LocalTime.parse("06:51:10.301")); + .isEqualTo(LocalTime.parse("06:51:10.306")); assertThat(walkSolution.getLegs().size()).isEqualTo(1); assertThat(walkSolution.getNumChanges()).isEqualTo(-1); From fd0a49099f6fc28a8d021bea27b04dd5f1ab74fa Mon Sep 17 00:00:00 2001 From: easbar Date: Mon, 29 Aug 2022 23:04:04 +0200 Subject: [PATCH 147/389] Disable flaky test --- .../routing/weighting/custom/CustomWeightingTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index a8a92603c8c..e510d6df946 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -13,6 +13,7 @@ import com.graphhopper.util.GHUtility; import com.graphhopper.util.JsonFeature; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.util.Random; @@ -320,6 +321,7 @@ public void bugWithNaNForBarrierEdges() { assertTrue(Double.isInfinite(weighting.calcEdgeWeight(motorway, false))); } + @Disabled("this can still fail in some very rare cases, so this is disabled") @Test void sameTimeAsFastestWeighting() { // we make sure the returned times are the same, so we can check for regressions more easily when we migrate from fastest to custom From 468f23a6890d1b3dfabe4851a93245186e1ff432 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 30 Aug 2022 08:20:31 +0200 Subject: [PATCH 148/389] custom and fastest calcEdgeMillis again: make them actually the same --- .../com/graphhopper/routing/weighting/AbstractWeighting.java | 2 +- .../routing/weighting/custom/CustomWeightingTest.java | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java index 6f4c8402dd4..67c3a50a7fc 100644 --- a/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java +++ b/core/src/main/java/com/graphhopper/routing/weighting/AbstractWeighting.java @@ -71,7 +71,7 @@ public long calcEdgeMillis(EdgeIteratorState edgeState, boolean reverse) { if (speed == 0) throw new IllegalStateException("Speed cannot be 0 for unblocked edge, use access properties to mark edge blocked! Should only occur for shortest path calculation. See #242."); - return Math.round(edgeState.getDistance() * 3600 / speed); + return Math.round(edgeState.getDistance() / speed * 3.6 * 1000); } @Override diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java index e510d6df946..a8a92603c8c 100644 --- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java +++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java @@ -13,7 +13,6 @@ import com.graphhopper.util.GHUtility; import com.graphhopper.util.JsonFeature; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.util.Random; @@ -321,7 +320,6 @@ public void bugWithNaNForBarrierEdges() { assertTrue(Double.isInfinite(weighting.calcEdgeWeight(motorway, false))); } - @Disabled("this can still fail in some very rare cases, so this is disabled") @Test void sameTimeAsFastestWeighting() { // we make sure the returned times are the same, so we can check for regressions more easily when we migrate from fastest to custom From f9bd8c55957511a5905f757f7063a013b909ec82 Mon Sep 17 00:00:00 2001 From: Lukas Weber <32765578+lukasalexanderweber@users.noreply.github.com> Date: Tue, 30 Aug 2022 08:32:42 +0200 Subject: [PATCH 149/389] Validate that osm ids are not negative (#2652) --- CHANGELOG.md | 1 + CONTRIBUTORS.md | 1 + .../com/graphhopper/reader/ReaderElement.java | 27 ++++++++------ .../com/graphhopper/reader/ReaderNode.java | 4 +- .../graphhopper/reader/ReaderRelation.java | 13 +++---- .../com/graphhopper/reader/ReaderWay.java | 2 +- .../graphhopper/reader/osm/OSMFileHeader.java | 2 +- .../com/graphhopper/reader/osm/OSMReader.java | 8 ++-- .../graphhopper/reader/osm/OSMXMLHelper.java | 9 ++++- .../reader/osm/WaySegmentParser.java | 8 ++-- .../reader/osm/pbf/PbfBlobDecoder.java | 8 ++-- .../graphhopper/reader/OSMElementTest.java | 10 +++++ .../graphhopper/reader/osm/OSMReaderTest.java | 37 ++++++------------- 13 files changed, 67 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2bfdef7ab3..d0b3f98cfb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - replaced car$access with car_access (and same for $average_speed and $priority) - don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) - faster flexible routing, especially in conjunction with turn costs (#2571) +- negative OSM Ids are not supported any longer (#2652) ### 5.0 [23 Mar 2022] diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 6ad9db58041..11a77144e6f 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -48,6 +48,7 @@ Here is an overview: * kodonnell, adding support for CH and other algorithms (#60) and penalizing inner-link U-turns (#88) * legraina, improved docker for dockerhub * lmar, improved instructions + * lukasalexanderweber, fixes like #2652 * matkoniecz, tweaking documentation * manueltimita, fixes like #1651 * mathstpierre, fixes like #1753 diff --git a/core/src/main/java/com/graphhopper/reader/ReaderElement.java b/core/src/main/java/com/graphhopper/reader/ReaderElement.java index ab4895ed2c6..c6eebed28f8 100644 --- a/core/src/main/java/com/graphhopper/reader/ReaderElement.java +++ b/core/src/main/java/com/graphhopper/reader/ReaderElement.java @@ -28,28 +28,33 @@ * @author Peter */ public abstract class ReaderElement { - public static final int NODE = 0; - public static final int WAY = 1; - public static final int RELATION = 2; - public static final int FILEHEADER = 3; - private final int type; + public static enum Type { + NODE, + WAY, + RELATION, + FILEHEADER; + } private final long id; + private final Type type; private final Map properties; - protected ReaderElement(long id, int type) { + protected ReaderElement(long id, Type type) { this(id, type, new HashMap<>(4)); } - protected ReaderElement(long id, int type, Map properties) { + protected ReaderElement(long id, Type type, Map properties) { + if (id < 0) { + throw new IllegalArgumentException("Invalid OSM " + type + " Id: " + id + "; Ids must not be negative"); + } this.id = id; this.type = type; this.properties = properties; } - + public long getId() { return id; } - + protected String tagsToString() { if (properties.isEmpty()) return ""; @@ -180,11 +185,11 @@ public void clearTags() { properties.clear(); } - public int getType() { + public Type getType() { return type; } - public boolean isType(int type) { + public boolean isType(Type type) { return this.type == type; } diff --git a/core/src/main/java/com/graphhopper/reader/ReaderNode.java b/core/src/main/java/com/graphhopper/reader/ReaderNode.java index 9a89b25e64d..acd96bc8a62 100644 --- a/core/src/main/java/com/graphhopper/reader/ReaderNode.java +++ b/core/src/main/java/com/graphhopper/reader/ReaderNode.java @@ -30,13 +30,13 @@ public class ReaderNode extends ReaderElement { private final double lon; public ReaderNode(long id, double lat, double lon) { - super(id, NODE); + super(id, Type.NODE); this.lat = lat; this.lon = lon; } public ReaderNode(long id, double lat, double lon, Map tags) { - super(id, NODE, tags); + super(id, Type.NODE, tags); this.lat = lat; this.lon = lon; } diff --git a/core/src/main/java/com/graphhopper/reader/ReaderRelation.java b/core/src/main/java/com/graphhopper/reader/ReaderRelation.java index 4011fbb530a..1d782d84c68 100644 --- a/core/src/main/java/com/graphhopper/reader/ReaderRelation.java +++ b/core/src/main/java/com/graphhopper/reader/ReaderRelation.java @@ -32,7 +32,7 @@ public class ReaderRelation extends ReaderElement { protected List members; public ReaderRelation(long id) { - super(id, RELATION, new HashMap<>(2)); + super(id, Type.RELATION, new HashMap<>(2)); } @Override @@ -50,7 +50,7 @@ public List getMembers() { public boolean isMetaRelation() { if (members != null) for (Member member : members) { - if (member.getType() == RELATION) { + if (member.getType() == Type.RELATION) { return true; } } @@ -67,14 +67,11 @@ public void add(Member member) { * Container class for relation members */ public static class Member { - public static final int NODE = 0; - public static final int WAY = 1; - public static final int RELATION = 2; - private final int type; + private final Type type; private final long ref; private final String role; - public Member(int type, long ref, String role) { + public Member(Type type, long ref, String role) { this.type = type; this.ref = ref; this.role = role; @@ -85,7 +82,7 @@ public String toString() { return "Member " + type + ":" + ref; } - public int getType() { + public Type getType() { return type; } diff --git a/core/src/main/java/com/graphhopper/reader/ReaderWay.java b/core/src/main/java/com/graphhopper/reader/ReaderWay.java index 9cb15a3d5ab..5255ff63951 100644 --- a/core/src/main/java/com/graphhopper/reader/ReaderWay.java +++ b/core/src/main/java/com/graphhopper/reader/ReaderWay.java @@ -29,7 +29,7 @@ public class ReaderWay extends ReaderElement { protected final LongArrayList nodes = new LongArrayList(5); public ReaderWay(long id) { - super(id, WAY); + super(id, Type.WAY); } public LongArrayList getNodes() { diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMFileHeader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMFileHeader.java index d88b4cbf174..85a0677319b 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMFileHeader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMFileHeader.java @@ -31,7 +31,7 @@ */ public class OSMFileHeader extends ReaderElement { public OSMFileHeader() { - super(0, FILEHEADER); + super(0, Type.FILEHEADER); } /** diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 759512a3781..cd6491ba62b 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -505,7 +505,7 @@ protected void preprocessRelations(ReaderRelation relation) { if (!relation.isMetaRelation() && relation.hasTag("type", "route")) { // we keep track of all route relations, so they are available when we create edges later for (ReaderRelation.Member member : relation.getMembers()) { - if (member.getType() != ReaderRelation.Member.WAY) + if (member.getType() != ReaderElement.Type.WAY) continue; IntsRef oldRelationFlags = getRelFlagsMap(member.getRef()); IntsRef newRelationFlags = osmParsers.handleRelationTags(relation, oldRelationFlags); @@ -600,15 +600,15 @@ static List createTurnRelations(ReaderRelation relation, String long toWayID = -1; for (ReaderRelation.Member member : relation.getMembers()) { - if (ReaderElement.WAY == member.getType() && "to".equals(member.getRole())) + if (ReaderElement.Type.WAY == member.getType() && "to".equals(member.getRole())) toWayID = member.getRef(); - else if (ReaderElement.NODE == member.getType() && "via".equals(member.getRole())) + else if (ReaderElement.Type.NODE == member.getType() && "via".equals(member.getRole())) viaNodeID = member.getRef(); } if (toWayID >= 0 && viaNodeID >= 0) { List res = new ArrayList<>(2); for (ReaderRelation.Member member : relation.getMembers()) { - if (ReaderElement.WAY == member.getType() && "from".equals(member.getRole())) { + if (ReaderElement.Type.WAY == member.getType() && "from".equals(member.getRole())) { OSMTurnRelation osmTurnRelation = new OSMTurnRelation(member.getRef(), viaNodeID, toWayID, type); osmTurnRelation.setVehicleTypeRestricted(vehicleTypeRestricted); osmTurnRelation.setVehicleTypesExcept(vehicleTypesExcept); diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMXMLHelper.java b/core/src/main/java/com/graphhopper/reader/osm/OSMXMLHelper.java index f2bd6d6837c..11db7304929 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMXMLHelper.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMXMLHelper.java @@ -32,7 +32,6 @@ * @author Peter Karich */ public class OSMXMLHelper { - private static final String TYPE_DECODE = "nwr"; public static ReaderNode createNode(long id, XMLStreamReader parser) throws XMLStreamException { ReaderNode node = new ReaderNode(id, @@ -105,7 +104,13 @@ private static void readMembers(ReaderRelation rel, XMLStreamReader parser) thro public static Member createMember(XMLStreamReader parser) { String typeName = parser.getAttributeValue(null, "type"); - int type = TYPE_DECODE.indexOf(typeName.charAt(0)); + ReaderElement.Type type = ReaderElement.Type.NODE; + if (typeName.startsWith("w")) { + type = ReaderElement.Type.WAY; + } + else if (typeName.startsWith("r")) { + type = ReaderElement.Type.RELATION; + } long ref = Long.parseLong(parser.getAttributeValue(null, "ref")); String role = parser.getAttributeValue(null, "role"); return new ReaderRelation.Member(type, ref, role); diff --git a/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java b/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java index b1efdcc80eb..0e4df35521e 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java +++ b/core/src/main/java/com/graphhopper/reader/osm/WaySegmentParser.java @@ -513,16 +513,16 @@ public WaySegmentParser build() { private interface ReaderElementHandler { default void handleElement(ReaderElement elem) throws ParseException { switch (elem.getType()) { - case ReaderElement.NODE: + case NODE: handleNode((ReaderNode) elem); break; - case ReaderElement.WAY: + case WAY: handleWay((ReaderWay) elem); break; - case ReaderElement.RELATION: + case RELATION: handleRelation((ReaderRelation) elem); break; - case ReaderElement.FILEHEADER: + case FILEHEADER: handleFileHeader((OSMFileHeader) elem); break; default: diff --git a/core/src/main/java/com/graphhopper/reader/osm/pbf/PbfBlobDecoder.java b/core/src/main/java/com/graphhopper/reader/osm/pbf/PbfBlobDecoder.java index 498af8d267d..70c154f8de5 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/pbf/PbfBlobDecoder.java +++ b/core/src/main/java/com/graphhopper/reader/osm/pbf/PbfBlobDecoder.java @@ -289,14 +289,14 @@ private void buildRelationMembers(ReaderRelation relation, Osmformat.Relation.MemberType memberType = memberTypeIterator.next(); refId += memberIdIterator.next(); - int entityType = ReaderRelation.Member.NODE; + ReaderElement.Type entityType = ReaderElement.Type.NODE; if (memberType == Osmformat.Relation.MemberType.WAY) { - entityType = ReaderRelation.Member.WAY; + entityType = ReaderElement.Type.WAY; } else if (memberType == Osmformat.Relation.MemberType.RELATION) { - entityType = ReaderRelation.Member.RELATION; + entityType = ReaderElement.Type.RELATION; } if (checkData) { - if (entityType == ReaderRelation.Member.NODE && memberType != Osmformat.Relation.MemberType.NODE) { + if (entityType == ReaderElement.Type.NODE && memberType != Osmformat.Relation.MemberType.NODE) { throw new RuntimeException("Member type of " + memberType + " is not supported."); } } diff --git a/core/src/test/java/com/graphhopper/reader/OSMElementTest.java b/core/src/test/java/com/graphhopper/reader/OSMElementTest.java index 7bbd7c0049b..37d991b20ed 100644 --- a/core/src/test/java/com/graphhopper/reader/OSMElementTest.java +++ b/core/src/test/java/com/graphhopper/reader/OSMElementTest.java @@ -23,6 +23,7 @@ import java.util.Map; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -48,4 +49,13 @@ public void testSetTags() { instance.setTags(null); assertFalse(instance.hasTag("test", "xy")); } + + @Test + public void testInvalidIDs() { + Exception exception = assertThrows(IllegalArgumentException.class, () -> { + new ReaderWay(-1); + }); + assertTrue(exception.getMessage().contains("Invalid OSM WAY Id: -1;")); + } + } diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index c942229ff3e..b0bb0bd64c7 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -22,6 +22,7 @@ import com.graphhopper.GraphHopper; import com.graphhopper.GraphHopperTest; import com.graphhopper.config.Profile; +import com.graphhopper.reader.ReaderElement; import com.graphhopper.reader.OSMTurnRelation; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.dem.ElevationProvider; @@ -318,26 +319,10 @@ public void testFoot() { @Test public void testNegativeIds() { String fileNegIds = "test-osm-negative-ids.xml"; - GraphHopper hopper = new GraphHopperFacade(fileNegIds).importOrLoad(); - Graph graph = hopper.getBaseGraph(); - assertEquals(4, graph.getNodes()); - int n20 = AbstractGraphStorageTester.getIdOf(graph, 52); - int n10 = AbstractGraphStorageTester.getIdOf(graph, 51.2492152); - int n30 = AbstractGraphStorageTester.getIdOf(graph, 51.2); - assertEquals(GHUtility.asSet(n20), GHUtility.getNeighbors(carOutExplorer.setBaseNode(n10))); - assertEquals(3, GHUtility.count(carOutExplorer.setBaseNode(n20))); - assertEquals(GHUtility.asSet(n20), GHUtility.getNeighbors(carOutExplorer.setBaseNode(n30))); - - EdgeIterator iter = carOutExplorer.setBaseNode(n20); - assertTrue(iter.next()); - - assertTrue(iter.next()); - assertEquals(n30, iter.getAdjNode()); - assertEquals(93147, iter.getDistance(), 1); - - assertTrue(iter.next()); - assertEquals(n10, iter.getAdjNode()); - assertEquals(88643, iter.getDistance(), 1); + Exception exception = assertThrows(RuntimeException.class, () -> { + new GraphHopperFacade(fileNegIds).importOrLoad(); + }); + assertTrue(exception.getCause().getMessage().contains("Invalid OSM NODE Id: -10;")); } @Test @@ -502,8 +487,8 @@ public void testRelation() { OSMParsers osmParsers = new OSMParsers() .addRelationTagParser(relConf -> new OSMBikeNetworkTagParser(bikeNetworkEnc, relConf)); ReaderRelation osmRel = new ReaderRelation(1); - osmRel.add(new ReaderRelation.Member(ReaderRelation.WAY, 1, "")); - osmRel.add(new ReaderRelation.Member(ReaderRelation.WAY, 2, "")); + osmRel.add(new ReaderRelation.Member(ReaderElement.Type.WAY, 1, "")); + osmRel.add(new ReaderRelation.Member(ReaderElement.Type.WAY, 2, "")); osmRel.setTag("route", "bicycle"); osmRel.setTag("network", "lcn"); @@ -598,10 +583,10 @@ public void testMultipleFromForNoEntry() { ReaderRelation rel = new ReaderRelation(1L); rel.setTag("restriction", "no_entry"); - rel.add(new ReaderRelation.Member(ReaderRelation.Member.WAY, 1L, "from")); - rel.add(new ReaderRelation.Member(ReaderRelation.Member.WAY, 2L, "from")); - rel.add(new ReaderRelation.Member(ReaderRelation.Member.NODE, 3L, "via")); - rel.add(new ReaderRelation.Member(ReaderRelation.Member.WAY, 4L, "to")); + rel.add(new ReaderRelation.Member(ReaderElement.Type.WAY, 1L, "from")); + rel.add(new ReaderRelation.Member(ReaderElement.Type.WAY, 2L, "from")); + rel.add(new ReaderRelation.Member(ReaderElement.Type.NODE, 3L, "via")); + rel.add(new ReaderRelation.Member(ReaderElement.Type.WAY, 4L, "to")); List osmRel = OSMReader.createTurnRelations(rel); assertEquals(2, osmRel.size()); From 5a4078a5fb23f82f4d2682b2e6db6de30f550d2e Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 30 Aug 2022 08:41:28 +0200 Subject: [PATCH 150/389] Add comment about negative osm ids, code formatting --- .../com/graphhopper/reader/ReaderElement.java | 23 ++++++++++--------- .../com/graphhopper/reader/osm/OSMReader.java | 1 + .../graphhopper/reader/osm/OSMXMLHelper.java | 8 +++---- .../graphhopper/reader/OSMElementTest.java | 16 ++++++------- .../graphhopper/reader/osm/OSMReaderTest.java | 6 ++--- 5 files changed, 26 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/ReaderElement.java b/core/src/main/java/com/graphhopper/reader/ReaderElement.java index c6eebed28f8..d7f0ce61b4a 100644 --- a/core/src/main/java/com/graphhopper/reader/ReaderElement.java +++ b/core/src/main/java/com/graphhopper/reader/ReaderElement.java @@ -28,12 +28,13 @@ * @author Peter */ public abstract class ReaderElement { - public static enum Type { - NODE, - WAY, - RELATION, - FILEHEADER; - } + public static enum Type { + NODE, + WAY, + RELATION, + FILEHEADER; + } + private final long id; private final Type type; private final Map properties; @@ -43,18 +44,18 @@ protected ReaderElement(long id, Type type) { } protected ReaderElement(long id, Type type, Map properties) { - if (id < 0) { - throw new IllegalArgumentException("Invalid OSM " + type + " Id: " + id + "; Ids must not be negative"); - } + if (id < 0) { + throw new IllegalArgumentException("Invalid OSM " + type + " Id: " + id + "; Ids must not be negative"); + } this.id = id; this.type = type; this.properties = properties; } - + public long getId() { return id; } - + protected String tagsToString() { if (properties.isEmpty()) return ""; diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index cd6491ba62b..700e66a228d 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -596,6 +596,7 @@ static List createTurnRelations(ReaderRelation relation, String String vehicleTypeRestricted, List vehicleTypesExcept) { OSMTurnRelation.Type type = OSMTurnRelation.Type.getRestrictionType(restrictionType); if (type != OSMTurnRelation.Type.UNSUPPORTED) { + // we use -1 to indicate 'missing', which is fine because we exclude negative OSM IDs (see #2652) long viaNodeID = -1; long toWayID = -1; diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMXMLHelper.java b/core/src/main/java/com/graphhopper/reader/osm/OSMXMLHelper.java index 11db7304929..b27c03f3f41 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMXMLHelper.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMXMLHelper.java @@ -26,7 +26,6 @@ import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; -import java.util.List; /** * @author Peter Karich @@ -106,10 +105,9 @@ public static Member createMember(XMLStreamReader parser) { String typeName = parser.getAttributeValue(null, "type"); ReaderElement.Type type = ReaderElement.Type.NODE; if (typeName.startsWith("w")) { - type = ReaderElement.Type.WAY; - } - else if (typeName.startsWith("r")) { - type = ReaderElement.Type.RELATION; + type = ReaderElement.Type.WAY; + } else if (typeName.startsWith("r")) { + type = ReaderElement.Type.RELATION; } long ref = Long.parseLong(parser.getAttributeValue(null, "ref")); String role = parser.getAttributeValue(null, "role"); diff --git a/core/src/test/java/com/graphhopper/reader/OSMElementTest.java b/core/src/test/java/com/graphhopper/reader/OSMElementTest.java index 37d991b20ed..754af4851b4 100644 --- a/core/src/test/java/com/graphhopper/reader/OSMElementTest.java +++ b/core/src/test/java/com/graphhopper/reader/OSMElementTest.java @@ -22,9 +22,7 @@ import java.util.HashMap; import java.util.Map; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; /** * @author Peter Karich @@ -49,13 +47,13 @@ public void testSetTags() { instance.setTags(null); assertFalse(instance.hasTag("test", "xy")); } - + @Test public void testInvalidIDs() { - Exception exception = assertThrows(IllegalArgumentException.class, () -> { - new ReaderWay(-1); - }); - assertTrue(exception.getMessage().contains("Invalid OSM WAY Id: -1;")); + Exception exception = assertThrows(IllegalArgumentException.class, () -> { + new ReaderWay(-1); + }); + assertTrue(exception.getMessage().contains("Invalid OSM WAY Id: -1;")); } - + } diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index b0bb0bd64c7..796816b547b 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -22,8 +22,8 @@ import com.graphhopper.GraphHopper; import com.graphhopper.GraphHopperTest; import com.graphhopper.config.Profile; -import com.graphhopper.reader.ReaderElement; import com.graphhopper.reader.OSMTurnRelation; +import com.graphhopper.reader.ReaderElement; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.dem.ElevationProvider; import com.graphhopper.reader.dem.SRTMProvider; @@ -320,8 +320,8 @@ public void testFoot() { public void testNegativeIds() { String fileNegIds = "test-osm-negative-ids.xml"; Exception exception = assertThrows(RuntimeException.class, () -> { - new GraphHopperFacade(fileNegIds).importOrLoad(); - }); + new GraphHopperFacade(fileNegIds).importOrLoad(); + }); assertTrue(exception.getCause().getMessage().contains("Invalid OSM NODE Id: -10;")); } From 8f5c7b2a0be13487c2a1b2e411eb3f4cf7051d26 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 30 Aug 2022 09:28:27 +0200 Subject: [PATCH 151/389] OSMParsers: don't accept null TagParser --- core/src/main/java/com/graphhopper/routing/util/OSMParsers.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java index 680aa3ab8ea..71ee8a42fe6 100644 --- a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java +++ b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java @@ -53,6 +53,7 @@ public OSMParsers(List wayTagParsers, List vehicleT } public OSMParsers addWayTagParser(TagParser tagParser) { + if (tagParser == null) throw new IllegalArgumentException("TagParser must not be null"); wayTagParsers.add(tagParser); return this; } From 3b22d490c685533436d4b5d7b6bee0ce61698ef2 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 30 Aug 2022 09:57:53 +0200 Subject: [PATCH 152/389] replace car4wd with roads and a custom_model (#2651) --- config-example.yml | 2 +- .../routing/util/Car4WDTagParser.java | 50 ------- .../DefaultVehicleEncodedValuesFactory.java | 4 +- .../util/DefaultVehicleTagParserFactory.java | 2 - .../routing/util/VehicleEncodedValues.java | 4 - .../util/VehicleEncodedValuesFactory.java | 1 - .../routing/util/Car4WDTagParserTest.java | 139 ------------------ docs/core/profiles.md | 1 - .../graphhopper/example/RoutingExample.java | 4 + .../com/graphhopper/maps/img/car4wd.svg | 81 ---------- .../application/resources/car4wd.yml | 10 ++ 11 files changed, 17 insertions(+), 281 deletions(-) delete mode 100644 core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java delete mode 100644 core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/car4wd.svg create mode 100644 web/src/test/resources/com/graphhopper/application/resources/car4wd.yml diff --git a/config-example.yml b/config-example.yml index 299b78062fe..5ce6cde71a0 100644 --- a/config-example.yml +++ b/config-example.yml @@ -8,7 +8,7 @@ graphhopper: ##### Vehicles ##### - # More options: foot,hike,bike,bike2,mtb,racingbike,motorcycle,car4wd,wheelchair (comma separated) + # More options: foot,hike,bike,bike2,mtb,racingbike,motorcycle,wheelchair (comma separated) # bike2 takes elevation data into account (like up-hill is slower than down-hill) and requires enabling graph.elevation.provider below. # graph.flag_encoders: car diff --git a/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java b/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java deleted file mode 100644 index 79ed0dd4b19..00000000000 --- a/core/src/main/java/com/graphhopper/routing/util/Car4WDTagParser.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.routing.util; - -import com.graphhopper.routing.ev.*; -import com.graphhopper.util.PMap; - - -/** - * Defines bit layout for cars with four wheel drive - * - * @author zstadler - */ -public class Car4WDTagParser extends CarTagParser { - - public Car4WDTagParser(EncodedValueLookup lookup, PMap properties) { - this( - lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "car4wd"))), - lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "car4wd"))), - lookup.hasEncodedValue(TurnCost.key(properties.getString("name", "car4wd"))) ? lookup.getDecimalEncodedValue(TurnCost.key(properties.getString("name", "car4wd"))) : null, - lookup.getBooleanEncodedValue(Roundabout.KEY), - new PMap(properties).putObject("name", "car4wd"), - TransportationMode.CAR - ); - } - - public Car4WDTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue turnCostEnc, - BooleanEncodedValue roundaboutEnc, - PMap properties, TransportationMode transportationMode) { - super(accessEnc, speedEnc, turnCostEnc, roundaboutEnc, new PMap(properties).putObject("name", properties.getString("name", "car4wd")), transportationMode, - speedEnc.getNextStorableValue(CAR_MAX_SPEED)); - trackTypeSpeedMap.put("grade4", 5); // ... some hard or compressed materials - trackTypeSpeedMap.put("grade5", 5); // ... no hard materials. soil/sand/grass - } -} diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java index 394d38fb64c..ff59913d555 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java @@ -33,8 +33,8 @@ public VehicleEncodedValues createVehicleEncodedValues(String name, PMap configu if (name.equals(CAR)) return VehicleEncodedValues.car(configuration); - if (name.equals(CAR4WD)) - return VehicleEncodedValues.car4wd(configuration); + if (name.equals("car4wd")) + throw new IllegalArgumentException("Instead of car4wd use the roads vehicle and a custom_model, see web/src/test/resources/com/graphhopper/application/resources/car4wd.yml"); if (name.equals(BIKE)) return VehicleEncodedValues.bike(configuration); diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java index b704d3793eb..a7109eedf16 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java @@ -29,8 +29,6 @@ public VehicleTagParser createParser(EncodedValueLookup lookup, String name, PMa return new RoadsTagParser(lookup, configuration); if (name.equals(CAR)) return new CarTagParser(lookup, configuration); - if (name.equals(CAR4WD)) - return new Car4WDTagParser(lookup, configuration); if (name.equals(BIKE)) return new BikeTagParser(lookup, configuration); if (name.equals(BIKE2)) diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index 59828288b7b..1363c806e55 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -105,10 +105,6 @@ public static VehicleEncodedValues car(PMap properties) { return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc); } - public static VehicleEncodedValues car4wd(PMap properties) { - return car(new PMap(properties).putObject("name", properties.getString("name", "car4wd"))); - } - public static VehicleEncodedValues motorcycle(PMap properties) { String name = properties.getString("name", "motorcycle"); int speedBits = properties.getInt("speed_bits", 5); diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java index 57402acfba4..263644e6911 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java @@ -25,7 +25,6 @@ public interface VehicleEncodedValuesFactory { String ROADS = "roads"; String CAR = "car"; - String CAR4WD = "car4wd"; String BIKE = "bike"; String BIKE2 = "bike2"; String RACINGBIKE = "racingbike"; diff --git a/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java deleted file mode 100644 index 90473eee929..00000000000 --- a/core/src/test/java/com/graphhopper/routing/util/Car4WDTagParserTest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.routing.util; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.reader.osm.conditional.DateRangeParser; -import com.graphhopper.routing.ev.EncodedValueLookup; -import com.graphhopper.util.Helper; -import com.graphhopper.util.PMap; -import org.junit.jupiter.api.Test; - -import java.text.DateFormat; -import java.util.Date; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * @author Peter Karich - * @author zstadler - */ -public class Car4WDTagParserTest extends CarTagParserTest { - - @Override - protected String getCarName() { - return "car4wd"; - } - - @Override - CarTagParser createParser(EncodedValueLookup lookup, PMap properties) { - Car4WDTagParser parser = new Car4WDTagParser(lookup, properties); - parser.init(new DateRangeParser()); - return parser; - } - - @Override - @Test - public void testAccess() { - ReaderWay way = new ReaderWay(1); - assertTrue(parser.getAccess(way).canSkip()); - way.setTag("highway", "service"); - assertTrue(parser.getAccess(way).isWay()); - way.setTag("access", "no"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "track"); - assertTrue(parser.getAccess(way).isWay()); - - way.setTag("motorcar", "no"); - assertTrue(parser.getAccess(way).canSkip()); - - // for now allow grade1+2+3 for every country, see #253 - way.clearTags(); - way.setTag("highway", "track"); - way.setTag("tracktype", "grade2"); - assertTrue(parser.getAccess(way).isWay()); - // This is the only difference from a "car" - way.setTag("tracktype", "grade4"); - assertTrue(parser.getAccess(way).isWay()); - - way.clearTags(); - way.setTag("highway", "service"); - way.setTag("access", "delivery"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "unclassified"); - way.setTag("ford", "yes"); - assertTrue(parser.getAccess(way).canSkip()); - way.setTag("motorcar", "yes"); - assertTrue(parser.getAccess(way).isWay()); - - way.clearTags(); - way.setTag("route", "ferry"); - assertTrue(parser.getAccess(way).isFerry()); - way.setTag("motorcar", "no"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("route", "ferry"); - way.setTag("foot", "yes"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("access", "yes"); - way.setTag("motor_vehicle", "no"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "service"); - way.setTag("access", "yes"); - way.setTag("motor_vehicle", "no"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "service"); - way.setTag("access", "no"); - way.setTag("motorcar", "yes"); - assertTrue(parser.getAccess(way).isWay()); - - way.clearTags(); - way.setTag("highway", "service"); - way.setTag("access", "emergency"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "service"); - way.setTag("motor_vehicle", "emergency"); - assertTrue(parser.getAccess(way).canSkip()); - - DateFormat simpleDateFormat = Helper.createFormatter("yyyy MMM dd"); - - way.clearTags(); - way.setTag("highway", "road"); - way.setTag("access:conditional", "no @ (" + simpleDateFormat.format(new Date().getTime()) + ")"); - assertTrue(parser.getAccess(way).canSkip()); - - way.clearTags(); - way.setTag("highway", "road"); - way.setTag("access", "no"); - way.setTag("access:conditional", "yes @ (" + simpleDateFormat.format(new Date().getTime()) + ")"); - assertTrue(parser.getAccess(way).isWay()); - } -} diff --git a/docs/core/profiles.md b/docs/core/profiles.md index 5999a595c41..0e72e276a35 100644 --- a/docs/core/profiles.md +++ b/docs/core/profiles.md @@ -38,7 +38,6 @@ The vehicle field must correspond to one of GraphHopper's built-in vehicle types - bike2 - mtb - car -- car4wd - motorcycle By choosing a vehicle GraphHopper determines the accessibility and a default travel speed for the different road types. diff --git a/example/src/main/java/com/graphhopper/example/RoutingExample.java b/example/src/main/java/com/graphhopper/example/RoutingExample.java index 8489adb940d..2eb0d6d54bd 100644 --- a/example/src/main/java/com/graphhopper/example/RoutingExample.java +++ b/example/src/main/java/com/graphhopper/example/RoutingExample.java @@ -115,6 +115,10 @@ public static void headingAndAlternativeRoute(GraphHopper hopper) { assert Helper.round(res.getBest().getDistance(), -2) == 2300; } + /** + * To customize profiles in the config.yml file you can use a json or yml file or embed it directly. See this list: + * web/src/test/resources/com/graphhopper/application/resources and https://www.graphhopper.com/?s=customizable+routing + */ public static void customizableRouting(String ghLoc) { GraphHopper hopper = new GraphHopper(); hopper.setOSMFile(ghLoc); diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/car4wd.svg b/web-bundle/src/main/resources/com/graphhopper/maps/img/car4wd.svg deleted file mode 100644 index 0ea884489cd..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/img/car4wd.svg +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/web/src/test/resources/com/graphhopper/application/resources/car4wd.yml b/web/src/test/resources/com/graphhopper/application/resources/car4wd.yml new file mode 100644 index 00000000000..930eb4364f7 --- /dev/null +++ b/web/src/test/resources/com/graphhopper/application/resources/car4wd.yml @@ -0,0 +1,10 @@ +# use this custom model with vehicle: roads +distance_influence: 1 +speed: + - if: "track_type == GRADE4 || track_type == GRADE5" + limit_to: 5 + - else: "" + limit_to: "car_average_speed" +priority: + - if: "track_type != GRADE4 && track_type != GRADE5 && car_access == false" + multiply_by: "0" \ No newline at end of file From 9dcc67c21b61ec666ea6137ba01596bf5d460b72 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 31 Aug 2022 09:45:45 +0200 Subject: [PATCH 153/389] Revert "OSMParsers: don't accept null TagParser" This reverts commit 8f5c7b2a0be13487c2a1b2e411eb3f4cf7051d26. --- core/src/main/java/com/graphhopper/routing/util/OSMParsers.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java index 71ee8a42fe6..680aa3ab8ea 100644 --- a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java +++ b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java @@ -53,7 +53,6 @@ public OSMParsers(List wayTagParsers, List vehicleT } public OSMParsers addWayTagParser(TagParser tagParser) { - if (tagParser == null) throw new IllegalArgumentException("TagParser must not be null"); wayTagParsers.add(tagParser); return this; } From a615a6b9c097f91dd7e7dc5852761f655e895a76 Mon Sep 17 00:00:00 2001 From: Andi Date: Wed, 31 Aug 2022 10:59:57 +0200 Subject: [PATCH 154/389] Add urban density encoded value to identify built-up areas (#2637) --- CHANGELOG.md | 1 + config-example.yml | 14 ++ .../java/com/graphhopper/GraphHopper.java | 59 +++++++- .../routing/ch/CHPreparationHandler.java | 10 +- .../graphhopper/routing/ev/Development.java | 40 ++++++ .../routing/lm/LMPreparationHandler.java | 10 +- .../routing/util/DevelopmentCalculator.java | 126 ++++++++++++++++++ .../routing/util/RoadDensityCalculator.java | 114 ++++++++++++++++ .../java/com/graphhopper/util/GHUtility.java | 11 +- .../graphhopper/resources/MVTResource.java | 40 +++--- .../graphhopper/maps/js/config/tileLayers.js | 89 +++++++++---- 11 files changed, 456 insertions(+), 58 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/ev/Development.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/DevelopmentCalculator.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/RoadDensityCalculator.java diff --git a/CHANGELOG.md b/CHANGELOG.md index d0b3f98cfb2..6dcecddca4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) - faster flexible routing, especially in conjunction with turn costs (#2571) - negative OSM Ids are not supported any longer (#2652) +- new development encoded value based on road density (#2637) ### 5.0 [23 Mar 2022] diff --git a/config-example.yml b/config-example.yml index 5ce6cde71a0..3a08898e3da 100644 --- a/config-example.yml +++ b/config-example.yml @@ -109,6 +109,20 @@ graphhopper: # elevation and will remove the extra points that long edge sampling added # graph.elevation.way_point_max_distance: 10 + #### Development (built-up areas) #### + + + # This feature allows classifying roads into 'rural', 'residential' and 'city' areas (encoded value 'development') + # Use 1 or more threads to enable the feature + # graph.development.threads: 8 + # Use higher/lower sensitivities if too little/many roads fall into the according categories. + # Using smaller radii will speed up the classification, but only change these values if you know what you are doing. + # If you do not need the (rather slow) city classification set city_radius to zero. + # graph.development.residential_radius: 300 + # graph.development.residential_sensitivity: 60 + # graph.development.city_radius: 2000 + # graph.development.city_sensitivity: 30 + #### Speed, hybrid and flexible mode #### diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 21a810bdbad..75cc300ebf8 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -105,8 +105,14 @@ public class GraphHopper { private LocationIndex locationIndex; private int preciseIndexResolution = 300; private int maxRegionSearch = 4; - // for prepare + // subnetworks private int minNetworkSize = 200; + // residential areas + private double residentialAreaRadius = 300; + private double residentialAreaSensitivity = 60; + private double cityAreaRadius = 2000; + private double cityAreaSensitivity = 30; + private int developmentCalculationThreads = 0; // preparation handlers private final LMPreparationHandler lmPreparationHandler = new LMPreparationHandler(); @@ -188,6 +194,32 @@ public GraphHopper setMinNetworkSize(int minNetworkSize) { return this; } + /** + * Configures the development classification. Each edge will be classified as 'rural','residential' or 'city', {@link Development} + * + * @param residentialAreaRadius in meters. The higher this value the longer the calculation will take and the bigger the area for + * which the road density used to identify residential areas is calculated. + * @param residentialAreaSensitivity Use this to find a trade-off between too many roads being classified as residential (too high + * values) and not enough roads being classified as residential (too small values) + * @param cityAreaRadius in meters. The higher this value the longer the calculation will take and the bigger the area for + * which the road density used to identify city areas is calculated. Set this to zero + * to skip the city classification. + * @param cityAreaSensitivity Use this to find a trade-off between too many roads being classified as city (too high values) + * and not enough roads being classified as city (too small values) + * @param threads the number of threads used for the calculation. If this is zero the development + * classification is skipped entirely + */ + public GraphHopper setDevelopmentClassification(double residentialAreaRadius, double residentialAreaSensitivity, + double cityAreaRadius, double cityAreaSensitivity, int threads) { + ensureNotLoaded(); + this.residentialAreaRadius = residentialAreaRadius; + this.residentialAreaSensitivity = residentialAreaSensitivity; + this.cityAreaRadius = cityAreaRadius; + this.cityAreaSensitivity = cityAreaSensitivity; + this.developmentCalculationThreads = threads; + return this; + } + /** * Only valid option for in-memory graph and if you e.g. want to disable store on flush for unit * tests. Specify storeOnFlush to true if you want that existing data will be loaded FROM disc @@ -539,6 +571,13 @@ public GraphHopper init(GraphHopperConfig ghConfig) { preciseIndexResolution = ghConfig.getInt("index.high_resolution", preciseIndexResolution); maxRegionSearch = ghConfig.getInt("index.max_region_search", maxRegionSearch); + // development calculation + residentialAreaRadius = ghConfig.getDouble("graph.development.residential_radius", residentialAreaRadius); + residentialAreaSensitivity = ghConfig.getDouble("graph.development.residential_sensitivity", residentialAreaSensitivity); + cityAreaRadius = ghConfig.getDouble("graph.development.city_radius", cityAreaRadius); + cityAreaSensitivity = ghConfig.getDouble("graph.development.city_sensitivity", cityAreaSensitivity); + developmentCalculationThreads = ghConfig.getInt("graph.development.threads", developmentCalculationThreads); + // routing routerConfig.setMaxVisitedNodes(ghConfig.getInt(Routing.INIT_MAX_VISITED_NODES, routerConfig.getMaxVisitedNodes())); routerConfig.setMaxRoundTripRetries(ghConfig.getInt(RoundTrip.INIT_MAX_RETRIES, routerConfig.getMaxRoundTripRetries())); @@ -553,7 +592,7 @@ public GraphHopper init(GraphHopperConfig ghConfig) { return this; } - private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String encodedValuesStr, String dateRangeParserString, Collection profiles) { + private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String encodedValuesStr, String dateRangeParserString, boolean withDevelopment, Collection profiles) { Map flagEncodersMap = new LinkedHashMap<>(); for (String encoderStr : flagEncodersStr.split(",")) { String name = encoderStr.split("\\|")[0].trim(); @@ -581,6 +620,8 @@ private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String en EncodingManager.Builder emBuilder = new EncodingManager.Builder(); flagEncodersMap.forEach((name, encoderStr) -> emBuilder.add(vehicleEncodedValuesFactory.createVehicleEncodedValues(name, new PMap(encoderStr)))); profiles.forEach(profile -> emBuilder.add(Subnetwork.create(profile.getName()))); + if (withDevelopment) + emBuilder.add(Development.create()); encodedValueStrings.forEach(s -> emBuilder.add(encodedValueFactory.create(s))); encodingManager = emBuilder.build(); @@ -739,7 +780,8 @@ public void importAndClose() { private void process(boolean closeEarly) { GHDirectory directory = new GHDirectory(ghLocation, dataAccessDefaultType); directory.configure(dataAccessConfig); - buildEncodingManagerAndOSMParsers(flagEncodersString, encodedValuesString, dateRangeParserString, profilesByName.values()); + boolean withDevelopment = developmentCalculationThreads > 0; + buildEncodingManagerAndOSMParsers(flagEncodersString, encodedValuesString, dateRangeParserString, withDevelopment, profilesByName.values()); baseGraph = new BaseGraph.Builder(getEncodingManager()) .setDir(directory) .set3D(hasElevation()) @@ -779,6 +821,17 @@ protected void postImport() { if (hasElevation()) interpolateBridgesTunnelsAndFerries(); + + if (encodingManager.hasEncodedValue(Development.KEY)) { + EnumEncodedValue developmentEnc = encodingManager.getEnumEncodedValue(Development.KEY, Development.class); + if (!encodingManager.hasEncodedValue(RoadClass.KEY)) + throw new IllegalArgumentException("Development calculation requires " + RoadClass.KEY); + if (!encodingManager.hasEncodedValue(RoadClassLink.KEY)) + throw new IllegalArgumentException("Development calculation requires " + RoadClassLink.KEY); + EnumEncodedValue roadClassEnc = encodingManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); + BooleanEncodedValue roadClassLinkEnc = encodingManager.getBooleanEncodedValue(RoadClassLink.KEY); + DevelopmentCalculator.calcDevelopment(baseGraph, developmentEnc, roadClassEnc, roadClassLinkEnc, residentialAreaRadius, residentialAreaSensitivity, cityAreaRadius, cityAreaSensitivity, developmentCalculationThreads); + } } protected void importOSM() { diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationHandler.java b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationHandler.java index 3a39fbf1bbe..80e471ad926 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationHandler.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationHandler.java @@ -29,6 +29,7 @@ import java.util.*; import java.util.concurrent.Callable; import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.graphhopper.util.Helper.createFormatter; import static com.graphhopper.util.Helper.getMemInfo; @@ -98,8 +99,8 @@ public void setPreparationThreads(int preparationThreads) { public Map load(BaseGraph graph, List chConfigs) { Map loaded = Collections.synchronizedMap(new LinkedHashMap<>()); - List> callables = chConfigs.stream() - .map(c -> (Callable) () -> { + Stream> callables = chConfigs.stream() + .map(c -> () -> { CHStorage chStorage = new CHStorage(graph.getDirectory(), c.getName(), graph.getSegmentSize(), c.isEdgeBased()); if (chStorage.loadExisting()) loaded.put(c.getName(), RoutingCHGraphImpl.fromGraph(graph, chStorage, c)); @@ -109,8 +110,7 @@ public Map load(BaseGraph graph, List chConfig graph.getDirectory().remove("shortcuts_" + c.getName()); } return c.getName(); - }) - .collect(Collectors.toList()); + }); GHUtility.runConcurrently(callables, preparationThreads); return loaded; } @@ -143,7 +143,7 @@ public Map prepare(BaseGraph baseG return name; }); } - GHUtility.runConcurrently(callables, preparationThreads); + GHUtility.runConcurrently(callables.stream(), preparationThreads); LOGGER.info("Finished CH preparation, {}", getMemInfo()); return results; } diff --git a/core/src/main/java/com/graphhopper/routing/ev/Development.java b/core/src/main/java/com/graphhopper/routing/ev/Development.java new file mode 100644 index 00000000000..1507c9d4914 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/Development.java @@ -0,0 +1,40 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.ev; + +public enum Development { + RURAL("rural"), RESIDENTIAL("residential"), CITY("city"); + + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, Development.class); + } + + public static final String KEY = "development"; + + private final String name; + + Development(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/lm/LMPreparationHandler.java b/core/src/main/java/com/graphhopper/routing/lm/LMPreparationHandler.java index 7e5ecbb626f..b821d506b42 100644 --- a/core/src/main/java/com/graphhopper/routing/lm/LMPreparationHandler.java +++ b/core/src/main/java/com/graphhopper/routing/lm/LMPreparationHandler.java @@ -42,6 +42,7 @@ import java.util.*; import java.util.concurrent.Callable; import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.graphhopper.util.Helper.*; @@ -146,8 +147,8 @@ public List getLMProfiles() { */ public List load(List lmConfigs, BaseGraph baseGraph, EncodedValueLookup encodedValueLookup) { List loaded = Collections.synchronizedList(new ArrayList<>()); - List> loadingCallables = lmConfigs.stream() - .map(lmConfig -> (Callable) () -> { + Stream> loadingCallables = lmConfigs.stream() + .map(lmConfig -> () -> { // todo: specifying ghStorage and landmarkCount should not be necessary, because all we want to do // is load the landmark data and these parameters are only needed to calculate the landmarks. // we should also work towards a separation of the storage and preparation related code in @@ -164,8 +165,7 @@ public List load(List lmConfigs, BaseGraph baseGraph, baseGraph.getDirectory().remove("landmarks_subnetwork_" + lmConfig.getName()); } return lmConfig.getName(); - }) - .collect(Collectors.toList()); + }); GHUtility.runConcurrently(loadingCallables, preparationThreads); return loaded; } @@ -191,7 +191,7 @@ public List prepare(List lmConfigs, BaseGraph baseGr return name; }); } - GHUtility.runConcurrently(prepareCallables, preparationThreads); + GHUtility.runConcurrently(prepareCallables.stream(), preparationThreads); LOGGER.info("Finished LM preparation, {}", getMemInfo()); return preparations; } diff --git a/core/src/main/java/com/graphhopper/routing/util/DevelopmentCalculator.java b/core/src/main/java/com/graphhopper/routing/util/DevelopmentCalculator.java new file mode 100644 index 00000000000..2f46c9edaf6 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/DevelopmentCalculator.java @@ -0,0 +1,126 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util; + +import com.graphhopper.routing.ev.BooleanEncodedValue; +import com.graphhopper.routing.ev.Development; +import com.graphhopper.routing.ev.EnumEncodedValue; +import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.storage.Graph; +import com.graphhopper.util.EdgeIteratorState; +import com.graphhopper.util.StopWatch; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.function.ToDoubleFunction; + +public class DevelopmentCalculator { + private static final Logger logger = LoggerFactory.getLogger(RoadDensityCalculator.class); + + /** + * Calculates the development (rural/residential/city) for all edges of the graph. + * First a weighted road density is calculated for every edge to determine whether it belongs to a residential area. + * In a second step very dense residential areas are classified as 'city'. + * + * @param residentialAreaRadius radius used for residential area calculation in meters + * @param residentialAreaSensitivity Use higher values if there are too many residential areas that are not recognized. Use + * smaller values if there are too many non-residential areas that are classified as residential. + * @param cityAreaRadius in meters, see residentialAreaRadius + * @param cityAreaSensitivity similar to residentialAreaSensitivity, but for the city classification + * @param threads number of threads used to calculate the road densities + */ + public static void calcDevelopment(Graph graph, EnumEncodedValue developmentEnc, + EnumEncodedValue roadClassEnc, BooleanEncodedValue roadClassLinkEnc, + double residentialAreaRadius, double residentialAreaSensitivity, + double cityAreaRadius, double cityAreaSensitivity, + int threads) { + logger.info("Calculating residential areas ..., radius={}, sensitivity={}, threads={}", residentialAreaRadius, residentialAreaSensitivity, threads); + StopWatch sw = StopWatch.started(); + calcResidential(graph, developmentEnc, roadClassEnc, roadClassLinkEnc, residentialAreaRadius, residentialAreaSensitivity, threads); + logger.info("Finished calculating residential areas, took: " + sw.stop().getSeconds() + "s"); + if (cityAreaRadius > 1) { + logger.info("Calculating city areas ..., radius={}, sensitivity={}, threads={}", cityAreaRadius, cityAreaSensitivity, threads); + sw = StopWatch.started(); + calcCity(graph, developmentEnc, cityAreaRadius, cityAreaSensitivity, threads); + logger.info("Finished calculating city areas, took: " + sw.stop().getSeconds() + "s"); + } + } + + private static void calcResidential(Graph graph, EnumEncodedValue developmentEnc, + EnumEncodedValue roadClassEnc, BooleanEncodedValue roadClassLinkEnc, + double radius, double sensitivity, int threads) { + final ToDoubleFunction calcRoadFactor = edge -> { + if (edge.get(roadClassLinkEnc)) + // highway exits sometimes have a 'high' density. By excluding them here we try to prevent them from + // being classified as residential areas when they are in the countryside. + return 0; + RoadClass roadClass = edge.get(roadClassEnc); + switch (roadClass) { + // we're interested in the road density of urban roads, so residential areas are particularly interesting + case RESIDENTIAL: + case LIVING_STREET: + case FOOTWAY: + case CYCLEWAY: + case STEPS: + return 2; + case MOTORWAY: + case TRUNK: + case PRIMARY: + case SECONDARY: + case TERTIARY: + case SERVICE: + case OTHER: + return 1; + default: + return 0; + } + }; + // temporarily write results to an external array for thread-safety + boolean[] isResidential = new boolean[graph.getEdges()]; + RoadDensityCalculator.calcRoadDensities(graph, (calculator, edge) -> { + RoadClass roadClass = edge.get(roadClassEnc); + if (roadClass == RoadClass.RESIDENTIAL || roadClass == RoadClass.LIVING_STREET) { + isResidential[edge.getEdge()] = true; + return; + } + double roadDensity = calculator.calcRoadDensity(edge, radius, calcRoadFactor); + isResidential[edge.getEdge()] = roadDensity * sensitivity >= 1.0; + }, threads); + for (int edge = 0; edge < isResidential.length; edge++) + graph.getEdgeIteratorState(edge, Integer.MIN_VALUE).set(developmentEnc, isResidential[edge] ? Development.RESIDENTIAL : Development.RURAL); + } + + private static void calcCity(Graph graph, EnumEncodedValue developmentEnc, + double radius, double sensitivity, int threads) { + // do not modify the development values as long as we are still reading them -> store city flags in this array first + boolean[] isCity = new boolean[graph.getEdges()]; + final ToDoubleFunction calcRoadFactor = edge -> edge.get(developmentEnc) == Development.RESIDENTIAL ? 1 : 0; + RoadDensityCalculator.calcRoadDensities(graph, (calculator, edge) -> { + Development development = edge.get(developmentEnc); + if (development == Development.RURAL) + return; + double roadDensity = calculator.calcRoadDensity(edge, radius, calcRoadFactor); + if (roadDensity * sensitivity >= 1.0) + isCity[edge.getEdge()] = true; + }, threads); + for (int edge = 0; edge < isCity.length; edge++) + if (isCity[edge]) + graph.getEdgeIteratorState(edge, Integer.MIN_VALUE).set(developmentEnc, Development.CITY); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/RoadDensityCalculator.java b/core/src/main/java/com/graphhopper/routing/util/RoadDensityCalculator.java new file mode 100644 index 00000000000..8cc46690f85 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/RoadDensityCalculator.java @@ -0,0 +1,114 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ + +package com.graphhopper.routing.util; + +import com.carrotsearch.hppc.IntArrayDeque; +import com.carrotsearch.hppc.IntScatterSet; +import com.carrotsearch.hppc.IntSet; +import com.graphhopper.storage.Graph; +import com.graphhopper.storage.NodeAccess; +import com.graphhopper.util.EdgeExplorer; +import com.graphhopper.util.EdgeIterator; +import com.graphhopper.util.EdgeIteratorState; +import com.graphhopper.util.GHUtility; +import com.graphhopper.util.shapes.GHPoint; + +import java.util.concurrent.Callable; +import java.util.function.BiConsumer; +import java.util.function.ToDoubleFunction; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static com.graphhopper.util.DistancePlaneProjection.DIST_PLANE; + +public class RoadDensityCalculator { + private final Graph graph; + private final EdgeExplorer edgeExplorer; + private final IntSet visited; + private final IntArrayDeque deque; + + public RoadDensityCalculator(Graph graph) { + this.graph = graph; + this.edgeExplorer = graph.createEdgeExplorer(); + visited = new IntScatterSet(); + deque = new IntArrayDeque(100); + } + + /** + * Loops over all edges of the graph and calls the given edgeHandler for each edge. This is done in parallel using + * the given number of threads. For every call we can calculate the road density using the provided thread local + * road density calculator. + */ + public static void calcRoadDensities(Graph graph, BiConsumer edgeHandler, int threads) { + ThreadLocal calculator = ThreadLocal.withInitial(() -> new RoadDensityCalculator(graph)); + Stream> roadDensityWorkers = IntStream.range(0, graph.getEdges()) + .mapToObj(i -> () -> { + EdgeIteratorState edge = graph.getEdgeIteratorState(i, Integer.MIN_VALUE); + edgeHandler.accept(calculator.get(), edge); + return "road_density_calc"; + }); + GHUtility.runConcurrently(roadDensityWorkers, threads); + } + + /** + * @param radius in meters + * @param calcRoadFactor weighting function. use this to define how different kinds of roads shall contribute to the calculated road density + * @return the road density in the vicinity of the given edge, i.e. the weighted road length divided by the squared radius + */ + public double calcRoadDensity(EdgeIteratorState edge, double radius, ToDoubleFunction calcRoadFactor) { + visited.clear(); + deque.head = deque.tail = 0; + double totalRoadWeight = 0; + NodeAccess na = graph.getNodeAccess(); + int baseNode = edge.getBaseNode(); + int adjNode = edge.getAdjNode(); + GHPoint center = new GHPoint(getLat(na, baseNode, adjNode), getLon(na, baseNode, adjNode)); + deque.addLast(baseNode); + deque.addLast(adjNode); + visited.add(baseNode); + visited.add(adjNode); + // we just do a BFS search and sum up all the road lengths + final double radiusNormalized = DIST_PLANE.calcNormalizedDist(radius); + while (!deque.isEmpty()) { + int node = deque.removeFirst(); + EdgeIterator iter = edgeExplorer.setBaseNode(node); + while (iter.next()) { + if (visited.contains(iter.getAdjNode())) + continue; + visited.add(iter.getAdjNode()); + double distance = DIST_PLANE.calcNormalizedDist(center.lat, center.lon, getLat(na, iter.getBaseNode(), iter.getAdjNode()), getLon(na, iter.getBaseNode(), iter.getAdjNode())); + if (distance > radiusNormalized) + continue; + double roadLength = Math.min(2 * radius, iter.getDistance()); + totalRoadWeight += roadLength * calcRoadFactor.applyAsDouble(iter); + deque.addLast(iter.getAdjNode()); + } + } + return totalRoadWeight / radius / radius; + } + + private static double getLat(NodeAccess na, int baseNode, int adjNode) { + return (na.getLat(baseNode) + na.getLat(adjNode)) / 2; + } + + private static double getLon(NodeAccess na, int baseNode, int adjNode) { + return (na.getLon(baseNode) + na.getLon(adjNode)) / 2; + } + +} diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index 69a5baa7ef6..cc5a6a10db6 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -49,6 +49,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.graphhopper.util.DistanceCalcEarth.DIST_EARTH; @@ -700,13 +701,17 @@ public static List readCountries() { } } - public static void runConcurrently(List> callables, int threads) { + public static void runConcurrently(Stream> callables, int threads) { ExecutorService executorService = Executors.newFixedThreadPool(threads); ExecutorCompletionService completionService = new ExecutorCompletionService<>(executorService); - callables.forEach(completionService::submit); + AtomicInteger count = new AtomicInteger(); + callables.forEach(c -> { + count.incrementAndGet(); + completionService.submit(c); + }); executorService.shutdown(); try { - for (int i = 0; i < callables.size(); i++) + for (int i = 0; i < count.get(); i++) completionService.take().get(); } catch (Exception e) { executorService.shutdownNow(); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java index 98f330b6deb..34ccd64b841 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java @@ -94,22 +94,32 @@ public Response doGetXyz( locationIndex.query(bbox, edgeId -> { EdgeIteratorState edge = graphHopper.getBaseGraph().getEdgeIteratorStateForKey(edgeId * 2); LineString lineString; - RoadClass rc = edge.get(roadClassEnc); - if (zInfo >= 14) { - PointList pl = edge.fetchWayGeometry(FetchMode.ALL); - lineString = pl.toLineString(false); - } else if (rc == RoadClass.MOTORWAY - || zInfo > 10 && (rc == RoadClass.PRIMARY || rc == RoadClass.TRUNK) - || zInfo > 11 && (rc == RoadClass.SECONDARY) - || zInfo > 12) { - double lat = na.getLat(edge.getBaseNode()); - double lon = na.getLon(edge.getBaseNode()); - double toLat = na.getLat(edge.getAdjNode()); - double toLon = na.getLon(edge.getAdjNode()); - lineString = geometryFactory.createLineString(new Coordinate[]{new Coordinate(lon, lat), new Coordinate(toLon, toLat)}); + if (pathDetails.contains(Development.KEY)) { + if (zInfo >= 9) { + PointList pl = edge.fetchWayGeometry(FetchMode.ALL); + lineString = pl.toLineString(false); + } else { + // skip edge for certain zoom + return; + } } else { - // skip edge for certain zoom - return; + RoadClass rc = edge.get(roadClassEnc); + if (zInfo >= 14) { + PointList pl = edge.fetchWayGeometry(FetchMode.ALL); + lineString = pl.toLineString(false); + } else if (rc == RoadClass.MOTORWAY + || zInfo > 10 && (rc == RoadClass.PRIMARY || rc == RoadClass.TRUNK) + || zInfo > 11 && (rc == RoadClass.SECONDARY) + || zInfo > 12) { + double lat = na.getLat(edge.getBaseNode()); + double lon = na.getLon(edge.getBaseNode()); + double toLat = na.getLat(edge.getAdjNode()); + double toLon = na.getLon(edge.getAdjNode()); + lineString = geometryFactory.createLineString(new Coordinate[]{new Coordinate(lon, lat), new Coordinate(toLon, toLat)}); + } else { + // skip edge for certain zoom + return; + } } edgeCounter.incrementAndGet(); diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js index 9ea9b155359..3d32ec28287 100644 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js +++ b/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js @@ -109,24 +109,24 @@ module.exports.enableVectorTiles = function () { // weight == line width var color, opacity = 1, weight = 1, rc = properties.road_class; // if(properties.speed < 30) console.log(properties) - if(rc == "motorway") { + if (rc == "motorway") { color = '#dd504b'; // red weight = 3; - } else if(rc == "primary" || rc == "trunk") { + } else if (rc == "primary" || rc == "trunk") { color = '#e2a012'; // orange weight = 2; - } else if(rc == "secondary") { + } else if (rc == "secondary") { weight = 2; color = '#f7c913'; // yellow } else { color = "#aaa5a7"; // grey } - if(zoom > 16) - weight += 3; - else if(zoom > 15) - weight += 2; - else if(zoom > 13) - weight += 1; + if (zoom > 16) + weight += 3; + else if (zoom > 15) + weight += 2; + else if (zoom > 13) + weight += 1; return { weight: weight, @@ -136,25 +136,60 @@ module.exports.enableVectorTiles = function () { }, }, }) - .on('click', function(e) { - }) - .on('mouseover', function(e) { - console.log(e.layer.properties); - // remove route info - $("#info").children("div").remove(); - // remove last vector tile info - $("#info").children("ul").remove(); - - var list = ""; - $.each(e.layer.properties, function (key, value) { - list += "

  • " + key + ": " + value + "
  • "; - }); - $("#info").append("
      "+list+"
    "); - $("#info").show(); - }).on('mouseout', function (e) { -// $("#info").html(""); + var developmentLayer = L.vectorGrid.protobuf("/mvt/{z}/{x}/{y}.mvt?details=max_speed&details=road_class&details=road_environment&details=development", { + rendererFactory: L.canvas.tile, + maxZoom: 20, + minZoom: 10, + interactive: true, + vectorTileLayerStyles: { + 'roads': function (properties, zoom) { + var rd = properties.development; + let c = getDevelopmentColor(rd); + return { + weight: 1 + c.weight, + color: c.color, + opacity: 1 + } + }, + }, }); - overlays = { "Local MVT": vtLayer }; + var vtLayers = [vtLayer, developmentLayer]; + for (var i = 0; i < vtLayers.length; ++i) { + vtLayers[i] + .on('click', function (e) { + }) + .on('mouseover', function (e) { + console.log(e.layer.properties); + // remove route info + $("#info").children("div").remove(); + // remove last vector tile info + $("#info").children("ul").remove(); + + var list = ""; + $.each(e.layer.properties, function (key, value) { + list += "
  • " + key + ": " + value + "
  • "; + }); + $("#info").append("
      " + list + "
    "); + $("#info").show(); + }).on('mouseout', function (e) { + // $("#info").html(""); + } + ); + } + overlays = { + "Local MVT": vtLayer, + "Show Development": developmentLayer + }; +} + +function getDevelopmentColor(development) { + var color = '#0aaff1'; + if (development === "residential") color = '#fd084a'; + else if (development === "city") color = '#edf259'; + return { + weight: 1, + color: color + } } module.exports.activeLayerName = "Omniscale"; From ddd2b1e99d9a431bcd3ab85db88b678a1dcb3354 Mon Sep 17 00:00:00 2001 From: jp-lopez Date: Wed, 31 Aug 2022 11:30:16 +0200 Subject: [PATCH 155/389] Fix compilation error --- .../matrix/algorithm/AbstractManyToMany.java | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/matrix/algorithm/AbstractManyToMany.java b/core/src/main/java/com/graphhopper/routing/matrix/algorithm/AbstractManyToMany.java index 610e80f3017..d431f643cc0 100644 --- a/core/src/main/java/com/graphhopper/routing/matrix/algorithm/AbstractManyToMany.java +++ b/core/src/main/java/com/graphhopper/routing/matrix/algorithm/AbstractManyToMany.java @@ -127,22 +127,22 @@ private void calculateMaxDistance(List sources, List targets,Distan } @Override - public DistanceMatrix calcMatrix(List sources, List targets) { + public DistanceMatrix calcMatrix(List sources, List targets){ checkAlreadyRun(); - DistanceMatrix matrix = new DistanceMatrix(sources.size(), targets.size()); + DistanceMatrix matrix = new DistanceMatrix(sources.size(),targets.size()); IntObjectMap targetIdxsNodes = new GHIntObjectHashMap<>(targets.size()); calculateMaxDistance(sources,targets,matrix); //Backward - int idxTarget = 0; - while (idxTarget < targets.size()) { + int idxTarget =0; + while(idxTarget < targets.size()){ int targetClosestNode = targets.get(idxTarget).getClosestNode(); //Avoid iterate over the same node two times - if (!targetIdxsNodes.containsKey(targetClosestNode)) { + if(!targetIdxsNodes.containsKey(targetClosestNode)){ IntArrayList a = new IntArrayList(); a.add(idxTarget); targetIdxsNodes.put(targetClosestNode,a); @@ -155,9 +155,9 @@ public DistanceMatrix calcMatrix(List sources, List targets) { } //Forward - int idxSource = 0; - while (idxSource < sources.size()) { - forwardSearch(sources.get(idxSource), idxSource, matrix, targetIdxsNodes); + int idxSource =0; + while(idxSource < sources.size()){ + forwardSearch(sources.get(idxSource),idxSource,matrix,targetIdxsNodes); idxSource++; } @@ -178,7 +178,7 @@ protected void backwardSearch( Snap targetSnap, int targetIdx){ this.map.clear(); this.heap.clear(); - MatrixEntry currEdge = new MatrixEntry(target, 0, 0, 0); + MatrixEntry currEdge = new MatrixEntry(target,0,0,0); heap.add(currEdge); // For the first step though we need all edges, so we need to ignore this filter. @@ -203,21 +203,21 @@ protected void backwardSearch( Snap targetSnap, int targetIdx){ int currNode = currEdge.adjNode; - if (visited.contains(currNode)) { + if(visited.contains(currNode)){ run = !heap.isEmpty(); continue; } RoutingCHEdgeIterator iterator = inEdgeExplorer.setBaseNode(currNode); - while (iterator.next()) { + while(iterator.next()){ - if (!accept(iterator, currEdge)) + if(!accept(iterator,currEdge)) continue; - final double weight = calcWeight(iterator, currEdge, true); + final double weight = calcWeight(iterator,currEdge,true); - if (!Double.isFinite(weight)) + if(!Double.isFinite(weight)) continue; final int origEdgeId = getOrigEdgeId(iterator, true); @@ -257,18 +257,18 @@ protected void backwardSearch( Snap targetSnap, int targetIdx){ visited.add(currNode); run = (visitedNodes <= maxVisitedNodes) && !heap.isEmpty(); - } while (run); + }while(run); } protected abstract int getTraversalId(RoutingCHEdgeIteratorState edge, int origEdgeId, Boolean reverse); protected int getOrigEdgeId(RoutingCHEdgeIteratorState edge, boolean reverse) { - return GHUtility.getEdgeFromEdgeKey(reverse ? edge.getOrigEdgeKeyFirst() : edge.getOrigEdgeKeyLast()); + return reverse ? edge.getOrigEdgeKeyFirst() : edge.getOrigEdgeKeyLast(); } protected boolean accept(RoutingCHEdgeIteratorState edge, MatrixEntry currEdge) { - if (edge.getEdge() == getIncomingEdge(currEdge)) + if(edge.getEdge() == getIncomingEdge(currEdge)) return false; else return levelEdgeFilter == null || levelEdgeFilter.accept(edge); @@ -284,19 +284,19 @@ protected int getIncomingEdge(MatrixEntry entry) { protected abstract double calcDistance(RoutingCHEdgeIteratorState iter, MatrixEntry currEdge); - protected void saveToBucket(MatrixEntry entry, RoutingCHEdgeIteratorState iter, int target) { + protected void saveToBucket(MatrixEntry entry, RoutingCHEdgeIteratorState iter, int target){ int node = iter.getAdjNode(); - if (node != target) { + if(node != target){ IntObjectMap bucketDistances = bucket.get(node); - if (bucketDistances == null) { + if(bucketDistances == null){ bucketDistances = new GHIntObjectHashMap<>(); - bucketDistances.put(target, new BucketEntry(entry.weight, entry.time, entry.distance)); - bucket.put(node, bucketDistances); - } else { + bucketDistances.put(target,new BucketEntry(entry.weight,entry.time ,entry.distance)); + bucket.put(node,bucketDistances); + }else { BucketEntry targetEntry = bucketDistances.get(target); if (targetEntry == null || targetEntry.weight > entry.weight) { @@ -306,7 +306,7 @@ protected void saveToBucket(MatrixEntry entry, RoutingCHEdgeIteratorState iter, } } - protected void forwardSearch(Snap sourceSnap, int idxSource, DistanceMatrix dm, IntObjectMap targets) { + protected void forwardSearch(Snap sourceSnap, int idxSource, DistanceMatrix dm, IntObjectMap targets){ int source = sourceSnap.getClosestNode(); @@ -316,10 +316,10 @@ protected void forwardSearch(Snap sourceSnap, int idxSource, DistanceMatrix dm, this.tentativeWeights.clear(); //For the case when the shortest path is the direct path between source and target - saveBestPath(source, idxSource, targets, source, 0, 0, 0, dm); + saveBestPath(source,idxSource,targets,source,0,0,0,dm); - MatrixEntry currEdge = new MatrixEntry(source, 0, 0, 0); - map.put(source, currEdge); + MatrixEntry currEdge = new MatrixEntry(source,0,0,0); + map.put(source,currEdge); heap.add(currEdge); // For the first step though we need all edges, so we need to ignore this filter. @@ -345,7 +345,7 @@ protected void forwardSearch(Snap sourceSnap, int idxSource, DistanceMatrix dm, int currNode = currEdge.adjNode; - if (visited.contains(currNode)) { + if(visited.contains(currNode)){ run = !heap.isEmpty(); continue; } @@ -373,7 +373,7 @@ protected void forwardSearch(Snap sourceSnap, int idxSource, DistanceMatrix dm, map.put(traversalId, entry); heap.add(entry); - saveBestPath(source, idxSource, targets, iterator.getAdjNode(), weight, time, distance, dm); + saveBestPath(source,idxSource,targets,iterator.getAdjNode(),weight,time,distance,dm); } else if (entry.getWeightOfVisitedPath() > weight) { @@ -387,7 +387,7 @@ protected void forwardSearch(Snap sourceSnap, int idxSource, DistanceMatrix dm, entry.time = time; heap.add(entry); - saveBestPath(source, idxSource, targets, iterator.getAdjNode(), weight, time, distance, dm); + saveBestPath(source,idxSource,targets,iterator.getAdjNode(),weight,time,distance,dm); } } @@ -396,43 +396,43 @@ protected void forwardSearch(Snap sourceSnap, int idxSource, DistanceMatrix dm, visited.add(currNode); run = (visitedNodes <= maxVisitedNodes) && !heap.isEmpty(); - } while (run); + }while(run); } - private void saveBestPath(int sourceNode, int idxSource, IntObjectMap targets, int currNode, double currentEdgeWeight, - long currentEdgeTime, double currentEdgeDistance, DistanceMatrix dm) { + private void saveBestPath( int sourceNode,int idxSource, IntObjectMap targets,int currNode, double currentEdgeWeight, + long currentEdgeTime, double currentEdgeDistance, DistanceMatrix dm){ final IntObjectMap bucketEntries = bucket.get(currNode); - if (bucketEntries != null) { + if(bucketEntries != null){ - for (IntObjectCursor next : bucketEntries) { + for( IntObjectCursor next : bucketEntries){ int target = next.key; - if (sourceNode == target) continue; + if(sourceNode == target) continue; final double savedWeight = tentativeWeights.get(target); final double currentWeight = currentEdgeWeight + next.value.weight; - if (savedWeight == 0.0) { + if(savedWeight == 0.0){ final long time = currentEdgeTime + next.value.time; final double distance = currentEdgeDistance + next.value.distance; - tentativeWeights.put(target, currentWeight); + tentativeWeights.put(target,currentWeight); - for (IntCursor idxNext : targets.get(target)) { - dm.setCell(idxSource, idxNext.value, distance, time); + for(IntCursor idxNext : targets.get(target)){ + dm.setCell(idxSource,idxNext.value,distance,time); } - } else if (currentWeight < savedWeight) { + } else if(currentWeight < savedWeight){ final long time = currentEdgeTime + next.value.time; final double distance = currentEdgeDistance + next.value.distance; - tentativeWeights.put(target, currentWeight); + tentativeWeights.put(target,currentWeight); - for (IntCursor idxNext : targets.get(target)) { - dm.setCell(idxSource, idxNext.value, distance, time); + for(IntCursor idxNext : targets.get(target)){ + dm.setCell(idxSource,idxNext.value,distance,time); } } } @@ -445,7 +445,7 @@ public int getVisitedNodes() { } @Override - public void setMaxVisitedNodes(int numberOfNodes) { + public void setMaxVisitedNodes(int numberOfNodes){ this.maxVisitedNodes = numberOfNodes; } } \ No newline at end of file From c9d85e6a5d9ee537568074653a6a2ff9d95468ef Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 31 Aug 2022 10:52:56 +0200 Subject: [PATCH 156/389] Rename Development -> UrbanDensity (#2637) --- CHANGELOG.md | 2 +- config-example.yml | 14 +++--- .../java/com/graphhopper/GraphHopper.java | 46 +++++++++---------- .../{Development.java => UrbanDensity.java} | 10 ++-- ...lator.java => UrbanDensityCalculator.java} | 38 +++++++-------- .../graphhopper/resources/MVTResource.java | 2 +- .../graphhopper/maps/js/config/tileLayers.js | 16 +++---- 7 files changed, 64 insertions(+), 64 deletions(-) rename core/src/main/java/com/graphhopper/routing/ev/{Development.java => UrbanDensity.java} (81%) rename core/src/main/java/com/graphhopper/routing/util/{DevelopmentCalculator.java => UrbanDensityCalculator.java} (78%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dcecddca4f..273e34d5622 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ - don't allow cars or motorcycles to use ways tagged with service=emergency_access (#2484) - faster flexible routing, especially in conjunction with turn costs (#2571) - negative OSM Ids are not supported any longer (#2652) -- new development encoded value based on road density (#2637) +- new urban_density encoded value based on road density calculation (#2637) ### 5.0 [23 Mar 2022] diff --git a/config-example.yml b/config-example.yml index 3a08898e3da..677b283c95f 100644 --- a/config-example.yml +++ b/config-example.yml @@ -109,19 +109,19 @@ graphhopper: # elevation and will remove the extra points that long edge sampling added # graph.elevation.way_point_max_distance: 10 - #### Development (built-up areas) #### + #### Urban density (built-up areas) #### - # This feature allows classifying roads into 'rural', 'residential' and 'city' areas (encoded value 'development') + # This feature allows classifying roads into 'rural', 'residential' and 'city' areas (encoded value 'urban_density') # Use 1 or more threads to enable the feature - # graph.development.threads: 8 + # graph.urban_density.threads: 8 # Use higher/lower sensitivities if too little/many roads fall into the according categories. # Using smaller radii will speed up the classification, but only change these values if you know what you are doing. # If you do not need the (rather slow) city classification set city_radius to zero. - # graph.development.residential_radius: 300 - # graph.development.residential_sensitivity: 60 - # graph.development.city_radius: 2000 - # graph.development.city_sensitivity: 30 + # graph.urban_density.residential_radius: 300 + # graph.urban_density.residential_sensitivity: 60 + # graph.urban_density.city_radius: 2000 + # graph.urban_density.city_sensitivity: 30 #### Speed, hybrid and flexible mode #### diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 75cc300ebf8..3a5b445b237 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -112,7 +112,7 @@ public class GraphHopper { private double residentialAreaSensitivity = 60; private double cityAreaRadius = 2000; private double cityAreaSensitivity = 30; - private int developmentCalculationThreads = 0; + private int urbanDensityCalculationThreads = 0; // preparation handlers private final LMPreparationHandler lmPreparationHandler = new LMPreparationHandler(); @@ -195,7 +195,7 @@ public GraphHopper setMinNetworkSize(int minNetworkSize) { } /** - * Configures the development classification. Each edge will be classified as 'rural','residential' or 'city', {@link Development} + * Configures the urban density classification. Each edge will be classified as 'rural','residential' or 'city', {@link UrbanDensity} * * @param residentialAreaRadius in meters. The higher this value the longer the calculation will take and the bigger the area for * which the road density used to identify residential areas is calculated. @@ -206,17 +206,17 @@ public GraphHopper setMinNetworkSize(int minNetworkSize) { * to skip the city classification. * @param cityAreaSensitivity Use this to find a trade-off between too many roads being classified as city (too high values) * and not enough roads being classified as city (too small values) - * @param threads the number of threads used for the calculation. If this is zero the development - * classification is skipped entirely + * @param threads the number of threads used for the calculation. If this is zero the urban density + * calculation is skipped entirely */ - public GraphHopper setDevelopmentClassification(double residentialAreaRadius, double residentialAreaSensitivity, - double cityAreaRadius, double cityAreaSensitivity, int threads) { + public GraphHopper setUrbanDensityCalculation(double residentialAreaRadius, double residentialAreaSensitivity, + double cityAreaRadius, double cityAreaSensitivity, int threads) { ensureNotLoaded(); this.residentialAreaRadius = residentialAreaRadius; this.residentialAreaSensitivity = residentialAreaSensitivity; this.cityAreaRadius = cityAreaRadius; this.cityAreaSensitivity = cityAreaSensitivity; - this.developmentCalculationThreads = threads; + this.urbanDensityCalculationThreads = threads; return this; } @@ -571,12 +571,12 @@ public GraphHopper init(GraphHopperConfig ghConfig) { preciseIndexResolution = ghConfig.getInt("index.high_resolution", preciseIndexResolution); maxRegionSearch = ghConfig.getInt("index.max_region_search", maxRegionSearch); - // development calculation - residentialAreaRadius = ghConfig.getDouble("graph.development.residential_radius", residentialAreaRadius); - residentialAreaSensitivity = ghConfig.getDouble("graph.development.residential_sensitivity", residentialAreaSensitivity); - cityAreaRadius = ghConfig.getDouble("graph.development.city_radius", cityAreaRadius); - cityAreaSensitivity = ghConfig.getDouble("graph.development.city_sensitivity", cityAreaSensitivity); - developmentCalculationThreads = ghConfig.getInt("graph.development.threads", developmentCalculationThreads); + // urban density calculation + residentialAreaRadius = ghConfig.getDouble("graph.urban_density.residential_radius", residentialAreaRadius); + residentialAreaSensitivity = ghConfig.getDouble("graph.urban_density.residential_sensitivity", residentialAreaSensitivity); + cityAreaRadius = ghConfig.getDouble("graph.urban_density.city_radius", cityAreaRadius); + cityAreaSensitivity = ghConfig.getDouble("graph.urban_density.city_sensitivity", cityAreaSensitivity); + urbanDensityCalculationThreads = ghConfig.getInt("graph.urban_density.threads", urbanDensityCalculationThreads); // routing routerConfig.setMaxVisitedNodes(ghConfig.getInt(Routing.INIT_MAX_VISITED_NODES, routerConfig.getMaxVisitedNodes())); @@ -592,7 +592,7 @@ public GraphHopper init(GraphHopperConfig ghConfig) { return this; } - private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String encodedValuesStr, String dateRangeParserString, boolean withDevelopment, Collection profiles) { + private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String encodedValuesStr, String dateRangeParserString, boolean withUrbanDensity, Collection profiles) { Map flagEncodersMap = new LinkedHashMap<>(); for (String encoderStr : flagEncodersStr.split(",")) { String name = encoderStr.split("\\|")[0].trim(); @@ -620,8 +620,8 @@ private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String en EncodingManager.Builder emBuilder = new EncodingManager.Builder(); flagEncodersMap.forEach((name, encoderStr) -> emBuilder.add(vehicleEncodedValuesFactory.createVehicleEncodedValues(name, new PMap(encoderStr)))); profiles.forEach(profile -> emBuilder.add(Subnetwork.create(profile.getName()))); - if (withDevelopment) - emBuilder.add(Development.create()); + if (withUrbanDensity) + emBuilder.add(UrbanDensity.create()); encodedValueStrings.forEach(s -> emBuilder.add(encodedValueFactory.create(s))); encodingManager = emBuilder.build(); @@ -780,8 +780,8 @@ public void importAndClose() { private void process(boolean closeEarly) { GHDirectory directory = new GHDirectory(ghLocation, dataAccessDefaultType); directory.configure(dataAccessConfig); - boolean withDevelopment = developmentCalculationThreads > 0; - buildEncodingManagerAndOSMParsers(flagEncodersString, encodedValuesString, dateRangeParserString, withDevelopment, profilesByName.values()); + boolean withUrbanDensity = urbanDensityCalculationThreads > 0; + buildEncodingManagerAndOSMParsers(flagEncodersString, encodedValuesString, dateRangeParserString, withUrbanDensity, profilesByName.values()); baseGraph = new BaseGraph.Builder(getEncodingManager()) .setDir(directory) .set3D(hasElevation()) @@ -822,15 +822,15 @@ protected void postImport() { if (hasElevation()) interpolateBridgesTunnelsAndFerries(); - if (encodingManager.hasEncodedValue(Development.KEY)) { - EnumEncodedValue developmentEnc = encodingManager.getEnumEncodedValue(Development.KEY, Development.class); + if (encodingManager.hasEncodedValue(UrbanDensity.KEY)) { + EnumEncodedValue urbanDensityEnc = encodingManager.getEnumEncodedValue(UrbanDensity.KEY, UrbanDensity.class); if (!encodingManager.hasEncodedValue(RoadClass.KEY)) - throw new IllegalArgumentException("Development calculation requires " + RoadClass.KEY); + throw new IllegalArgumentException("Urban density calculation requires " + RoadClass.KEY); if (!encodingManager.hasEncodedValue(RoadClassLink.KEY)) - throw new IllegalArgumentException("Development calculation requires " + RoadClassLink.KEY); + throw new IllegalArgumentException("Urban density calculation requires " + RoadClassLink.KEY); EnumEncodedValue roadClassEnc = encodingManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BooleanEncodedValue roadClassLinkEnc = encodingManager.getBooleanEncodedValue(RoadClassLink.KEY); - DevelopmentCalculator.calcDevelopment(baseGraph, developmentEnc, roadClassEnc, roadClassLinkEnc, residentialAreaRadius, residentialAreaSensitivity, cityAreaRadius, cityAreaSensitivity, developmentCalculationThreads); + UrbanDensityCalculator.calcUrbanDensity(baseGraph, urbanDensityEnc, roadClassEnc, roadClassLinkEnc, residentialAreaRadius, residentialAreaSensitivity, cityAreaRadius, cityAreaSensitivity, urbanDensityCalculationThreads); } } diff --git a/core/src/main/java/com/graphhopper/routing/ev/Development.java b/core/src/main/java/com/graphhopper/routing/ev/UrbanDensity.java similarity index 81% rename from core/src/main/java/com/graphhopper/routing/ev/Development.java rename to core/src/main/java/com/graphhopper/routing/ev/UrbanDensity.java index 1507c9d4914..b5500259eeb 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Development.java +++ b/core/src/main/java/com/graphhopper/routing/ev/UrbanDensity.java @@ -18,18 +18,18 @@ package com.graphhopper.routing.ev; -public enum Development { +public enum UrbanDensity { RURAL("rural"), RESIDENTIAL("residential"), CITY("city"); - public static EnumEncodedValue create() { - return new EnumEncodedValue<>(KEY, Development.class); + public static EnumEncodedValue create() { + return new EnumEncodedValue<>(KEY, UrbanDensity.class); } - public static final String KEY = "development"; + public static final String KEY = "urban_density"; private final String name; - Development(String name) { + UrbanDensity(String name) { this.name = name; } diff --git a/core/src/main/java/com/graphhopper/routing/util/DevelopmentCalculator.java b/core/src/main/java/com/graphhopper/routing/util/UrbanDensityCalculator.java similarity index 78% rename from core/src/main/java/com/graphhopper/routing/util/DevelopmentCalculator.java rename to core/src/main/java/com/graphhopper/routing/util/UrbanDensityCalculator.java index 2f46c9edaf6..600981b4de1 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DevelopmentCalculator.java +++ b/core/src/main/java/com/graphhopper/routing/util/UrbanDensityCalculator.java @@ -19,9 +19,9 @@ package com.graphhopper.routing.util; import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.Development; import com.graphhopper.routing.ev.EnumEncodedValue; import com.graphhopper.routing.ev.RoadClass; +import com.graphhopper.routing.ev.UrbanDensity; import com.graphhopper.storage.Graph; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.StopWatch; @@ -30,11 +30,11 @@ import java.util.function.ToDoubleFunction; -public class DevelopmentCalculator { - private static final Logger logger = LoggerFactory.getLogger(RoadDensityCalculator.class); +public class UrbanDensityCalculator { + private static final Logger logger = LoggerFactory.getLogger(UrbanDensityCalculator.class); /** - * Calculates the development (rural/residential/city) for all edges of the graph. + * Calculates the urban density (rural/residential/city) for all edges of the graph. * First a weighted road density is calculated for every edge to determine whether it belongs to a residential area. * In a second step very dense residential areas are classified as 'city'. * @@ -45,24 +45,24 @@ public class DevelopmentCalculator { * @param cityAreaSensitivity similar to residentialAreaSensitivity, but for the city classification * @param threads number of threads used to calculate the road densities */ - public static void calcDevelopment(Graph graph, EnumEncodedValue developmentEnc, - EnumEncodedValue roadClassEnc, BooleanEncodedValue roadClassLinkEnc, - double residentialAreaRadius, double residentialAreaSensitivity, - double cityAreaRadius, double cityAreaSensitivity, - int threads) { + public static void calcUrbanDensity(Graph graph, EnumEncodedValue urbanDensityEnc, + EnumEncodedValue roadClassEnc, BooleanEncodedValue roadClassLinkEnc, + double residentialAreaRadius, double residentialAreaSensitivity, + double cityAreaRadius, double cityAreaSensitivity, + int threads) { logger.info("Calculating residential areas ..., radius={}, sensitivity={}, threads={}", residentialAreaRadius, residentialAreaSensitivity, threads); StopWatch sw = StopWatch.started(); - calcResidential(graph, developmentEnc, roadClassEnc, roadClassLinkEnc, residentialAreaRadius, residentialAreaSensitivity, threads); + calcResidential(graph, urbanDensityEnc, roadClassEnc, roadClassLinkEnc, residentialAreaRadius, residentialAreaSensitivity, threads); logger.info("Finished calculating residential areas, took: " + sw.stop().getSeconds() + "s"); if (cityAreaRadius > 1) { logger.info("Calculating city areas ..., radius={}, sensitivity={}, threads={}", cityAreaRadius, cityAreaSensitivity, threads); sw = StopWatch.started(); - calcCity(graph, developmentEnc, cityAreaRadius, cityAreaSensitivity, threads); + calcCity(graph, urbanDensityEnc, cityAreaRadius, cityAreaSensitivity, threads); logger.info("Finished calculating city areas, took: " + sw.stop().getSeconds() + "s"); } } - private static void calcResidential(Graph graph, EnumEncodedValue developmentEnc, + private static void calcResidential(Graph graph, EnumEncodedValue urbanDensityEnc, EnumEncodedValue roadClassEnc, BooleanEncodedValue roadClassLinkEnc, double radius, double sensitivity, int threads) { final ToDoubleFunction calcRoadFactor = edge -> { @@ -103,17 +103,17 @@ private static void calcResidential(Graph graph, EnumEncodedValue d isResidential[edge.getEdge()] = roadDensity * sensitivity >= 1.0; }, threads); for (int edge = 0; edge < isResidential.length; edge++) - graph.getEdgeIteratorState(edge, Integer.MIN_VALUE).set(developmentEnc, isResidential[edge] ? Development.RESIDENTIAL : Development.RURAL); + graph.getEdgeIteratorState(edge, Integer.MIN_VALUE).set(urbanDensityEnc, isResidential[edge] ? UrbanDensity.RESIDENTIAL : UrbanDensity.RURAL); } - private static void calcCity(Graph graph, EnumEncodedValue developmentEnc, + private static void calcCity(Graph graph, EnumEncodedValue urbanDensityEnc, double radius, double sensitivity, int threads) { - // do not modify the development values as long as we are still reading them -> store city flags in this array first + // do not modify the urban density values as long as we are still reading them -> store city flags in this array first boolean[] isCity = new boolean[graph.getEdges()]; - final ToDoubleFunction calcRoadFactor = edge -> edge.get(developmentEnc) == Development.RESIDENTIAL ? 1 : 0; + final ToDoubleFunction calcRoadFactor = edge -> edge.get(urbanDensityEnc) == UrbanDensity.RESIDENTIAL ? 1 : 0; RoadDensityCalculator.calcRoadDensities(graph, (calculator, edge) -> { - Development development = edge.get(developmentEnc); - if (development == Development.RURAL) + UrbanDensity urbanDensity = edge.get(urbanDensityEnc); + if (urbanDensity == UrbanDensity.RURAL) return; double roadDensity = calculator.calcRoadDensity(edge, radius, calcRoadFactor); if (roadDensity * sensitivity >= 1.0) @@ -121,6 +121,6 @@ private static void calcCity(Graph graph, EnumEncodedValue developm }, threads); for (int edge = 0; edge < isCity.length; edge++) if (isCity[edge]) - graph.getEdgeIteratorState(edge, Integer.MIN_VALUE).set(developmentEnc, Development.CITY); + graph.getEdgeIteratorState(edge, Integer.MIN_VALUE).set(urbanDensityEnc, UrbanDensity.CITY); } } diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java index 34ccd64b841..16908e14db4 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java @@ -94,7 +94,7 @@ public Response doGetXyz( locationIndex.query(bbox, edgeId -> { EdgeIteratorState edge = graphHopper.getBaseGraph().getEdgeIteratorStateForKey(edgeId * 2); LineString lineString; - if (pathDetails.contains(Development.KEY)) { + if (pathDetails.contains(UrbanDensity.KEY)) { if (zInfo >= 9) { PointList pl = edge.fetchWayGeometry(FetchMode.ALL); lineString = pl.toLineString(false); diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js index 3d32ec28287..d637a4d62bc 100644 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js +++ b/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js @@ -136,15 +136,15 @@ module.exports.enableVectorTiles = function () { }, }, }) - var developmentLayer = L.vectorGrid.protobuf("/mvt/{z}/{x}/{y}.mvt?details=max_speed&details=road_class&details=road_environment&details=development", { + var urbanDensityLayer = L.vectorGrid.protobuf("/mvt/{z}/{x}/{y}.mvt?details=max_speed&details=road_class&details=road_environment&details=urban_density", { rendererFactory: L.canvas.tile, maxZoom: 20, minZoom: 10, interactive: true, vectorTileLayerStyles: { 'roads': function (properties, zoom) { - var rd = properties.development; - let c = getDevelopmentColor(rd); + var ud = properties.urban_density; + let c = getUrbanDensityColor(ud); return { weight: 1 + c.weight, color: c.color, @@ -153,7 +153,7 @@ module.exports.enableVectorTiles = function () { }, }, }); - var vtLayers = [vtLayer, developmentLayer]; + var vtLayers = [vtLayer, urbanDensityLayer]; for (var i = 0; i < vtLayers.length; ++i) { vtLayers[i] .on('click', function (e) { @@ -178,14 +178,14 @@ module.exports.enableVectorTiles = function () { } overlays = { "Local MVT": vtLayer, - "Show Development": developmentLayer + "Show Urban Density": urbanDensityLayer }; } -function getDevelopmentColor(development) { +function getUrbanDensityColor(urbanDensity) { var color = '#0aaff1'; - if (development === "residential") color = '#fd084a'; - else if (development === "city") color = '#edf259'; + if (urbanDensity === "residential") color = '#fd084a'; + else if (urbanDensity === "city") color = '#edf259'; return { weight: 1, color: color From c9495bc3581d339af856c2b4cc121bcc24ec2ed1 Mon Sep 17 00:00:00 2001 From: ratrun Date: Mon, 5 Sep 2022 07:39:02 +0200 Subject: [PATCH 157/389] Support ";" access delimiter for car access. (#2655) * Support ";" access delimiter for car access. One example is motor_vehicle = agricultural;forestry * Add support for ";" access delimiter for MotorcycleTagParser and road_access EV. * Move logic for access delimiter handling for ";" from RoadAccess into OSMRoadAccessParser * Fix for OSMRoadAccessParserTest --- .../com/graphhopper/routing/util/CarTagParser.java | 12 ++++++++---- .../routing/util/MotorcycleTagParser.java | 12 ++++++++---- .../routing/util/parsers/OSMRoadAccessParser.java | 12 +++++++++--- .../conditional/ConditionalOSMTagInspectorTest.java | 8 ++++---- .../graphhopper/routing/util/CarTagParserTest.java | 13 +++++++++++++ .../routing/util/MotorcycleTagParserTest.java | 2 ++ .../util/parsers/OSMRoadAccessParserTest.java | 9 +++++++++ 7 files changed, 53 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java index fa4a84444d2..3d7b6cbfb84 100644 --- a/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/CarTagParser.java @@ -195,10 +195,14 @@ public WayAccess getAccess(ReaderWay way) { // multiple restrictions needs special handling compared to foot and bike, see also motorcycle if (!firstValue.isEmpty()) { - if (restrictedValues.contains(firstValue) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way)) - return WayAccess.CAN_SKIP; - if (intendedValues.contains(firstValue)) - return WayAccess.WAY; + String[] restrict = firstValue.split(";"); + boolean notConditionalyPermitted = !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way); + for (String value: restrict) { + if (restrictedValues.contains(value) && notConditionalyPermitted) + return WayAccess.CAN_SKIP; + if (intendedValues.contains(value)) + return WayAccess.WAY; + } } // do not drive street cars into fords diff --git a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java index 9c3e872883f..3ee9d53ca76 100644 --- a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java @@ -145,10 +145,14 @@ public WayAccess getAccess(ReaderWay way) { return WayAccess.CAN_SKIP; if (!firstValue.isEmpty()) { - if (restrictedValues.contains(firstValue) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way)) - return WayAccess.CAN_SKIP; - if (intendedValues.contains(firstValue)) - return WayAccess.WAY; + String[] restrict = firstValue.split(";"); + boolean notConditionalyPermitted = !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way); + for (String value: restrict) { + if (restrictedValues.contains(value) && notConditionalyPermitted) + return WayAccess.CAN_SKIP; + if (intendedValues.contains(value)) + return WayAccess.WAY; + } } // do not drive street cars into fords diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java index c27d58b0fc8..5a8f0eaaf8a 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParser.java @@ -43,9 +43,15 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef rel RoadAccess accessValue = YES; RoadAccess tmpAccessValue; for (String restriction : restrictions) { - tmpAccessValue = RoadAccess.find(readerWay.getTag(restriction, "yes")); - if (tmpAccessValue != null && tmpAccessValue.ordinal() > accessValue.ordinal()) { - accessValue = tmpAccessValue; + String tagValue = readerWay.getTag(restriction); + if (tagValue != null) { + String[] complex = tagValue.split(";"); + for ( String simple: complex) { + tmpAccessValue = RoadAccess.find(simple); + if (tmpAccessValue != null && tmpAccessValue.ordinal() > accessValue.ordinal()) { + accessValue = tmpAccessValue; + } + } } } diff --git a/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspectorTest.java b/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspectorTest.java index c8560c553af..364d2383ea0 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspectorTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspectorTest.java @@ -44,10 +44,10 @@ private static Set getSampleRestrictedValues() { } private static Set getSamplePermissiveValues() { - Set restrictedValues = new HashSet<>(); - restrictedValues.add("yes"); - restrictedValues.add("permissive"); - return restrictedValues; + Set permissiveValues = new HashSet<>(); + permissiveValues.add("yes"); + permissiveValues.add("permissive"); + return permissiveValues; } private static List getSampleConditionalTags() { diff --git a/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java index f0b1b937a4c..52daa3da1c3 100644 --- a/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/CarTagParserTest.java @@ -111,6 +111,19 @@ public void testAccess() { way.setTag("motor_vehicle", "no"); assertTrue(parser.getAccess(way).canSkip()); + way.clearTags(); + way.setTag("highway", "track"); + way.setTag("motor_vehicle", "agricultural"); + assertTrue(parser.getAccess(way).canSkip()); + way.setTag("motor_vehicle", "agricultural;forestry"); + assertTrue(parser.getAccess(way).canSkip()); + way.setTag("motor_vehicle", "forestry;agricultural"); + assertTrue(parser.getAccess(way).canSkip()); + way.setTag("motor_vehicle", "forestry;agricultural;unknown"); + assertTrue(parser.getAccess(way).canSkip()); + way.setTag("motor_vehicle", "yes;forestry;agricultural"); + assertTrue(parser.getAccess(way).isWay()); + way.clearTags(); way.setTag("highway", "service"); way.setTag("access", "no"); diff --git a/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java index 1f67e1c3e12..4dbb55f071e 100644 --- a/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java @@ -114,6 +114,8 @@ public void testAccess() { way.setTag("access", "yes"); way.setTag("motor_vehicle", "no"); assertTrue(parser.getAccess(way).canSkip()); + way.setTag("motor_vehicle", "agricultural;forestry"); + assertTrue(parser.getAccess(way).canSkip()); way.clearTags(); way.setTag("highway", "service"); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java index ca23d472d15..1d790b649fc 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMRoadAccessParserTest.java @@ -55,6 +55,15 @@ public RoadAccess getAccess(ReaderWay readerWay, TransportationMode transportati way.removeTag("country_rule"); parser.handleWayTags(edgeFlags, way, relFlags); assertEquals(RoadAccess.YES, roadAccessEnc.getEnum(false, edgeFlags)); + + way.setTag("motor_vehicle", "agricultural;forestry"); + parser.handleWayTags(edgeFlags, way, relFlags); + assertEquals(RoadAccess.AGRICULTURAL, roadAccessEnc.getEnum(false, edgeFlags)); + + way.setTag("motor_vehicle", "forestry;agricultural"); + parser.handleWayTags(edgeFlags, way, relFlags); + assertEquals(RoadAccess.AGRICULTURAL, roadAccessEnc.getEnum(false, edgeFlags)); + } } \ No newline at end of file From abbee4e62e7c9587e794e757935dd21065e0f0bc Mon Sep 17 00:00:00 2001 From: Andi Date: Fri, 9 Sep 2022 22:34:39 +0200 Subject: [PATCH 158/389] map match without graphhopper class (#2657) --- .../com/graphhopper/matching/MapMatching.java | 69 ++++++++++++------- .../resources/MapMatchingResource.java | 2 +- .../application/cli/MatchCommand.java | 2 +- .../application/MapMatching2Test.java | 6 +- .../application/MapMatchingTest.java | 20 +++--- 5 files changed, 61 insertions(+), 38 deletions(-) diff --git a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java index aba6870c005..2bd9d7def94 100644 --- a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java +++ b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java @@ -44,8 +44,6 @@ import com.graphhopper.util.*; import com.graphhopper.util.shapes.BBox; import org.locationtech.jts.geom.Envelope; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.*; import java.util.stream.Collectors; @@ -71,24 +69,15 @@ * @author kodonnell */ public class MapMatching { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final BaseGraph graph; - private final LandmarkStorage landmarks; + private final Router router; private final LocationIndexTree locationIndex; private double measurementErrorSigma = 50.0; private double transitionProbabilityBeta = 2.0; - private final int maxVisitedNodes; private final DistanceCalc distanceCalc = new DistancePlaneProjection(); - private final Weighting unwrappedWeighting; - private Weighting weighting; - private final BooleanEncodedValue inSubnetworkEnc; private QueryGraph queryGraph; - public MapMatching(GraphHopper graphHopper, PMap hints) { - this.locationIndex = (LocationIndexTree) graphHopper.getLocationIndex(); - + public static MapMatching fromGraphHopper(GraphHopper graphHopper, PMap hints) { if (hints.has("vehicle")) throw new IllegalArgumentException("MapMatching hints may no longer contain a vehicle, use the profile parameter instead, see core/#1958"); if (hints.has("weighting")) @@ -118,6 +107,7 @@ public MapMatching(GraphHopper graphHopper, PMap hints) { // (=faster) choice when the observations are close to each other boolean useDijkstra = disableLM || disableCH; + LandmarkStorage landmarks; if (graphHopper.getLMPreparationHandler().isEnabled() && !useDijkstra) { // using LM because u-turn prevention does not work properly with (node-based) CH landmarks = graphHopper.getLandmarks().get(profile.getName()); @@ -129,10 +119,35 @@ public MapMatching(GraphHopper graphHopper, PMap hints) { } else { landmarks = null; } - graph = graphHopper.getBaseGraph(); - unwrappedWeighting = graphHopper.createWeighting(profile, hints); - inSubnetworkEnc = graphHopper.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(profileStr)); - this.maxVisitedNodes = hints.getInt(Parameters.Routing.MAX_VISITED_NODES, Integer.MAX_VALUE); + Weighting weighting = graphHopper.createWeighting(profile, hints); + BooleanEncodedValue inSubnetworkEnc = graphHopper.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(profileStr)); + DefaultSnapFilter snapFilter = new DefaultSnapFilter(weighting, inSubnetworkEnc); + int maxVisitedNodes = hints.getInt(Parameters.Routing.MAX_VISITED_NODES, Integer.MAX_VALUE); + + Router router = new Router() { + @Override + public EdgeFilter getSnapFilter() { + return snapFilter; + } + + @Override + public BidirRoutingAlgorithm createAlgo(QueryGraph queryGraph) { + return createRouter(queryGraph, queryGraph.wrapWeighting(weighting), landmarks, maxVisitedNodes); + } + + @Override + public Weighting getWeighting() { + return weighting; + } + }; + + return new MapMatching(graphHopper.getBaseGraph(), (LocationIndexTree) graphHopper.getLocationIndex(), router); + } + + public MapMatching(BaseGraph graph, LocationIndexTree locationIndex, Router router) { + this.graph = graph; + this.locationIndex = locationIndex; + this.router = router; } /** @@ -162,7 +177,6 @@ public MatchResult match(List observations) { // Create the query graph, containing split edges so that all the places where an observation might have happened // are a node. This modifies the Snap objects and puts the new node numbers into them. queryGraph = QueryGraph.create(graph, snapsPerObservation.stream().flatMap(Collection::stream).collect(Collectors.toList())); - weighting = queryGraph.wrapWeighting(unwrappedWeighting); // Creates candidates from the Snaps of all observations (a candidate is basically a // Snap + direction). @@ -174,12 +188,13 @@ public MatchResult match(List observations) { List path = seq.stream().filter(s1 -> s1.transitionDescriptor != null).flatMap(s1 -> s1.transitionDescriptor.calcEdges().stream()).collect(Collectors.toList()); MatchResult result = new MatchResult(prepareEdgeMatches(seq)); - result.setMergedPath(new MapMatchedPath(queryGraph, weighting, path)); + Weighting queryGraphWeighting = queryGraph.wrapWeighting(router.getWeighting()); + result.setMergedPath(new MapMatchedPath(queryGraph, queryGraphWeighting, path)); result.setMatchMillis(seq.stream().filter(s -> s.transitionDescriptor != null).mapToLong(s -> s.transitionDescriptor.getTime()).sum()); result.setMatchLength(seq.stream().filter(s -> s.transitionDescriptor != null).mapToDouble(s -> s.transitionDescriptor.getDistance()).sum()); result.setGPXEntriesLength(gpxLength(observations)); result.setGraph(queryGraph); - result.setWeighting(weighting); + result.setWeighting(queryGraphWeighting); return result; } @@ -239,7 +254,7 @@ public List findCandidateSnaps(final double queryLat, final double queryLo } private List findCandidateSnapsInBBox(double queryLat, double queryLon, BBox queryShape) { - EdgeFilter edgeFilter = new DefaultSnapFilter(unwrappedWeighting, inSubnetworkEnc); + EdgeFilter edgeFilter = router.getSnapFilter(); List snaps = new ArrayList<>(); IntHashSet seenEdges = new IntHashSet(); IntHashSet seenNodes = new IntHashSet(); @@ -347,7 +362,7 @@ private List> computeViterbiSequence(Lis for (State from : prevTimeStep.candidates) { for (State to : timeStep.candidates) { - final Path path = createRouter().calcPath(from.getSnap().getClosestNode(), to.getSnap().getClosestNode(), from.isOnDirectedEdge() ? from.getOutgoingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE, to.isOnDirectedEdge() ? to.getIncomingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE); + final Path path = router.createAlgo(queryGraph).calcPath(from.getSnap().getClosestNode(), to.getSnap().getClosestNode(), from.isOnDirectedEdge() ? from.getOutgoingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE, to.isOnDirectedEdge() ? to.getIncomingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE); if (path.isFound()) { double transitionLogProbability = probabilities.transitionLogProbability(path.getDistance(), linearDistance); Transition transition = new Transition<>(from, to); @@ -389,7 +404,7 @@ private void fail(int timeStepCounter, ObservationWithCandidateStates prevTimeSt + ". If a match is expected consider increasing max_visited_nodes."); } - private BidirRoutingAlgorithm createRouter() { + private static BidirRoutingAlgorithm createRouter(QueryGraph queryGraph, Weighting weighting, LandmarkStorage landmarks, int maxVisitedNodes) { BidirRoutingAlgorithm router; if (landmarks != null) { AStarBidirection algo = new AStarBidirection(queryGraph, weighting, TraversalMode.EDGE_BASED) { @@ -532,4 +547,12 @@ private static class MapMatchedPath extends Path { } } + public interface Router { + EdgeFilter getSnapFilter(); + + BidirRoutingAlgorithm createAlgo(QueryGraph graph); + + Weighting getWeighting(); + } + } \ No newline at end of file diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java index 1dc05c60e9e..ed01763b729 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java @@ -117,7 +117,7 @@ public Response match( hints.putObject("profile", profile); removeLegacyParameters(hints); - MapMatching matching = new MapMatching(graphHopper, hints); + MapMatching matching = MapMatching.fromGraphHopper(graphHopper, hints); matching.setMeasurementErrorSigma(gpsAccuracy); List measurements = GpxConversions.getEntries(gpx.trk.get(0)); diff --git a/web/src/main/java/com/graphhopper/application/cli/MatchCommand.java b/web/src/main/java/com/graphhopper/application/cli/MatchCommand.java index 995de0dceae..f20ea56dcdb 100644 --- a/web/src/main/java/com/graphhopper/application/cli/MatchCommand.java +++ b/web/src/main/java/com/graphhopper/application/cli/MatchCommand.java @@ -96,7 +96,7 @@ protected void run(Bootstrap bootstrap, Namespac PMap hints = new PMap(); hints.putObject("profile", args.get("profile")); - MapMatching mapMatching = new MapMatching(hopper, hints); + MapMatching mapMatching = MapMatching.fromGraphHopper(hopper, hints); mapMatching.setTransitionProbabilityBeta(args.getDouble("transition_probability_beta")); mapMatching.setMeasurementErrorSigma(args.getInt("gps_accuracy")); diff --git a/web/src/test/java/com/graphhopper/application/MapMatching2Test.java b/web/src/test/java/com/graphhopper/application/MapMatching2Test.java index f2c30de04b3..18b0b0939e4 100644 --- a/web/src/test/java/com/graphhopper/application/MapMatching2Test.java +++ b/web/src/test/java/com/graphhopper/application/MapMatching2Test.java @@ -63,7 +63,7 @@ public void testIssue13() throws IOException { hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("my_profile")); hopper.importOrLoad(); - MapMatching mapMatching = new MapMatching(hopper, new PMap().putObject("profile", "my_profile")); + MapMatching mapMatching = MapMatching.fromGraphHopper(hopper, new PMap().putObject("profile", "my_profile")); Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/issue-13.gpx"), Gpx.class); MatchResult mr = mapMatching.match(GpxConversions.getEntries(gpx.trk.get(0))); @@ -88,7 +88,7 @@ public void testIssue70() throws IOException { hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("my_profile")); hopper.importOrLoad(); - MapMatching mapMatching = new MapMatching(hopper, new PMap().putObject("profile", "my_profile")); + MapMatching mapMatching = MapMatching.fromGraphHopper(hopper, new PMap().putObject("profile", "my_profile")); Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/issue-70.gpx"), Gpx.class); MatchResult mr = mapMatching.match(GpxConversions.getEntries(gpx.trk.get(0))); @@ -108,7 +108,7 @@ public void testIssue127() throws IOException { hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("my_profile")); hopper.importOrLoad(); - MapMatching mapMatching = new MapMatching(hopper, new PMap().putObject("profile", "my_profile")); + MapMatching mapMatching = MapMatching.fromGraphHopper(hopper, new PMap().putObject("profile", "my_profile")); // query with two identical points Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/issue-127.gpx"), Gpx.class); diff --git a/web/src/test/java/com/graphhopper/application/MapMatchingTest.java b/web/src/test/java/com/graphhopper/application/MapMatchingTest.java index 5d3a0644cee..7321b3e749b 100644 --- a/web/src/test/java/com/graphhopper/application/MapMatchingTest.java +++ b/web/src/test/java/com/graphhopper/application/MapMatchingTest.java @@ -99,7 +99,7 @@ public Stream provideArguments(ExtensionContext context) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testDoWork(PMap hints) { - MapMatching mapMatching = new MapMatching(graphHopper, hints); + MapMatching mapMatching = MapMatching.fromGraphHopper(graphHopper, hints); ResponsePath route2 = graphHopper.route(new GHRequest( new GHPoint(51.358735, 12.360574), new GHPoint(51.358594, 12.360032)) @@ -134,7 +134,7 @@ public void testDoWork(PMap hints) { new GHPoint(51.323317, 12.387085)) .setProfile("my_profile")).getBest(); inputGPXEntries = createRandomGPXEntriesAlongRoute(route); - mapMatching = new MapMatching(graphHopper, hints); + mapMatching = MapMatching.fromGraphHopper(graphHopper, hints); mapMatching.setMeasurementErrorSigma(20); mr = mapMatching.match(inputGPXEntries); @@ -147,7 +147,7 @@ public void testDoWork(PMap hints) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testLongTrackWithLotsOfPoints(PMap hints) { - MapMatching mapMatching = new MapMatching(graphHopper, hints); + MapMatching mapMatching = MapMatching.fromGraphHopper(graphHopper, hints); ResponsePath route = graphHopper.route(new GHRequest( new GHPoint(51.23, 12.18), new GHPoint(51.45, 12.59)) @@ -163,7 +163,7 @@ public void testLongTrackWithLotsOfPoints(PMap hints) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testLongTrackWithTwoPoints(PMap hints) { - MapMatching mapMatching = new MapMatching(graphHopper, hints); + MapMatching mapMatching = MapMatching.fromGraphHopper(graphHopper, hints); List inputGPXEntries = Arrays.asList( new Observation(new GHPoint(51.23, 12.18)), new Observation(new GHPoint(51.45, 12.59))); @@ -174,7 +174,7 @@ public void testLongTrackWithTwoPoints(PMap hints) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testClosePoints(PMap hints) { - MapMatching mapMatching = new MapMatching(graphHopper, hints); + MapMatching mapMatching = MapMatching.fromGraphHopper(graphHopper, hints); ResponsePath route = graphHopper.route(new GHRequest( new GHPoint(51.342422, 12.3613358), new GHPoint(51.342328, 12.3613358)) @@ -192,7 +192,7 @@ public void testClosePoints(PMap hints) { @ArgumentsSource(FixtureProvider.class) public void testTour3WithLongEdge(PMap hints) throws IOException { Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/tour3-with-long-edge.gpx"), Gpx.class); - MapMatching mapMatching = new MapMatching(graphHopper, hints); + MapMatching mapMatching = MapMatching.fromGraphHopper(graphHopper, hints); mapMatching.setMeasurementErrorSigma(20); MatchResult mr = mapMatching.match(GpxConversions.getEntries(gpx.trk.get(0))); assertEquals(Arrays.asList("Marbachstraße", "Weinligstraße", "Fechnerstraße"), fetchStreets(mr.getEdgeMatches())); @@ -203,7 +203,7 @@ public void testTour3WithLongEdge(PMap hints) throws IOException { @ArgumentsSource(FixtureProvider.class) public void testSimplification(PMap hints) throws IOException { Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/tour3-with-long-edge.gpx"), Gpx.class); - MapMatching mapMatching = new MapMatching(graphHopper, hints); + MapMatching mapMatching = MapMatching.fromGraphHopper(graphHopper, hints); mapMatching.setMeasurementErrorSigma(20); List observations = GpxConversions.getEntries(gpx.trk.get(0)); // Warning, this has to be calculated before filtering, because (of course) observations @@ -241,7 +241,7 @@ private double linearDistance(List observations) { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testLoop(PMap hints) throws IOException { - MapMatching mapMatching = new MapMatching(graphHopper, hints); + MapMatching mapMatching = MapMatching.fromGraphHopper(graphHopper, hints); // Need to reduce GPS accuracy because too many GPX are filtered out otherwise. mapMatching.setMeasurementErrorSigma(40); @@ -261,7 +261,7 @@ public void testLoop(PMap hints) throws IOException { @ParameterizedTest @ArgumentsSource(FixtureProvider.class) public void testLoop2(PMap hints) throws IOException { - MapMatching mapMatching = new MapMatching(graphHopper, hints); + MapMatching mapMatching = MapMatching.fromGraphHopper(graphHopper, hints); // TODO smaller sigma like 40m leads to U-turn at Tschaikowskistraße mapMatching.setMeasurementErrorSigma(50); Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/tour-with-loop.gpx"), Gpx.class); @@ -284,7 +284,7 @@ public void testUTurns(PMap hints) throws IOException { // Reduce penalty to allow U-turns .putObject(Parameters.Routing.HEADING_PENALTY, 50); - MapMatching mapMatching = new MapMatching(graphHopper, hints); + MapMatching mapMatching = MapMatching.fromGraphHopper(graphHopper, hints); Gpx gpx = xmlMapper.readValue(getClass().getResourceAsStream("/tour4-with-uturn.gpx"), Gpx.class); // with large measurement error, we expect no U-turn From 789580c479e9388c542bf81911f714e93abac8b4 Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Fri, 9 Sep 2022 17:52:53 -0700 Subject: [PATCH 159/389] Solve Viterbi problem with Dijkstra to calculate fewer routes --- hmm-lib/LICENSE | 191 -------- hmm-lib/NOTICE | 18 - hmm-lib/README.md | 89 ---- hmm-lib/pom.xml | 60 --- hmm-lib/src/main/java/com/bmw/hmm/Utils.java | 31 -- .../java/com/bmw/hmm/ViterbiAlgorithm.java | 442 ------------------ .../com/bmw/hmm/ViterbiAlgorithmTest.java | 355 -------------- .../com/graphhopper/matching/MapMatching.java | 134 +++--- .../graphhopper/matching}/SequenceState.java | 2 +- .../com/graphhopper/matching}/Transition.java | 2 +- pom.xml | 1 - 11 files changed, 60 insertions(+), 1265 deletions(-) delete mode 100644 hmm-lib/LICENSE delete mode 100644 hmm-lib/NOTICE delete mode 100644 hmm-lib/README.md delete mode 100644 hmm-lib/pom.xml delete mode 100644 hmm-lib/src/main/java/com/bmw/hmm/Utils.java delete mode 100644 hmm-lib/src/main/java/com/bmw/hmm/ViterbiAlgorithm.java delete mode 100644 hmm-lib/src/test/java/com/bmw/hmm/ViterbiAlgorithmTest.java rename {hmm-lib/src/main/java/com/bmw/hmm => map-matching/src/main/java/com/graphhopper/matching}/SequenceState.java (98%) rename {hmm-lib/src/main/java/com/bmw/hmm => map-matching/src/main/java/com/graphhopper/matching}/Transition.java (98%) diff --git a/hmm-lib/LICENSE b/hmm-lib/LICENSE deleted file mode 100644 index 8405e89a0b1..00000000000 --- a/hmm-lib/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. \ No newline at end of file diff --git a/hmm-lib/NOTICE b/hmm-lib/NOTICE deleted file mode 100644 index e2bc3f38711..00000000000 --- a/hmm-lib/NOTICE +++ /dev/null @@ -1,18 +0,0 @@ -Copyright (C) 2015-2016, BMW Car IT GmbH and BMW AG -Author: Stefan Holder (stefan.holder@bmw.de) - -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. - -This project has dependencies to: - Apache Maven, under The Apache Software License, Version 2.0 - JUnit under Eclipse Public License - v 1.0 \ No newline at end of file diff --git a/hmm-lib/README.md b/hmm-lib/README.md deleted file mode 100644 index a84d9cce0a0..00000000000 --- a/hmm-lib/README.md +++ /dev/null @@ -1,89 +0,0 @@ -# Overview - -This library implements Hidden Markov Models (HMM) for time-inhomogeneous Markov processes. -This means that, in contrast to many other HMM implementations, there can be different -states and a different transition matrix at each time step. - -Currently, this library provides an implementation of the Viterbi algorithm, which computes the -most likely sequence of states. More HMM algorithms such as the forward backward algorithm will -follow. - -# Applications - -This library was initially created for HMM-based map matching according to the paper -"NEWSON, Paul; KRUMM, John. Hidden Markov map matching through noise and sparseness. -In: Proceedings of the 17th ACM SIGSPATIAL international conference on advances in geographic -information systems. ACM, 2009. S. 336-343." - -[Graphhopper](https://graphhopper.com/) [map matching](https://github.com/graphhopper/graphhopper/tree/master/map-matching) -is using the hmm-lib for matching GPS positions to the OpenStreetMap road network. - -The [offline-map-matching](https://github.com/bmwcarit/offline-map-matching) project -demonstrates how to use the hmm-lib for map matching but does not provide integration to any -particular map. - -Besides map matching, the hmm-lib can also be used for other applications. - -# License - -This library is licensed under the -[Apache 2.0 license](http://www.apache.org/licenses/LICENSE-2.0.html). - -# Dependencies - -Except for testing, there are no dependencies to other libraries. - -# Maven - -To use this library, add the following to your pom.xml: - -``` - - ... - - com.bmw.hmm - hmm-lib - 1.0.0 - - - - - ... - - hmm-lib-releases - https://raw.github.com/bmwcarit/hmm-lib/mvn-releases/ - - -``` - - -If you want to use snapshots, add -``` - - ... - - hmm-lib-snapshots - https://raw.github.com/bmwcarit/hmm-lib/mvn-snapshots/ - - true - always - - - -``` - -# Contribute -Contributions are welcome! For bug reports, please create an issue. -For code contributions (e.g. new features or bugfixes), please create a pull request. - -# Changes -* 1.0.0: - * API redesign to allow calling the Viterbi algorithm iteratively. This gives the library user - increased flexibility and optimization opportunities when computing transition and observation - probabilities. Moreover, the new API enables better handling of HMM breaks. - * Add support for transition descriptors. For map matching, this allows retrieving the paths - between matched positions (the entire matched route) after computing the most likely sequence. - * Reduce memory footprint from O(t\*n�) to O(t\*n) or even O(t) in many applications, where t is - the number of time steps and n is the number of candidates per time step. -* 0.2.0: Extend HmmProbabilities interface to include the observation -* 0.1.0: Initial release diff --git a/hmm-lib/pom.xml b/hmm-lib/pom.xml deleted file mode 100644 index 166904c5d4a..00000000000 --- a/hmm-lib/pom.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - 4.0.0 - hmm-lib-external - - 6.0-SNAPSHOT - jar - - hmm-lib - Hidden Markov Model (HMM) library for time-inhomogeneous Markov processes - https://github.com/bmwcarit/hmm-lib - - - com.graphhopper - graphhopper-parent - 6.0-SNAPSHOT - - - - - BMW Car IT GmbH, BMW AG - http://www.bmw-carit.com, http://www.bmw.com - - - - - - Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - scm:git:git@github.com:bmwcarit/hmm-lib.git - scm:git:git@github.com:bmwcarit/hmm-lib.git - git@github.com:bmwcarit/hmm-lib - - - - UTF-8 - UTF-8 - - diff --git a/hmm-lib/src/main/java/com/bmw/hmm/Utils.java b/hmm-lib/src/main/java/com/bmw/hmm/Utils.java deleted file mode 100644 index aa9d3dc63fc..00000000000 --- a/hmm-lib/src/main/java/com/bmw/hmm/Utils.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (C) 2015, BMW Car IT GmbH - * Author: Stefan Holder (stefan.holder@bmw.de) - * - * 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. - */ - -package com.bmw.hmm; - -/** - * Implementation utilities. - */ -class Utils { - - public static int initialHashMapCapacity(int maxElements) { - // Default load factor of HashMaps is 0.75 - return (int)(maxElements / 0.75) + 1; - } - - -} diff --git a/hmm-lib/src/main/java/com/bmw/hmm/ViterbiAlgorithm.java b/hmm-lib/src/main/java/com/bmw/hmm/ViterbiAlgorithm.java deleted file mode 100644 index a7477401f5e..00000000000 --- a/hmm-lib/src/main/java/com/bmw/hmm/ViterbiAlgorithm.java +++ /dev/null @@ -1,442 +0,0 @@ -/** - * Copyright (C) 2015-2016, BMW Car IT GmbH and BMW AG - * Author: Stefan Holder (stefan.holder@bmw.de) - * - * 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. - */ - -package com.bmw.hmm; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * Implementation of the Viterbi algorithm for time-inhomogeneous Markov processes, - * meaning that the set of states and state transition probabilities are not necessarily fixed - * for all time steps. The plain Viterbi algorithm for stationary Markov processes is described e.g. - * in Rabiner, Juang, An introduction to Hidden Markov Models, IEEE ASSP Mag., pp 4-16, June 1986. - * - *

    Generally expects logarithmic probabilities as input to prevent arithmetic underflows for - * small probability values. - * - *

    This algorithm supports storing transition objects in - * {@link #nextStep(Object, Collection, Map, Map, Map)}. For instance if a HMM is - * used for map matching, this could be routes between road position candidates. - * The transition descriptors of the most likely sequence can be retrieved later in - * {@link SequenceState#transitionDescriptor} and hence do not need to be stored by the - * caller. Since the caller does not know in advance which transitions will occur in the most - * likely sequence, this reduces the number of transitions that need to be kept in memory - * from t*n² to t*n since only one transition descriptor is stored per back pointer, - * where t is the number of time steps and n the number of candidates per time step. - * - *

    For long observation sequences, back pointers usually converge to a single path after a - * certain number of time steps. For instance, when matching GPS coordinates to roads, the last - * GPS positions in the trace usually do not affect the first road matches anymore. - * This implementation exploits this fact by letting the Java garbage collector - * take care of unreachable back pointers. If back pointers converge to a single path after a - * constant number of time steps, only O(t) back pointers and transition descriptors need to be - * stored in memory. - * - * @param the state type - * @param the observation type - * @param the transition descriptor type. Pass {@link Object} if transition descriptors are not - * needed. - */ -public class ViterbiAlgorithm { - - /** - * Stores addition information for each candidate. - */ - private static class ExtendedState { - - S state; - - /** - * Back pointer to previous state candidate in the most likely sequence. - * Back pointers are chained using plain Java references. - * This allows garbage collection of unreachable back pointers. - */ - ExtendedState backPointer; - - O observation; - D transitionDescriptor; - - ExtendedState(S state, - ExtendedState backPointer, - O observation, D transitionDescriptor) { - this.state = state; - this.backPointer = backPointer; - this.observation = observation; - this.transitionDescriptor = transitionDescriptor; - } - } - - private static class ForwardStepResult { - final Map newMessage; - - /** - * Includes back pointers to previous state candidates for retrieving the most likely - * sequence after the forward pass. - */ - final Map> newExtendedStates; - - ForwardStepResult(int numberStates) { - newMessage = new LinkedHashMap<>(Utils.initialHashMapCapacity(numberStates)); - newExtendedStates = new LinkedHashMap<>(Utils.initialHashMapCapacity(numberStates)); - } - } - - /** - * Allows to retrieve the most likely sequence using back pointers. - */ - private Map> lastExtendedStates; - - private Collection prevCandidates; - - /** - * For each state s_t of the current time step t, message.get(s_t) contains the log - * probability of the most likely sequence ending in state s_t with given observations - * o_1, ..., o_t. - * - * Formally, this is max log p(s_1, ..., s_t, o_1, ..., o_t) w.r.t. s_1, ..., s_{t-1}. - * Note that to compute the most likely state sequence, it is sufficient and more - * efficient to compute in each time step the joint probability of states and observations - * instead of computing the conditional probability of states given the observations. - */ - private Map message; - - private boolean isBroken = false; - - private List> messageHistory; // For debugging only. - - /** - * Need to construct a new instance for each sequence of observations. - * Does not keep the message history. - */ - public ViterbiAlgorithm() { - this(false); - } - - /** - * Need to construct a new instance for each sequence of observations. - * @param keepMessageHistory Whether to store intermediate forward messages - * (probabilities of intermediate most likely paths) for debugging. - */ - public ViterbiAlgorithm(boolean keepMessageHistory) { - if (keepMessageHistory) { - messageHistory = new ArrayList<>(); - } - } - - /** - * Lets the HMM computation start with the given initial state probabilities. - * - * @param initialStates Pass a collection with predictable iteration order such as - * {@link ArrayList} to ensure deterministic results. - * @param initialLogProbabilities Initial log probabilities for each initial state. - * - * @throws NullPointerException if any initial probability is missing - * - * @throws IllegalStateException if this method or - * {@link #startWithInitialObservation(Object, Collection, Map)} - * has already been called - */ - public void startWithInitialStateProbabilities(Collection initialStates, - Map initialLogProbabilities) { - initializeStateProbabilities(null, initialStates, initialLogProbabilities); - } - - /** - * Lets the HMM computation start at the given first observation and uses the given emission - * probabilities as the initial state probability for each starting state s. - * - * @param candidates Pass a collection with predictable iteration order such as - * {@link ArrayList} to ensure deterministic results. - * @param emissionLogProbabilities Emission log probabilities of the first observation for - * each of the road position candidates. - * - * @throws NullPointerException if any emission probability is missing - * - * @throws IllegalStateException if this method or - * {@link #startWithInitialStateProbabilities(Collection, Map)}} has already been called - */ - public void startWithInitialObservation(O observation, Collection candidates, - Map emissionLogProbabilities) { - initializeStateProbabilities(observation, candidates, emissionLogProbabilities); - } - - /** - * Processes the next time step. Must not be called if the HMM is broken. - * - * @param candidates Pass a collection with predictable iteration order such as - * {@link ArrayList} to ensure deterministic results. - * @param emissionLogProbabilities Emission log probabilities for each candidate state. - * - * @param transitionLogProbabilities Transition log probability between all pairs of candidates. - * A transition probability of zero is assumed for every missing transition. - * - * @param transitionDescriptors Optional objects that describes the transitions. - * - * @throws NullPointerException if any emission probability is missing - * - * @throws IllegalStateException if neither - * {@link #startWithInitialStateProbabilities(Collection, Map)} nor - * {@link #startWithInitialObservation(Object, Collection, Map)} - * has not been called before or if this method is called after an HMM break has occurred - */ - public void nextStep(O observation, Collection candidates, - Map emissionLogProbabilities, - Map, Double> transitionLogProbabilities, - Map, D> transitionDescriptors) { - if (message == null) { - throw new IllegalStateException( - "startWithInitialStateProbabilities() or startWithInitialObservation() " - + "must be called first."); - } - if (isBroken) { - throw new IllegalStateException("Method must not be called after an HMM break."); - } - - // Forward step - ForwardStepResult forwardStepResult = forwardStep(observation, prevCandidates, - candidates, message, emissionLogProbabilities, transitionLogProbabilities, - transitionDescriptors); - isBroken = hmmBreak(forwardStepResult.newMessage); - if (isBroken) return; - if (messageHistory != null) { - messageHistory.add(forwardStepResult.newMessage); - } - message = forwardStepResult.newMessage; - lastExtendedStates = forwardStepResult.newExtendedStates; - - prevCandidates = new ArrayList<>(candidates); // Defensive copy. - } - - /** - * See {@link #nextStep(Object, Collection, Map, Map, Map)} - */ - public void nextStep(O observation, Collection candidates, - Map emissionLogProbabilities, - Map, Double> transitionLogProbabilities) { - nextStep(observation, candidates, emissionLogProbabilities, transitionLogProbabilities, - new LinkedHashMap, D>()); - } - - /** - * Returns the most likely sequence of states for all time steps. This includes the initial - * states / initial observation time step. If an HMM break occurred in the last time step t, - * then the most likely sequence up to t-1 is returned. See also {@link #isBroken()}. - * - *

    Formally, the most likely sequence is argmax p([s_0,] s_1, ..., s_T | o_1, ..., o_T) - * with respect to s_1, ..., s_T, where s_t is a state candidate at time step t, - * o_t is the observation at time step t and T is the number of time steps. - */ - public List> computeMostLikelySequence() { - if (message == null) { - // Return empty most likely sequence if there are no time steps or if initial - // observations caused an HMM break. - return new ArrayList<>(); - } else { - return retrieveMostLikelySequence(); - } - } - - /** - * Returns whether an HMM occurred in the last time step. - * - * An HMM break means that the probability of all states equals zero. - */ - public boolean isBroken() { - return isBroken; - } - - /** - * Returns the sequence of intermediate forward messages for each time step. - * Returns null if message history is not kept. - */ - public List> messageHistory() { - return messageHistory; - } - - public String messageHistoryString() { - if (messageHistory == null) { - throw new IllegalStateException("Message history was not recorded."); - } - - final StringBuilder sb = new StringBuilder(); - sb.append("Message history with log probabilies\n\n"); - int i = 0; - for (Map message : messageHistory) { - sb.append("Time step " + i + "\n"); - i++; - for (S state : message.keySet()) { - sb.append(state + ": " + message.get(state) + "\n"); - } - sb.append("\n"); - } - return sb.toString(); - } - - /** - * Returns whether the specified message is either empty or only contains state candidates - * with zero probability and thus causes the HMM to break. - */ - private boolean hmmBreak(Map message) { - for (double logProbability : message.values()) { - if (logProbability != Double.NEGATIVE_INFINITY) { - return false; - } - } - return true; - } - - /** - * @param observation Use only if HMM only starts with first observation. - */ - private void initializeStateProbabilities(O observation, Collection candidates, - Map initialLogProbabilities) { - if (message != null) { - throw new IllegalStateException("Initial probabilities have already been set."); - } - - // Set initial log probability for each start state candidate based on first observation. - // Do not assign initialLogProbabilities directly to message to not rely on its iteration - // order. - final Map initialMessage = new LinkedHashMap<>(); - for (S candidate : candidates) { - final Double logProbability = initialLogProbabilities.get(candidate); - if (logProbability == null) { - throw new NullPointerException("No initial probability for " + candidate); - } - initialMessage.put(candidate, logProbability); - } - - isBroken = hmmBreak(initialMessage); - if (isBroken) return; - - message = initialMessage; - if (messageHistory != null) { - messageHistory.add(message); - } - - lastExtendedStates = new LinkedHashMap<>(); - for (S candidate : candidates) { - lastExtendedStates.put(candidate, - new ExtendedState(candidate, null, observation, null)); - } - - prevCandidates = new ArrayList<>(candidates); // Defensive copy. - } - - /** - * Computes the new forward message and the back pointers to the previous states. - * - * @throws NullPointerException if any emission probability is missing - */ - private ForwardStepResult forwardStep(O observation, Collection prevCandidates, - Collection curCandidates, Map message, - Map emissionLogProbabilities, - Map, Double> transitionLogProbabilities, - Map,D> transitionDescriptors) { - final ForwardStepResult result = new ForwardStepResult<>(curCandidates.size()); - assert !prevCandidates.isEmpty(); - - for (S curState : curCandidates) { - double maxLogProbability = Double.NEGATIVE_INFINITY; - S maxPrevState = null; - for (S prevState : prevCandidates) { - final double logProbability = message.get(prevState) + transitionLogProbability( - prevState, curState, transitionLogProbabilities); - if (logProbability > maxLogProbability) { - maxLogProbability = logProbability; - maxPrevState = prevState; - } - } - // Throws NullPointerException if curState is not stored in the map. - result.newMessage.put(curState, maxLogProbability - + emissionLogProbabilities.get(curState)); - - // Note that maxPrevState == null if there is no transition with non-zero probability. - // In this case curState has zero probability and will not be part of the most likely - // sequence, so we don't need an ExtendedState. - if (maxPrevState != null) { - final Transition transition = new Transition<>(maxPrevState, curState); - final ExtendedState extendedState = new ExtendedState<>(curState, - lastExtendedStates.get(maxPrevState), observation, - transitionDescriptors.get(transition)); - result.newExtendedStates.put(curState, extendedState); - } - } - return result; - } - - private double transitionLogProbability(S prevState, S curState, Map, - Double> transitionLogProbabilities) { - final Double transitionLogProbability = - transitionLogProbabilities.get(new Transition(prevState, curState)); - if (transitionLogProbability == null) { - return Double.NEGATIVE_INFINITY; // Transition has zero probability. - } else { - return transitionLogProbability; - } - } - - /** - * Retrieves the first state of the current forward message with maximum probability. - */ - private S mostLikelyState() { - // Otherwise an HMM break would have occurred and message would be null. - assert !message.isEmpty(); - - S result = null; - double maxLogProbability = Double.NEGATIVE_INFINITY; - for (Map.Entry entry : message.entrySet()) { - if (entry.getValue() > maxLogProbability) { - result = entry.getKey(); - maxLogProbability = entry.getValue(); - } - } - - assert result != null; // Otherwise an HMM break would have occurred. - return result; - } - - /** - * Retrieves most likely sequence from the internal back pointer sequence. - */ - private List> retrieveMostLikelySequence() { - // Otherwise an HMM break would have occurred and message would be null. - assert !message.isEmpty(); - - final S lastState = mostLikelyState(); - - // Retrieve most likely state sequence in reverse order - final List> result = new ArrayList<>(); - ExtendedState es = lastExtendedStates.get(lastState); - while(es != null) { - final SequenceState ss = new SequenceState<>(es.state, es.observation, - es.transitionDescriptor); - result.add(ss); - es = es.backPointer; - } - - Collections.reverse(result); - return result; - } - - -} diff --git a/hmm-lib/src/test/java/com/bmw/hmm/ViterbiAlgorithmTest.java b/hmm-lib/src/test/java/com/bmw/hmm/ViterbiAlgorithmTest.java deleted file mode 100644 index 3d782fc9e65..00000000000 --- a/hmm-lib/src/test/java/com/bmw/hmm/ViterbiAlgorithmTest.java +++ /dev/null @@ -1,355 +0,0 @@ -/** - * Copyright (C) 2015-2016, BMW Car IT GmbH and BMW AG - * Author: Stefan Holder (stefan.holder@bmw.de) - *

    - * 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. - */ - -package com.bmw.hmm; - -import org.junit.jupiter.api.Test; - -import java.util.*; - -import static java.lang.Math.log; -import static org.junit.jupiter.api.Assertions.*; - -public class ViterbiAlgorithmTest { - - private static class Rain { - final static Rain T = new Rain(); - final static Rain F = new Rain(); - - @Override - public String toString() { - if (this == T) { - return "Rain"; - } else if (this == F) { - return "Sun"; - } - throw new IllegalStateException(); - } - } - - private static class Umbrella { - final static Umbrella T = new Umbrella(); - final static Umbrella F = new Umbrella(); - - @Override - public String toString() { - if (this == T) { - return "Umbrella"; - } else if (this == F) { - return "No umbrella"; - } - throw new IllegalStateException(); - } - } - - private static class Descriptor { - final static Descriptor R2R = new Descriptor(); - final static Descriptor R2S = new Descriptor(); - final static Descriptor S2R = new Descriptor(); - final static Descriptor S2S = new Descriptor(); - - @Override - public String toString() { - if (this == R2R) { - return "R2R"; - } else if (this == R2S) { - return "R2S"; - } else if (this == S2R) { - return "S2R"; - } else if (this == S2S) { - return "S2S"; - } - throw new IllegalStateException(); - } - } - - private static double DELTA = 1e-8; - - private List states(List> sequenceStates) { - final List result = new ArrayList<>(); - for (SequenceState ss : sequenceStates) { - result.add(ss.state); - } - return result; - } - - /** - * Tests the Viterbi algorithms with the umbrella example taken from Russell, Norvig: Aritifical - * Intelligence - A Modern Approach, 3rd edition, chapter 15.2.3. Note that the probabilities in - * Figure 15.5 are different, since the book uses initial probabilities and the probabilities - * for message m1:1 are normalized (not wrong but unnecessary). - */ - @Test - public void testComputeMostLikelySequence() { - final List candidates = new ArrayList<>(); - candidates.add(Rain.T); - candidates.add(Rain.F); - - final Map emissionLogProbabilitiesForUmbrella = new LinkedHashMap<>(); - emissionLogProbabilitiesForUmbrella.put(Rain.T, log(0.9)); - emissionLogProbabilitiesForUmbrella.put(Rain.F, log(0.2)); - - final Map emissionLogProbabilitiesForNoUmbrella = new LinkedHashMap<>(); - emissionLogProbabilitiesForNoUmbrella.put(Rain.T, log(0.1)); - emissionLogProbabilitiesForNoUmbrella.put(Rain.F, log(0.8)); - - final Map, Double> transitionLogProbabilities = new LinkedHashMap<>(); - transitionLogProbabilities.put(new Transition(Rain.T, Rain.T), log(0.7)); - transitionLogProbabilities.put(new Transition(Rain.T, Rain.F), log(0.3)); - transitionLogProbabilities.put(new Transition(Rain.F, Rain.T), log(0.3)); - transitionLogProbabilities.put(new Transition(Rain.F, Rain.F), log(0.7)); - - final Map, Descriptor> transitionDescriptors = new LinkedHashMap<>(); - transitionDescriptors.put(new Transition(Rain.T, Rain.T), Descriptor.R2R); - transitionDescriptors.put(new Transition(Rain.T, Rain.F), Descriptor.R2S); - transitionDescriptors.put(new Transition(Rain.F, Rain.T), Descriptor.S2R); - transitionDescriptors.put(new Transition(Rain.F, Rain.F), Descriptor.S2S); - - final ViterbiAlgorithm viterbi = new ViterbiAlgorithm<>(true); - viterbi.startWithInitialObservation(Umbrella.T, candidates, - emissionLogProbabilitiesForUmbrella); - viterbi.nextStep(Umbrella.T, candidates, emissionLogProbabilitiesForUmbrella, - transitionLogProbabilities, transitionDescriptors); - viterbi.nextStep(Umbrella.F, candidates, emissionLogProbabilitiesForNoUmbrella, - transitionLogProbabilities, transitionDescriptors); - viterbi.nextStep(Umbrella.T, candidates, emissionLogProbabilitiesForUmbrella, - transitionLogProbabilities, transitionDescriptors); - - final List> result = - viterbi.computeMostLikelySequence(); - - // Check most likely sequence - assertEquals(4, result.size()); - assertEquals(Rain.T, result.get(0).state); - assertEquals(Rain.T, result.get(1).state); - assertEquals(Rain.F, result.get(2).state); - assertEquals(Rain.T, result.get(3).state); - - assertEquals(Umbrella.T, result.get(0).observation); - assertEquals(Umbrella.T, result.get(1).observation); - assertEquals(Umbrella.F, result.get(2).observation); - assertEquals(Umbrella.T, result.get(3).observation); - - assertEquals(null, result.get(0).transitionDescriptor); - assertEquals(Descriptor.R2R, result.get(1).transitionDescriptor); - assertEquals(Descriptor.R2S, result.get(2).transitionDescriptor); - assertEquals(Descriptor.S2R, result.get(3).transitionDescriptor); - - // Check for HMM breaks - assertFalse(viterbi.isBroken()); - - // Check message history - List> expectedMessageHistory = new ArrayList<>(); - Map message = new LinkedHashMap<>(); - message.put(Rain.T, 0.9); - message.put(Rain.F, 0.2); - expectedMessageHistory.add(message); - - message = new LinkedHashMap<>(); - message.put(Rain.T, 0.567); - message.put(Rain.F, 0.054); - expectedMessageHistory.add(message); - - message = new LinkedHashMap<>(); - message.put(Rain.T, 0.03969); - message.put(Rain.F, 0.13608); - expectedMessageHistory.add(message); - - message = new LinkedHashMap<>(); - message.put(Rain.T, 0.0367416); - message.put(Rain.F, 0.0190512); - expectedMessageHistory.add(message); - - List> actualMessageHistory = viterbi.messageHistory(); - checkMessageHistory(expectedMessageHistory, actualMessageHistory); - } - - private void checkMessageHistory(List> expectedMessageHistory, - List> actualMessageHistory) { - assertEquals(expectedMessageHistory.size(), actualMessageHistory.size()); - for (int i = 0; i < expectedMessageHistory.size(); i++) { - checkMessage(expectedMessageHistory.get(i), actualMessageHistory.get(i)); - } - } - - private void checkMessage(Map expectedMessage, Map actualMessage) { - assertEquals(expectedMessage.size(), actualMessage.size()); - for (Map.Entry entry : expectedMessage.entrySet()) { - assertEquals(entry.getValue(), Math.exp(actualMessage.get(entry.getKey())), DELTA); - } - } - - @Test - public void testEmptySequence() { - final ViterbiAlgorithm viterbi = new ViterbiAlgorithm<>(); - final List> result = - viterbi.computeMostLikelySequence(); - - assertEquals(Arrays.asList(), result); - assertFalse(viterbi.isBroken()); - } - - @Test - public void testBreakAtInitialMessage() { - final ViterbiAlgorithm viterbi = new ViterbiAlgorithm<>(); - final List candidates = new ArrayList<>(); - candidates.add(Rain.T); - candidates.add(Rain.F); - - final Map emissionLogProbabilities = new LinkedHashMap<>(); - emissionLogProbabilities.put(Rain.T, log(0.0)); - emissionLogProbabilities.put(Rain.F, log(0.0)); - viterbi.startWithInitialObservation(Umbrella.T, candidates, emissionLogProbabilities); - assertTrue(viterbi.isBroken()); - assertEquals(Arrays.asList(), viterbi.computeMostLikelySequence()); - } - - @Test - public void testEmptyInitialMessage() { - final ViterbiAlgorithm viterbi = new ViterbiAlgorithm<>(); - viterbi.startWithInitialObservation(Umbrella.T, new ArrayList(), - new LinkedHashMap()); - assertTrue(viterbi.isBroken()); - assertEquals(Arrays.asList(), viterbi.computeMostLikelySequence()); - } - - @Test - public void testBreakAtFirstTransition() { - final ViterbiAlgorithm viterbi = new ViterbiAlgorithm<>(); - final List candidates = new ArrayList<>(); - candidates.add(Rain.T); - candidates.add(Rain.F); - - final Map emissionLogProbabilities = new LinkedHashMap<>(); - emissionLogProbabilities.put(Rain.T, log(0.9)); - emissionLogProbabilities.put(Rain.F, log(0.2)); - viterbi.startWithInitialObservation(Umbrella.T, candidates, emissionLogProbabilities); - assertFalse(viterbi.isBroken()); - - final Map, Double> transitionLogProbabilities = new LinkedHashMap<>(); - transitionLogProbabilities.put(new Transition(Rain.T, Rain.T), log(0.0)); - transitionLogProbabilities.put(new Transition(Rain.T, Rain.F), log(0.0)); - transitionLogProbabilities.put(new Transition(Rain.F, Rain.T), log(0.0)); - transitionLogProbabilities.put(new Transition(Rain.F, Rain.F), log(0.0)); - viterbi.nextStep(Umbrella.T, candidates, emissionLogProbabilities, - transitionLogProbabilities); - - assertTrue(viterbi.isBroken()); - assertEquals(Arrays.asList(Rain.T), states(viterbi.computeMostLikelySequence())); - } - - @Test - public void testBreakAtFirstTransitionWithNoCandidates() { - final ViterbiAlgorithm viterbi = new ViterbiAlgorithm<>(); - final List candidates = new ArrayList<>(); - candidates.add(Rain.T); - candidates.add(Rain.F); - - final Map emissionLogProbabilities = new LinkedHashMap<>(); - emissionLogProbabilities.put(Rain.T, log(0.9)); - emissionLogProbabilities.put(Rain.F, log(0.2)); - viterbi.startWithInitialObservation(Umbrella.T, candidates, emissionLogProbabilities); - assertFalse(viterbi.isBroken()); - - viterbi.nextStep(Umbrella.T, new ArrayList(), new LinkedHashMap(), - new LinkedHashMap, Double>()); - assertTrue(viterbi.isBroken()); - - assertEquals(Arrays.asList(Rain.T), states(viterbi.computeMostLikelySequence())); - } - - @Test - public void testBreakAtSecondTransition() { - final ViterbiAlgorithm viterbi = new ViterbiAlgorithm<>(); - final List candidates = new ArrayList<>(); - candidates.add(Rain.T); - candidates.add(Rain.F); - - final Map emissionLogProbabilities = new LinkedHashMap<>(); - emissionLogProbabilities.put(Rain.T, log(0.9)); - emissionLogProbabilities.put(Rain.F, log(0.2)); - viterbi.startWithInitialObservation(Umbrella.T, candidates, emissionLogProbabilities); - assertFalse(viterbi.isBroken()); - - Map, Double> transitionLogProbabilities = new LinkedHashMap<>(); - transitionLogProbabilities.put(new Transition(Rain.T, Rain.T), log(0.5)); - transitionLogProbabilities.put(new Transition(Rain.T, Rain.F), log(0.5)); - transitionLogProbabilities.put(new Transition(Rain.F, Rain.T), log(0.5)); - transitionLogProbabilities.put(new Transition(Rain.F, Rain.F), log(0.5)); - viterbi.nextStep(Umbrella.T, candidates, emissionLogProbabilities, - transitionLogProbabilities); - assertFalse(viterbi.isBroken()); - - transitionLogProbabilities = new LinkedHashMap<>(); - transitionLogProbabilities.put(new Transition(Rain.T, Rain.T), log(0.0)); - transitionLogProbabilities.put(new Transition(Rain.T, Rain.F), log(0.0)); - transitionLogProbabilities.put(new Transition(Rain.F, Rain.T), log(0.0)); - transitionLogProbabilities.put(new Transition(Rain.F, Rain.F), log(0.0)); - viterbi.nextStep(Umbrella.T, candidates, emissionLogProbabilities, - transitionLogProbabilities); - - assertTrue(viterbi.isBroken()); - assertEquals(Arrays.asList(Rain.T, Rain.T), states(viterbi.computeMostLikelySequence())); - } - - @Test - /** - * Checks if the first candidate is returned if multiple candidates are equally likely. - */ - public void testDeterministicCandidateOrder() { - final List candidates = new ArrayList<>(); - candidates.add(Rain.T); - candidates.add(Rain.F); - - // Reverse usual order of emission and transition probabilities keys since their order - // should not matter. - final Map emissionLogProbabilitiesForUmbrella = new LinkedHashMap<>(); - emissionLogProbabilitiesForUmbrella.put(Rain.F, log(0.5)); - emissionLogProbabilitiesForUmbrella.put(Rain.T, log(0.5)); - - final Map emissionLogProbabilitiesForNoUmbrella = new LinkedHashMap<>(); - emissionLogProbabilitiesForNoUmbrella.put(Rain.F, log(0.5)); - emissionLogProbabilitiesForNoUmbrella.put(Rain.T, log(0.5)); - - final Map, Double> transitionLogProbabilities = new LinkedHashMap<>(); - transitionLogProbabilities.put(new Transition(Rain.F, Rain.T), log(0.5)); - transitionLogProbabilities.put(new Transition(Rain.F, Rain.F), log(0.5)); - transitionLogProbabilities.put(new Transition(Rain.T, Rain.T), log(0.5)); - transitionLogProbabilities.put(new Transition(Rain.T, Rain.F), log(0.5)); - - final ViterbiAlgorithm viterbi = new ViterbiAlgorithm<>(true); - viterbi.startWithInitialObservation(Umbrella.T, candidates, - emissionLogProbabilitiesForUmbrella); - viterbi.nextStep(Umbrella.T, candidates, emissionLogProbabilitiesForUmbrella, - transitionLogProbabilities); - viterbi.nextStep(Umbrella.F, candidates, emissionLogProbabilitiesForNoUmbrella, - transitionLogProbabilities); - viterbi.nextStep(Umbrella.T, candidates, emissionLogProbabilitiesForUmbrella, - transitionLogProbabilities); - - final List> result = - viterbi.computeMostLikelySequence(); - - // Check most likely sequence - assertEquals(4, result.size()); - assertEquals(Rain.T, result.get(0).state); - assertEquals(Rain.T, result.get(1).state); - assertEquals(Rain.T, result.get(2).state); - assertEquals(Rain.T, result.get(3).state); - } - -} \ No newline at end of file diff --git a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java index 2bd9d7def94..7dc0ef7aac3 100644 --- a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java +++ b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java @@ -17,9 +17,6 @@ */ package com.graphhopper.matching; -import com.bmw.hmm.SequenceState; -import com.bmw.hmm.Transition; -import com.bmw.hmm.ViterbiAlgorithm; import com.carrotsearch.hppc.IntHashSet; import com.graphhopper.GraphHopper; import com.graphhopper.config.Profile; @@ -334,74 +331,71 @@ private List createTimeSteps(List f return timeSteps; } - /** - * Computes the most likely state sequence for the observations. - */ + static class Label { + int timeStep; + State state; + Label back; + boolean isDeleted; + double minusLogProbability; + } + private List> computeViterbiSequence(List timeSteps) { final HmmProbabilities probabilities = new HmmProbabilities(measurementErrorSigma, transitionProbabilityBeta); - final ViterbiAlgorithm viterbi = new ViterbiAlgorithm<>(); - - int timeStepCounter = 0; - ObservationWithCandidateStates prevTimeStep = null; - for (ObservationWithCandidateStates timeStep : timeSteps) { - final Map emissionLogProbabilities = new HashMap<>(); - Map, Double> transitionLogProbabilities = new HashMap<>(); - Map, Path> roadPaths = new HashMap<>(); - for (State candidate : timeStep.candidates) { - // distance from observation to road in meters - final double distance = candidate.getSnap().getQueryDistance(); - emissionLogProbabilities.put(candidate, probabilities.emissionLogProbability(distance)); - } - - if (prevTimeStep == null) { - viterbi.startWithInitialObservation(timeStep.observation, timeStep.candidates, emissionLogProbabilities); - } else { - final double linearDistance = distanceCalc.calcDist(prevTimeStep.observation.getPoint().lat, prevTimeStep.observation.getPoint().lon, - timeStep.observation.getPoint().lat, timeStep.observation.getPoint().lon) - + timeStep.observation.getAccumulatedLinearDistanceToPrevious(); - - for (State from : prevTimeStep.candidates) { - for (State to : timeStep.candidates) { - final Path path = router.createAlgo(queryGraph).calcPath(from.getSnap().getClosestNode(), to.getSnap().getClosestNode(), from.isOnDirectedEdge() ? from.getOutgoingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE, to.isOnDirectedEdge() ? to.getIncomingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE); - if (path.isFound()) { - double transitionLogProbability = probabilities.transitionLogProbability(path.getDistance(), linearDistance); - Transition transition = new Transition<>(from, to); - roadPaths.put(transition, path); - transitionLogProbabilities.put(transition, transitionLogProbability); - } + final Map labels = new HashMap<>(); + Map, Path> roadPaths = new HashMap<>(); + + PriorityQueue

    Click to see older releases * See our [changelog file](./CHANGELOG.md) for Java API Changes. +* 5.x: [documentation](https://github.com/graphhopper/graphhopper/blob/5.x/docs/index.md) + , [web service jar](https://github.com/graphhopper/graphhopper/releases/download/5.3/graphhopper-web-5.3.jar) + , [announcement](https://www.graphhopper.com/blog/2022/03/23/graphhopper-routing-engine-5-0-released/) * 4.x: [documentation](https://github.com/graphhopper/graphhopper/blob/4.x/docs/index.md) , [web service jar](https://github.com/graphhopper/graphhopper/releases/download/4.0/graphhopper-web-4.0.jar) , [announcement](https://www.graphhopper.com/blog/2021/09/29/graphhopper-routing-engine-4-0-released/) @@ -78,7 +81,7 @@ To get started you can try [GraphHopper Maps](README.md#graphhopper-maps), read To install the [GraphHopper Maps](https://graphhopper.com/maps/) UI and the web service locally you [need a JVM](https://adoptium.net) (>= Java 8) and do: ```bash -wget https://github.com/graphhopper/graphhopper/releases/download/5.3/graphhopper-web-5.3.jar https://raw.githubusercontent.com/graphhopper/graphhopper/5.x/config-example.yml http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf +wget https://github.com/graphhopper/graphhopper/releases/download/6.0/graphhopper-web-6.0.jar https://raw.githubusercontent.com/graphhopper/graphhopper/6.x/config-example.yml http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf java -Ddw.graphhopper.datareader.file=berlin-latest.osm.pbf -jar *.jar server config-example.yml ``` From 9d2b7e68cc37e20bc38492cd342dee05ee29fb50 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 13 Sep 2022 10:31:04 +0200 Subject: [PATCH 162/389] use 7.0-SNAPSHOT --- client-hc/pom.xml | 4 ++-- core/pom.xml | 4 ++-- example/pom.xml | 4 ++-- map-matching/pom.xml | 4 ++-- navigation/pom.xml | 4 ++-- pom.xml | 2 +- reader-gtfs/pom.xml | 2 +- tools/pom.xml | 2 +- web-api/pom.xml | 4 ++-- web-bundle/pom.xml | 4 ++-- web/pom.xml | 4 ++-- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/client-hc/pom.xml b/client-hc/pom.xml index 274b00df454..431a04e5bb7 100644 --- a/client-hc/pom.xml +++ b/client-hc/pom.xml @@ -22,14 +22,14 @@ 4.0.0 directions-api-client-hc - 6.0-SNAPSHOT + 7.0-SNAPSHOT jar GraphHopper Directions API hand-crafted Java Client. com.graphhopper graphhopper-parent - 6.0-SNAPSHOT + 7.0-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index 5c8d792bda3..d060a9e3b7b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ graphhopper-core GraphHopper Core - 6.0-SNAPSHOT + 7.0-SNAPSHOT jar GraphHopper is a fast and memory efficient Java road routing engine @@ -14,7 +14,7 @@ com.graphhopper graphhopper-parent - 6.0-SNAPSHOT + 7.0-SNAPSHOT diff --git a/example/pom.xml b/example/pom.xml index fb8788d5c98..bc9b9cbe018 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -5,14 +5,14 @@ 4.0.0 graphhopper-example - 6.0-SNAPSHOT + 7.0-SNAPSHOT jar GraphHopper Example com.graphhopper graphhopper-parent - 6.0-SNAPSHOT + 7.0-SNAPSHOT diff --git a/map-matching/pom.xml b/map-matching/pom.xml index d00caebef4d..2d6bcb0f33c 100644 --- a/map-matching/pom.xml +++ b/map-matching/pom.xml @@ -3,14 +3,14 @@ 4.0.0 com.graphhopper graphhopper-map-matching - 6.0-SNAPSHOT + 7.0-SNAPSHOT jar GraphHopper Map Matching com.graphhopper graphhopper-parent - 6.0-SNAPSHOT + 7.0-SNAPSHOT diff --git a/navigation/pom.xml b/navigation/pom.xml index 95ee214b4ca..a55db2fd6c1 100644 --- a/navigation/pom.xml +++ b/navigation/pom.xml @@ -5,14 +5,14 @@ 4.0.0 graphhopper-nav - 6.0-SNAPSHOT + 7.0-SNAPSHOT jar GraphHopper Navigation com.graphhopper graphhopper-parent - 6.0-SNAPSHOT + 7.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 7ce57c16c82..b99c235a107 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.graphhopper graphhopper-parent GraphHopper Parent Project - 6.0-SNAPSHOT + 7.0-SNAPSHOT pom https://www.graphhopper.com 2012 diff --git a/reader-gtfs/pom.xml b/reader-gtfs/pom.xml index 3e605c859ac..a5ede60be48 100644 --- a/reader-gtfs/pom.xml +++ b/reader-gtfs/pom.xml @@ -10,7 +10,7 @@ com.graphhopper graphhopper-parent - 6.0-SNAPSHOT + 7.0-SNAPSHOT diff --git a/tools/pom.xml b/tools/pom.xml index 2ecbcea38af..a1d103cfba9 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -10,7 +10,7 @@ com.graphhopper graphhopper-parent - 6.0-SNAPSHOT + 7.0-SNAPSHOT package diff --git a/web-api/pom.xml b/web-api/pom.xml index 6e9772ee598..17f8d81aec8 100644 --- a/web-api/pom.xml +++ b/web-api/pom.xml @@ -5,14 +5,14 @@ 4.0.0 graphhopper-web-api jar - 6.0-SNAPSHOT + 7.0-SNAPSHOT GraphHopper Web API JSON Representation of the API classes com.graphhopper graphhopper-parent - 6.0-SNAPSHOT + 7.0-SNAPSHOT diff --git a/web-bundle/pom.xml b/web-bundle/pom.xml index b028a33b985..31cab763042 100644 --- a/web-bundle/pom.xml +++ b/web-bundle/pom.xml @@ -5,14 +5,14 @@ 4.0.0 graphhopper-web-bundle jar - 6.0-SNAPSHOT + 7.0-SNAPSHOT GraphHopper Dropwizard Bundle Use the GraphHopper routing engine as a web-service com.graphhopper graphhopper-parent - 6.0-SNAPSHOT + 7.0-SNAPSHOT diff --git a/web/pom.xml b/web/pom.xml index 23fe722b4e2..62e2c7b2bb8 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -5,14 +5,14 @@ 4.0.0 graphhopper-web jar - 6.0-SNAPSHOT + 7.0-SNAPSHOT GraphHopper Web Use the GraphHopper routing engine as a web-service com.graphhopper graphhopper-parent - 6.0-SNAPSHOT + 7.0-SNAPSHOT package From 1a5c237e99d1d0f674aca1962d0973323c2ffa59 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 14 Sep 2022 15:58:13 +0200 Subject: [PATCH 163/389] use TestUtils in MapMatching tests too --- .../application/resources/MapMatchingResourceTest.java | 9 +++++---- .../resources/MapMatchingResourceTurnCostsTest.java | 8 +++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTest.java index efdec281dc1..5f62a3d8458 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTest.java @@ -38,6 +38,7 @@ import java.io.File; import java.util.Arrays; +import static com.graphhopper.application.util.TestUtils.clientTarget; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -69,7 +70,7 @@ public static void cleanUp() { @Test public void testGPX() { - final Response response = app.client().target("http://localhost:8080/match?profile=fast_car") + final Response response = clientTarget(app, "/match?profile=fast_car") .request() .buildPost(Entity.xml(getClass().getResourceAsStream("/tour2-with-loop.gpx"))) .invoke(); @@ -89,7 +90,7 @@ public void testGPX() { @Test public void testBike() throws ParseException { WKTReader wktReader = new WKTReader(); - final Response response = app.client().target("http://localhost:8080/match?profile=fast_bike") + final Response response = clientTarget(app, "/match?profile=fast_bike") .request() .buildPost(Entity.xml(getClass().getResourceAsStream("another-tour-with-loop.gpx"))) .invoke(); @@ -107,7 +108,7 @@ public void testBike() throws ParseException { @Test public void testGPX10() { - final Response response = app.client().target("http://localhost:8080/match?profile=fast_car") + final Response response = clientTarget(app, "/match?profile=fast_car") .request() .buildPost(Entity.xml(getClass().getResourceAsStream("gpxv1_0.gpx"))) .invoke(); @@ -116,7 +117,7 @@ public void testGPX10() { @Test public void testEmptyGPX() { - final Response response = app.client().target("http://localhost:8080/match?profile=fast_car") + final Response response = clientTarget(app, "/match?profile=fast_car") .request() .buildPost(Entity.xml(getClass().getResourceAsStream("test-only-wpt.gpx"))) .invoke(); diff --git a/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java b/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java index 7f4f786e47e..46bcbdffdd6 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.graphhopper.application.GraphHopperApplication; import com.graphhopper.application.GraphHopperServerConfiguration; +import com.graphhopper.application.util.TestUtils; import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; @@ -42,6 +43,7 @@ import java.util.Arrays; import java.util.Collections; +import static com.graphhopper.application.util.TestUtils.clientTarget; import static org.junit.jupiter.api.Assertions.*; /** @@ -105,7 +107,7 @@ public void disableCHLM() { @Test public void errorOnUnknownProfile() { - final Response response = app.client().target("http://localhost:8080/match?profile=xyz") + final Response response = clientTarget(app, "/match?profile=xyz") .request() .buildPost(Entity.xml(getClass().getResourceAsStream("another-tour-with-loop.gpx"))) .invoke(); @@ -116,7 +118,7 @@ public void errorOnUnknownProfile() { } private void runCar(String urlParams) { - final Response response = app.client().target("http://localhost:8080/match?" + urlParams) + final Response response = clientTarget(app, "/match?" + urlParams) .request() .buildPost(Entity.xml(getClass().getResourceAsStream("another-tour-with-loop.gpx"))) .invoke(); @@ -135,7 +137,7 @@ private void runCar(String urlParams) { } private void runBike(String urlParams) { - final Response response = app.client().target("http://localhost:8080/match?" + urlParams) + final Response response = clientTarget(app, "/match?" + urlParams) .request() .buildPost(Entity.xml(getClass().getResourceAsStream("another-tour-with-loop.gpx"))) .invoke(); From 7adbce5417612417ac1be73d27405b0b5ff6ce80 Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Sat, 17 Sep 2022 14:20:55 -0700 Subject: [PATCH 164/389] MapMatching router interface --- .../com/graphhopper/matching/MapMatching.java | 81 +++++++++++-------- .../ObservationWithCandidateStates.java | 6 +- .../graphhopper/http/GraphHopperBundle.java | 24 ++++++ .../resources/MapMatchingResource.java | 11 ++- 4 files changed, 83 insertions(+), 39 deletions(-) diff --git a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java index 7dc0ef7aac3..291ba89c173 100644 --- a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java +++ b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java @@ -21,7 +21,6 @@ import com.graphhopper.GraphHopper; import com.graphhopper.config.Profile; import com.graphhopper.routing.AStarBidirection; -import com.graphhopper.routing.BidirRoutingAlgorithm; import com.graphhopper.routing.DijkstraBidirectionRef; import com.graphhopper.routing.Path; import com.graphhopper.routing.ev.BooleanEncodedValue; @@ -75,6 +74,11 @@ public class MapMatching { private QueryGraph queryGraph; public static MapMatching fromGraphHopper(GraphHopper graphHopper, PMap hints) { + Router router = routerFromGraphHopper(graphHopper, hints); + return new MapMatching(graphHopper.getBaseGraph(), (LocationIndexTree) graphHopper.getLocationIndex(), router); + } + + public static Router routerFromGraphHopper(GraphHopper graphHopper, PMap hints) { if (hints.has("vehicle")) throw new IllegalArgumentException("MapMatching hints may no longer contain a vehicle, use the profile parameter instead, see core/#1958"); if (hints.has("weighting")) @@ -128,8 +132,38 @@ public EdgeFilter getSnapFilter() { } @Override - public BidirRoutingAlgorithm createAlgo(QueryGraph queryGraph) { - return createRouter(queryGraph, queryGraph.wrapWeighting(weighting), landmarks, maxVisitedNodes); + public List calcPaths(QueryGraph queryGraph, int fromNode, int fromOutEdge, int[] toNodes, int[] toInEdges) { + assert(toNodes.length == toInEdges.length); + List result = new ArrayList<>(); + for (int i = 0; i < toNodes.length; i++) { + result.add(calcOnePath(queryGraph, fromNode, toNodes[i], fromOutEdge, toInEdges[i])); + } + return result; + } + + private Path calcOnePath(QueryGraph queryGraph, int fromNode, int toNode, int fromOutEdge, int toInEdge) { + if (landmarks != null) { + AStarBidirection aStarBidirection = new AStarBidirection(queryGraph, queryGraph.wrapWeighting(weighting), TraversalMode.EDGE_BASED) { + @Override + protected void initCollections(int size) { + super.initCollections(50); + } + }; + int activeLM = Math.min(8, landmarks.getLandmarkCount()); + LMApproximator lmApproximator = LMApproximator.forLandmarks(queryGraph, landmarks, activeLM); + aStarBidirection.setApproximation(lmApproximator); + aStarBidirection.setMaxVisitedNodes(maxVisitedNodes); + return aStarBidirection.calcPath(fromNode, toNode, fromOutEdge, toInEdge); + } else { + DijkstraBidirectionRef dijkstraBidirectionRef = new DijkstraBidirectionRef(queryGraph, queryGraph.wrapWeighting(weighting), TraversalMode.EDGE_BASED) { + @Override + protected void initCollections(int size) { + super.initCollections(50); + } + }; + dijkstraBidirectionRef.setMaxVisitedNodes(maxVisitedNodes); + return dijkstraBidirectionRef.calcPath(fromNode, toNode, fromOutEdge, toInEdge); + } } @Override @@ -137,8 +171,7 @@ public Weighting getWeighting() { return weighting; } }; - - return new MapMatching(graphHopper.getBaseGraph(), (LocationIndexTree) graphHopper.getLocationIndex(), router); + return router; } public MapMatching(BaseGraph graph, LocationIndexTree locationIndex, Router router) { @@ -367,8 +400,14 @@ private List> computeViterbiSequence(Lis final double linearDistance = distanceCalc.calcDist(timeStep.observation.getPoint().lat, timeStep.observation.getPoint().lon, nextTimeStep.observation.getPoint().lat, nextTimeStep.observation.getPoint().lon) + nextTimeStep.observation.getAccumulatedLinearDistanceToPrevious(); - for (State to : nextTimeStep.candidates) { - final Path path = router.createAlgo(queryGraph).calcPath(from.getSnap().getClosestNode(), to.getSnap().getClosestNode(), from.isOnDirectedEdge() ? from.getOutgoingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE, to.isOnDirectedEdge() ? to.getIncomingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE); + int fromNode = from.getSnap().getClosestNode(); + int fromOutEdge = from.isOnDirectedEdge() ? from.getOutgoingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE; + int[] toNodes = nextTimeStep.candidates.stream().mapToInt(c -> c.getSnap().getClosestNode()).toArray(); + int[] toInEdges = nextTimeStep.candidates.stream().mapToInt(to -> to.isOnDirectedEdge() ? to.getIncomingVirtualEdge().getEdge() : EdgeIterator.ANY_EDGE).toArray(); + List paths = router.calcPaths(queryGraph, fromNode, fromOutEdge, toNodes, toInEdges); + for (int i = 0; i < nextTimeStep.candidates.size(); i++) { + State to = nextTimeStep.candidates.get(i); + Path path = paths.get(i); if (path.isFound()) { double transitionLogProbability = probabilities.transitionLogProbability(path.getDistance(), linearDistance); Transition transition = new Transition<>(from, to); @@ -398,32 +437,6 @@ private List> computeViterbiSequence(Lis return result; } - private static BidirRoutingAlgorithm createRouter(QueryGraph queryGraph, Weighting weighting, LandmarkStorage landmarks, int maxVisitedNodes) { - BidirRoutingAlgorithm router; - if (landmarks != null) { - AStarBidirection algo = new AStarBidirection(queryGraph, weighting, TraversalMode.EDGE_BASED) { - @Override - protected void initCollections(int size) { - super.initCollections(50); - } - }; - int activeLM = Math.min(8, landmarks.getLandmarkCount()); - LMApproximator lmApproximator = LMApproximator.forLandmarks(queryGraph, landmarks, activeLM); - algo.setApproximation(lmApproximator); - algo.setMaxVisitedNodes(maxVisitedNodes); - router = algo; - } else { - router = new DijkstraBidirectionRef(queryGraph, weighting, TraversalMode.EDGE_BASED) { - @Override - protected void initCollections(int size) { - super.initCollections(50); - } - }; - router.setMaxVisitedNodes(maxVisitedNodes); - } - return router; - } - private List prepareEdgeMatches(List> seq) { // This creates a list of directed edges (EdgeIteratorState instances turned the right way), // each associated with 0 or more of the observations. @@ -532,7 +545,7 @@ private static class MapMatchedPath extends Path { public interface Router { EdgeFilter getSnapFilter(); - BidirRoutingAlgorithm createAlgo(QueryGraph graph); + List calcPaths(QueryGraph queryGraph, int fromNode, int fromOutEdge, int[] toNodes, int[] toInEdges); Weighting getWeighting(); } diff --git a/map-matching/src/main/java/com/graphhopper/matching/ObservationWithCandidateStates.java b/map-matching/src/main/java/com/graphhopper/matching/ObservationWithCandidateStates.java index d85143fbbf3..892d2242696 100644 --- a/map-matching/src/main/java/com/graphhopper/matching/ObservationWithCandidateStates.java +++ b/map-matching/src/main/java/com/graphhopper/matching/ObservationWithCandidateStates.java @@ -16,7 +16,7 @@ */ package com.graphhopper.matching; -import java.util.Collection; +import java.util.List; public class ObservationWithCandidateStates { @@ -28,9 +28,9 @@ public class ObservationWithCandidateStates { /** * State candidates at this time step. */ - public final Collection candidates; + public final List candidates; - public ObservationWithCandidateStates(Observation observation, Collection candidates) { + public ObservationWithCandidateStates(Observation observation, List candidates) { if (observation == null || candidates == null) { throw new NullPointerException("observation and candidates must not be null."); } diff --git a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java index 6d748315d8a..89b9e4446b4 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java +++ b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperBundle.java @@ -28,10 +28,12 @@ import com.graphhopper.isochrone.algorithm.JTSTriangulator; import com.graphhopper.isochrone.algorithm.Triangulator; import com.graphhopper.jackson.Jackson; +import com.graphhopper.matching.MapMatching; import com.graphhopper.resources.*; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.index.LocationIndex; +import com.graphhopper.util.PMap; import com.graphhopper.util.TranslationMap; import com.graphhopper.util.details.PathDetailsBuilderFactory; import io.dropwizard.ConfiguredBundle; @@ -178,6 +180,27 @@ public void dispose(PathDetailsBuilderFactory profileResolver) { } } + static class MapMatchingRouterFactoryFactory implements Factory { + + @Inject + GraphHopper graphHopper; + + @Override + public MapMatchingResource.MapMatchingRouterFactory provide() { + return new MapMatchingResource.MapMatchingRouterFactory() { + @Override + public MapMatching.Router createMapMatchingRouter(PMap hints) { + return MapMatching.routerFromGraphHopper(graphHopper, hints); + } + }; + } + + @Override + public void dispose(MapMatchingResource.MapMatchingRouterFactory mapMatchingRouterFactory) { + + } + } + static class HasElevation implements Factory { @Inject @@ -253,6 +276,7 @@ protected void configure() { bind(graphHopper).to(GraphHopper.class); bind(new JTSTriangulator(graphHopper.getRouterConfig())).to(Triangulator.class); + bindFactory(MapMatchingRouterFactoryFactory.class).to(MapMatchingResource.MapMatchingRouterFactory.class); bindFactory(PathDetailsBuilderFactoryFactory.class).to(PathDetailsBuilderFactory.class); bindFactory(LegacyProfileResolverFactory.class).to(LegacyProfileResolver.class); bindFactory(ProfileResolverFactory.class).to(ProfileResolver.class); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java index ed01763b729..06a7711bee5 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java @@ -29,6 +29,7 @@ import com.graphhopper.jackson.Gpx; import com.graphhopper.jackson.ResponsePathSerializer; import com.graphhopper.matching.*; +import com.graphhopper.storage.index.LocationIndexTree; import com.graphhopper.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,17 +55,23 @@ @javax.ws.rs.Path("match") public class MapMatchingResource { + public interface MapMatchingRouterFactory { + public MapMatching.Router createMapMatchingRouter(PMap hints); + } + private static final Logger logger = LoggerFactory.getLogger(MapMatchingResource.class); private final GraphHopper graphHopper; private final ProfileResolver profileResolver; private final TranslationMap trMap; + private final MapMatchingRouterFactory mapMatchingRouterFactory; @Inject - public MapMatchingResource(GraphHopper graphHopper, ProfileResolver profileResolver, TranslationMap trMap) { + public MapMatchingResource(GraphHopper graphHopper, ProfileResolver profileResolver, TranslationMap trMap, MapMatchingRouterFactory mapMatchingRouterFactory) { this.graphHopper = graphHopper; this.profileResolver = profileResolver; this.trMap = trMap; + this.mapMatchingRouterFactory = mapMatchingRouterFactory; } @POST @@ -117,7 +124,7 @@ public Response match( hints.putObject("profile", profile); removeLegacyParameters(hints); - MapMatching matching = MapMatching.fromGraphHopper(graphHopper, hints); + MapMatching matching = new MapMatching(graphHopper.getBaseGraph(), (LocationIndexTree) graphHopper.getLocationIndex(), mapMatchingRouterFactory.createMapMatchingRouter(hints)); matching.setMeasurementErrorSigma(gpsAccuracy); List measurements = GpxConversions.getEntries(gpx.trk.get(0)); From cbb83501bae3659faf82ef6ca5d4065b8bf3d5a4 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 19 Sep 2022 13:37:22 +0200 Subject: [PATCH 165/389] announcement --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 68e4e802e09..ebf3349cabc 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ To get started you can try [GraphHopper Maps](README.md#graphhopper-maps), read * 6.x: [documentation](https://github.com/graphhopper/graphhopper/blob/6.x/docs/index.md) , [web service jar](https://github.com/graphhopper/graphhopper/releases/download/6.0/graphhopper-web-6.0.jar) - , [announcement](https://www.graphhopper.com/blog/2022/09/20/graphhopper-routing-engine-6-0-released/) + , [announcement](https://www.graphhopper.com/blog/2022/09/19/graphhopper-routing-engine-6-0-released/) * unstable master: [documentation](https://github.com/graphhopper/graphhopper/blob/master/docs/index.md)
    Click to see older releases From 046ff5881878932bd14f404434758f4d48b9364b Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Wed, 21 Sep 2022 13:44:25 -0700 Subject: [PATCH 166/389] fall back to best available algorithm instead of demanding a "hint" --- .../main/java/com/graphhopper/matching/MapMatching.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java index 291ba89c173..36aeb67785c 100644 --- a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java +++ b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java @@ -109,14 +109,9 @@ public static Router routerFromGraphHopper(GraphHopper graphHopper, PMap hints) boolean useDijkstra = disableLM || disableCH; LandmarkStorage landmarks; - if (graphHopper.getLMPreparationHandler().isEnabled() && !useDijkstra) { + if (!useDijkstra && graphHopper.getLandmarks().get(profile.getName()) != null) { // using LM because u-turn prevention does not work properly with (node-based) CH landmarks = graphHopper.getLandmarks().get(profile.getName()); - if (landmarks == null) { - throw new IllegalArgumentException("Cannot find LM preparation for the requested profile: '" + profile.getName() + "'" + - "\nYou can try disabling LM using " + Parameters.Landmark.DISABLE + "=true" + - "\navailable LM profiles: " + graphHopper.getLandmarks().keySet()); - } } else { landmarks = null; } From fb8d1df3cb3cb7a0709dd77ef5d283d0abf1a9f1 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 20 Sep 2022 17:07:47 +0200 Subject: [PATCH 167/389] Add edge details to /mvt --- .../java/com/graphhopper/storage/BaseGraph.java | 3 +-- .../com/graphhopper/resources/MVTResource.java | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index 77af892a16c..491a8513d3f 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -974,8 +974,7 @@ public Object getValue(String key) { @Override public String getName() { - long kvEntryRef = Helper.toUnsignedLong(store.getKeyValuesRef(edgePointer)); - String name = (String) baseGraph.edgeKVStorage.get(kvEntryRef, "name", reverse); + String name = (String) getValue("name"); // preserve backward compatibility (returns empty string if name tag missing) return name == null ? "" : name; } diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java index 16908e14db4..729c7147b56 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java @@ -29,11 +29,13 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import static com.graphhopper.util.Parameters.Details.*; + @Path("mvt") public class MVTResource { @@ -123,8 +125,15 @@ public Response doGetXyz( } edgeCounter.incrementAndGet(); - Map map = new HashMap<>(2); - map.put("name", edge.getName()); + Map map = new LinkedHashMap<>(); + map.put("name", edge.getValue(STREET_NAME)); + map.put("ref", edge.getValue(STREET_REF)); + map.put("destination", edge.getValue(STREET_DESTINATION)); + map.put("edge_id", edge.getEdge()); + map.put("edge_key", edge.getEdgeKey()); + map.put("base_node", edge.getBaseNode()); + map.put("adj_node", edge.getAdjNode()); + map.put("distance", edge.getDistance()); for (String str : pathDetails) { // how to indicate an erroneous parameter? if (str.contains(",") || !encodingManager.hasEncodedValue(str)) From 6131eb8d9b8ebed9bd444d263a518267c9d3ddf1 Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 22 Sep 2022 09:43:17 +0200 Subject: [PATCH 168/389] Fix /mvt test --- .../java/com/graphhopper/resources/MVTResource.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java index 729c7147b56..bd4ffd6adbd 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java @@ -32,9 +32,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; - -import static com.graphhopper.util.Parameters.Details.*; +import java.util.stream.Stream; @Path("mvt") public class MVTResource { @@ -126,9 +126,9 @@ public Response doGetXyz( edgeCounter.incrementAndGet(); Map map = new LinkedHashMap<>(); - map.put("name", edge.getValue(STREET_NAME)); - map.put("ref", edge.getValue(STREET_REF)); - map.put("destination", edge.getValue(STREET_DESTINATION)); + Stream.of("name", "ref", "destination", "destination_ref").forEach( + key -> map.put(key, Optional.ofNullable(edge.getValue(key)).orElse("")) + ); map.put("edge_id", edge.getEdge()); map.put("edge_key", edge.getEdgeKey()); map.put("base_node", edge.getBaseNode()); From 87d80386dd0de45316246148111917e06fc1a8d8 Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 22 Sep 2022 10:40:08 +0200 Subject: [PATCH 169/389] All all EVs to /mvt unconditionally, remove details parameter --- .../graphhopper/resources/MVTResource.java | 27 +++++++------------ .../com/graphhopper/maps/isochrone/index.js | 2 +- .../graphhopper/maps/js/config/tileLayers.js | 10 +++---- .../resources/MvtResourceTest.java | 17 ++++++------ 4 files changed, 24 insertions(+), 32 deletions(-) diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java index bd4ffd6adbd..852f26b3092 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java @@ -5,7 +5,10 @@ import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.NodeAccess; import com.graphhopper.storage.index.LocationIndexTree; -import com.graphhopper.util.*; +import com.graphhopper.util.EdgeIteratorState; +import com.graphhopper.util.FetchMode; +import com.graphhopper.util.PointList; +import com.graphhopper.util.StopWatch; import com.graphhopper.util.shapes.BBox; import com.wdtinc.mapbox_vector_tile.VectorTile; import com.wdtinc.mapbox_vector_tile.adapt.jts.IGeometryFilter; @@ -59,7 +62,7 @@ public Response doGetXyz( @PathParam("z") int zInfo, @PathParam("x") int xInfo, @PathParam("y") int yInfo, - @QueryParam(Parameters.Details.PATH_DETAILS) List pathDetails) { + @QueryParam("render_all") @DefaultValue("false") Boolean renderAll) { if (zInfo <= 9) { VectorTile.Tile.Builder mvtBuilder = VectorTile.Tile.newBuilder(); @@ -96,14 +99,9 @@ public Response doGetXyz( locationIndex.query(bbox, edgeId -> { EdgeIteratorState edge = graphHopper.getBaseGraph().getEdgeIteratorStateForKey(edgeId * 2); LineString lineString; - if (pathDetails.contains(UrbanDensity.KEY)) { - if (zInfo >= 9) { - PointList pl = edge.fetchWayGeometry(FetchMode.ALL); - lineString = pl.toLineString(false); - } else { - // skip edge for certain zoom - return; - } + if (renderAll) { + PointList pl = edge.fetchWayGeometry(FetchMode.ALL); + lineString = pl.toLineString(false); } else { RoadClass rc = edge.get(roadClassEnc); if (zInfo >= 14) { @@ -134,12 +132,7 @@ public Response doGetXyz( map.put("base_node", edge.getBaseNode()); map.put("adj_node", edge.getAdjNode()); map.put("distance", edge.getDistance()); - for (String str : pathDetails) { - // how to indicate an erroneous parameter? - if (str.contains(",") || !encodingManager.hasEncodedValue(str)) - continue; - - EncodedValue ev = encodingManager.getEncodedValue(str, EncodedValue.class); + encodingManager.getEncodedValues().forEach(ev -> { if (ev instanceof EnumEncodedValue) map.put(ev.getName(), edge.get((EnumEncodedValue) ev).toString()); else if (ev instanceof DecimalEncodedValue) @@ -148,7 +141,7 @@ else if (ev instanceof BooleanEncodedValue) map.put(ev.getName(), edge.get((BooleanEncodedValue) ev)); else if (ev instanceof IntEncodedValue) map.put(ev.getName(), edge.get((IntEncodedValue) ev)); - } + }); lineString.setUserData(map); diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.js b/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.js index 307bbc5706c..d68ae56ebf2 100644 --- a/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.js +++ b/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.js @@ -105,7 +105,7 @@ function _drawMap(bbox) { // add GraphHopper vector tiles of road network. this is also called when we change the style map.addSource('gh-mvt', { type: 'vector', - tiles: ['http://' + window.location.host + '/mvt/{z}/{x}/{y}.mvt?details=road_class'] + tiles: ['http://' + window.location.host + '/mvt/{z}/{x}/{y}.mvt'] }); var boundsPolygon = [[bbox[0], bbox[1]], [bbox[2], bbox[1]], [bbox[2], bbox[3]], [bbox[0], bbox[3]], [bbox[0], bbox[1]]]; map.addLayer({ diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js index d637a4d62bc..ba2e2dd898c 100644 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js +++ b/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js @@ -99,7 +99,7 @@ module.exports.enableVectorTiles = function () { availableTileLayers["Omniscale Dev"] = omniscaleGray; require('leaflet.vectorgrid'); - var vtLayer = L.vectorGrid.protobuf("/mvt/{z}/{x}/{y}.mvt?details=max_speed&details=road_class&details=road_environment", { + var vtLayer = L.vectorGrid.protobuf("/mvt/{z}/{x}/{y}.mvt", { rendererFactory: L.canvas.tile, maxZoom: 20, minZoom: 10, @@ -109,13 +109,13 @@ module.exports.enableVectorTiles = function () { // weight == line width var color, opacity = 1, weight = 1, rc = properties.road_class; // if(properties.speed < 30) console.log(properties) - if (rc == "motorway") { + if (rc === "motorway") { color = '#dd504b'; // red weight = 3; - } else if (rc == "primary" || rc == "trunk") { + } else if (rc === "primary" || rc === "trunk") { color = '#e2a012'; // orange weight = 2; - } else if (rc == "secondary") { + } else if (rc === "secondary") { weight = 2; color = '#f7c913'; // yellow } else { @@ -136,7 +136,7 @@ module.exports.enableVectorTiles = function () { }, }, }) - var urbanDensityLayer = L.vectorGrid.protobuf("/mvt/{z}/{x}/{y}.mvt?details=max_speed&details=road_class&details=road_environment&details=urban_density", { + var urbanDensityLayer = L.vectorGrid.protobuf("/mvt/{z}/{x}/{y}.mvt?render_all=true", { rendererFactory: L.canvas.tile, maxZoom: 20, minZoom: 10, diff --git a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java index f4df3193516..cecd04201b9 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java @@ -85,13 +85,12 @@ public void testBasicMvtQuery() throws IOException { JtsLayer layer = layerValues.values().iterator().next(); MultiLineString multiLineString = (MultiLineString) layer.getGeometries().iterator().next(); assertEquals(42, multiLineString.getCoordinates().length); - Map map = attributes(multiLineString); - assertEquals("Camì de les Pardines", map.get("name")); + assertEquals("Camì de les Pardines", getUserData(multiLineString).get("name")); } @Test - public void testWithDetailsInResponse() throws IOException { - final Response response = clientTarget(app, "/mvt/15/16522/12102.mvt?details=max_speed&details=road_class&details=road_environment").request().buildGet().invoke(); + public void testDetailsInResponse() throws IOException { + final Response response = clientTarget(app, "/mvt/15/16522/12102.mvt").request().buildGet().invoke(); assertEquals(200, response.getStatus()); InputStream is = response.readEntity(InputStream.class); JtsMvt result = MvtReader.loadMvt(is, new GeometryFactory(), new TagKeyValueMapConverter()); @@ -100,14 +99,14 @@ public void testWithDetailsInResponse() throws IOException { assertEquals(21, layer.getGeometries().size()); Geometry geometry = layer.getGeometries().stream(). - filter(g -> attributes(g).get("name").equals("Avinguda de Tarragona")) + filter(g -> getUserData(g).get("name").equals("Avinguda de Tarragona")) .findFirst().get(); - assertEquals("road", attributes(geometry).get("road_environment")); - assertEquals(50.0, attributes(geometry).get("max_speed")); - assertEquals("primary", attributes(geometry).get("road_class")); + assertEquals("road", getUserData(geometry).get("road_environment")); + assertEquals(50.0, getUserData(geometry).get("max_speed")); + assertEquals("primary", getUserData(geometry).get("road_class")); } - private Map attributes(Geometry g) { + private Map getUserData(Geometry g) { return (Map) g.getUserData(); } } From a3d6ca1c0ada941a86a0feace39f793a9120419c Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 22 Sep 2022 15:05:58 +0200 Subject: [PATCH 170/389] No longer mention FlagEncoder in profiles.md --- docs/core/profiles.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/core/profiles.md b/docs/core/profiles.md index 0e72e276a35..c25ba199b17 100644 --- a/docs/core/profiles.md +++ b/docs/core/profiles.md @@ -41,8 +41,6 @@ The vehicle field must correspond to one of GraphHopper's built-in vehicle types - motorcycle By choosing a vehicle GraphHopper determines the accessibility and a default travel speed for the different road types. -If you are interested in the low-level Java API note that the vehicles correspond to implementations of the -`FlagEncoder` interface. The weighting determines the 'cost function' for the route calculation and must match one of the following built-in weightings: From 65b70f97186c31f3e8a2d39d9a1ad9ee120f5bd9 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 22 Sep 2022 22:35:49 +0200 Subject: [PATCH 171/389] read from GeoJSON export of boundaries.osm (#2658) * read from GeoJSON file export of boundaries.osm (josm project) * minor renaming * manually tweaked countries.json to fix the problem for the US (only) * Revert "manually tweaked countries.json to fix the problem for the US (only)" This reverts commit 5022e2b2c3455990e1ad50f85f06945d349ce40a. * create a converter that corrects these MultiPolygons * minor fix due to alpha2 vs alpha3 * no need for ConcurrentHashMap * use boundaries.json from generator github.com/westnordost/countryboundaries/ (including PR 10 and 11) * make clear that we use 2 chars only * some changes are no longer necessary for the newly generated file * minor * Use Country enum instead of relying on 'name:en' in countries.geojson -> use master of westnordost/countryboundaries * avoid name mixing and only use alpha3 to get country border * fix to alpha3 * use getCountryName --- .../java/com/graphhopper/GraphHopper.java | 4 +- .../com/graphhopper/reader/osm/OSMReader.java | 8 +- .../com/graphhopper/routing/ev/Country.java | 24 +- .../graphhopper/routing/util/AreaIndex.java | 1 + .../graphhopper/routing/util/CustomArea.java | 6 +- .../java/com/graphhopper/util/GHUtility.java | 25 +- .../com/graphhopper/util/shapes/Polygon.java | 4 +- .../graphhopper/countries/countries.geojson | 219 +----------------- .../{spatialrules => }/AreaIndexTest.java | 19 +- 9 files changed, 55 insertions(+), 255 deletions(-) rename core/src/test/java/com/graphhopper/routing/util/{spatialrules => }/AreaIndexTest.java (92%) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 3a5b445b237..3a9f8d862d6 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -846,8 +846,10 @@ protected void importOSM() { logger.info("Creating custom area index, reading custom areas from: '" + customAreasDirectory + "'"); customAreas.addAll(readCustomAreas()); } + CustomArea area = GHUtility.getFirstDuplicateArea(customAreas, Country.ISO_ALPHA3); + if (area != null) + throw new IllegalArgumentException("area used duplicate '" + Country.ISO_ALPHA3 + "' see properties: " + area.getProperties()); AreaIndex areaIndex = new AreaIndex<>(customAreas); - if (countryRuleFactory == null || countryRuleFactory.getCountryToRuleMap().isEmpty()) { logger.info("No country rules available"); } else { diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 700e66a228d..5e33ec84e04 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -252,12 +252,12 @@ protected void setArtificialWayTags(PointList pointList, ReaderWay way, double d // special handling for countries: since they are built-in with GraphHopper they are always fed to the EncodingManager Country country = Country.MISSING; for (CustomArea customArea : customAreas) { - Object countryCode = customArea.getProperties().get("ISO3166-1:alpha3"); - if (countryCode == null) + Object alpha3 = customArea.getProperties().get(Country.ISO_ALPHA3); + if (alpha3 == null) continue; if (country != Country.MISSING) - LOGGER.warn("Multiple countries found for way {}: {}, {}", way.getId(), country, countryCode); - country = Country.valueOf(countryCode.toString()); + LOGGER.warn("Multiple countries found for way {}: {}, {}", way.getId(), country, alpha3); + country = Country.valueOf((String) alpha3); } way.setTag("country", country); diff --git a/core/src/main/java/com/graphhopper/routing/ev/Country.java b/core/src/main/java/com/graphhopper/routing/ev/Country.java index 0569995f858..c618412cba9 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/Country.java +++ b/core/src/main/java/com/graphhopper/routing/ev/Country.java @@ -21,7 +21,7 @@ * The enum constants correspond to the the ISO3166-1:alpha3 code of the corresponding country */ public enum Country { - // values were taken from `countries.geojson`: + // ISO3166-1:alpha3(name:en, ISO3166-1:alpha2) MISSING("missing", "--"), AFG("Afghanistan", "AF"), @@ -242,28 +242,28 @@ public enum Country { ZMB("Zambia", "ZM"), ZWE("Zimbabwe", "ZW"); - public static final String KEY = "country"; + public static final String KEY = "country", ISO_ALPHA3 = "ISO3166-1:alpha3"; - private final String name; - private final String twoLetterCode; + private final String countryName; + private final String alpha2; - Country(String name, String twoLetterCode) { - this.name = name; - this.twoLetterCode = twoLetterCode; + Country(String countryName, String alpha2) { + this.countryName = countryName; + this.alpha2 = alpha2; } /** - * @return the name:en field of this country + * @return the name of this country. Avoids clash with name() method of this enum. */ - public String getName() { - return name; + public String getCountryName() { + return countryName; } /** * @return the ISO3166-1:alpha2 code of this country */ - public String getTwoLetterCode() { - return twoLetterCode; + public String getAlpha2() { + return alpha2; } public static EnumEncodedValue create() { diff --git a/core/src/main/java/com/graphhopper/routing/util/AreaIndex.java b/core/src/main/java/com/graphhopper/routing/util/AreaIndex.java index 4e42c2dae4b..5fb5f6bcb85 100644 --- a/core/src/main/java/com/graphhopper/routing/util/AreaIndex.java +++ b/core/src/main/java/com/graphhopper/routing/util/AreaIndex.java @@ -21,6 +21,7 @@ import org.locationtech.jts.geom.*; import org.locationtech.jts.geom.prep.PreparedGeometry; import org.locationtech.jts.geom.prep.PreparedGeometryFactory; +import org.locationtech.jts.geom.prep.PreparedPolygon; import org.locationtech.jts.index.strtree.STRtree; import java.util.List; diff --git a/core/src/main/java/com/graphhopper/routing/util/CustomArea.java b/core/src/main/java/com/graphhopper/routing/util/CustomArea.java index dd26a62b8e0..fe1b3fea49b 100644 --- a/core/src/main/java/com/graphhopper/routing/util/CustomArea.java +++ b/core/src/main/java/com/graphhopper/routing/util/CustomArea.java @@ -18,9 +18,7 @@ package com.graphhopper.routing.util; import com.graphhopper.util.JsonFeature; -import org.locationtech.jts.geom.Geometry; -import org.locationtech.jts.geom.Polygon; -import org.locationtech.jts.geom.util.PolygonExtracter; +import org.locationtech.jts.geom.*; import java.util.ArrayList; import java.util.List; @@ -35,7 +33,7 @@ public static CustomArea fromJsonFeature(JsonFeature j) { for (int i = 0; i < j.getGeometry().getNumGeometries(); i++) { Geometry geometry = j.getGeometry().getGeometryN(i); if (geometry instanceof Polygon) { - PolygonExtracter.getPolygons(geometry, borders); + borders.add((Polygon) geometry); } else { throw new IllegalArgumentException("Custom area features must be of type 'Polygon', but was: " + geometry.getClass().getSimpleName()); } diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java index cc5a6a10db6..1dddec45037 100644 --- a/core/src/main/java/com/graphhopper/util/GHUtility.java +++ b/core/src/main/java/com/graphhopper/util/GHUtility.java @@ -691,16 +691,39 @@ public static long calcMillisWithTurnMillis(Weighting weighting, EdgeIteratorSta public static List readCountries() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new JtsModule()); + + Map map = new HashMap<>(Country.values().length); + for (Country c : Country.values()) map.put(c.getAlpha2(), c); + try (Reader reader = new InputStreamReader(GHUtility.class.getResourceAsStream("/com/graphhopper/countries/countries.geojson"), StandardCharsets.UTF_8)) { JsonFeatureCollection jsonFeatureCollection = objectMapper.readValue(reader, JsonFeatureCollection.class); return jsonFeatureCollection.getFeatures().stream() - .map(CustomArea::fromJsonFeature) + // exclude areas not in the list of Country enums like FX => Metropolitan France + .filter(customArea -> map.get((String) customArea.getProperties().get("id")) != null) + .map((f) -> { + CustomArea ca = CustomArea.fromJsonFeature(f); + Country country = map.get((String) f.getProperties().get("id")); + ca.getProperties().put(Country.ISO_ALPHA3, country.name()); + return ca; + }) .collect(Collectors.toList()); } catch (IOException e) { throw new UncheckedIOException(e); } } + public static CustomArea getFirstDuplicateArea(List areas, String id) { + Set result = new HashSet<>(areas.size()); + for (CustomArea area : areas) { + String countryCode = (String) area.getProperties().get(id); + // in our country file there are not only countries but "subareas" (with ISO3166-2) or other unnamed areas + // like Metropolitan Netherlands + if (countryCode != null && !result.add(countryCode)) + return area; + } + return null; + } + public static void runConcurrently(Stream> callables, int threads) { ExecutorService executorService = Executors.newFixedThreadPool(threads); ExecutorCompletionService completionService = new ExecutorCompletionService<>(executorService); diff --git a/core/src/main/java/com/graphhopper/util/shapes/Polygon.java b/core/src/main/java/com/graphhopper/util/shapes/Polygon.java index 7aa9a744745..5477a7bd8d1 100644 --- a/core/src/main/java/com/graphhopper/util/shapes/Polygon.java +++ b/core/src/main/java/com/graphhopper/util/shapes/Polygon.java @@ -35,7 +35,7 @@ */ public class Polygon implements Shape { - private final GeometryFactory factory = new GeometryFactory(); + private static final GeometryFactory factory = new GeometryFactory(); public final PreparedGeometry prepPolygon; public final boolean rectangle; public final Envelope envelope; @@ -102,7 +102,7 @@ public double getMaxLat() { public double getMaxLon() { return envelope.getMaxX(); } - + public boolean isRectangle() { return rectangle; } diff --git a/core/src/main/resources/com/graphhopper/countries/countries.geojson b/core/src/main/resources/com/graphhopper/countries/countries.geojson index 99dea8455aa..bd2cc5fbfba 100644 --- a/core/src/main/resources/com/graphhopper/countries/countries.geojson +++ b/core/src/main/resources/com/graphhopper/countries/countries.geojson @@ -1,218 +1 @@ -{"type":"FeatureCollection", "features": [ -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-179.3865,-23.786],[-179.3735,-23.879],[-179.341,-23.948],[-179.292,-24.008],[-179.2285,-24.0555],[-179.154,-24.0875],[-179.074,-24.1025],[-178.992,-24.0995],[-178.913,-24.0785],[-178.842,-24.0415],[-178.7825,-23.9895],[-178.739,-23.926],[-178.713,-23.855],[-178.706,-23.78],[-178.7195,-23.706],[-178.7515,-23.6365],[-178.8005,-23.5765],[-178.8645,-23.529],[-178.958,-23.4915],[-179.06,-23.481],[-179.141,-23.493],[-179.234,-23.5325],[-179.2965,-23.581],[-179.3445,-23.642],[-179.375,-23.7115],[-179.3865,-23.786]]],[[[-176.434,-22.3355],[-176.4045,-22.4355],[-176.3605,-22.49],[-176.3025,-22.5285],[-176.235,-22.5475],[-176.1675,-22.546],[-176.0975,-22.523],[-176.0205,-22.4565],[-175.9865,-22.3815],[-175.9925,-22.2765],[-176.033,-22.209],[-176.1075,-22.1535],[-176.1805,-22.1335],[-176.2565,-22.1365],[-176.3265,-22.1605],[-176.4055,-22.2345],[-176.434,-22.3355]]],[[[-175.8855,-15.6275],[-175.87,-15.6885],[-175.8125,-15.7685],[-175.7545,-15.8125],[-175.6695,-15.839],[-175.616,-15.84],[-175.521,-15.8105],[-175.431,-15.7265],[-175.395,-15.621],[-175.3965,-15.5575],[-175.4205,-15.4885],[-175.4795,-15.4205],[-175.5785,-15.3715],[-175.6595,-15.367],[-175.769,-15.4045],[-175.822,-15.4455],[-175.8725,-15.529],[-175.8855,-15.6275]]],[[[-175.621,-20.5565],[-175.588,-20.6615],[-175.541,-20.7115],[-175.486,-20.744],[-175.4145,-20.7675],[-175.293,-20.7535],[-175.2305,-20.715],[-175.182,-20.6525],[-175.1625,-20.5805],[-175.163,-20.5155],[-175.187,-20.443],[-175.238,-20.3845],[-175.3565,-20.3345],[-175.4295,-20.337],[-175.511,-20.367],[-175.555,-20.3995],[-175.6,-20.461],[-175.621,-20.5565]]],[[[-175.5705,-21.0995],[-175.5515,-21.192],[-175.5225,-21.2585],[-175.47,-21.3135],[-175.2755,-21.4325],[-175.1715,-21.47],[-175.1395,-21.5765],[-175.091,-21.629],[-175.026,-21.663],[-174.9525,-21.674],[-174.8985,-21.6675],[-174.805,-21.6345],[-174.751,-21.596],[-174.6975,-21.5135],[-174.6855,-21.443],[-174.6945,-21.308],[-174.708,-21.228],[-174.763,-21.1415],[-174.763,-21.087],[-174.8015,-20.957],[-174.8345,-20.899],[-174.889,-20.852],[-174.9595,-20.8245],[-175.037,-20.8225],[-175.0925,-20.8385],[-175.227,-20.813],[-175.303,-20.827],[-175.413,-20.8725],[-175.479,-20.92],[-175.532,-20.9775],[-175.5625,-21.0395],[-175.5705,-21.0995]]],[[[-175.3185,-19.7385],[-175.3005,-19.8385],[-175.272,-19.883],[-175.2015,-19.949],[-175.0945,-19.987],[-175.01,-19.9845],[-174.9935,-20.041],[-174.9955,-20.153],[-175.0305,-20.2715],[-175.0165,-20.34],[-174.981,-20.401],[-174.9995,-20.484],[-174.9855,-20.5525],[-174.9475,-20.6125],[-174.8905,-20.6565],[-174.778,-20.7025],[-174.7015,-20.704],[-174.6305,-20.682],[-174.572,-20.638],[-174.545,-20.6],[-174.4885,-20.596],[-174.4085,-20.5635],[-174.3535,-20.514],[-174.3135,-20.421],[-174.306,-20.35],[-174.317,-20.252],[-174.348,-20.195],[-174.301,-20.16],[-174.261,-20.1015],[-174.246,-20.049],[-174.152,-19.93],[-174.097,-19.848],[-174.054,-19.714],[-174.0625,-19.628],[-174.0895,-19.569],[-174.144,-19.5015],[-174.2095,-19.461],[-174.3075,-19.4465],[-174.34,-19.4225],[-174.4435,-19.3915],[-174.516,-19.4005],[-174.588,-19.437],[-174.6675,-19.5215],[-174.6925,-19.5715],[-174.8065,-19.5835],[-174.874,-19.4935],[-174.94,-19.458],[-175.0325,-19.446],[-175.108,-19.4645],[-175.1725,-19.508],[-175.2475,-19.576],[-175.2965,-19.652],[-175.3185,-19.7385]]],[[[-174.881,-18.8085],[-174.865,-18.8795],[-174.8315,-18.9355],[-174.782,-18.984],[-174.6935,-19.0225],[-174.627,-19.027],[-174.5465,-19.0075],[-174.4835,-18.966],[-174.4185,-18.862],[-174.409,-18.7915],[-174.4225,-18.73],[-174.4595,-18.67],[-174.556,-18.6005],[-174.636,-18.5815],[-174.7475,-18.602],[-174.836,-18.672],[-174.8695,-18.736],[-174.881,-18.8085]]],[[[-174.5375,-18.028],[-174.5085,-18.1305],[-174.4285,-18.2055],[-174.3835,-18.224],[-174.3315,-18.3065],[-174.269,-18.348],[-174.192,-18.3655],[-174.114,-18.356],[-174.0505,-18.325],[-174.0035,-18.279],[-173.9675,-18.19],[-173.9695,-18.122],[-173.9975,-18.0535],[-174.047,-18.0005],[-174.102,-17.972],[-174.119,-17.927],[-174.1645,-17.869],[-174.219,-17.832],[-174.2835,-17.813],[-174.372,-17.818],[-174.442,-17.849],[-174.5015,-17.9075],[-174.527,-17.961],[-174.5375,-18.028]]],[[[-174.382,-18.8075],[-174.343,-18.907],[-174.2885,-18.957],[-174.0295,-19.057],[-173.964,-19.0575],[-173.894,-19.035],[-173.8365,-18.9915],[-173.7875,-18.9185],[-173.722,-18.761],[-173.71,-18.648],[-173.725,-18.5635],[-173.7825,-18.454],[-173.8665,-18.388],[-173.9355,-18.3705],[-174.007,-18.376],[-174.1065,-18.433],[-174.1765,-18.458],[-174.271,-18.532],[-174.325,-18.599],[-174.375,-18.7365],[-174.382,-18.8075]]],[[[-174.016,-15.9565],[-174.0015,-16.026],[-173.944,-16.1155],[-173.8555,-16.1705],[-173.7925,-16.183],[-173.726,-16.1755],[-173.6665,-16.1495],[-173.582,-16.067],[-173.549,-16.003],[-173.5295,-15.8555],[-173.5355,-15.804],[-173.5765,-15.724],[-173.63,-15.675],[-173.711,-15.6415],[-173.7775,-15.6395],[-173.843,-15.658],[-173.897,-15.694],[-173.937,-15.746],[-173.9585,-15.8135],[-173.9915,-15.857],[-174.016,-15.9565]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9a/Flag_of_Tonga.svg","name:en":"Tonga","wikidata":"Q678","ISO3166-1:alpha2":"TO","ISO3166-1:alpha3":"TON","ISO3166-1:numeric":"776"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-42.3545,-53.5505],[-42.338,-53.612],[-42.2835,-53.6725],[-42.2085,-53.7145],[-42.0535,-53.748],[-41.9675,-53.799],[-41.895,-53.822],[-41.7705,-53.8345],[-41.6015,-53.8055],[-41.5325,-53.7725],[-41.447,-53.675],[-41.4495,-53.59],[-41.492,-53.529],[-41.547,-53.4895],[-41.641,-53.4525],[-41.744,-53.4365],[-41.8415,-53.381],[-41.954,-53.354],[-42.0435,-53.3505],[-42.1625,-53.369],[-42.2425,-53.401],[-42.3355,-53.483],[-42.3545,-53.5505]]],[[[-38.642,-53.991],[-38.62,-54.063],[-38.538,-54.148],[-38.4455,-54.195],[-38.358,-54.217],[-38.2535,-54.224],[-38.182,-54.249],[-38.026,-54.27],[-37.957,-54.307],[-37.8025,-54.365],[-37.702,-54.385],[-37.585,-54.447],[-37.4755,-54.472],[-37.4635,-54.554],[-37.407,-54.618],[-37.31,-54.668],[-37.214,-54.698],[-37.084,-54.715],[-37.014,-54.772],[-36.8875,-54.818],[-36.774,-54.83],[-36.6345,-54.815],[-36.552,-54.907],[-36.432,-54.97],[-36.342,-55.039],[-36.181,-55.088],[-36.0275,-55.089],[-35.8585,-55.06],[-35.7145,-55.01],[-35.533,-54.96],[-35.455,-54.906],[-35.409,-54.826],[-35.4095,-54.77],[-35.4515,-54.7],[-35.555,-54.615],[-35.553,-54.509],[-35.5855,-54.456],[-35.666,-54.395],[-35.8315,-54.31],[-35.952,-54.187],[-36.028,-54.135],[-36.206,-54.074],[-36.2985,-54.018],[-36.531,-53.931],[-36.6875,-53.908],[-36.874,-53.868],[-37.0115,-53.856],[-37.247,-53.805],[-37.455,-53.77],[-37.621,-53.784],[-37.7565,-53.776],[-37.881,-53.793],[-38.085,-53.802],[-38.3,-53.791],[-38.478,-53.821],[-38.593,-53.889],[-38.642,-53.991]]],[[[-28.5075,-56.706],[-28.4685,-56.8],[-28.383,-56.861],[-28.3045,-56.89],[-28.1785,-56.91],[-28.073,-56.908],[-27.959,-56.886],[-27.8425,-56.83],[-27.7875,-56.772],[-27.77,-56.698],[-27.8005,-56.628],[-27.883,-56.563],[-28.057,-56.511],[-28.1765,-56.507],[-28.269,-56.519],[-28.4305,-56.585],[-28.4915,-56.65],[-28.5075,-56.706]]],[[[-27.971,-56.308],[-27.96,-56.356],[-27.9075,-56.42],[-27.797,-56.488],[-27.696,-56.518],[-27.57,-56.53],[-27.468,-56.523],[-27.3695,-56.499],[-27.268,-56.446],[-27.1735,-56.344],[-27.1715,-56.26],[-27.261,-56.155],[-27.426,-56.087],[-27.544,-56.075],[-27.7205,-56.096],[-27.8175,-56.13],[-27.892,-56.174],[-27.944,-56.228],[-27.971,-56.308]]],[[[-27.8125,-59.442],[-27.7445,-59.558],[-27.6535,-59.613],[-27.4575,-59.669],[-27.1585,-59.684],[-27.0595,-59.677],[-26.9235,-59.643],[-26.773,-59.562],[-26.7185,-59.516],[-26.68,-59.444],[-26.6895,-59.382],[-26.7775,-59.296],[-26.931,-59.239],[-27.0455,-59.224],[-27.2375,-59.238],[-27.4615,-59.236],[-27.6015,-59.264],[-27.7205,-59.313],[-27.78,-59.362],[-27.8125,-59.442]]],[[[-27.5665,-56.708],[-27.527,-56.816],[-27.4295,-56.884],[-27.307,-56.92],[-27.1905,-56.935],[-27.0775,-56.932],[-27.167,-57.044],[-27.176,-57.132],[-27.092,-57.237],[-26.9565,-57.292],[-26.853,-57.31],[-26.7045,-57.31],[-26.4795,-57.272],[-26.3955,-57.24],[-26.3115,-57.176],[-26.281,-57.062],[-26.3265,-56.983],[-26.373,-56.942],[-26.4745,-56.893],[-26.6075,-56.865],[-26.7025,-56.86],[-26.7675,-56.824],[-26.716,-56.743],[-26.7255,-56.669],[-26.7605,-56.619],[-26.8815,-56.54],[-27.0465,-56.495],[-27.224,-56.49],[-27.418,-56.541],[-27.538,-56.63],[-27.5665,-56.708]]],[[[-27.128,-59.045],[-27.1175,-59.091],[-27.0495,-59.165],[-26.942,-59.216],[-26.741,-59.264],[-26.5715,-59.28],[-26.443,-59.268],[-26.2745,-59.215],[-26.1645,-59.144],[-26.125,-59.084],[-26.1195,-59.02],[-26.16,-58.948],[-26.224,-58.901],[-26.375,-58.836],[-26.553,-58.804],[-26.7535,-58.821],[-26.9395,-58.871],[-27.064,-58.933],[-27.1125,-58.987],[-27.128,-59.045]]],[[[-26.887,-57.774],[-26.8465,-57.874],[-26.778,-57.932],[-26.5935,-58.0],[-26.44,-58.016],[-26.324,-58.009],[-26.1715,-57.975],[-26.0815,-57.935],[-25.9945,-57.857],[-25.9765,-57.795],[-25.9915,-57.737],[-26.0625,-57.665],[-26.177,-57.605],[-26.334,-57.555],[-26.457,-57.543],[-26.563,-57.55],[-26.665,-57.574],[-26.8105,-57.652],[-26.8625,-57.702],[-26.887,-57.774]]],[[[-26.8335,-58.435],[-26.7755,-58.545],[-26.6425,-58.623],[-26.503,-58.668],[-26.304,-58.701],[-26.11,-58.693],[-26.0245,-58.671],[-25.922,-58.619],[-25.869,-58.562],[-25.8485,-58.5],[-25.8715,-58.354],[-25.918,-58.3],[-26.028,-58.238],[-26.122,-58.209],[-26.264,-58.185],[-26.46,-58.186],[-26.55,-58.202],[-26.7035,-58.256],[-26.7815,-58.317],[-26.8335,-58.435]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/e/ed/Flag_of_South_Georgia_and_the_South_Sandwich_Islands.svg","name:en":"South Georgia and the South Sandwich Islands","wikidata":"Q35086","ISO3166-1:alpha2":"GS","ISO3166-1:alpha3":"SGS","ISO3166-1:numeric":"239"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-57.649,-30.194],[-57.615,-30.256],[-57.6435,-30.3425],[-57.7675,-30.4185],[-57.8885,-30.509],[-57.883,-30.593],[-57.848,-30.6185],[-57.844,-30.6585],[-57.809,-30.6955],[-57.7995,-30.853],[-57.822,-30.908],[-57.915,-30.921],[-57.8615,-31.0325],[-57.8715,-31.0705],[-57.9165,-31.1225],[-57.913,-31.212],[-57.9385,-31.2755],[-57.997,-31.36],[-57.98,-31.3895],[-58.0815,-31.4545],[-58.075,-31.492],[-58.004,-31.532],[-57.981,-31.5905],[-58.0385,-31.7595],[-58.0845,-31.82],[-58.191,-31.853],[-58.207,-31.871],[-58.1385,-32.002],[-58.142,-32.0565],[-58.168,-32.0935],[-58.18,-32.1655],[-58.109,-32.24],[-58.103,-32.3095],[-58.182,-32.3745],[-58.204,-32.465],[-58.1605,-32.5725],[-58.1455,-32.667],[-58.15,-32.727],[-58.1205,-32.8115],[-58.1145,-32.924],[-58.0845,-33.001],[-58.176,-33.077],[-58.257,-33.1025],[-58.3605,-33.12],[-58.4045,-33.1805],[-58.41,-33.231],[-58.3905,-33.277],[-58.432,-33.366],[-58.4435,-33.5375],[-58.494,-33.5815],[-58.474,-33.6525],[-58.4345,-33.7205],[-58.4235,-33.9165],[-58.377,-34.0],[-58.3445,-34.007],[-58.295,-34.178],[-58.1805,-34.233],[-58.0,-34.3765],[-57.9345,-34.452],[-57.9345,-34.685],[-57.508,-34.781],[-57.328,-34.863],[-57.0,-35.189],[-56.705,-35.173],[-55.869,-35.632],[-55.7035,-35.7825],[-55.2495,-35.4505],[-54.9375,-35.222],[-54.837,-35.2285],[-54.7785,-35.2155],[-54.6885,-35.1645],[-54.6495,-35.117],[-54.625,-35.0415],[-54.497,-35.0145],[-54.4365,-34.9705],[-54.182,-34.8655],[-54.1275,-34.8675],[-54.0335,-34.844],[-53.9765,-34.812],[-53.6185,-34.575],[-53.5295,-34.5005],[-53.4995,-34.429],[-53.3145,-34.154],[-53.288,-34.0755],[-53.234,-33.9845],[-53.231,-33.912],[-53.181,-33.869],[-53.3715,-33.743],[-53.4305,-33.739],[-53.4395,-33.6935],[-53.5325,-33.689],[-53.5255,-33.5265],[-53.511,-33.4595],[-53.508,-33.353],[-53.5215,-33.265],[-53.518,-33.1535],[-53.4445,-33.053],[-53.2445,-32.9345],[-53.2945,-32.8995],[-53.185,-32.8505],[-53.1385,-32.7895],[-53.086,-32.7885],[-53.0755,-32.741],[-53.1935,-32.6415],[-53.2795,-32.6195],[-53.3715,-32.5695],[-53.433,-32.5575],[-53.471,-32.4805],[-53.5565,-32.4725],[-53.644,-32.385],[-53.6335,-32.3505],[-53.685,-32.2195],[-53.711,-32.1995],[-53.746,-32.0785],[-53.8065,-32.07],[-53.8495,-32.001],[-53.9725,-31.9395],[-54.0315,-31.896],[-54.081,-31.9295],[-54.4565,-31.6515],[-54.4745,-31.5695],[-54.5155,-31.5105],[-54.5865,-31.4565],[-54.6705,-31.454],[-54.755,-31.4245],[-54.8365,-31.442],[-54.858,-31.408],[-54.9385,-31.354],[-55.0025,-31.2695],[-55.0745,-31.332],[-55.1835,-31.2655],[-55.2465,-31.2525],[-55.25,-31.206],[-55.3055,-31.141],[-55.3715,-31.0235],[-55.4375,-31.0045],[-55.4415,-30.9595],[-55.4805,-30.9525],[-55.51,-30.902],[-55.5455,-30.8905],[-55.582,-30.834],[-55.661,-30.8695],[-55.6485,-30.923],[-55.7805,-31.017],[-55.8135,-31.0155],[-55.8715,-31.071],[-55.933,-31.087],[-56.008,-31.0705],[-56.019,-31.0435],[-56.008,-30.8945],[-55.9895,-30.8585],[-56.023,-30.7855],[-56.062,-30.7745],[-56.146,-30.706],[-56.1885,-30.6045],[-56.384,-30.4975],[-56.3995,-30.447],[-56.49,-30.3985],[-56.5375,-30.3355],[-56.6055,-30.2925],[-56.6625,-30.1975],[-56.7845,-30.1505],[-56.781,-30.126],[-56.8505,-30.089],[-56.906,-30.1075],[-56.994,-30.086],[-57.115,-30.1135],[-57.168,-30.198],[-57.167,-30.248],[-57.2035,-30.2855],[-57.291,-30.289],[-57.31,-30.259],[-57.3975,-30.3045],[-57.4185,-30.2775],[-57.5495,-30.2735],[-57.5665,-30.2075],[-57.649,-30.194]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/fe/Flag_of_Uruguay.svg","name:en":"Uruguay","wikidata":"Q77","ISO3166-1:alpha2":"UY","ISO3166-1:alpha3":"URY","ISO3166-1:numeric":"858"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-57.015,6.225],[-57.032,6.1695],[-57.0785,6.0845],[-57.1625,6.0515],[-57.1435,5.989],[-57.135,5.8935],[-57.1675,5.8095],[-57.183,5.74],[-57.1605,5.6995],[-57.1735,5.5995],[-57.1985,5.553],[-57.2705,5.464],[-57.2695,5.4035],[-57.327,5.351],[-57.2915,5.3215],[-57.2925,5.2405],[-57.2515,5.2765],[-57.227,5.262],[-57.183,5.168],[-57.23,5.1365],[-57.251,5.1855],[-57.299,5.1735],[-57.3005,5.1385],[-57.3515,5.0155],[-57.4105,4.993],[-57.476,4.991],[-57.5495,5.004],[-57.608,4.992],[-57.688,5.0105],[-57.746,4.9675],[-57.776,4.921],[-57.844,4.9245],[-57.9245,4.8165],[-57.8905,4.772],[-57.844,4.682],[-57.8445,4.6335],[-57.877,4.574],[-57.928,4.441],[-57.9585,4.4035],[-57.9535,4.288],[-58.034,4.217],[-58.071,4.1595],[-58.049,4.079],[-58.0435,3.998],[-57.957,3.9205],[-57.876,3.8095],[-57.849,3.741],[-57.8455,3.6895],[-57.821,3.653],[-57.755,3.623],[-57.7065,3.556],[-57.6565,3.5235],[-57.637,3.4555],[-57.6655,3.401],[-57.6465,3.361],[-57.5975,3.3415],[-57.5205,3.3645],[-57.4735,3.3385],[-57.4275,3.361],[-57.358,3.358],[-57.3,3.384],[-57.279,3.3245],[-57.2945,3.2785],[-57.2905,3.1815],[-57.2465,3.088],[-57.221,3.076],[-57.2045,3.0255],[-57.226,2.956],[-57.2085,2.8525],[-57.1465,2.7825],[-57.089,2.766],[-57.103,2.7345],[-57.0605,2.6715],[-57.018,2.6345],[-57.023,2.583],[-56.997,2.5555],[-56.9895,2.5025],[-56.93,2.436],[-56.9345,2.397],[-56.8855,2.3575],[-56.886,2.302],[-56.8265,2.2655],[-56.821,2.211],[-56.7265,2.0865],[-56.691,2.026],[-56.586,2.028],[-56.537,2.0085],[-56.469,1.949],[-56.412,1.9285],[-56.335,1.937],[-56.244,1.878],[-56.2345,1.8985],[-56.1525,1.8905],[-56.0985,1.8465],[-56.0365,1.85],[-55.999,1.8315],[-55.9565,1.845],[-55.904,1.888],[-55.9365,1.9865],[-55.909,2.0475],[-55.967,2.0885],[-56.003,2.1675],[-56.0565,2.1895],[-56.043,2.228],[-56.1205,2.2505],[-56.1255,2.278],[-56.094,2.321],[-56.0505,2.335],[-56.0365,2.374],[-55.9895,2.427],[-55.978,2.5275],[-55.9345,2.5335],[-55.83,2.459],[-55.7665,2.455],[-55.747,2.4105],[-55.6985,2.4215],[-55.5705,2.4235],[-55.4995,2.443],[-55.4295,2.439],[-55.3855,2.4185],[-55.3455,2.448],[-55.356,2.4755],[-55.32,2.5155],[-55.2345,2.5035],[-55.173,2.5595],[-55.1235,2.5675],[-55.103,2.5255],[-55.0035,2.591],[-54.954,2.5835],[-54.9125,2.485],[-54.87,2.468],[-54.87,2.431],[-54.828,2.4215],[-54.7605,2.4635],[-54.6965,2.4625],[-54.7,2.406],[-54.642,2.322],[-54.601,2.3375],[-54.572,2.3545],[-54.521,2.337],[-54.5045,2.3925],[-54.4735,2.4365],[-54.42,2.436],[-54.349,2.5215],[-54.3175,2.6285],[-54.2805,2.6625],[-54.263,2.7225],[-54.206,2.7765],[-54.2075,2.829],[-54.1715,2.9415],[-54.1945,3.0655],[-54.1935,3.1975],[-54.174,3.2075],[-54.13,3.2845],[-54.064,3.3135],[-54.048,3.3875],[-54.023,3.4105],[-54.009,3.466],[-54.004,3.563],[-53.98,3.6055],[-54.003,3.645],[-54.051,3.635],[-54.0835,3.6755],[-54.0785,3.708],[-54.127,3.798],[-54.183,3.7995],[-54.1995,3.8525],[-54.2345,3.858],[-54.2485,3.9055],[-54.2955,3.9475],[-54.3185,4.015],[-54.358,4.0515],[-54.324,4.149],[-54.396,4.2025],[-54.382,4.269],[-54.386,4.349],[-54.4405,4.4195],[-54.452,4.509],[-54.414,4.597],[-54.4335,4.634],[-54.433,4.7035],[-54.4775,4.748],[-54.4735,4.857],[-54.4865,4.8985],[-54.44,4.949],[-54.4375,5.017],[-54.4055,5.084],[-54.374,5.109],[-54.2965,5.2405],[-54.193,5.315],[-54.128,5.4065],[-54.0485,5.4915],[-54.008,5.551],[-54.0205,5.6585],[-53.967,5.761],[-53.8435,5.978],[-53.8765,6.004],[-53.949,6.032],[-54.0715,6.049],[-54.144,6.078],[-54.4035,6.132],[-54.6795,6.178],[-54.818,6.189],[-55.0215,6.195],[-55.1345,6.183],[-55.247,6.141],[-55.3435,6.17],[-55.5185,6.18],[-55.602,6.172],[-55.765,6.168],[-55.8565,6.148],[-56.003,6.085],[-56.0585,6.033],[-56.105,6.048],[-56.3675,6.104],[-56.4855,6.114],[-56.553,6.155],[-56.683,6.182],[-56.814,6.172],[-56.9045,6.197],[-56.999,6.197],[-57.015,6.225]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/60/Flag_of_Suriname.svg","name:en":"Suriname","wikidata":"Q730","ISO3166-1:alpha2":"SR","ISO3166-1:alpha3":"SUR","ISO3166-1:numeric":"740"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-18.3935,27.7165],[-18.387,27.664],[-18.336,27.5755],[-18.283,27.5335],[-18.087,27.453],[-18.0095,27.4345],[-17.893,27.4525],[-17.834,27.482],[-17.764,27.556],[-17.6785,27.7075],[-17.6575,27.767],[-17.6675,27.867],[-17.7295,27.9665],[-17.7865,28.0105],[-17.8555,28.0385],[-17.952,28.0475],[-18.031,28.0325],[-18.254,27.942],[-18.3235,27.893],[-18.3825,27.792],[-18.3935,27.7165]]],[[[-18.2375,28.76],[-18.2305,28.7075],[-18.1725,28.5785],[-18.104,28.4635],[-18.062,28.3585],[-18.013,28.3055],[-17.9065,28.2525],[-17.8035,28.247],[-17.7445,28.263],[-17.6745,28.3045],[-17.6365,28.346],[-17.547,28.486],[-17.531,28.5315],[-17.492,28.745],[-17.5185,28.833],[-17.591,28.9515],[-17.6655,29.0165],[-17.7575,29.0445],[-17.934,29.0585],[-18.0175,29.0395],[-18.126,28.9715],[-18.194,28.8985],[-18.2305,28.826],[-18.2375,28.76]]],[[[-17.578,28.1005],[-17.557,28.01],[-17.5055,27.9365],[-17.4545,27.89],[-17.379,27.8425],[-17.265,27.813],[-17.176,27.8175],[-17.074,27.846],[-17.022,27.875],[-16.9355,27.948],[-16.884,27.8745],[-16.8045,27.8175],[-16.6795,27.791],[-16.4965,27.8225],[-16.4015,27.864],[-16.2535,28.0085],[-16.2015,28.0985],[-16.177,28.179],[-15.954,28.3935],[-15.921,28.434],[-15.893,28.5365],[-15.9135,28.6495],[-15.9605,28.7175],[-16.007,28.7515],[-16.132,28.7825],[-16.321,28.781],[-16.3985,28.768],[-16.5245,28.6995],[-16.9025,28.585],[-17.025,28.5375],[-17.118,28.4585],[-17.147,28.3955],[-17.2235,28.416],[-17.344,28.41],[-17.4255,28.3805],[-17.4855,28.3395],[-17.5385,28.267],[-17.5725,28.178],[-17.578,28.1005]]],[[[-16.064,27.9105],[-16.0475,27.836],[-15.99,27.7355],[-15.9265,27.6665],[-15.82,27.5855],[-15.715,27.543],[-15.592,27.529],[-15.4665,27.5545],[-15.3165,27.625],[-15.239,27.6845],[-15.179,27.7615],[-15.137,27.872],[-15.1275,27.9335],[-15.137,28.0265],[-15.1715,28.199],[-15.1935,28.257],[-15.2385,28.31],[-15.3075,28.357],[-15.4275,28.382],[-15.7195,28.3695],[-15.8005,28.35],[-15.8985,28.2765],[-16.011,28.127],[-16.0425,28.07],[-16.0625,27.989],[-16.064,27.9105]]],[[[-14.735,28.059],[-14.703,27.958],[-14.6655,27.916],[-14.6045,27.8785],[-14.533,27.86],[-14.3125,27.8405],[-14.2215,27.864],[-13.8105,28.0595],[-13.7545,28.1045],[-13.7025,28.17],[-13.638,28.3235],[-13.6225,28.443],[-13.597,28.5285],[-13.4385,28.7885],[-13.334,28.8495],[-13.252,28.9355],[-13.1215,29.192],[-13.1015,29.262],[-13.106,29.315],[-13.1495,29.399],[-13.2615,29.497],[-13.291,29.7305],[-13.338,29.833],[-13.4065,29.885],[-13.463,29.905],[-13.539,29.9115],[-13.64,29.884],[-13.6885,29.8515],[-13.7405,29.7805],[-14.026,29.1165],[-14.226,28.7945],[-14.389,28.4545],[-14.6395,28.2625],[-14.6965,28.196],[-14.735,28.059]]],[[[-1.804,43.595],[-1.8685,43.591],[-2.1925,43.524],[-2.66,43.6475],[-2.7885,43.658],[-2.943,43.644],[-3.3695,43.6645],[-3.5455,43.7135],[-3.6215,43.7145],[-3.8455,43.695],[-4.3565,43.611],[-4.872,43.661],[-5.3355,43.749],[-5.7525,43.852],[-5.8135,43.8625],[-5.934,43.8605],[-6.2885,43.7965],[-6.6375,43.7775],[-6.895,43.778],[-7.5885,43.9795],[-7.7155,43.9925],[-7.893,43.981],[-8.0335,43.9465],[-8.214,43.8755],[-8.4645,43.739],[-8.979,43.54],[-9.3365,43.3515],[-9.4165,43.301],[-9.5375,43.1565],[-9.5755,43.046],[-9.573,42.9185],[-9.5375,42.8045],[-9.344,42.4985],[-9.1835,42.165],[-9.144,41.9785],[-9.1565,41.8725],[-8.871,41.864],[-8.746,41.9645],[-8.6615,42.0035],[-8.637,42.0475],[-8.547,42.054],[-8.518,42.0795],[-8.429,42.0725],[-8.332,42.084],[-8.2535,42.1365],[-8.1955,42.148],[-8.186,42.0725],[-8.1185,42.0825],[-8.086,42.0165],[-8.1305,42.0035],[-8.217,41.913],[-8.162,41.861],[-8.165,41.818],[-8.094,41.808],[-8.0125,41.8335],[-7.9885,41.8675],[-7.9215,41.882],[-7.7335,41.8925],[-7.704,41.9075],[-7.574,41.8295],[-7.4525,41.865],[-7.39,41.8425],[-7.3155,41.8425],[-7.1965,41.88],[-7.1735,41.919],[-7.1865,41.9695],[-7.1415,41.991],[-7.077,41.952],[-6.7505,41.9435],[-6.7,41.9335],[-6.5995,41.9485],[-6.546,41.931],[-6.571,41.8835],[-6.5175,41.875],[-6.5645,41.7515],[-6.5485,41.6855],[-6.5125,41.661],[-6.4525,41.681],[-6.3545,41.6765],[-6.2545,41.633],[-6.189,41.575],[-6.3055,41.4495],[-6.3155,41.39],[-6.4155,41.348],[-6.469,41.3015],[-6.5805,41.239],[-6.6485,41.2475],[-6.7015,41.1805],[-6.768,41.135],[-6.754,41.104],[-6.809,41.0365],[-6.9315,41.017],[-6.86,40.951],[-6.8035,40.846],[-6.8305,40.743],[-6.799,40.6555],[-6.8455,40.566],[-6.801,40.5505],[-6.8495,40.4515],[-6.8385,40.4145],[-6.781,40.364],[-6.7905,40.334],[-6.864,40.296],[-6.868,40.2645],[-6.9515,40.2575],[-7.009,40.2275],[-7.019,40.1425],[-6.954,40.1155],[-6.881,40.0415],[-6.8855,39.94],[-6.9035,39.8705],[-6.987,39.81],[-6.977,39.772],[-7.0155,39.6705],[-7.1515,39.653],[-7.2515,39.667],[-7.331,39.641],[-7.534,39.667],[-7.5,39.591],[-7.377,39.489],[-7.2945,39.457],[-7.323,39.382],[-7.3105,39.341],[-7.2315,39.2785],[-7.248,39.2535],[-7.2215,39.1935],[-7.132,39.1645],[-7.144,39.1085],[-7.028,39.1155],[-6.981,39.088],[-6.951,39.0235],[-7.052,38.907],[-7.033,38.879],[-7.0965,38.816],[-7.1255,38.8155],[-7.203,38.752],[-7.26,38.723],[-7.2725,38.6385],[-7.264,38.588],[-7.3035,38.543],[-7.318,38.44],[-7.143,38.2615],[-7.097,38.179],[-7.0285,38.1825],[-6.969,38.1605],[-7.007,38.021],[-7.0445,38.014],[-7.1085,38.041],[-7.1285,38.0015],[-7.2455,37.992],[-7.255,37.9235],[-7.3215,37.8185],[-7.419,37.7435],[-7.445,37.664],[-7.5225,37.553],[-7.4905,37.5185],[-7.4405,37.391],[-7.441,37.3075],[-7.422,37.275],[-7.397,37.1575],[-7.3865,36.9745],[-7.3065,36.968],[-7.0065,36.9685],[-6.9115,36.9375],[-6.6875,36.624],[-6.5325,36.428],[-6.4185,36.2575],[-6.233,36.0605],[-6.1865,36.0225],[-6.0565,35.9595],[-5.8855,35.965],[-5.6665,35.9355],[-5.6215,35.9405],[-5.3,36.033],[-5.213,36.0475],[-5.112,36.047],[-5.075,36.136],[-4.897,36.266],[-4.6805,36.287],[-4.5245,36.327],[-4.0425,36.524],[-3.965,36.5245],[-3.407,36.4885],[-3.3375,36.4985],[-3.1915,36.537],[-2.8165,36.4815],[-2.678,36.4815],[-2.1725,36.517],[-2.1105,36.524],[-1.997,36.558],[-1.879,36.6365],[-1.801,36.716],[-1.764,36.77],[-1.714,36.8065],[-1.6635,36.874],[-1.647,36.9325],[-1.606,37.0055],[-1.5825,37.078],[-1.3545,37.2465],[-1.0455,37.337],[-0.845,37.3575],[-0.7315,37.382],[-0.6045,37.4225],[-0.466,37.514],[-0.418,37.568],[-0.3925,37.655],[-0.389,37.9215],[-0.2715,38.027],[-0.217,38.1085],[-0.1775,38.2275],[0.0585,38.3575],[0.242,38.469],[0.442,38.6065],[0.487,38.6775],[0.496,38.73],[0.473,38.8355],[0.417,38.911],[0.3085,38.992],[0.047,39.254],[0.0545,39.58],[0.36,39.927],[0.353,39.831],[0.378,39.7685],[0.4225,39.713],[0.4835,39.6675],[0.5575,39.6355],[0.682,39.6165],[0.766,39.6245],[0.845,39.648],[0.914,39.6865],[0.968,39.7365],[1.0045,39.7955],[1.02,39.8595],[1.0145,39.9245],[0.988,39.9865],[0.942,40.041],[0.88,40.085],[0.805,40.116],[0.723,40.1315],[0.638,40.1305],[0.4955,40.088],[0.614,40.2275],[1.075,40.5755],[1.111,40.6095],[1.3775,40.9225],[1.509,40.9485],[1.567,40.976],[1.81,41.011],[2.0015,41.06],[2.0945,41.069],[2.22,41.102],[2.309,41.1475],[2.3565,41.1875],[2.7165,41.4085],[2.9105,41.4715],[2.9755,41.5085],[3.1065,41.5575],[3.207,41.615],[3.363,41.718],[3.4605,41.8205],[3.4995,41.9085],[3.5995,42.2775],[3.5985,42.3625],[3.5585,42.4355],[3.448,42.4355],[3.11,42.4355],[2.9455,42.48],[2.9185,42.456],[2.84,42.459],[2.8005,42.4195],[2.6795,42.407],[2.661,42.367],[2.5795,42.3585],[2.542,42.334],[2.481,42.341],[2.4145,42.392],[2.257,42.4385],[2.2,42.4165],[2.129,42.4125],[2.083,42.3635],[2.012,42.353],[1.9645,42.3825],[1.9585,42.424],[1.8045,42.4905],[1.726,42.5025],[1.597,42.4675],[1.5525,42.4335],[1.4445,42.4415],[1.425,42.558],[1.442,42.6035],[1.3575,42.7195],[1.166,42.709],[1.109,42.7715],[0.9605,42.806],[0.9265,42.7895],[0.8585,42.8255],[0.7085,42.8615],[0.646,42.7825],[0.675,42.6915],[0.527,42.7025],[0.4225,42.6905],[0.3585,42.7195],[0.2955,42.674],[0.2595,42.7165],[0.1845,42.7355],[0.0015,42.686],[-0.062,42.695],[-0.156,42.785],[-0.189,42.787],[-0.308,42.8425],[-0.394,42.799],[-0.4435,42.796],[-0.5055,42.8275],[-0.5675,42.781],[-0.602,42.8315],[-0.718,42.8865],[-0.7515,42.967],[-0.8105,42.9515],[-0.9455,42.9535],[-1.0065,42.989],[-1.111,43.0205],[-1.2475,43.0425],[-1.346,43.0905],[-1.354,43.0285],[-1.441,43.0465],[-1.471,43.079],[-1.4145,43.128],[-1.383,43.19],[-1.379,43.25],[-1.533,43.2935],[-1.609,43.252],[-1.6695,43.315],[-1.73,43.296],[-1.79,43.3535],[-1.772,43.388],[-1.772,43.488],[-1.804,43.595]],[[-5.4005,36.1485],[-5.277,36.1495],[-5.2905,36.0855],[-5.364,36.061],[-5.4005,36.1485]]],[[[-3.2715,35.944],[-3.2635,35.8845],[-3.233,35.8305],[-3.1825,35.7865],[-3.1175,35.758],[-3.045,35.7475],[-2.938,35.768],[-2.878,35.803],[-2.8355,35.852],[-2.814,35.909],[-2.816,35.969],[-2.841,36.025],[-2.887,36.0715],[-2.949,36.104],[-3.02,36.119],[-3.094,36.1155],[-3.162,36.0925],[-3.218,36.0535],[-3.2555,36.0025],[-3.2715,35.944]]],[[[0.898,38.9805],[0.9315,38.824],[0.974,38.746],[1.173,38.5235],[1.2525,38.4655],[1.3145,38.4445],[1.4,38.437],[1.584,38.4455],[1.6945,38.4705],[1.805,38.557],[1.8395,38.632],[1.91,39.002],[1.9115,39.0545],[1.8885,39.118],[1.7785,39.24],[1.71,39.278],[1.6035,39.313],[1.519,39.3205],[1.3895,39.298],[1.2255,39.2475],[1.023,39.152],[0.9645,39.114],[0.9075,39.033],[0.898,38.9805]]],[[[2.04,39.5765],[2.053,39.5075],[2.126,39.4185],[2.741,38.977],[2.7965,38.9465],[2.8935,38.9235],[3.019,38.928],[3.0825,38.9465],[3.1545,38.9905],[3.4245,39.225],[3.4545,39.2565],[3.6415,39.4945],[3.6925,39.571],[3.7375,39.682],[3.741,39.728],[4.198,39.6065],[4.2715,39.5955],[4.369,39.604],[4.432,39.625],[4.518,39.689],[4.5875,39.8385],[4.589,39.9045],[4.5175,40.066],[4.4425,40.149],[4.2845,40.244],[4.172,40.282],[4.021,40.291],[3.77,40.2505],[3.6725,40.218],[3.593,40.149],[3.5365,40.046],[3.5295,39.994],[3.4105,40.097],[3.3385,40.1405],[3.2055,40.1645],[3.1065,40.1565],[2.858,40.109],[2.7425,40.059],[2.625,40.0205],[2.5025,39.95],[2.417,39.885],[2.296,39.816],[2.181,39.763],[2.1145,39.7195],[2.0515,39.6325],[2.04,39.5765]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/32/Flag_of_Spain_%28Civil%29.svg","name:en":"Spain","wikidata":"Q29","ISO3166-1:alpha2":"ES","ISO3166-1:alpha3":"ESP","ISO3166-1:numeric":"724"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-61.7295,10.948],[-61.731,10.904],[-61.803,10.7145],[-61.803,10.589],[-61.8625,10.5885],[-62.083,10.046],[-61.9735,10.008],[-61.855,9.9865],[-61.6305,9.9865],[-61.5,9.97],[-61.2235,9.876],[-61.2075,9.8745],[-61.092,9.8855],[-60.9135,9.9495],[-60.833,10.0025],[-60.795,10.061],[-60.305,11.218],[-60.2895,11.286],[-60.2985,11.3555],[-60.3315,11.451],[-60.373,11.5055],[-60.431,11.5435],[-60.5085,11.563],[-60.5735,11.558],[-60.7445,11.5085],[-61.7295,10.948]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/64/Flag_of_Trinidad_and_Tobago.svg","name:en":"Trinidad and Tobago","wikidata":"Q754","ISO3166-1:alpha2":"TT","ISO3166-1:alpha3":"TTO","ISO3166-1:numeric":"780"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[51.586,24.664],[51.5845,24.599],[51.5475,24.531],[51.4665,24.4625],[51.416,24.393],[51.456,24.364],[51.5295,24.3365],[51.59,24.266],[51.5905,24.127],[51.92,23.7375],[52.1635,23.4425],[52.581,22.939],[53.3315,22.8535],[53.8075,22.797],[54.38,22.727],[55.1375,22.6315],[55.2115,22.7055],[55.2275,22.7925],[55.2135,22.9355],[55.2325,23.1105],[55.2805,23.1775],[55.4015,23.3925],[55.437,23.412],[55.447,23.457],[55.5725,23.6295],[55.569,23.7205],[55.533,23.756],[55.5335,23.8495],[55.485,23.94],[55.495,23.9535],[55.633,24.02],[55.731,24.058],[55.782,24.056],[55.833,24.0145],[55.9025,24.047],[56.0175,24.0665],[55.9605,24.1705],[55.9545,24.2225],[55.8335,24.201],[55.777,24.2345],[55.791,24.2795],[55.834,24.3275],[55.834,24.4095],[55.765,24.5295],[55.7675,24.5725],[55.816,24.6155],[55.8365,24.6715],[55.8315,24.78],[55.8145,24.7995],[55.8125,24.911],[55.8515,24.966],[55.911,24.9655],[55.961,25.006],[56.007,24.9945],[56.059,24.9495],[56.042,24.8865],[55.9785,24.8775],[56.036,24.811],[56.0675,24.7415],[56.1195,24.7345],[56.201,24.785],[56.2055,24.8505],[56.2595,24.86],[56.3255,24.8985],[56.349,24.933],[56.3235,24.973],[56.594,25.009],[56.5855,25.0875],[56.5975,25.1855],[56.6025,25.3235],[56.59,25.414],[56.5915,25.549],[56.549,25.6925],[56.4185,25.6825],[56.202,25.612],[56.1585,25.6615],[56.1675,25.725],[56.14,25.827],[56.18,25.91],[56.163,25.942],[56.1955,25.9795],[56.153,26.0695],[56.0865,26.0505],[55.8885,26.1515],[55.8265,26.007],[55.768,25.926],[55.666,25.898],[55.5545,25.811],[55.4975,25.7965],[55.432,25.76],[55.378,25.702],[55.2795,25.5665],[55.2385,25.5705],[55.1315,25.5445],[55.068,25.5005],[55.0105,25.4145],[54.969,25.38],[54.9295,25.318],[54.9045,25.226],[54.8565,25.206],[54.7925,25.154],[54.7155,25.0695],[54.5925,25.033],[54.525,24.9985],[54.447,24.9055],[54.4265,24.86],[54.014,24.555],[53.8205,24.5235],[53.575,24.5935],[53.552,24.691],[53.5035,24.75],[53.4345,24.7895],[53.3025,24.8135],[53.312,24.877],[53.299,24.945],[53.263,25.0075],[53.2235,25.046],[53.1485,25.0865],[53.098,25.0975],[53.104,25.1895],[53.079,25.2555],[52.9885,25.336],[52.909,25.3615],[52.804,25.3545],[52.647,25.143],[52.67,25.062],[52.6315,24.992],[52.5555,25.003],[52.45,24.983],[52.3965,25.0195],[52.346,24.9975],[52.334,24.967],[52.3785,24.9005],[52.3475,24.874],[52.3295,24.802],[52.337,24.7415],[52.2235,24.729],[52.1515,24.686],[52.092,24.6105],[52.0255,24.7585],[51.829,24.716],[51.586,24.664]],[[56.208,25.256],[56.2455,25.2755],[56.2705,25.328],[56.344,25.264],[56.2735,25.232],[56.208,25.256]]],[[[53.9775,25.224],[54.017,25.1145],[54.0535,25.0745],[54.131,25.03],[54.23,25.012],[54.34,25.033],[54.3995,25.073],[54.4405,25.127],[54.46,25.1895],[54.455,25.272],[54.428,25.339],[54.357,25.4125],[54.239,25.4525],[54.1825,25.4505],[54.082,25.414],[54.0255,25.366],[53.9885,25.2985],[53.9775,25.224]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/cb/Flag_of_the_United_Arab_Emirates.svg","name:en":"United Arab Emirates","wikidata":"Q878","ISO3166-1:alpha2":"AE","ISO3166-1:alpha3":"ARE","ISO3166-1:numeric":"784"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-172.7215,-8.53],[-172.715,-8.5865],[-172.6795,-8.688],[-172.635,-8.739],[-172.5325,-8.784],[-172.4625,-8.781],[-172.388,-8.76],[-172.31,-8.702],[-172.2765,-8.6445],[-172.264,-8.5655],[-172.274,-8.4985],[-172.306,-8.4365],[-172.382,-8.3675],[-172.44,-8.341],[-172.527,-8.333],[-172.624,-8.3625],[-172.673,-8.404],[-172.709,-8.4645],[-172.7215,-8.53]]],[[[-172.0695,-9.178],[-172.0635,-9.228],[-172.0155,-9.319],[-171.947,-9.3845],[-171.8265,-9.4285],[-171.7555,-9.4285],[-171.6745,-9.3995],[-171.6215,-9.355],[-171.588,-9.307],[-171.566,-9.2375],[-171.581,-9.073],[-171.6235,-8.9775],[-171.6815,-8.9285],[-171.793,-8.903],[-171.9215,-8.925],[-171.986,-8.9595],[-172.032,-9.0095],[-172.058,-9.072],[-172.0695,-9.178]]],[[[-171.4715,-9.384],[-171.456,-9.455],[-171.4155,-9.516],[-171.336,-9.5975],[-171.238,-9.6415],[-171.1265,-9.6285],[-171.057,-9.5805],[-171.023,-9.536],[-170.997,-9.4715],[-170.9815,-9.3865],[-170.9955,-9.2795],[-171.072,-9.1775],[-171.161,-9.131],[-171.232,-9.126],[-171.3305,-9.1625],[-171.401,-9.222],[-171.447,-9.2805],[-171.4715,-9.384]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/8e/Flag_of_Tokelau.svg","name:en":"Tokelau","wikidata":"Q36823","ISO3166-1:alpha2":"TK","ISO3166-1:alpha3":"TKL","ISO3166-1:numeric":"772"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-72.55,21.9485],[-72.6095,21.858],[-72.63,21.804],[-72.6725,21.6405],[-72.6775,21.54],[-72.6465,21.493],[-72.5895,21.4485],[-72.347,21.324],[-71.937,21.0165],[-71.837,20.975],[-71.7075,20.9555],[-71.5955,20.9785],[-71.2495,20.97],[-71.18,20.9795],[-71.0835,21.038],[-70.979,21.149],[-70.893,21.2525],[-70.866,21.3575],[-70.8685,21.422],[-70.938,21.6],[-71.0125,21.68],[-71.364,21.898],[-71.459,21.925],[-71.5455,21.9945],[-71.618,22.027],[-71.7025,22.0375],[-71.7505,22.086],[-71.807,22.1205],[-71.893,22.149],[-71.992,22.163],[-72.117,22.14],[-72.2085,22.084],[-72.2425,22.0475],[-72.312,22.0655],[-72.3865,22.06],[-72.4545,22.0315],[-72.55,21.9485]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/a/a0/Flag_of_the_Turks_and_Caicos_Islands.svg","name:en":"Turks and Caicos Islands","wikidata":"Q18221","ISO3166-1:alpha2":"TC","ISO3166-1:alpha3":"TCA","ISO3166-1:numeric":"796"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-14.0155,57.6025],[-13.991,57.53],[-13.903,57.4645],[-13.718,57.4215],[-13.5555,57.4365],[-13.4375,57.484],[-13.379,57.5385],[-13.3615,57.6075],[-13.4155,57.694],[-13.4855,57.735],[-13.5995,57.7665],[-13.76,57.769],[-13.875,57.7415],[-13.956,57.6975],[-14.0155,57.6025]]],[[[-9.0235,57.829],[-9.0075,57.772],[-8.939,57.703],[-8.857,57.66],[-8.6765,57.605],[-8.5035,57.593],[-8.32,57.62],[-8.2,57.679],[-8.154,57.726],[-8.103,57.855],[-8.1435,57.962],[-8.267,58.043],[-8.3875,58.075],[-8.533,58.082],[-8.6475,58.066],[-8.867,57.996],[-8.966,57.938],[-9.0235,57.829]]],[[[-6.7445,55.415],[-6.7195,55.28],[-6.8215,55.2165],[-6.942,55.2045],[-7.218,55.0795],[-7.345,55.051],[-7.3915,55.0225],[-7.405,54.942],[-7.4455,54.9365],[-7.442,54.8755],[-7.484,54.824],[-7.549,54.7895],[-7.5785,54.742],[-7.6365,54.7515],[-7.746,54.7045],[-7.855,54.727],[-7.9135,54.6765],[-7.7715,54.6215],[-7.8505,54.533],[-8.006,54.546],[-8.042,54.506],[-8.1605,54.4405],[-8.056,54.3655],[-7.9865,54.344],[-7.9465,54.3045],[-7.8885,54.3005],[-7.862,54.2185],[-7.702,54.208],[-7.566,54.1265],[-7.4905,54.123],[-7.442,54.154],[-7.347,54.1175],[-7.31,54.1675],[-7.248,54.2045],[-7.147,54.2255],[-7.1735,54.286],[-7.1525,54.3355],[-7.104,54.3555],[-7.0535,54.412],[-6.982,54.4095],[-6.8775,54.347],[-6.8025,54.215],[-6.746,54.189],[-6.664,54.1925],[-6.6315,54.147],[-6.6615,54.1225],[-6.661,54.0625],[-6.623,54.039],[-6.48,54.067],[-6.3675,54.07],[-6.368,54.1115],[-6.2805,54.111],[-6.1135,54.033],[-5.951,53.9315],[-5.826,53.87],[-5.634,53.977],[-5.5795,54.031],[-5.493,54.051],[-5.3825,54.099],[-5.2705,54.172],[-5.202,54.232],[-5.123,54.346],[-5.0875,54.456],[-4.8685,54.434],[-4.6725,54.4995],[-4.4005,54.5465],[-4.1535,54.5505],[-4.0345,54.479],[-3.779,54.288],[-3.7275,54.196],[-3.606,54.079],[-3.544,53.984],[-3.3915,53.8695],[-3.397,53.774],[-3.3685,53.696],[-3.4265,53.616],[-3.44,53.547],[-3.631,53.508],[-3.7705,53.535],[-3.904,53.541],[-4.0055,53.526],[-4.1125,53.588],[-4.212,53.612],[-4.442,53.635],[-4.6815,53.619],[-4.7565,53.603],[-4.9005,53.523],[-4.9445,53.447],[-5.0135,53.377],[-5.0345,53.309],[-5.014,53.239],[-4.9405,53.155],[-4.812,53.085],[-4.994,52.971],[-5.094,52.853],[-5.1275,52.783],[-5.1175,52.687],[-5.062,52.623],[-4.919,52.559],[-4.835,52.547],[-4.7265,52.551],[-4.609,52.583],[-4.454,52.582],[-4.398,52.495],[-4.4425,52.413],[-4.539,52.389],[-4.648,52.339],[-4.786,52.325],[-4.9185,52.281],[-5.004,52.228],[-5.1855,52.218],[-5.278,52.186],[-5.3665,52.121],[-5.528,52.054],[-5.6395,51.963],[-5.6735,51.894],[-5.7675,51.827],[-5.805,51.756],[-5.777,51.645],[-5.7,51.581],[-5.622,51.549],[-5.47,51.529],[-5.3805,51.5025],[-5.3725,51.229],[-5.356,50.619],[-5.378,50.543],[-5.4905,50.434],[-5.717,50.384],[-5.8825,50.314],[-6.01,50.2],[-6.048,50.114],[-6.12,50.148],[-6.241,50.179],[-6.4,50.174],[-6.492,50.15],[-6.5975,50.101],[-6.687,50.014],[-6.7045,49.949],[-6.6735,49.828],[-6.603,49.741],[-6.5035,49.693],[-6.425,49.677],[-6.3165,49.677],[-6.1695,49.716],[-6.068,49.767],[-5.992,49.829],[-5.9395,49.909],[-5.8115,49.854],[-5.733,49.838],[-5.6185,49.838],[-5.4975,49.858],[-5.363,49.783],[-5.247,49.76],[-5.145,49.762],[-5.017,49.795],[-4.89,49.858],[-4.7795,49.961],[-4.744,50.022],[-4.652,50.043],[-4.5235,50.124],[-4.3815,50.139],[-4.279,50.115],[-4.0845,50.095],[-3.9895,50.048],[-3.8525,50.014],[-3.754,50.003],[-3.622,50.012],[-3.5115,50.039],[-3.389,50.103],[-3.3355,50.178],[-3.2595,50.233],[-3.183,50.338],[-3.1555,50.453],[-3.0855,50.485],[-2.865,50.517],[-2.769,50.477],[-2.745,50.431],[-2.6705,50.366],[-2.5275,50.318],[-2.4245,50.314],[-2.313,50.335],[-2.1955,50.397],[-2.1205,50.381],[-1.9835,50.382],[-1.788,50.423],[-1.699,50.4745],[-1.567,50.458],[-1.4775,50.409],[-1.3325,50.376],[-1.185,50.385],[-1.031,50.423],[-0.9435,50.468],[-0.867,50.528],[-0.7825,50.522],[-0.6665,50.537],[-0.545,50.593],[-0.348,50.608],[-0.2345,50.626],[0.177,50.538],[0.2445,50.534],[0.416,50.564],[0.55,50.642],[0.789,50.687],[0.867,50.717],[1.0415,50.716],[1.152,50.745],[1.2635,50.8245],[1.2815,50.8955],[1.3555,50.949],[1.5465,51.038],[1.724,51.0985],[1.8875,51.1995],[1.7325,51.265],[1.7715,51.379],[1.717,51.493],[1.6185,51.556],[1.4605,51.592],[1.291,51.602],[1.435,51.661],[1.5415,51.726],[1.61,51.83],[1.7075,51.9],[1.8085,51.944],[1.8935,52.03],[1.944,52.151],[1.9515,52.207],[2.0425,52.342],[2.0915,52.473],[2.068,52.568],[2.069,52.668],[1.987,52.82],[1.889,52.902],[1.6445,53.037],[1.422,53.12],[1.196,53.148],[1.0195,53.179],[0.8105,53.18],[0.689,53.189],[0.6575,53.299],[0.6245,53.355],[0.487,53.5315],[0.47,53.668],[0.38,53.79],[0.166,53.972],[0.2305,54.026],[0.262,54.143],[0.2235,54.212],[0.173,54.255],[0.042,54.312],[-0.089,54.39],[-0.1535,54.476],[-0.244,54.565],[-0.3275,54.622],[-0.587,54.724],[-0.8635,54.784],[-0.9755,54.862],[-1.004,54.921],[-1.0325,55.04],[-1.15,55.172],[-1.19,55.288],[-1.183,55.346],[-1.2235,55.429],[-1.2695,55.581],[-1.252,55.634],[-1.2645,55.698],[-1.313,55.757],[-1.455,55.826],[-1.6845,55.879],[-1.7735,55.978],[-1.863,56.045],[-1.9815,56.0965],[-2.164,56.276],[-2.0625,56.345],[-2.0265,56.4175],[-2.0575,56.5155],[-2.129,56.573],[-2.0845,56.644],[-1.9125,56.767],[-1.8455,56.853],[-1.8235,56.926],[-1.769,56.974],[-1.691,57.081],[-1.671,57.204],[-1.5835,57.257],[-1.4365,57.385],[-1.4055,57.438],[-1.3955,57.526],[-1.5005,57.713],[-1.6925,57.834],[-1.9305,57.896],[-2.1575,57.9],[-2.3745,57.891],[-2.4635,57.875],[-2.8145,57.905],[-3.0515,57.885],[-3.158,57.9135],[-3.254,58.0235],[-3.135,58.108],[-2.928,58.176],[-2.788,58.264],[-2.69,58.387],[-2.6665,58.452],[-2.6725,58.516],[-2.583,58.5625],[-2.5235,58.6215],[-2.509,58.713],[-2.4265,58.741],[-2.304,58.827],[-2.268,58.899],[-2.1945,58.963],[-2.139,59.07],[-2.1385,59.117],[-2.048,59.166],[-1.984,59.254],[-1.978,59.397],[-1.889,59.349],[-1.738,59.313],[-1.52,59.319],[-1.4225,59.342],[-1.308,59.394],[-1.237,59.454],[-1.2015,59.537],[-1.2635,59.654],[-1.0545,59.687],[-0.9325,59.751],[-0.863,59.865],[-0.769,59.972],[-0.645,60.052],[-0.6095,60.109],[-0.6085,60.1795],[-0.404,60.3035],[-0.346,60.3565],[-0.3235,60.448],[-0.3825,60.5315],[-0.358,60.616],[-0.392,60.687],[-0.349,60.824],[-0.4145,60.927],[-0.521,60.985],[-0.705,61.044],[-0.866,61.061],[-1.0785,61.034],[-1.215,60.977],[-1.281,60.923],[-1.454,60.8525],[-1.643,60.8015],[-1.782,60.728],[-1.889,60.69],[-1.974,60.6295],[-2.0165,60.551],[-2.1335,60.5015],[-2.206,60.4395],[-2.23,60.345],[-2.422,60.273],[-2.51,60.182],[-2.508,60.094],[-2.457,60.03],[-2.287,59.944],[-2.1885,59.92],[-2.0225,59.911],[-1.784,59.954],[-1.7865,59.88],[-1.7525,59.814],[-1.6735,59.753],[-1.84,59.725],[-1.9185,59.695],[-2.0085,59.625],[-2.053,59.504],[-2.192,59.568],[-2.269,59.584],[-2.424,59.591],[-2.655,59.551],[-2.8095,59.583],[-2.97,59.581],[-3.0585,59.565],[-3.3045,59.493],[-3.409,59.433],[-3.462,59.328],[-3.615,59.279],[-3.7005,59.213],[-3.7385,59.143],[-3.7545,59.007],[-3.814,58.919],[-3.7995,58.808],[-3.873,58.787],[-3.983,58.801],[-4.148,58.791],[-4.2605,58.759],[-4.585,58.781],[-4.7945,58.814],[-5.0635,58.8245],[-6.328,58.716],[-6.453,58.691],[-6.975,58.4865],[-7.15,58.4455],[-7.248,58.407],[-7.3475,58.455],[-7.444,58.479],[-7.63,58.489],[-7.835,58.46],[-7.9655,58.397],[-8.0135,58.347],[-8.0215,58.232],[-7.9575,58.162],[-7.783,58.094],[-7.64,58.075],[-8.02,57.808],[-8.095,57.695],[-8.1045,57.5465],[-8.065,57.4505],[-7.8445,57.2105],[-7.886,57.061],[-8.001,56.892],[-8.0305,56.807],[-8.0065,56.724],[-7.9645,56.676],[-7.5315,56.3095],[-7.513,56.2245],[-7.4035,56.1365],[-7.272,56.098],[-7.15,56.0905],[-6.968,56.02],[-6.886,55.669],[-6.8095,55.56],[-6.7625,55.528],[-6.5785,55.4435],[-6.7445,55.415]]],[[[-6.56,59.102],[-6.5335,59.03],[-6.4625,58.963],[-6.286,58.899],[-6.091,58.891],[-5.9385,58.923],[-5.7425,58.917],[-5.579,58.953],[-5.489,59.001],[-5.4345,59.061],[-5.4225,59.141],[-5.4515,59.202],[-5.509,59.255],[-5.6455,59.313],[-5.8185,59.335],[-5.936,59.327],[-6.061,59.295],[-6.21,59.301],[-6.394,59.266],[-6.4885,59.218],[-6.5525,59.142],[-6.56,59.102]]],[[[-4.8965,59.025],[-4.873,58.956],[-4.747,58.866],[-4.634,58.834],[-4.4205,58.828],[-4.2715,58.864],[-4.0815,58.973],[-4.011,59.081],[-4.0625,59.188],[-4.161,59.246],[-4.305,59.282],[-4.478,59.286],[-4.671,59.238],[-4.835,59.134],[-4.8965,59.025]]]]},"properties":{"flag":"https://upload.wikimedia.org/wikipedia/commons/a/ae/Flag_of_the_United_Kingdom.svg","name:en":"United Kingdom","wikidata":"Q145","ISO3166-1:alpha2":"GB","ISO3166-1:alpha3":"GBR","ISO3166-1:numeric":"826"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[29.3755,-22.1955],[29.2175,-22.1785],[29.1495,-22.216],[29.0375,-22.217],[28.964,-22.319],[28.971,-22.378],[28.922,-22.458],[28.869,-22.4475],[28.8325,-22.4875],[28.709,-22.515],[28.6425,-22.5575],[28.566,-22.5595],[28.5195,-22.5875],[28.48,-22.571],[28.345,-22.5715],[28.2685,-22.6385],[28.213,-22.6635],[28.1585,-22.7215],[28.163,-22.7555],[28.11,-22.801],[28.0395,-22.841],[28.0365,-22.914],[27.935,-22.963],[27.944,-23.031],[27.9195,-23.0685],[27.7825,-23.143],[27.784,-23.1735],[27.7145,-23.2285],[27.6045,-23.216],[27.573,-23.266],[27.564,-23.3485],[27.5285,-23.3855],[27.462,-23.384],[27.4015,-23.4115],[27.327,-23.4045],[27.3035,-23.4625],[27.1925,-23.4985],[27.148,-23.5515],[27.108,-23.5705],[27.064,-23.627],[27.071,-23.67],[26.9995,-23.653],[26.9715,-23.703],[26.9645,-23.7775],[26.9415,-23.8435],[26.955,-23.874],[26.928,-23.9225],[26.909,-24.029],[26.863,-24.0995],[26.8805,-24.197],[26.866,-24.2485],[26.8,-24.3],[26.704,-24.322],[26.665,-24.3795],[26.6015,-24.41],[26.5145,-24.485],[26.4705,-24.5905],[26.3935,-24.637],[26.1835,-24.688],[26.009,-24.7235],[25.956,-24.7475],[25.859,-24.7555],[25.8885,-24.882],[25.8615,-24.9225],[25.7315,-25.249],[25.7015,-25.289],[25.6905,-25.3745],[25.6635,-25.468],[25.5815,-25.638],[25.514,-25.684],[25.337,-25.771],[25.199,-25.76],[25.1695,-25.7665],[25.038,-25.7215],[24.912,-25.798],[24.7935,-25.8255],[24.713,-25.8055],[24.678,-25.819],[24.606,-25.799],[24.4485,-25.734],[24.379,-25.765],[24.2885,-25.7255],[24.1955,-25.622],[24.1065,-25.63],[24.066,-25.6505],[24.003,-25.648],[23.9665,-25.615],[23.929,-25.638],[23.8435,-25.5515],[23.817,-25.51],[23.7615,-25.5005],[23.759,-25.469],[23.677,-25.427],[23.5945,-25.397],[23.4415,-25.2775],[23.42,-25.3135],[23.3605,-25.286],[23.294,-25.294],[23.274,-25.2745],[23.1925,-25.2775],[23.1365,-25.317],[23.1135,-25.3035],[22.978,-25.34],[22.9675,-25.3835],[22.91,-25.4225],[22.864,-25.4795],[22.8525,-25.5355],[22.814,-25.583],[22.8535,-25.6115],[22.8,-25.723],[22.7695,-25.733],[22.723,-25.9085],[22.721,-26.0185],[22.669,-26.0145],[22.673,-26.0735],[22.5795,-26.157],[22.5495,-26.226],[22.4745,-26.2],[22.422,-26.223],[22.367,-26.319],[22.2475,-26.347],[22.1935,-26.395],[22.201,-26.4205],[22.166,-26.504],[22.0775,-26.5815],[22.0485,-26.635],[21.953,-26.6685],[21.8235,-26.6595],[21.7875,-26.676],[21.7935,-26.7705],[21.78,-26.8025],[21.6945,-26.8615],[21.627,-26.8665],[21.6045,-26.846],[21.486,-26.8415],[21.404,-26.822],[21.264,-26.837],[21.1335,-26.8735],[21.083,-26.8495],[21.0065,-26.8445],[20.978,-26.8115],[20.885,-26.7975],[20.818,-26.823],[20.763,-26.8665],[20.676,-26.861],[20.6505,-26.81],[20.6145,-26.6865],[20.635,-26.665],[20.6315,-26.5845],[20.604,-26.521],[20.6175,-26.4445],[20.646,-26.435],[20.761,-26.2855],[20.7895,-26.2715],[20.8155,-26.192],[20.862,-26.1355],[20.817,-26.005],[20.84,-25.962],[20.807,-25.926],[20.7875,-25.86],[20.7885,-25.803],[20.7615,-25.7915],[20.7135,-25.7115],[20.6765,-25.6835],[20.6975,-25.589],[20.631,-25.526],[20.643,-25.4985],[20.5985,-25.422],[20.566,-25.395],[20.4965,-25.269],[20.4465,-25.199],[20.4125,-25.0825],[20.384,-25.0345],[20.286,-24.9695],[20.2655,-24.9285],[20.2035,-24.8965],[20.1155,-24.8805],[20.0905,-24.833],[20.038,-24.8095],[19.999,-24.764],[19.999,-25.2205],[19.999,-25.7805],[19.9995,-26.1425],[19.999,-26.6185],[20.0,-26.9125],[19.999,-27.547],[19.999,-27.8885],[19.999,-28.428],[19.847,-28.46],[19.813,-28.5085],[19.73,-28.488],[19.671,-28.5295],[19.622,-28.511],[19.5485,-28.541],[19.507,-28.598],[19.4895,-28.682],[19.4055,-28.7365],[19.27,-28.742],[19.24,-28.806],[19.285,-28.9085],[19.23,-28.9125],[19.1965,-28.947],[19.1185,-28.9695],[19.006,-28.9245],[18.9835,-28.879],[18.9355,-28.857],[18.7285,-28.8315],[18.533,-28.868],[18.4235,-28.901],[18.351,-28.8805],[18.2635,-28.8795],[18.194,-28.9155],[18.079,-28.87],[18.046,-28.8745],[17.972,-28.7915],[17.9255,-28.769],[17.736,-28.7565],[17.619,-28.765],[17.599,-28.6945],[17.4935,-28.693],[17.43,-28.7215],[17.4295,-28.57],[17.389,-28.571],[17.3655,-28.509],[17.333,-28.475],[17.3555,-28.437],[17.3965,-28.4275],[17.414,-28.376],[17.376,-28.321],[17.3825,-28.296],[17.334,-28.226],[17.215,-28.248],[17.184,-28.209],[17.1965,-28.128],[17.1445,-28.0955],[17.0825,-28.033],[16.8845,-28.09],[16.888,-28.173],[16.857,-28.207],[16.803,-28.222],[16.755,-28.302],[16.808,-28.361],[16.7695,-28.396],[16.777,-28.44],[16.734,-28.4945],[16.6885,-28.4705],[16.621,-28.5],[16.5925,-28.5355],[16.48,-28.5655],[16.453,-28.633],[16.3335,-28.8005],[16.3895,-28.9405],[16.4305,-29.004],[16.5,-29.0525],[16.5265,-29.1085],[16.6095,-29.1985],[16.6225,-29.273],[16.6715,-29.3755],[16.7245,-29.4495],[16.7515,-29.5105],[16.7855,-29.642],[16.8275,-29.7295],[16.85,-29.85],[16.898,-29.9865],[16.9355,-30.0515],[16.972,-30.185],[17.0415,-30.3325],[17.057,-30.4045],[17.193,-30.624],[17.2155,-30.689],[17.28,-30.7955],[17.311,-30.8285],[17.397,-31.0055],[17.4695,-31.092],[17.5455,-31.24],[17.6525,-31.361],[17.7145,-31.4715],[17.897,-31.667],[17.9975,-31.8175],[18.0325,-31.924],[18.038,-31.985],[18.068,-32.073],[18.066,-32.1205],[18.0875,-32.2335],[17.6955,-32.605],[17.6625,-32.644],[17.6155,-32.7755],[17.61,-32.8515],[17.637,-33.0245],[17.6955,-33.1475],[17.762,-33.236],[17.856,-33.495],[18.088,-34.202],[18.195,-34.412],[18.269,-34.4805],[18.3655,-34.5365],[18.4485,-34.5565],[18.746,-34.5815],[19.2985,-34.87],[19.532,-34.9615],[19.6255,-34.985],[19.9645,-35.032],[20.0355,-35.0325],[20.125,-35.009],[20.9165,-34.6685],[21.3275,-34.637],[21.759,-34.5945],[21.994,-34.545],[22.065,-34.5115],[22.2605,-34.378],[22.99,-34.2945],[23.39,-34.3115],[23.9365,-34.3505],[24.496,-34.3905],[24.818,-34.4135],[24.8955,-34.408],[25.47,-34.287],[25.7875,-34.217],[26.373,-34.0295],[26.723,-33.9025],[26.8505,-33.8355],[26.941,-33.8165],[27.0415,-33.768],[27.1215,-33.747],[27.2455,-33.691],[27.303,-33.6455],[27.6085,-33.4675],[27.7385,-33.387],[27.878,-33.286],[27.959,-33.2515],[28.097,-33.167],[28.1355,-33.125],[28.2385,-33.062],[28.3215,-32.9575],[28.4005,-32.9255],[28.53,-32.8555],[28.581,-32.8005],[28.6455,-32.768],[28.7325,-32.7015],[28.7705,-32.6555],[28.8345,-32.6095],[28.9515,-32.492],[29.0665,-32.4075],[29.198,-32.264],[29.2605,-32.217],[29.3365,-32.114],[29.3905,-32.076],[29.468,-31.974],[29.528,-31.9315],[29.5915,-31.8515],[29.686,-31.802],[29.8315,-31.694],[29.8905,-31.6365],[29.9995,-31.589],[30.1295,-31.48],[30.2405,-31.3725],[30.37,-31.219],[30.4135,-31.178],[30.546,-30.999],[30.578,-30.9655],[30.663,-30.837],[30.747,-30.7275],[30.933,-30.442],[31.079,-30.1675],[31.154,-30.1],[31.2705,-29.9575],[31.29,-29.897],[31.288,-29.826],[31.3335,-29.743],[31.5285,-29.499],[31.6305,-29.3975],[31.7495,-29.292],[31.901,-29.132],[32.1015,-29.0625],[32.193,-29.0035],[32.3885,-28.825],[32.4515,-28.78],[32.5425,-28.696],[32.5855,-28.64],[32.634,-28.528],[32.652,-28.4265],[32.722,-28.3095],[32.7755,-28.1865],[32.7835,-28.1105],[32.8185,-27.944],[32.816,-27.8975],[32.8395,-27.7815],[32.869,-27.691],[32.9015,-27.538],[32.9595,-27.4095],[33.0515,-27.176],[33.0855,-27.052],[33.1025,-26.921],[32.902,-26.858],[32.692,-26.868],[32.33,-26.8635],[32.2205,-26.833],[32.1865,-26.863],[32.1345,-26.8405],[32.0925,-26.805],[32.016,-26.82],[31.996,-26.924],[31.9745,-27.1165],[31.978,-27.3175],[31.4935,-27.315],[31.1505,-27.202],[31.0615,-27.0965],[30.985,-27.037],[30.9585,-26.992],[30.9735,-26.908],[30.9075,-26.86],[30.8875,-26.8035],[30.813,-26.8445],[30.791,-26.7125],[30.792,-26.569],[30.805,-26.4665],[30.892,-26.321],[30.9615,-26.2615],[31.071,-26.0675],[31.113,-25.9825],[31.1265,-25.921],[31.2635,-25.8095],[31.316,-25.743],[31.4165,-25.719],[31.868,-25.9995],[31.975,-25.9525],[31.9305,-25.841],[31.9785,-25.6935],[32.006,-25.645],[31.996,-25.5265],[31.9795,-25.457],[32.016,-25.3775],[32.0335,-25.1325],[31.998,-24.6895],[32.009,-24.5755],[32.009,-24.4555],[31.987,-24.302],[31.908,-24.182],[31.8805,-23.9525],[31.768,-23.885],[31.6975,-23.722],[31.69,-23.6255],[31.6625,-23.586],[31.561,-23.482],[31.5505,-23.4105],[31.5635,-23.198],[31.4755,-22.9255],[31.3075,-22.424],[31.2735,-22.375],[31.221,-22.37],[31.162,-22.3285],[31.094,-22.3485],[30.9995,-22.3165],[30.839,-22.292],[30.704,-22.317],[30.667,-22.3105],[30.626,-22.3365],[30.492,-22.3165],[30.379,-22.3515],[30.283,-22.354],[30.2275,-22.295],[30.1215,-22.3085],[30.0165,-22.229],[29.972,-22.224],[29.923,-22.189],[29.805,-22.1655],[29.7735,-22.1415],[29.677,-22.139],[29.6545,-22.125],[29.6055,-22.1555],[29.541,-22.1525],[29.528,-22.178],[29.472,-22.1655],[29.3755,-22.1955]],[[27.0115,-29.649],[27.0595,-29.635],[27.12,-29.5775],[27.206,-29.559],[27.363,-29.476],[27.392,-29.4155],[27.4195,-29.4105],[27.4365,-29.334],[27.466,-29.294],[27.5115,-29.283],[27.548,-29.2475],[27.515,-29.224],[27.617,-29.153],[27.652,-29.1005],[27.6825,-29.024],[27.7155,-29.007],[27.7295,-28.947],[27.8325,-28.906],[27.896,-28.9085],[27.948,-28.8525],[27.9905,-28.883],[28.073,-28.8155],[28.166,-28.713],[28.233,-28.695],[28.2795,-28.714],[28.357,-28.6925],[28.414,-28.6275],[28.4715,-28.6055],[28.507,-28.618],[28.613,-28.5965],[28.648,-28.5715],[28.7035,-28.619],[28.7045,-28.6715],[28.795,-28.6995],[28.808,-28.771],[28.905,-28.759],[28.944,-28.7825],[28.939,-28.86],[28.975,-28.893],[29.075,-28.919],[29.1515,-28.9875],[29.2155,-29.0265],[29.259,-29.0905],[29.308,-29.0765],[29.3555,-29.127],[29.3565,-29.2015],[29.408,-29.212],[29.437,-29.2645],[29.4555,-29.341],[29.4035,-29.444],[29.3295,-29.47],[29.297,-29.5225],[29.3195,-29.5815],[29.285,-29.5865],[29.279,-29.6445],[29.236,-29.64],[29.1835,-29.668],[29.145,-29.7165],[29.1315,-29.8255],[29.1025,-29.85],[29.16,-29.883],[29.1695,-29.9165],[29.109,-29.937],[29.006,-30.0045],[28.9855,-30.0315],[28.879,-30.07],[28.859,-30.088],[28.69,-30.1245],[28.6675,-30.1405],[28.5685,-30.123],[28.452,-30.158],[28.4,-30.1435],[28.365,-30.1685],[28.3405,-30.2345],[28.3055,-30.255],[28.2365,-30.26],[28.2155,-30.307],[28.253,-30.3235],[28.271,-30.371],[28.229,-30.43],[28.1795,-30.439],[28.1555,-30.472],[28.1775,-30.5225],[28.1505,-30.5845],[28.114,-30.599],[28.123,-30.6635],[28.004,-30.659],[27.94,-30.644],[27.918,-30.6025],[27.7815,-30.6175],[27.7415,-30.604],[27.693,-30.545],[27.6215,-30.5045],[27.6015,-30.4465],[27.534,-30.3845],[27.475,-30.3565],[27.4645,-30.314],[27.3765,-30.3255],[27.3655,-30.219],[27.394,-30.1425],[27.327,-30.148],[27.2965,-30.056],[27.223,-29.997],[27.0965,-29.73],[27.0115,-29.649]]],[[[37.3005,-46.9355],[37.319,-47.0125],[37.393,-47.097],[37.491,-47.1475],[37.646,-47.1765],[37.8925,-47.176],[37.9845,-47.1535],[38.0645,-47.1125],[38.136,-47.049],[38.201,-46.935],[38.197,-46.86],[38.175,-46.8175],[38.234,-46.7745],[38.2795,-46.7065],[38.29,-46.63],[38.2375,-46.5265],[38.1585,-46.466],[38.052,-46.43],[37.938,-46.411],[37.8225,-46.418],[37.7385,-46.444],[37.6445,-46.502],[37.5915,-46.5795],[37.5835,-46.643],[37.4595,-46.704],[37.3575,-46.798],[37.3005,-46.9355]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/a/af/Flag_of_South_Africa.svg","name:en":"South Africa","wikidata":"Q258","ISO3166-1:alpha2":"ZA","ISO3166-1:alpha3":"ZAF","ISO3166-1:numeric":"710"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[30.796,-8.2765],[30.567,-8.2975],[30.537,-8.2795],[30.4985,-8.2965],[30.429,-8.275],[29.702,-8.3695],[29.6255,-8.415],[29.56,-8.381],[28.991,-8.462],[28.9365,-8.545],[28.962,-8.6105],[28.956,-8.686],[28.8865,-8.8135],[28.734,-9.0],[28.6695,-9.058],[28.512,-9.1705],[28.3995,-9.226],[28.3735,-9.2555],[28.379,-9.2935],[28.431,-9.324],[28.518,-9.3545],[28.5115,-9.44],[28.574,-9.493],[28.57,-9.545],[28.6095,-9.589],[28.6055,-9.619],[28.636,-9.747],[28.6685,-9.751],[28.6755,-9.812],[28.6595,-9.883],[28.626,-9.9475],[28.6215,-9.9935],[28.644,-10.02],[28.629,-10.066],[28.627,-10.161],[28.577,-10.221],[28.636,-10.3105],[28.6185,-10.3645],[28.644,-10.425],[28.63,-10.5185],[28.675,-10.5685],[28.6585,-10.6265],[28.695,-10.6765],[28.6255,-10.7155],[28.562,-10.8215],[28.544,-10.869],[28.5405,-10.9475],[28.5105,-10.97],[28.5125,-11.0205],[28.4765,-11.1035],[28.5,-11.147],[28.4825,-11.1975],[28.49,-11.238],[28.457,-11.2925],[28.456,-11.3715],[28.396,-11.4755],[28.386,-11.5875],[28.434,-11.6515],[28.4305,-11.73],[28.4555,-11.775],[28.4355,-11.816],[28.493,-11.845],[28.5135,-11.877],[28.5755,-11.911],[28.61,-11.9065],[28.634,-11.9415],[28.719,-11.9905],[28.765,-11.9935],[28.7775,-12.0475],[28.807,-12.067],[28.8545,-12.135],[28.9175,-12.1725],[29.0095,-12.2935],[29.0405,-12.3835],[29.1205,-12.395],[29.177,-12.3725],[29.2395,-12.379],[29.2695,-12.3605],[29.3465,-12.421],[29.3825,-12.415],[29.4795,-12.46],[29.53,-12.422],[29.4815,-12.388],[29.459,-12.3095],[29.479,-12.254],[29.562,-12.2025],[29.5985,-12.1955],[29.6475,-12.2345],[29.721,-12.2185],[29.7455,-12.1675],[29.815,-12.15],[29.815,-12.4565],[29.815,-13.097],[29.815,-13.4445],[29.7645,-13.4355],[29.7265,-13.459],[29.613,-13.4035],[29.6515,-13.347],[29.6465,-13.2945],[29.678,-13.262],[29.576,-13.2055],[29.53,-13.229],[29.4345,-13.315],[29.3615,-13.3255],[29.183,-13.4415],[29.1435,-13.379],[29.0895,-13.3795],[29.0055,-13.423],[28.9625,-13.3765],[28.959,-13.334],[28.922,-13.2345],[28.918,-13.1905],[28.8905,-13.154],[28.8475,-13.1555],[28.8475,-13.111],[28.8235,-13.08],[28.8255,-13.005],[28.781,-12.9375],[28.754,-12.9415],[28.7125,-12.866],[28.654,-12.8145],[28.609,-12.8335],[28.5805,-12.899],[28.543,-12.868],[28.543,-12.8235],[28.4515,-12.722],[28.467,-12.69],[28.5085,-12.6895],[28.534,-12.635],[28.4925,-12.5885],[28.4455,-12.563],[28.4385,-12.514],[28.399,-12.5005],[28.3395,-12.4315],[28.194,-12.4045],[28.1695,-12.378],[28.122,-12.438],[28.083,-12.3515],[28.043,-12.3555],[27.961,-12.3145],[27.932,-12.2425],[27.823,-12.2275],[27.7685,-12.2745],[27.65,-12.286],[27.615,-12.241],[27.5245,-12.1615],[27.496,-12.0565],[27.4665,-12.044],[27.4765,-11.9545],[27.3955,-11.8725],[27.287,-11.8035],[27.231,-11.787],[27.219,-11.746],[27.2355,-11.685],[27.2075,-11.5685],[27.1605,-11.601],[27.0535,-11.593],[27.016,-11.618],[27.0475,-11.707],[27.0065,-11.745],[26.996,-11.8285],[26.961,-11.916],[26.9155,-11.9375],[26.891,-11.9775],[26.8195,-11.987],[26.776,-11.956],[26.709,-12.0065],[26.6905,-11.993],[26.576,-11.9855],[26.5,-11.952],[26.479,-11.9195],[26.4235,-11.9115],[26.3125,-11.9635],[26.303,-11.9475],[26.2065,-11.921],[26.1855,-11.938],[26.048,-11.9365],[25.968,-11.8825],[25.927,-11.886],[25.891,-11.852],[25.887,-11.8085],[25.8305,-11.8295],[25.721,-11.817],[25.671,-11.7755],[25.656,-11.733],[25.5055,-11.7915],[25.4955,-11.7145],[25.332,-11.627],[25.3065,-11.565],[25.3135,-11.518],[25.306,-11.4335],[25.2835,-11.397],[25.2945,-11.301],[25.354,-11.201],[25.318,-11.1885],[25.205,-11.236],[25.1455,-11.2375],[25.06,-11.259],[25.028,-11.245],[24.873,-11.2655],[24.8635,-11.2915],[24.7945,-11.31],[24.7505,-11.303],[24.672,-11.3525],[24.6415,-11.401],[24.5915,-11.42],[24.5275,-11.465],[24.4385,-11.4665],[24.42,-11.427],[24.3645,-11.4005],[24.3415,-11.367],[24.4015,-11.2645],[24.4015,-11.1995],[24.3795,-11.085],[24.302,-11.0415],[24.256,-11.045],[24.186,-11.0205],[24.144,-11.031],[24.1325,-10.9245],[24.065,-10.8885],[24.0,-10.89],[24.018,-10.942],[24.0105,-11.0185],[24.032,-11.134],[24.0315,-11.2745],[24.056,-11.3085],[24.0875,-11.4035],[24.024,-11.446],[24.038,-11.531],[23.9755,-11.6505],[23.993,-11.743],[24.023,-11.83],[23.998,-11.856],[23.9805,-12.0775],[23.9825,-12.1715],[24.0,-12.208],[24.0595,-12.2635],[24.078,-12.362],[24.064,-12.426],[24.0405,-12.4345],[23.947,-12.5595],[23.96,-12.592],[23.9205,-12.6815],[23.933,-12.698],[23.898,-12.7695],[23.8935,-12.8415],[23.945,-12.8955],[23.9835,-12.8985],[24.025,-12.9705],[24.058,-13.001],[23.6725,-13.001],[23.229,-13.0005],[22.6525,-12.9995],[22.0035,-12.9995],[22.001,-13.3095],[22.0005,-13.73],[22.0005,-14.146],[22.0005,-14.7385],[22.0005,-15.4065],[22.0005,-15.8865],[22.0,-16.2075],[22.03,-16.2185],[22.1205,-16.348],[22.1395,-16.459],[22.1355,-16.49],[22.185,-16.546],[22.264,-16.602],[22.42,-16.7455],[22.492,-16.835],[22.599,-16.9185],[22.6285,-16.961],[22.716,-17.0425],[22.729,-17.075],[22.7915,-17.12],[22.802,-17.1655],[22.8965,-17.201],[22.9095,-17.2225],[22.9955,-17.274],[23.087,-17.4135],[23.136,-17.4665],[23.1775,-17.475],[23.2215,-17.5325],[23.3415,-17.554],[23.391,-17.5765],[23.434,-17.638],[23.927,-17.539],[24.2485,-17.474],[24.327,-17.492],[24.3815,-17.4715],[24.453,-17.48],[24.559,-17.539],[24.6275,-17.511],[24.7085,-17.497],[24.8025,-17.5365],[24.829,-17.52],[24.8835,-17.529],[24.9075,-17.5545],[24.975,-17.5535],[24.998,-17.592],[25.032,-17.5865],[25.0895,-17.663],[25.194,-17.7695],[25.262,-17.7905],[25.263,-17.7915],[25.3315,-17.8365],[25.379,-17.8525],[25.453,-17.8435],[25.5155,-17.8655],[25.5465,-17.8395],[25.6185,-17.841],[25.682,-17.809],[25.705,-17.8385],[25.771,-17.8515],[25.856,-17.918],[25.863,-17.975],[25.9705,-18.003],[26.0015,-17.977],[26.092,-17.981],[26.0885,-17.9385],[26.2075,-17.8885],[26.245,-17.918],[26.3085,-17.937],[26.411,-17.9385],[26.51,-17.9905],[26.5635,-17.988],[26.602,-18.051],[26.698,-18.062],[26.752,-18.021],[26.803,-18.024],[26.8365,-17.991],[26.895,-17.9895],[26.9675,-17.965],[27.041,-17.959],[27.0845,-17.901],[27.153,-17.837],[27.144,-17.8065],[27.226,-17.6905],[27.2985,-17.6125],[27.424,-17.51],[27.559,-17.4105],[27.6245,-17.3325],[27.63,-17.2465],[27.801,-17.0055],[27.8335,-16.969],[27.9185,-16.9225],[28.1355,-16.8245],[28.269,-16.718],[28.642,-16.5715],[28.7355,-16.5545],[28.8225,-16.4705],[28.8165,-16.4455],[28.851,-16.3745],[28.821,-16.303],[28.857,-16.2495],[28.836,-16.2125],[28.8435,-16.1535],[28.87,-16.1035],[28.8495,-16.0405],[28.9335,-15.9435],[29.0305,-15.932],[29.0465,-15.8985],[29.222,-15.7685],[29.288,-15.7545],[29.4155,-15.6865],[29.487,-15.6925],[29.571,-15.6445],[29.63,-15.6645],[29.8295,-15.6095],[29.9325,-15.6235],[29.9705,-15.6435],[30.176,-15.6235],[30.2195,-15.667],[30.2745,-15.6445],[30.354,-15.6555],[30.421,-15.621],[30.3665,-15.5405],[30.4015,-15.4765],[30.377,-15.437],[30.383,-15.387],[30.361,-15.3295],[30.283,-15.2645],[30.257,-15.164],[30.213,-15.0835],[30.234,-15.0355],[30.2165,-14.9975],[30.365,-14.9595],[30.5175,-14.888],[30.799,-14.7835],[31.079,-14.7175],[31.19,-14.6795],[31.491,-14.612],[31.6835,-14.5065],[31.8265,-14.473],[31.9295,-14.42],[32.0565,-14.3885],[32.2415,-14.3235],[32.4515,-14.2825],[32.6105,-14.2145],[33.2165,-13.9995],[33.186,-13.959],[33.145,-13.939],[33.0865,-13.9705],[33.041,-14.0495],[32.994,-14.007],[32.998,-13.943],[32.9685,-13.9375],[32.9545,-13.8885],[32.907,-13.8255],[32.844,-13.7935],[32.8075,-13.8005],[32.7725,-13.7695],[32.843,-13.722],[32.7835,-13.6495],[32.7185,-13.651],[32.6785,-13.6255],[32.6705,-13.5745],[32.6975,-13.559],[32.7575,-13.5735],[32.8475,-13.526],[32.86,-13.469],[32.8985,-13.4495],[32.932,-13.3735],[32.9305,-13.325],[33.008,-13.1935],[32.984,-13.14],[32.99,-13.037],[33.017,-12.954],[33.0175,-12.8925],[32.976,-12.886],[32.946,-12.8465],[32.9525,-12.7615],[33.0575,-12.5945],[33.1815,-12.6135],[33.232,-12.595],[33.272,-12.5485],[33.3225,-12.533],[33.3755,-12.554],[33.399,-12.516],[33.5485,-12.364],[33.531,-12.34],[33.4755,-12.3255],[33.376,-12.348],[33.3115,-12.2485],[33.3135,-12.202],[33.257,-12.14],[33.2735,-12.066],[33.3325,-11.9875],[33.3485,-11.93],[33.3285,-11.8955],[33.3405,-11.823],[33.327,-11.6975],[33.331,-11.612],[33.301,-11.592],[33.2455,-11.5915],[33.2605,-11.539],[33.256,-11.475],[33.232,-11.444],[33.3335,-11.311],[33.3545,-11.255],[33.3805,-11.234],[33.4045,-11.156],[33.328,-11.0705],[33.305,-10.939],[33.259,-10.889],[33.277,-10.8495],[33.3165,-10.8615],[33.336,-10.821],[33.418,-10.794],[33.4535,-10.808],[33.5355,-10.7525],[33.598,-10.658],[33.6835,-10.6085],[33.6725,-10.5375],[33.633,-10.4985],[33.6335,-10.458],[33.5725,-10.401],[33.5445,-10.342],[33.561,-10.239],[33.5555,-10.212],[33.467,-10.158],[33.433,-10.1165],[33.3175,-10.0555],[33.355,-9.934],[33.391,-9.912],[33.35,-9.815],[33.3065,-9.804],[33.2425,-9.7055],[33.2275,-9.6295],[33.201,-9.601],[33.1135,-9.5865],[33.1065,-9.659],[33.0605,-9.616],[32.9965,-9.626],[32.994,-9.5625],[33.0145,-9.5025],[32.9475,-9.487],[32.9535,-9.4015],[32.8925,-9.366],[32.8675,-9.374],[32.7655,-9.323],[32.7555,-9.285],[32.6485,-9.276],[32.5955,-9.2485],[32.541,-9.2545],[32.4865,-9.1725],[32.4315,-9.1185],[32.3265,-9.132],[32.243,-9.125],[32.164,-9.063],[32.061,-9.0515],[31.996,-9.076],[31.9365,-9.018],[31.947,-8.937],[31.8295,-8.892],[31.7795,-8.8905],[31.735,-8.9235],[31.68,-8.9115],[31.6585,-8.88],[31.585,-8.839],[31.57,-8.809],[31.582,-8.7455],[31.5705,-8.7095],[31.5265,-8.681],[31.4895,-8.684],[31.4585,-8.6405],[31.3105,-8.608],[31.2855,-8.631],[31.211,-8.5835],[31.16,-8.626],[31.078,-8.622],[31.028,-8.592],[30.978,-8.5385],[30.8785,-8.4085],[30.796,-8.2765]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/06/Flag_of_Zambia.svg","name:en":"Zambia","wikidata":"Q953","ISO3166-1:alpha2":"ZM","ISO3166-1:alpha3":"ZMB","ISO3166-1:numeric":"894"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[32.9535,-9.4015],[32.9925,-9.3685],[33.022,-9.4],[33.1435,-9.4925],[33.2135,-9.506],[33.326,-9.486],[33.3905,-9.5335],[33.4435,-9.6145],[33.508,-9.626],[33.554,-9.5875],[33.699,-9.6145],[33.7315,-9.5845],[33.7735,-9.5865],[33.8125,-9.63],[33.871,-9.664],[33.9165,-9.713],[33.9555,-9.654],[33.9455,-9.5725],[33.9785,-9.522],[34.038,-9.4935],[34.209,-9.6455],[34.3265,-9.7575],[34.345,-9.8],[34.416,-9.885],[34.54,-10.0665],[34.5195,-10.119],[34.5695,-10.2065],[34.565,-10.258],[34.5845,-10.3035],[34.56,-10.4325],[34.5935,-10.49],[34.568,-10.5285],[34.584,-10.5725],[34.625,-10.597],[34.681,-10.7515],[34.6705,-10.8945],[34.6545,-10.9535],[34.612,-11.029],[34.6375,-11.053],[34.638,-11.118],[34.7565,-11.2085],[34.8005,-11.281],[34.7895,-11.3135],[34.928,-11.3985],[34.9305,-11.4625],[34.956,-11.4915],[34.959,-11.5735],[35.2315,-11.5685],[35.4155,-11.572],[35.561,-11.566],[35.6505,-11.5505],[35.708,-11.509],[35.7195,-11.475],[35.766,-11.471],[35.8115,-11.4195],[35.8465,-11.412],[35.9135,-11.438],[35.95,-11.4315],[36.0085,-11.487],[36.042,-11.4945],[36.063,-11.5405],[36.128,-11.518],[36.132,-11.5555],[36.1885,-11.598],[36.183,-11.671],[36.221,-11.708],[36.27,-11.6905],[36.2875,-11.7205],[36.3545,-11.7135],[36.3835,-11.6805],[36.494,-11.6815],[36.517,-11.6975],[36.5195,-11.7615],[36.5735,-11.6985],[36.6225,-11.737],[36.767,-11.649],[36.794,-11.6085],[36.8365,-11.584],[36.9105,-11.6055],[36.9865,-11.58],[37.044,-11.593],[37.08,-11.625],[37.1575,-11.6315],[37.2255,-11.6545],[37.301,-11.641],[37.333,-11.678],[37.415,-11.6855],[37.4455,-11.6365],[37.502,-11.614],[37.581,-11.626],[37.6555,-11.5795],[37.753,-11.547],[37.7855,-11.505],[37.7775,-11.4575],[37.8275,-11.3725],[37.8305,-11.311],[37.944,-11.2585],[37.9705,-11.2725],[38.064,-11.2775],[38.1115,-11.2605],[38.265,-11.2875],[38.2825,-11.3275],[38.316,-11.3265],[38.3705,-11.3745],[38.489,-11.4165],[38.5365,-11.3655],[38.5775,-11.3475],[38.611,-11.307],[38.6635,-11.273],[38.7495,-11.274],[38.7675,-11.25],[38.8495,-11.2085],[38.883,-11.172],[39.0785,-11.159],[39.123,-11.1435],[39.2365,-11.173],[39.274,-11.1575],[39.356,-11.083],[39.438,-11.0485],[39.522,-10.9815],[39.595,-10.9515],[39.7595,-10.9155],[39.876,-10.846],[39.999,-10.807],[40.1345,-10.69],[40.176,-10.668],[40.2155,-10.6105],[40.298,-10.566],[40.371,-10.5505],[40.419,-10.483],[40.493,-10.4145],[40.647,-10.325],[40.644,-10.2745],[40.574,-10.1725],[40.5365,-10.133],[39.9945,-9.7],[39.8295,-9.034],[39.793,-8.6],[40.0765,-7.8755],[40.1145,-7.705],[40.1295,-6.908],[40.0985,-6.797],[39.7985,-6.3195],[40.0505,-5.2535],[40.074,-5.101],[40.0805,-4.8905],[40.055,-4.8095],[39.987,-4.727],[39.91,-4.691],[39.7955,-4.6985],[39.7645,-4.681],[39.647,-4.681],[39.605,-4.681],[39.478,-4.892],[39.424,-4.898],[39.3645,-4.8635],[39.347,-4.832],[39.2195,-4.68],[38.8255,-4.405],[38.367,-4.086],[37.99,-3.8155],[37.784,-3.6715],[37.7495,-3.5445],[37.6655,-3.505],[37.617,-3.52],[37.6175,-3.466],[37.5845,-3.4405],[37.712,-3.3105],[37.673,-3.061],[37.512,-2.9545],[37.381,-2.884],[37.004,-2.6715],[36.6315,-2.463],[36.1455,-2.189],[36.001,-2.1055],[35.484,-1.8135],[35.141,-1.6225],[34.776,-1.4145],[34.3865,-1.194],[34.0805,-1.022],[34.046,-1.046],[34.019,-1.0],[33.9335,-1.0],[33.5195,-1.0],[32.7505,-1.0],[31.999,-1.0],[31.832,-0.9985],[31.27,-1.0],[30.7995,-1.0],[30.763,-0.986],[30.6985,-1.015],[30.6585,-1.0625],[30.583,-1.061],[30.5405,-1.0745],[30.473,-1.0575],[30.453,-1.081],[30.471,-1.157],[30.5095,-1.172],[30.5515,-1.252],[30.5685,-1.337],[30.6125,-1.35],[30.6295,-1.385],[30.6825,-1.397],[30.739,-1.454],[30.745,-1.5235],[30.84,-1.651],[30.8215,-1.693],[30.832,-1.8145],[30.808,-1.938],[30.899,-2.0775],[30.8435,-2.2055],[30.8525,-2.321],[30.7765,-2.389],[30.717,-2.3555],[30.657,-2.4135],[30.61,-2.3995],[30.5435,-2.413],[30.485,-2.556],[30.42,-2.6625],[30.4595,-2.691],[30.4405,-2.745],[30.439,-2.802],[30.415,-2.843],[30.4495,-2.913],[30.5065,-2.9535],[30.5765,-2.8945],[30.647,-2.954],[30.668,-2.9935],[30.704,-2.9715],[30.7475,-2.9975],[30.8375,-2.976],[30.816,-3.0395],[30.836,-3.094],[30.846,-3.206],[30.8135,-3.2235],[30.826,-3.264],[30.6665,-3.3205],[30.635,-3.3595],[30.6775,-3.398],[30.618,-3.4665],[30.501,-3.517],[30.451,-3.5605],[30.4555,-3.607],[30.4215,-3.6415],[30.388,-3.713],[30.41,-3.7665],[30.331,-3.7845],[30.308,-3.8455],[30.256,-3.884],[30.2135,-3.9905],[30.215,-4.0465],[30.1575,-4.115],[30.078,-4.168],[30.04,-4.2765],[30.006,-4.28],[29.9615,-4.3255],[29.8935,-4.3535],[29.8665,-4.381],[29.8155,-4.364],[29.765,-4.4275],[29.7685,-4.4565],[29.7075,-4.462],[29.6595,-4.448],[29.436,-4.449],[29.3715,-4.5695],[29.336,-4.652],[29.3285,-4.775],[29.3515,-4.9515],[29.3825,-5.052],[29.4245,-5.1425],[29.4585,-5.1845],[29.485,-5.289],[29.5345,-5.448],[29.5975,-5.579],[29.626,-5.6855],[29.632,-5.7485],[29.614,-5.799],[29.5355,-5.894],[29.5045,-5.946],[29.4985,-6.0565],[29.533,-6.167],[29.537,-6.239],[29.571,-6.338],[29.656,-6.4465],[29.704,-6.5865],[29.746,-6.6415],[29.8915,-6.7555],[30.0375,-6.822],[30.1885,-6.9625],[30.3115,-7.137],[30.382,-7.284],[30.426,-7.428],[30.4355,-7.5095],[30.456,-7.5805],[30.5095,-7.6795],[30.6495,-7.878],[30.697,-7.9705],[30.7595,-8.145],[30.796,-8.2765],[30.8785,-8.4085],[30.978,-8.5385],[31.028,-8.592],[31.078,-8.622],[31.16,-8.626],[31.211,-8.5835],[31.2855,-8.631],[31.3105,-8.608],[31.4585,-8.6405],[31.4895,-8.684],[31.5265,-8.681],[31.5705,-8.7095],[31.582,-8.7455],[31.57,-8.809],[31.585,-8.839],[31.6585,-8.88],[31.68,-8.9115],[31.735,-8.9235],[31.7795,-8.8905],[31.8295,-8.892],[31.947,-8.937],[31.9365,-9.018],[31.996,-9.076],[32.061,-9.0515],[32.164,-9.063],[32.243,-9.125],[32.3265,-9.132],[32.4315,-9.1185],[32.4865,-9.1725],[32.541,-9.2545],[32.5955,-9.2485],[32.6485,-9.276],[32.7555,-9.285],[32.7655,-9.323],[32.8675,-9.374],[32.8925,-9.366],[32.9535,-9.4015]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/38/Flag_of_Tanzania.svg","name:en":"Tanzania","wikidata":"Q924","ISO3166-1:alpha2":"TZ","ISO3166-1:alpha3":"TZA","ISO3166-1:numeric":"834"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[166.3355,-14.861],[166.443,-15.4325],[166.4605,-15.484],[166.5855,-15.738],[166.7295,-15.9395],[167.2875,-16.699],[167.449,-16.9615],[167.977,-17.815],[168.414,-18.428],[168.803,-18.969],[169.0265,-19.542],[169.074,-19.6365],[169.5825,-20.3705],[169.6435,-20.428],[169.729,-20.46],[169.7865,-20.462],[169.9165,-20.4455],[169.97,-20.4255],[170.029,-20.384],[170.0915,-20.2985],[170.4275,-19.6255],[170.45,-19.516],[170.4285,-19.4215],[170.3795,-19.3595],[169.4655,-18.565],[169.0815,-18.0215],[168.8095,-17.635],[168.857,-17.0215],[168.847,-16.942],[168.72,-16.568],[168.4855,-15.877],[168.3,-14.596],[168.264,-14.376],[167.8395,-13.191],[167.792,-13.116],[167.735,-13.075],[167.678,-13.057],[166.583,-12.874],[166.4785,-12.883],[166.413,-12.92],[166.365,-12.9785],[166.3445,-13.0335],[166.3375,-13.1345],[166.3415,-14.425],[166.3425,-14.7745],[166.3355,-14.861]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/bc/Flag_of_Vanuatu.svg","name:en":"Vanuatu","wikidata":"Q686","ISO3166-1:alpha2":"VU","ISO3166-1:alpha3":"VUT","ISO3166-1:numeric":"548"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-0.136,11.1395],[-0.1265,11.106],[-0.0545,11.086],[-0.005,11.108],[0.024,11.0625],[0.032,10.9805],[-0.005,10.9645],[-0.0255,10.8805],[-0.022,10.8185],[-0.074,10.7575],[-0.0785,10.6905],[-0.059,10.6325],[0.0415,10.6015],[0.061,10.561],[0.1425,10.5265],[0.1735,10.426],[0.2645,10.409],[0.334,10.3365],[0.3615,10.258],[0.351,10.1925],[0.3565,10.091],[0.4175,10.0575],[0.4095,10.0205],[0.3605,10.0275],[0.3575,9.8465],[0.325,9.772],[0.3245,9.7225],[0.351,9.675],[0.3175,9.652],[0.264,9.6635],[0.303,9.5965],[0.3565,9.625],[0.366,9.576],[0.239,9.5715],[0.2475,9.5215],[0.309,9.502],[0.23,9.4625],[0.2655,9.4305],[0.337,9.452],[0.3595,9.499],[0.4485,9.4995],[0.489,9.487],[0.4955,9.446],[0.567,9.406],[0.5385,9.306],[0.506,9.255],[0.5335,9.2095],[0.457,9.0355],[0.494,8.954],[0.5165,8.9375],[0.5275,8.878],[0.5005,8.8145],[0.441,8.7895],[0.3795,8.792],[0.3745,8.754],[0.4715,8.5995],[0.511,8.564],[0.647,8.491],[0.654,8.42],[0.6865,8.4115],[0.729,8.343],[0.731,8.2875],[0.6385,8.2605],[0.5845,8.093],[0.6025,8.022],[0.5965,7.987],[0.6275,7.8675],[0.6115,7.753],[0.5905,7.703],[0.586,7.622],[0.524,7.594],[0.52,7.514],[0.536,7.4275],[0.5685,7.392],[0.644,7.401],[0.6585,7.3175],[0.634,7.207],[0.595,7.12],[0.6115,7.1055],[0.59,6.999],[0.5435,6.9885],[0.5265,6.941],[0.5655,6.923],[0.535,6.8755],[0.532,6.829],[0.5675,6.822],[0.5815,6.7615],[0.6485,6.74],[0.6355,6.6415],[0.657,6.6075],[0.7475,6.563],[0.7125,6.529],[0.7495,6.444],[0.789,6.4085],[0.857,6.384],[0.893,6.3335],[1.0035,6.3355],[1.008,6.294],[1.054,6.2345],[1.0835,6.169],[1.1995,6.169],[1.1995,6.1125],[1.2735,5.9265],[1.3375,5.9385],[1.417,5.9785],[1.673,6.04],[1.63,6.2355],[1.7765,6.2855],[1.7965,6.3205],[1.745,6.4735],[1.703,6.532],[1.61,6.6135],[1.6075,6.665],[1.58,6.6915],[1.6235,6.7375],[1.5945,6.7995],[1.6065,6.9045],[1.584,6.91],[1.559,6.997],[1.6425,6.9955],[1.6445,7.443],[1.656,7.5325],[1.6425,7.62],[1.638,7.8465],[1.6345,8.358],[1.613,8.369],[1.631,8.452],[1.661,8.497],[1.6245,8.548],[1.628,8.881],[1.617,8.9595],[1.6265,9.0075],[1.6045,9.1045],[1.57,9.166],[1.5105,9.211],[1.4315,9.3015],[1.407,9.3445],[1.393,9.479],[1.3705,9.4815],[1.3395,9.546],[1.3685,9.5965],[1.3635,9.826],[1.355,9.9955],[1.153,10.121],[1.098,10.15],[0.7765,10.3765],[0.7855,10.5245],[0.8075,10.607],[0.8005,10.681],[0.8095,10.728],[0.8795,10.7995],[0.8885,10.92],[0.912,10.996],[0.6565,10.9975],[0.4945,10.931],[0.5005,11.009],[0.039,11.101],[-0.136,11.1395]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/68/Flag_of_Togo.svg","name:en":"Togo","wikidata":"Q945","ISO3166-1:alpha2":"TG","ISO3166-1:alpha3":"TGO","ISO3166-1:numeric":"768"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[6.2605,0.2495],[6.2665,0.154],[6.318,-0.0595],[6.339,-0.1095],[6.399,-0.175],[6.4735,-0.2085],[6.514,-0.2135],[6.6045,-0.196],[6.714,-0.1415],[6.783,-0.0845],[6.935,0.1425],[7.2925,0.8185],[7.61,1.418],[7.659,1.588],[7.6695,1.666],[7.6585,1.754],[7.627,1.81],[7.58,1.8525],[7.461,1.9085],[7.358,1.9245],[7.272,1.8945],[7.211,1.8325],[6.7675,1.129],[6.323,0.424],[6.2835,0.3415],[6.2605,0.2495]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/4f/Flag_of_Sao_Tome_and_Principe.svg","name:en":"São Tomé and Príncipe","wikidata":"Q1039","ISO3166-1:alpha2":"ST","ISO3166-1:alpha3":"STP","ISO3166-1:numeric":"678"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[33.9335,-1.0],[33.9335,-0.903],[33.9255,-0.5605],[33.929,-0.4575],[33.9845,-0.1335],[33.91,0.099],[34.108,0.3695],[34.0885,0.4555],[34.1195,0.4835],[34.116,0.523],[34.138,0.583],[34.2005,0.6255],[34.2795,0.646],[34.314,0.698],[34.315,0.7615],[34.3615,0.774],[34.4465,0.864],[34.48,0.94],[34.5025,1.0705],[34.5265,1.107],[34.575,1.0985],[34.579,1.1495],[34.612,1.1595],[34.6685,1.2075],[34.795,1.223],[34.831,1.269],[34.829,1.3095],[34.787,1.365],[34.794,1.4135],[34.8445,1.4575],[34.864,1.5285],[34.9435,1.5765],[34.991,1.6645],[35.0005,1.7615],[35.0,1.9625],[34.9455,2.2115],[34.9165,2.4205],[34.9525,2.461],[34.913,2.5165],[34.8975,2.588],[34.852,2.5835],[34.7755,2.698],[34.7835,2.755],[34.767,2.811],[34.7365,2.855],[34.653,2.8675],[34.6395,2.9065],[34.599,2.9245],[34.5765,3.0205],[34.5725,3.0915],[34.546,3.1365],[34.456,3.182],[34.4475,3.283],[34.43,3.3425],[34.4005,3.3705],[34.4195,3.4335],[34.396,3.488],[34.4515,3.517],[34.463,3.6695],[34.405,3.6925],[34.3825,3.7275],[34.331,3.733],[34.308,3.7115],[34.2455,3.784],[34.2155,3.881],[34.128,3.872],[34.1345,3.9615],[34.059,4.0275],[34.0915,4.0615],[34.0495,4.121],[34.0475,4.179],[33.988,4.234],[33.5145,3.755],[33.496,3.7535],[33.179,3.7785],[33.027,3.8935],[32.901,3.8155],[32.72,3.768],[32.4155,3.7455],[32.197,3.6005],[32.2185,3.5605],[32.1935,3.5095],[32.09,3.535],[32.0535,3.5895],[31.9615,3.572],[31.9605,3.648],[31.865,3.789],[31.8275,3.8185],[31.7075,3.724],[31.5755,3.6825],[31.5455,3.6565],[31.3525,3.753],[31.29,3.796],[31.182,3.7945],[31.105,3.7505],[31.0695,3.743],[31.0225,3.6935],[30.9725,3.691],[30.949,3.633],[30.8505,3.5005],[30.942,3.506],[30.937,3.399],[30.8875,3.338],[30.8415,3.243],[30.8025,3.1365],[30.791,3.0635],[30.769,3.045],[30.8565,2.962],[30.888,2.8785],[30.884,2.814],[30.8265,2.729],[30.779,2.606],[30.753,2.591],[30.762,2.51],[30.7415,2.4485],[30.834,2.427],[30.882,2.341],[30.934,2.335],[30.9595,2.395],[30.9825,2.405],[31.0745,2.3435],[31.077,2.2955],[31.131,2.262],[31.203,2.2895],[31.203,2.2215],[31.3055,2.157],[31.3055,2.1165],[31.011,1.785],[30.5495,1.266],[30.5195,1.266],[30.4955,1.206],[30.391,1.1875],[30.36,1.2015],[30.336,1.1505],[30.29,1.1725],[30.235,1.125],[30.2285,0.9885],[30.1765,0.9445],[30.169,0.905],[30.1115,0.895],[29.989,0.8455],[29.9635,0.7785],[29.977,0.745],[29.9545,0.639],[29.973,0.597],[29.979,0.5155],[29.8725,0.388],[29.82,0.1655],[29.7895,0.1695],[29.7375,0.126],[29.7185,0.075],[29.7325,-0.0805],[29.7115,-0.22],[29.6745,-0.5385],[29.6255,-0.725],[29.641,-0.831],[29.631,-0.8905],[29.589,-0.9005],[29.591,-1.0535],[29.5735,-1.186],[29.607,-1.219],[29.595,-1.2805],[29.608,-1.318],[29.591,-1.3875],[29.6765,-1.3835],[29.7115,-1.345],[29.777,-1.3665],[29.823,-1.309],[29.882,-1.357],[29.8855,-1.4235],[29.916,-1.4825],[29.997,-1.446],[30.014,-1.416],[30.17,-1.345],[30.1695,-1.2745],[30.214,-1.269],[30.2925,-1.1885],[30.307,-1.145],[30.359,-1.0605],[30.473,-1.0575],[30.5405,-1.0745],[30.583,-1.061],[30.6585,-1.0625],[30.6985,-1.015],[30.763,-0.986],[30.7995,-1.0],[31.27,-1.0],[31.832,-0.9985],[31.999,-1.0],[32.7505,-1.0],[33.5195,-1.0],[33.9335,-1.0]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/4e/Flag_of_Uganda.svg","name:en":"Uganda","wikidata":"Q1036","ISO3166-1:alpha2":"UG","ISO3166-1:alpha3":"UGA","ISO3166-1:numeric":"800"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[33.988,4.234],[34.0565,4.282],[34.3875,4.61],[34.4765,4.724],[34.5035,4.7395],[34.7125,4.798],[35.009,4.9105],[35.152,4.988],[35.1965,4.956],[35.304,5.0205],[35.3465,5.008],[35.3105,4.9075],[35.4695,4.921],[35.477,4.903],[35.421,4.771],[35.5085,4.617],[35.608,4.618],[35.6985,4.6185],[35.944,4.619],[35.949,4.631],[35.818,4.774],[35.8185,5.1005],[35.866,5.184],[35.828,5.261],[35.8635,5.301],[35.84,5.336],[35.7705,5.351],[35.7205,5.388],[35.628,5.383],[35.5675,5.412],[35.505,5.4235],[35.4115,5.3645],[35.321,5.336],[35.2895,5.378],[35.3095,5.464],[35.306,5.5035],[35.126,5.6245],[35.13,5.6875],[35.0065,5.89],[34.993,5.945],[35.007,6.021],[35.0,6.0805],[34.964,6.1365],[34.9735,6.203],[34.95,6.2465],[35.0005,6.35],[34.9915,6.3935],[35.022,6.435],[35.009,6.475],[34.9275,6.556],[34.8515,6.6095],[34.765,6.6035],[34.7185,6.653],[34.7045,6.6915],[34.6245,6.743],[34.589,6.7285],[34.53,6.755],[34.5435,6.816],[34.5305,6.852],[34.4605,6.9195],[34.372,6.913],[34.311,6.9505],[34.2705,7.0025],[34.1945,7.0405],[34.19,7.1315],[34.105,7.17],[34.074,7.218],[34.024,7.2435],[34.04,7.272],[34.0365,7.3555],[34.004,7.4185],[33.8995,7.5125],[33.866,7.559],[33.7855,7.587],[33.724,7.6565],[33.6285,7.695],[33.5815,7.689],[33.5195,7.728],[33.437,7.7525],[33.323,7.7075],[33.2505,7.778],[33.1785,7.789],[33.071,7.7915],[33.0065,7.8565],[32.998,7.9455],[33.038,7.9675],[33.0395,8.009],[33.078,8.024],[33.0845,8.0735],[33.1185,8.107],[33.193,8.137],[33.171,8.2025],[33.173,8.301],[33.2045,8.3315],[33.187,8.383],[33.214,8.4275],[33.309,8.466],[33.3975,8.4265],[33.423,8.453],[33.561,8.473],[33.6195,8.4715],[33.6755,8.446],[33.689,8.3875],[33.7675,8.3675],[33.809,8.402],[33.8765,8.412],[33.876,8.4555],[33.9005,8.4835],[33.971,8.502],[34.0215,8.4885],[34.045,8.53],[34.1005,8.556],[34.1455,8.6075],[34.1455,9.033],[34.1065,9.5],[33.8775,9.5],[33.9045,9.73],[33.916,9.7655],[33.964,9.807],[33.99,9.9185],[33.9995,10.006],[33.995,10.0635],[33.9715,10.092],[33.9705,10.146],[33.9035,10.1715],[33.8035,10.3355],[33.6685,10.442],[33.517,10.6425],[33.246,10.7775],[33.271,10.828],[33.203,11.2325],[33.1385,11.437],[33.1805,11.75],[33.2535,12.1495],[33.2945,12.219],[32.7315,12.2365],[32.739,12.1395],[32.7595,12.014],[32.7455,11.951],[32.0965,11.951],[32.391,11.706],[32.391,11.181],[32.4695,11.0435],[32.412,11.0],[32.149,10.7375],[31.9885,10.6505],[31.8395,10.379],[31.7785,10.289],[31.734,10.2535],[31.365,9.816],[31.282,9.7595],[31.18,9.75],[30.838,9.75],[30.8345,9.7115],[30.53,9.9605],[30.0,10.288],[29.941,10.288],[29.5375,10.082],[29.5375,9.75],[29.1175,9.75],[29.0465,9.7365],[29.0005,9.67],[28.8165,9.4985],[28.768,9.419],[28.768,9.352],[28.036,9.344],[27.907,9.61],[27.75,9.6065],[27.5,9.6235],[27.2505,9.6285],[27.1425,9.6265],[27.0235,9.603],[26.75,9.4965],[26.703,9.489],[26.548,9.522],[26.394,9.564],[26.346,9.594],[26.3035,9.659],[26.214,9.9165],[26.1165,10.0],[26.038,10.125],[25.988,10.162],[25.932,10.179],[25.9335,10.374],[25.835,10.4225],[25.712,10.4195],[25.6915,10.403],[25.5465,10.398],[25.4715,10.373],[25.4185,10.3915],[25.377,10.372],[25.2775,10.3515],[25.211,10.358],[25.183,10.3225],[25.0985,10.317],[25.062,10.267],[25.0585,10.209],[25.031,10.167],[25.0735,10.1275],[25.079,10.09],[25.0345,10.06],[25.048,10.022],[24.9845,9.9565],[24.9705,9.9045],[24.8375,9.81],[24.828,9.785],[24.7365,9.7175],[24.7515,9.689],[24.752,9.5905],[24.7305,9.5755],[24.697,9.4915],[24.6645,9.4595],[24.6655,9.419],[24.624,9.387],[24.612,9.328],[24.5555,9.2355],[24.5685,9.1475],[24.541,9.0985],[24.549,8.9865],[24.5775,8.941],[24.532,8.8755],[24.4485,8.8445],[24.459,8.814],[24.41,8.7985],[24.386,8.729],[24.319,8.7255],[24.256,8.687],[24.229,8.6305],[24.268,8.592],[24.1635,8.474],[24.141,8.3765],[24.163,8.3315],[24.2305,8.285],[24.3335,8.2665],[24.4705,8.2685],[24.483,8.2345],[24.539,8.2055],[24.6345,8.221],[24.7225,8.2105],[24.7625,8.1865],[24.8,8.1955],[24.8585,8.1695],[24.8805,8.0935],[24.9125,8.0315],[24.969,7.977],[25.047,7.9445],[25.0875,7.8955],[25.1775,7.9105],[25.2465,7.846],[25.282,7.7835],[25.2895,7.652],[25.2305,7.6335],[25.1725,7.5745],[25.1975,7.495],[25.287,7.47],[25.3405,7.426],[25.369,7.3445],[25.4055,7.341],[25.484,7.27],[25.536,7.278],[25.57,7.238],[25.6535,7.205],[25.8205,7.156],[25.841,7.111],[25.895,7.099],[25.9385,7.0405],[26.0395,7.003],[26.0585,6.957],[26.0785,6.85],[26.109,6.8165],[26.175,6.8125],[26.184,6.757],[26.2485,6.739],[26.2655,6.6965],[26.31,6.7105],[26.345,6.6815],[26.415,6.6535],[26.403,6.6175],[26.32,6.5125],[26.3,6.3965],[26.3635,6.352],[26.3965,6.31],[26.489,6.2795],[26.4695,6.2235],[26.5305,6.224],[26.514,6.1155],[26.569,6.028],[26.5965,6.032],[26.6615,5.997],[26.7025,6.0175],[26.7825,6.0005],[26.829,5.9015],[26.9195,5.904],[26.9335,5.865],[26.9875,5.8645],[27.0685,5.8005],[27.103,5.8105],[27.2005,5.744],[27.244,5.651],[27.2375,5.606],[27.2815,5.601],[27.287,5.54],[27.2635,5.5185],[27.2345,5.429],[27.254,5.3235],[27.3035,5.28],[27.318,5.2175],[27.4135,5.148],[27.4355,5.099],[27.466,5.0855],[27.449,5.0195],[27.512,4.9615],[27.5065,4.9395],[27.559,4.892],[27.6485,4.896],[27.707,4.817],[27.7715,4.7915],[27.7825,4.7275],[27.766,4.69],[27.7925,4.6065],[27.842,4.5895],[27.886,4.5425],[27.9225,4.5355],[27.9435,4.5735],[28.0175,4.555],[28.0415,4.531],[28.0375,4.4795],[28.089,4.4345],[28.15,4.426],[28.2065,4.352],[28.3015,4.361],[28.356,4.353],[28.3825,4.2855],[28.4645,4.295],[28.5175,4.3795],[28.584,4.384],[28.6015,4.4185],[28.668,4.4285],[28.6955,4.5025],[28.7305,4.545],[28.8025,4.5565],[28.8095,4.5005],[28.91,4.476],[29.035,4.4915],[29.08,4.4345],[29.138,4.429],[29.2215,4.341],[29.25,4.352],[29.269,4.3975],[29.347,4.3975],[29.3695,4.471],[29.404,4.473],[29.446,4.52],[29.4485,4.5665],[29.4745,4.5925],[29.473,4.6485],[29.4905,4.6945],[29.62,4.6595],[29.7495,4.5695],[29.826,4.56],[29.797,4.4375],[29.8,4.373],[29.838,4.3375],[29.903,4.3475],[29.9655,4.2955],[29.9445,4.248],[29.958,4.224],[30.028,4.2055],[30.0595,4.133],[30.1225,4.112],[30.1635,4.1155],[30.161,4.049],[30.195,4.024],[30.2115,3.94],[30.277,3.9565],[30.3465,3.924],[30.411,3.8655],[30.47,3.8315],[30.5485,3.844],[30.578,3.754],[30.574,3.671],[30.5565,3.6275],[30.6195,3.6055],[30.688,3.643],[30.7275,3.6235],[30.777,3.681],[30.798,3.6555],[30.8045,3.5955],[30.8505,3.5825],[30.864,3.5475],[30.8505,3.5005],[30.949,3.633],[30.9725,3.691],[31.0225,3.6935],[31.0695,3.743],[31.105,3.7505],[31.182,3.7945],[31.29,3.796],[31.3525,3.753],[31.5455,3.6565],[31.5755,3.6825],[31.7075,3.724],[31.8275,3.8185],[31.865,3.789],[31.9605,3.648],[31.9615,3.572],[32.0535,3.5895],[32.09,3.535],[32.1935,3.5095],[32.2185,3.5605],[32.197,3.6005],[32.4155,3.7455],[32.72,3.768],[32.901,3.8155],[33.027,3.8935],[33.179,3.7785],[33.496,3.7535],[33.5145,3.755],[33.988,4.234]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/7/7a/Flag_of_South_Sudan.svg","name:en":"South Sudan","wikidata":"Q958","ISO3166-1:alpha2":"SS","ISO3166-1:alpha3":"SSD","ISO3166-1:numeric":"728"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[34.1065,9.5],[34.086,9.553],[34.14,9.758],[34.207,9.905],[34.2315,10.0305],[34.323,10.117],[34.3215,10.164],[34.348,10.2465],[34.293,10.522],[34.3015,10.5715],[34.357,10.6385],[34.4395,10.7845],[34.5945,10.888],[34.674,10.8345],[34.733,10.7695],[34.798,10.7195],[34.8525,10.7265],[34.8685,10.786],[34.9755,10.8645],[34.9785,10.9155],[34.9335,10.9565],[35.0055,11.1745],[35.0075,11.1985],[34.9405,11.249],[35.0045,11.349],[35.0875,11.536],[35.096,11.583],[35.064,11.6545],[35.0585,11.74],[35.081,11.801],[35.1345,11.864],[35.227,11.8955],[35.269,11.9385],[35.271,11.9755],[35.347,12.0385],[35.3465,12.0835],[35.386,12.17],[35.437,12.21],[35.438,12.2505],[35.649,12.594],[35.6995,12.622],[35.6995,12.666],[36.0065,12.724],[36.081,12.7235],[36.1405,12.704],[36.1655,12.8755],[36.133,12.9235],[36.1695,12.984],[36.1555,13.0245],[36.2485,13.368],[36.3975,13.568],[36.4075,13.652],[36.487,13.8395],[36.4465,13.957],[36.5285,14.212],[36.5605,14.2575],[36.5415,14.278],[36.5235,14.3645],[36.4605,14.983],[36.4335,15.1675],[36.5485,15.252],[36.6105,15.437],[36.698,15.753],[36.7635,15.808],[36.9205,16.2245],[36.9655,16.256],[36.9695,16.3055],[36.9505,16.3475],[36.9575,16.419],[36.906,16.4865],[36.8985,16.537],[36.9195,16.593],[36.9165,16.6505],[36.9805,16.706],[37.009,16.7825],[37.0135,16.9135],[36.9885,16.9375],[37.026,17.077],[37.099,17.0525],[37.158,17.0155],[37.2035,17.0325],[37.252,17.025],[37.307,17.061],[37.396,17.0545],[37.502,17.197],[37.502,17.3165],[37.5835,17.3485],[37.7445,17.382],[37.791,17.4685],[37.831,17.483],[37.8955,17.4415],[37.934,17.4585],[37.9685,17.5015],[38.046,17.548],[38.087,17.5495],[38.0905,17.502],[38.137,17.504],[38.1335,17.5485],[38.19,17.559],[38.2225,17.529],[38.262,17.5355],[38.2735,17.603],[38.3445,17.6445],[38.452,17.8995],[38.5825,18.0205],[38.788,18.071],[38.749,18.1455],[38.8255,18.162],[38.888,18.2],[38.9305,18.252],[38.9555,18.3385],[39.021,18.4075],[39.041,18.457],[39.0415,18.548],[39.0575,18.6275],[39.039,18.707],[38.9895,18.777],[38.9745,18.879],[38.9285,18.956],[38.8805,19.0005],[38.828,19.026],[38.752,19.0365],[38.679,19.0865],[38.5825,19.1035],[38.495,19.0815],[38.451,19.053],[38.422,19.081],[38.394,19.1595],[38.4015,19.2455],[38.371,19.3245],[38.3285,19.371],[38.273,19.403],[38.1875,19.419],[38.123,19.4095],[38.109,19.4625],[38.0625,19.527],[37.9935,19.57],[37.9115,19.5845],[37.8305,19.569],[37.7485,19.511],[37.7125,19.45],[37.7005,19.3895],[37.6285,19.313],[37.6045,19.216],[37.5445,19.2445],[37.525,19.412],[37.496,19.544],[37.46,19.614],[37.473,19.659],[37.4815,19.848],[37.4665,19.9175],[37.4175,20.0075],[37.43,20.0775],[37.4265,20.193],[37.41,20.3375],[37.4505,20.447],[37.456,20.6165],[37.5175,20.6755],[37.5495,20.7505],[37.551,20.817],[37.5215,20.8945],[37.49,20.9335],[37.528,21.0195],[37.5315,21.0935],[37.508,21.161],[37.4555,21.238],[37.3475,21.3615],[37.3055,21.391],[37.238,21.4725],[37.189,21.547],[37.116,21.71],[37.0945,21.886],[37.0905,22.0],[36.737,21.999],[36.6195,22.0055],[36.485,22.0],[36.0995,22.0],[35.556,22.0],[35.1815,22.0],[34.475,21.9995],[34.3535,21.996],[34.3,22.0055],[34.215,21.9975],[34.08,22.0],[34.0,21.7665],[33.553,21.725],[33.1665,22.0],[32.5425,22.0],[32.0,22.0],[31.399,22.0],[31.43,22.078],[31.506,22.185],[31.47,22.225],[31.3765,22.148],[31.3385,22.081],[31.315,22.0],[31.0,22.0],[30.4155,22.0],[30.0,22.0],[29.5745,22.0],[29.024,22.0],[28.316,22.0],[27.7535,22.0],[27.242,22.0],[26.643,22.0],[26.2895,22.0],[25.527,22.0],[25.0,22.0],[25.004,21.943],[25.0035,21.6245],[25.002,21.086],[25.0015,20.479],[25.0,20.0],[24.0,20.0],[24.0,19.5],[23.999,19.066],[23.999,18.5325],[23.9995,18.033],[23.999,17.6995],[23.999,17.0995],[24.0,16.733],[23.999,16.1995],[23.9995,15.6975],[23.8115,15.7515],[23.6635,15.7745],[23.552,15.7685],[23.397,15.6975],[23.3375,15.694],[23.207,15.7185],[23.1105,15.715],[23.0755,15.6675],[22.9875,15.5835],[22.937,15.5645],[22.9185,15.4945],[22.9305,15.462],[22.988,15.415],[23.003,15.322],[22.985,15.2595],[23.004,15.2405],[22.9675,15.1825],[22.935,15.169],[22.9405,15.116],[22.882,15.0885],[22.8125,15.0345],[22.7515,14.97],[22.76,14.908],[22.7095,14.8955],[22.667,14.8635],[22.6775,14.766],[22.7025,14.6915],[22.47,14.6295],[22.4035,14.592],[22.3845,14.5195],[22.4345,14.496],[22.4475,14.384],[22.4695,14.351],[22.436,14.315],[22.444,14.272],[22.4785,14.2445],[22.5555,14.232],[22.567,14.164],[22.5525,14.121],[22.477,14.101],[22.4345,14.0515],[22.3965,14.052],[22.3445,14.0135],[22.234,13.966],[22.0845,13.779],[22.1405,13.723],[22.134,13.6695],[22.1635,13.6235],[22.2265,13.567],[22.2395,13.454],[22.2885,13.3915],[22.2695,13.321],[22.183,13.231],[22.1595,13.1905],[22.0755,13.151],[22.0295,13.143],[21.941,13.049],[21.91,12.99],[21.847,12.838],[21.8145,12.8065],[21.858,12.772],[21.8565,12.741],[21.9015,12.6775],[21.977,12.6385],[22.0745,12.64],[22.166,12.672],[22.2235,12.747],[22.335,12.6705],[22.467,12.6215],[22.409,12.487],[22.3865,12.4545],[22.433,12.4035],[22.4365,12.3545],[22.5015,12.177],[22.478,12.03],[22.5375,12.058],[22.641,12.071],[22.6145,12.0045],[22.573,11.799],[22.5535,11.6725],[22.5615,11.6215],[22.642,11.516],[22.7755,11.462],[22.791,11.4015],[22.931,11.416],[22.9485,11.316],[22.972,11.2775],[22.9755,11.216],[22.9195,11.0665],[22.878,10.9205],[22.8905,10.8825],[23.013,10.6955],[23.151,10.6005],[23.252,10.493],[23.3065,10.459],[23.6695,9.867],[23.6965,9.6715],[23.6265,9.547],[23.632,9.4495],[23.666,9.436],[23.6405,9.346],[23.65,9.2755],[23.5515,9.1805],[23.4935,9.174],[23.4715,9.1245],[23.4575,8.9905],[23.5335,8.9605],[23.583,8.9945],[23.5805,8.9015],[23.5495,8.847],[23.509,8.812],[23.4975,8.773],[23.5265,8.7085],[23.5585,8.705],[23.597,8.7345],[23.734,8.705],[23.8305,8.727],[23.8835,8.708],[23.926,8.7185],[24.127,8.6855],[24.1685,8.6985],[24.256,8.687],[24.319,8.7255],[24.386,8.729],[24.41,8.7985],[24.459,8.814],[24.4485,8.8445],[24.532,8.8755],[24.5775,8.941],[24.549,8.9865],[24.541,9.0985],[24.5685,9.1475],[24.5555,9.2355],[24.612,9.328],[24.624,9.387],[24.6655,9.419],[24.6645,9.4595],[24.697,9.4915],[24.7305,9.5755],[24.752,9.5905],[24.7515,9.689],[24.7365,9.7175],[24.828,9.785],[24.8375,9.81],[24.9705,9.9045],[24.9845,9.9565],[25.048,10.022],[25.0345,10.06],[25.079,10.09],[25.0735,10.1275],[25.031,10.167],[25.0585,10.209],[25.062,10.267],[25.0985,10.317],[25.183,10.3225],[25.211,10.358],[25.2775,10.3515],[25.377,10.372],[25.4185,10.3915],[25.4715,10.373],[25.5465,10.398],[25.6915,10.403],[25.712,10.4195],[25.835,10.4225],[25.9335,10.374],[25.932,10.179],[25.988,10.162],[26.038,10.125],[26.1165,10.0],[26.214,9.9165],[26.3035,9.659],[26.346,9.594],[26.394,9.564],[26.548,9.522],[26.703,9.489],[26.75,9.4965],[27.0235,9.603],[27.1425,9.6265],[27.2505,9.6285],[27.5,9.6235],[27.75,9.6065],[27.907,9.61],[28.036,9.344],[28.768,9.352],[28.768,9.419],[28.8165,9.4985],[29.0005,9.67],[29.0465,9.7365],[29.1175,9.75],[29.5375,9.75],[29.5375,10.082],[29.941,10.288],[30.0,10.288],[30.53,9.9605],[30.8345,9.7115],[30.838,9.75],[31.18,9.75],[31.282,9.7595],[31.365,9.816],[31.734,10.2535],[31.7785,10.289],[31.8395,10.379],[31.9885,10.6505],[32.149,10.7375],[32.412,11.0],[32.4695,11.0435],[32.391,11.181],[32.391,11.706],[32.0965,11.951],[32.7455,11.951],[32.7595,12.014],[32.739,12.1395],[32.7315,12.2365],[33.2945,12.219],[33.2535,12.1495],[33.1805,11.75],[33.1385,11.437],[33.203,11.2325],[33.271,10.828],[33.246,10.7775],[33.517,10.6425],[33.6685,10.442],[33.8035,10.3355],[33.9035,10.1715],[33.9705,10.146],[33.9715,10.092],[33.995,10.0635],[33.9995,10.006],[33.99,9.9185],[33.964,9.807],[33.916,9.7655],[33.9045,9.73],[33.8775,9.5],[34.1065,9.5]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/01/Flag_of_Sudan.svg","name:en":"Sudan","wikidata":"Q1049","ISO3166-1:alpha2":"SD","ISO3166-1:alpha3":"SDN","ISO3166-1:numeric":"729"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[8.5905,37.143],[8.642,36.941],[8.6295,36.8605],[8.6695,36.8175],[8.5725,36.773],[8.484,36.7795],[8.4595,36.7515],[8.4875,36.6975],[8.447,36.6235],[8.418,36.6225],[8.326,36.574],[8.286,36.538],[8.1615,36.4985],[8.176,36.4595],[8.4045,36.4235],[8.372,36.298],[8.3395,36.267],[8.355,36.2335],[8.3095,36.1615],[8.346,36.097],[8.2975,36.0415],[8.291,35.957],[8.2715,35.9075],[8.2645,35.7305],[8.356,35.67],[8.36,35.5255],[8.3535,35.463],[8.3145,35.3775],[8.3125,35.3125],[8.4545,35.22],[8.4,35.128],[8.3615,35.103],[8.3155,35.009],[8.3075,34.947],[8.253,34.9155],[8.2995,34.7415],[8.25,34.664],[8.244,34.6205],[8.206,34.5775],[8.1615,34.569],[8.1155,34.5125],[8.043,34.4935],[8.011,34.458],[7.959,34.4485],[7.9285,34.4185],[7.8565,34.4055],[7.845,34.329],[7.7965,34.209],[7.723,34.1705],[7.6515,34.201],[7.614,34.1135],[7.5305,34.061],[7.5605,34.0145],[7.522,33.905],[7.547,33.837],[7.5255,33.7985],[7.562,33.7775],[7.565,33.727],[7.634,33.572],[7.7365,33.4245],[7.749,33.3275],[7.786,33.2905],[7.832,33.188],[7.9015,33.1855],[8.1175,33.1],[8.116,33.05],[8.247,32.9245],[8.3225,32.8235],[8.357,32.5025],[8.8005,32.236],[9.0655,32.0875],[9.0985,31.9995],[9.187,31.676],[9.3595,31.0],[9.474,30.559],[9.559,30.229],[9.832,30.337],[9.8775,30.337],[9.944,30.3835],[10.017,30.479],[10.0695,30.5085],[10.202,30.6935],[10.272,30.8005],[10.2975,30.8865],[10.275,31.041],[10.294,31.0915],[10.1665,31.377],[10.139,31.49],[10.2125,31.566],[10.312,31.703],[10.386,31.7405],[10.4485,31.7305],[10.527,31.741],[10.635,31.8795],[10.6125,31.9165],[10.658,31.9775],[10.7225,31.9675],[10.795,31.998],[10.861,32.0855],[10.8615,32.1055],[11.029,32.1995],[11.3845,32.345],[11.549,32.4085],[11.595,32.4545],[11.6,32.519],[11.5515,32.581],[11.5015,32.612],[11.478,32.656],[11.494,32.694],[11.4875,32.7625],[11.5015,32.8305],[11.4955,32.918],[11.5275,32.986],[11.527,33.0785],[11.5615,33.167],[11.664,33.349],[11.554,33.3795],[11.461,33.435],[11.3695,33.4755],[11.336,33.6185],[11.2905,33.69],[11.3025,33.7955],[11.2935,33.8595],[11.234,33.9605],[11.16,34.0065],[11.2725,34.4445],[11.38,34.4775],[11.531,34.502],[11.6745,34.555],[11.769,34.6335],[11.865,34.7885],[11.88,34.854],[11.868,34.92],[11.8305,34.979],[11.7475,35.047],[11.7005,35.118],[11.6415,35.1765],[11.4005,35.2885],[11.3555,35.359],[11.294,35.4025],[11.319,35.4555],[11.3265,35.524],[11.294,35.609],[11.2695,35.713],[11.2915,35.8125],[11.252,35.9085],[11.1485,35.985],[11.0145,36.005],[10.911,35.979],[10.817,35.989],[10.762,36.0535],[10.7145,36.148],[10.728,36.2135],[10.8065,36.248],[10.9085,36.272],[10.98,36.312],[11.026,36.3595],[11.0935,36.4875],[11.206,36.6465],[11.3085,36.7055],[11.356,36.7685],[11.3785,36.826],[11.384,36.9],[11.3455,36.9835],[11.3085,37.123],[11.214,37.232],[11.13,37.274],[10.8325,37.342],[10.378,37.38],[10.351,37.4525],[10.2995,37.5055],[10.229,37.542],[10.147,37.558],[10.043,37.5465],[9.97,37.515],[9.9225,37.5295],[9.7305,37.5475],[9.5985,37.533],[9.482,37.496],[9.3635,37.502],[9.2815,37.4795],[9.2155,37.4405],[9.204,37.602],[9.1685,37.6685],[9.1025,37.723],[9.011,37.756],[8.921,37.7595],[8.802,37.7205],[8.668,37.6185],[8.63,37.5605],[8.6175,37.4895],[8.636,37.4215],[8.6895,37.356],[8.7495,37.3205],[8.869,37.293],[8.797,37.242],[8.7335,37.17],[8.5905,37.143]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/ce/Flag_of_Tunisia.svg","name:en":"Tunisia","wikidata":"Q948","ISO3166-1:alpha2":"TN","ISO3166-1:alpha3":"TUN","ISO3166-1:numeric":"788"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[35.692,36.034],[35.6175,35.9875],[35.5705,35.926],[35.556,35.8275],[35.568,35.787],[35.5,35.68],[35.4745,35.617],[35.489,35.51],[35.556,35.3985],[35.6755,35.315],[35.686,35.2205],[35.649,35.1455],[35.638,35.0465],[35.611,34.9105],[35.6195,34.8105],[35.6745,34.686],[35.754,34.662],[35.8395,34.6005],[36.0055,34.642],[36.036,34.6285],[36.1895,34.6375],[36.2975,34.6355],[36.3115,34.683],[36.4095,34.6115],[36.3805,34.508],[36.4435,34.5055],[36.4635,34.4645],[36.572,34.405],[36.5285,34.37],[36.5805,34.2775],[36.595,34.1895],[36.564,34.1345],[36.476,34.0505],[36.4405,34.0585],[36.328,33.978],[36.2835,33.918],[36.356,33.8815],[36.3965,33.8335],[36.323,33.833],[36.246,33.8595],[36.202,33.833],[36.1525,33.8555],[36.067,33.8245],[35.9685,33.715],[35.946,33.6375],[36.019,33.6135],[36.059,33.5795],[36.029,33.549],[35.952,33.534],[35.9535,33.488],[35.8765,33.426],[35.827,33.405],[35.7735,33.3355],[35.813,33.317],[35.7775,33.2765],[35.815,33.245],[35.8445,33.1675],[35.817,33.113],[35.8505,33.1025],[35.8715,32.9815],[35.895,32.945],[35.851,32.89],[35.8375,32.828],[35.7565,32.745],[35.7865,32.7475],[35.882,32.7145],[35.936,32.718],[35.967,32.6625],[36.027,32.6535],[36.0295,32.597],[36.0625,32.576],[36.0785,32.5135],[36.1225,32.5245],[36.2065,32.5195],[36.3055,32.4595],[36.407,32.377],[36.512,32.357],[36.6895,32.3345],[36.71,32.3165],[36.838,32.3115],[36.881,32.334],[36.9625,32.44],[37.065,32.4285],[37.105,32.4545],[37.2065,32.5575],[37.2555,32.572],[37.36,32.56],[37.4245,32.607],[37.444,32.643],[37.5205,32.7175],[37.741,32.762],[37.762,32.788],[37.7695,32.8785],[37.818,32.9055],[37.8885,32.894],[38.3505,33.1415],[38.7695,33.358],[38.7935,33.375],[39.3045,33.64],[39.9825,33.985],[40.64,34.315],[40.978,34.398],[41.0165,34.448],[41.1225,34.6535],[41.2285,34.7785],[41.2275,34.974],[41.218,35.132],[41.2425,35.2855],[41.275,35.385],[41.262,35.456],[41.382,35.6255],[41.3695,35.8435],[41.256,36.06],[41.294,36.365],[41.402,36.524],[41.817,36.5875],[41.9705,36.7005],[42.0,36.7385],[42.3745,37.073],[42.3515,37.1055],[42.3205,37.1855],[42.3435,37.23],[42.2345,37.283],[42.1835,37.2865],[42.035,37.182],[41.794,37.1285],[41.5975,37.1055],[41.5175,37.078],[41.2925,37.081],[41.218,37.062],[41.1635,37.0945],[41.117,37.0945],[40.9165,37.1315],[40.7625,37.1255],[40.695,37.1035],[40.528,37.028],[40.419,37.0165],[40.379,36.9795],[40.181,36.877],[40.0595,36.8545],[40.0275,36.826],[39.854,36.7765],[39.8165,36.756],[39.7105,36.75],[39.6385,36.7245],[39.491,36.7005],[39.361,36.692],[39.2095,36.6695],[39.019,36.711],[38.8955,36.701],[38.7475,36.707],[38.689,36.7365],[38.5525,36.8455],[38.3925,36.902],[38.3455,36.8995],[38.243,36.924],[38.0365,36.8605],[38.0195,36.8265],[37.9405,36.8185],[37.902,36.791],[37.7775,36.749],[37.7005,36.7575],[37.5245,36.6875],[37.471,36.635],[37.284,36.67],[37.217,36.6755],[37.1625,36.657],[37.106,36.6715],[37.0855,36.6345],[37.0205,36.666],[37.037,36.7365],[36.985,36.762],[36.7935,36.797],[36.752,36.8195],[36.685,36.8255],[36.613,36.744],[36.6315,36.7125],[36.5735,36.659],[36.5915,36.5855],[36.544,36.502],[36.5995,36.3685],[36.6575,36.3375],[36.6565,36.298],[36.695,36.245],[36.6245,36.2145],[36.534,36.2455],[36.373,36.1785],[36.371,36.1175],[36.3905,36.082],[36.376,36.0115],[36.299,35.963],[36.2085,35.9535],[36.176,35.9215],[36.1735,35.8355],[36.113,35.862],[35.9985,35.884],[36.018,35.921],[35.976,35.939],[35.9115,35.9335],[35.692,36.034]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/5/53/Flag_of_Syria.svg","name:en":"Syria","wikidata":"Q858","ISO3166-1:alpha2":"SY","ISO3166-1:alpha3":"SYR","ISO3166-1:numeric":"760"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[42.3515,37.1055],[42.464,37.142],[42.579,37.146],[42.6175,37.2185],[42.73,37.3175],[42.78,37.3755],[42.8245,37.371],[42.8975,37.3285],[42.9635,37.3155],[43.072,37.3665],[43.151,37.371],[43.2405,37.345],[43.3015,37.3035],[43.3275,37.326],[43.4745,37.253],[43.578,37.25],[43.6205,37.2215],[43.694,37.2355],[43.9165,37.2235],[44.0145,37.322],[44.1245,37.323],[44.2685,37.2445],[44.2765,37.165],[44.222,37.158],[44.185,37.098],[44.235,37.042],[44.2675,36.976],[44.3065,36.97],[44.392,37.0505],[44.5115,37.101],[44.576,37.1625],[44.627,37.19],[44.682,37.171],[44.769,37.164],[44.7845,37.144],[44.7575,37.2285],[44.815,37.2795],[44.798,37.311],[44.743,37.3345],[44.711,37.38],[44.6575,37.386],[44.619,37.437],[44.5875,37.4395],[44.6145,37.6005],[44.568,37.645],[44.6245,37.698],[44.588,37.7635],[44.5305,37.783],[44.445,37.771],[44.392,37.828],[44.403,37.852],[44.317,37.8765],[44.268,37.867],[44.2225,37.888],[44.2405,37.9555],[44.3015,38.0325],[44.351,38.135],[44.3925,38.1465],[44.402,38.251],[44.478,38.3025],[44.4975,38.3335],[44.4395,38.3835],[44.3765,38.3595],[44.3165,38.3745],[44.3055,38.441],[44.3255,38.502],[44.3095,38.531],[44.3215,38.6245],[44.2815,38.6415],[44.261,38.7055],[44.315,38.809],[44.2965,38.841],[44.2115,38.89],[44.1895,38.934],[44.181,39.0105],[44.2115,39.0205],[44.191,39.0765],[44.2135,39.1305],[44.1665,39.1775],[44.094,39.2155],[44.0755,39.332],[44.0375,39.3615],[44.051,39.403],[44.1415,39.3975],[44.233,39.4155],[44.295,39.3755],[44.432,39.443],[44.4395,39.501],[44.416,39.5565],[44.48,39.6105],[44.467,39.684],[44.6145,39.7825],[44.669,39.7145],[44.7135,39.7145],[44.8095,39.6275],[44.7635,39.7145],[44.711,39.77],[44.652,39.7955],[44.554,39.9005],[44.4805,39.967],[44.351,40.0275],[44.2745,40.0495],[44.1705,40.0275],[43.994,40.032],[43.8965,40.0215],[43.761,40.084],[43.6785,40.096],[43.6485,40.132],[43.714,40.1615],[43.6765,40.2605],[43.591,40.346],[43.62,40.398],[43.6055,40.438],[43.56,40.459],[43.558,40.4945],[43.611,40.514],[43.6865,40.593],[43.7485,40.731],[43.707,40.82],[43.6785,40.8445],[43.6715,40.9365],[43.5975,40.9835],[43.4685,41.0305],[43.447,41.099],[43.474,41.123],[43.4485,41.1765],[43.3675,41.2035],[43.247,41.177],[43.1925,41.253],[43.2125,41.2905],[43.132,41.321],[43.109,41.3495],[43.0215,41.3785],[42.967,41.4515],[42.8995,41.479],[42.8015,41.497],[42.8365,41.585],[42.7745,41.5785],[42.684,41.6],[42.601,41.585],[42.573,41.51],[42.513,41.472],[42.5195,41.4365],[42.439,41.4415],[42.2745,41.494],[42.203,41.492],[42.085,41.51],[42.043,41.494],[41.9555,41.5235],[41.8815,41.4605],[41.824,41.4315],[41.747,41.4715],[41.6355,41.4865],[41.2995,41.612],[41.231,41.554],[41.122,41.51],[40.972,41.429],[40.9195,41.391],[40.7385,41.359],[40.641,41.32],[40.553,41.255],[40.5145,41.241],[40.3385,41.222],[40.2175,41.183],[40.1515,41.14],[40.0195,41.163],[39.9525,41.162],[39.8545,41.195],[39.7065,41.211],[39.6115,41.268],[39.449,41.305],[39.3905,41.305],[39.2615,41.27],[39.136,41.278],[39.0015,41.238],[38.9065,41.242],[38.719,41.197],[38.657,41.173],[38.512,41.154],[38.4585,41.13],[38.2295,41.144],[38.0395,41.178],[37.9945,41.241],[37.874,41.305],[37.7095,41.334],[37.591,41.323],[37.5075,41.286],[37.3455,41.34],[37.2635,41.346],[37.2295,41.391],[37.154,41.446],[37.025,41.504],[36.917,41.539],[36.6845,41.583],[36.5475,41.568],[36.4325,41.508],[36.399,41.572],[36.368,41.69],[36.292,41.788],[36.218,41.846],[36.081,41.914],[35.9335,41.934],[35.8545,41.92],[35.7365,41.877],[35.5915,41.837],[35.4535,41.882],[35.436,41.907],[35.471,41.966],[35.4785,42.042],[35.4495,42.111],[35.357,42.198],[35.2975,42.224],[35.198,42.241],[35.1125,42.28],[34.9175,42.296],[34.8355,42.28],[34.718,42.206],[34.682,42.146],[34.5625,42.169],[34.4355,42.172],[34.289,42.1495],[34.165,42.173],[34.029,42.182],[33.8395,42.175],[33.632,42.188],[33.3855,42.218],[33.284,42.215],[33.2115,42.198],[33.049,42.141],[32.9105,42.107],[32.813,42.062],[32.7225,42.055],[32.4845,42.013],[32.3875,41.983],[32.3165,41.947],[32.1705,41.901],[32.0535,41.842],[31.976,41.775],[31.8475,41.721],[31.756,41.694],[31.5575,41.589],[31.388,41.535],[31.2405,41.475],[31.151,41.389],[31.127,41.297],[31.009,41.276],[30.838,41.281],[30.771,41.31],[30.5115,41.351],[30.3435,41.408],[30.2315,41.416],[30.1475,41.399],[30.047,41.339],[29.882,41.343],[29.6385,41.3805],[29.573,41.3795],[29.472,41.4045],[29.3135,41.4305],[29.201,41.4325],[29.028,41.4565],[28.7795,41.5355],[28.7195,41.5465],[28.4345,41.659],[28.3655,41.717],[28.3055,41.808],[28.3205,41.846],[28.324,41.9815],[28.0405,41.9815],[27.9075,41.975],[27.8685,41.9995],[27.778,41.966],[27.714,41.977],[27.5745,41.9375],[27.447,41.967],[27.393,42.007],[27.3765,42.046],[27.3125,42.0865],[27.2215,42.098],[27.1915,42.0605],[27.107,42.086],[27.022,42.079],[27.0145,42.045],[26.9575,41.997],[26.871,41.991],[26.833,41.969],[26.787,41.9895],[26.755,41.96],[26.641,41.972],[26.561,41.9255],[26.584,41.902],[26.5385,41.8235],[26.369,41.821],[26.3295,41.752],[26.358,41.711],[26.471,41.6695],[26.5295,41.6215],[26.595,41.61],[26.591,41.5285],[26.6355,41.3835],[26.5865,41.3225],[26.498,41.3285],[26.4605,41.282],[26.4075,41.254],[26.323,41.2535],[26.3075,41.172],[26.332,41.097],[26.3105,41.0805],[26.3665,41.018],[26.328,40.977],[26.302,40.9025],[26.248,40.8815],[26.158,40.809],[26.125,40.7425],[26.083,40.73],[25.955,40.7295],[26.05,40.3715],[25.6935,40.2335],[25.643,40.199],[25.6225,40.129],[25.6985,39.992],[25.732,39.9575],[25.8915,39.8905],[25.8925,39.8415],[25.928,39.7145],[25.9275,39.48],[25.9815,39.396],[26.143,39.4055],[26.432,39.434],[26.674,39.122],[26.7045,39.032],[26.6995,38.98],[26.6465,38.9095],[26.6185,38.809],[26.451,38.7725],[26.324,38.756],[26.2665,38.736],[26.2225,38.688],[26.216,38.6515],[26.3125,38.537],[26.3155,38.453],[26.243,38.446],[26.213,38.3835],[26.1945,38.2415],[26.2215,38.1675],[26.363,38.0955],[26.9185,37.965],[27.054,37.914],[27.101,37.846],[27.1605,37.7905],[27.165,37.724],[27.0865,37.6995],[27.0085,37.6965],[26.9585,37.649],[27.054,37.564],[27.109,37.4575],[27.1535,37.312],[27.1595,37.2425],[27.1435,37.065],[27.1875,36.981],[27.246,36.9425],[27.3935,36.905],[27.351,36.8075],[27.247,36.726],[27.298,36.6335],[27.3515,36.586],[27.462,36.543],[27.6415,36.5745],[27.775,36.6935],[27.814,36.7085],[27.8955,36.6975],[27.931,36.5375],[27.9605,36.4705],[28.002,36.4695],[28.2095,36.5615],[28.2825,36.55],[28.4435,36.561],[28.5345,36.513],[28.5895,36.501],[28.6135,36.461],[28.711,36.389],[28.853,36.368],[28.895,36.277],[29.0015,36.191],[29.0875,36.149],[29.1745,36.065],[29.236,36.03],[29.3105,36.011],[29.484,36.1855],[29.6135,36.149],[29.7005,36.086],[29.7295,35.923],[29.8065,35.93],[30.0065,35.996],[30.1175,36.047],[30.2,36.059],[30.257,36.01],[30.382,35.97],[30.51,35.983],[30.59,36.02],[30.6915,36.127],[30.727,36.21],[30.76,36.254],[30.802,36.47],[30.836,36.551],[30.832,36.647],[30.9815,36.657],[31.2095,36.622],[31.291,36.579],[31.436,36.537],[31.5145,36.486],[31.686,36.418],[31.779,36.396],[31.9205,36.335],[31.965,36.292],[32.084,36.132],[32.223,36.016],[32.3505,35.944],[32.62,35.847],[32.7775,35.818],[32.8685,35.824],[32.988,35.884],[33.1065,35.871],[33.199,35.894],[33.2565,35.928],[33.3525,35.915],[33.4665,35.927],[33.537,35.921],[33.6385,35.936],[33.7345,35.938],[33.7915,35.953],[33.938,36.033],[34.0485,36.045],[34.0925,36.062],[34.2605,36.187],[34.3075,36.252],[34.3255,36.312],[34.449,36.433],[34.5655,36.497],[34.6365,36.553],[34.7155,36.593],[34.7995,36.543],[34.91,36.523],[35.151,36.408],[35.21,36.368],[35.595,36.158],[35.692,36.034],[35.9115,35.9335],[35.976,35.939],[36.018,35.921],[35.9985,35.884],[36.113,35.862],[36.1735,35.8355],[36.176,35.9215],[36.2085,35.9535],[36.299,35.963],[36.376,36.0115],[36.3905,36.082],[36.371,36.1175],[36.373,36.1785],[36.534,36.2455],[36.6245,36.2145],[36.695,36.245],[36.6565,36.298],[36.6575,36.3375],[36.5995,36.3685],[36.544,36.502],[36.5915,36.5855],[36.5735,36.659],[36.6315,36.7125],[36.613,36.744],[36.685,36.8255],[36.752,36.8195],[36.7935,36.797],[36.985,36.762],[37.037,36.7365],[37.0205,36.666],[37.0855,36.6345],[37.106,36.6715],[37.1625,36.657],[37.217,36.6755],[37.284,36.67],[37.471,36.635],[37.5245,36.6875],[37.7005,36.7575],[37.7775,36.749],[37.902,36.791],[37.9405,36.8185],[38.0195,36.8265],[38.0365,36.8605],[38.243,36.924],[38.3455,36.8995],[38.3925,36.902],[38.5525,36.8455],[38.689,36.7365],[38.7475,36.707],[38.8955,36.701],[39.019,36.711],[39.2095,36.6695],[39.361,36.692],[39.491,36.7005],[39.6385,36.7245],[39.7105,36.75],[39.8165,36.756],[39.854,36.7765],[40.0275,36.826],[40.0595,36.8545],[40.181,36.877],[40.379,36.9795],[40.419,37.0165],[40.528,37.028],[40.695,37.1035],[40.7625,37.1255],[40.9165,37.1315],[41.117,37.0945],[41.1635,37.0945],[41.218,37.062],[41.2925,37.081],[41.5175,37.078],[41.5975,37.1055],[41.794,37.1285],[42.035,37.182],[42.1835,37.2865],[42.2345,37.283],[42.3435,37.23],[42.3205,37.1855],[42.3515,37.1055]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/b4/Flag_of_Turkey.svg","name:en":"Turkey","wikidata":"Q43","ISO3166-1:alpha2":"TR","ISO3166-1:alpha3":"TUR","ISO3166-1:numeric":"792"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[41.6085,15.5425],[41.619,15.4705],[41.668,15.3905],[41.768,15.3315],[41.8375,15.324],[41.9395,15.3525],[41.996,15.3925],[42.034,15.4425],[42.056,15.5105],[42.0585,15.562],[42.0225,15.6635],[41.9665,15.719],[41.88,15.7535],[41.7715,15.747],[41.689,15.703],[41.625,15.6195],[41.6085,15.5425]]],[[[41.7555,16.29],[41.787,16.192],[41.865,16.122],[41.9375,16.0995],[41.997,16.098],[42.067,16.118],[42.0965,16.035],[42.126,16.001],[42.083,15.918],[42.08,15.838],[42.0965,15.7885],[42.0755,15.7025],[42.0995,15.592],[42.1515,15.524],[42.1645,15.4615],[42.214,15.3705],[42.2015,15.3575],[42.1135,15.376],[42.0595,15.37],[41.973,15.326],[41.9045,15.2275],[41.892,15.161],[41.912,15.038],[41.986,14.8985],[42.032,14.8545],[42.119,14.8175],[42.1885,14.8145],[42.2835,14.849],[42.37,14.9385],[42.4005,15.0285],[42.5415,14.9745],[42.668,14.9825],[42.662,14.894],[42.69,14.783],[42.7215,14.7315],[42.694,14.652],[42.6945,14.5985],[42.7155,14.533],[42.775,14.427],[42.8035,14.3315],[42.83,14.28],[42.7595,14.287],[42.6985,14.2785],[42.6145,14.23],[42.526,14.144],[42.4775,14.061],[42.5965,13.741],[42.6275,13.6585],[42.637,13.5975],[42.7235,13.458],[42.834,13.4275],[42.9255,13.4945],[42.9985,13.602],[43.015,13.683],[43.05,13.73],[43.078,13.657],[43.055,13.543],[43.0445,13.405],[43.021,13.322],[43.0345,13.213],[43.079,13.1335],[43.145,13.068],[43.2125,12.9695],[43.249,12.8675],[43.298,12.7925],[43.273,12.687],[43.29,12.633],[43.3205,12.5955],[43.4305,12.5525],[43.5355,12.5525],[43.6365,12.518],[43.738,12.492],[43.8125,12.433],[43.8655,12.408],[43.9355,12.394],[44.0785,12.406],[44.1295,12.4205],[44.1905,12.4165],[44.329,12.4335],[44.416,12.47],[44.4705,12.4765],[44.5295,12.5015],[44.593,12.5645],[44.653,12.539],[44.7665,12.538],[44.8885,12.5255],[44.9935,12.5535],[45.05,12.5525],[45.152,12.586],[45.209,12.6305],[45.246,12.691],[45.267,12.8245],[45.4265,12.86],[45.525,12.9115],[45.6095,12.9985],[45.6995,13.1205],[45.743,13.1585],[45.8495,13.1865],[46.0325,13.2175],[46.0765,13.2135],[46.245,13.23],[46.4425,13.2025],[46.618,13.2355],[46.6705,13.226],[46.7415,13.231],[46.924,13.3045],[46.9955,13.351],[47.1225,13.375],[47.437,13.457],[47.509,13.4895],[47.584,13.543],[47.7865,13.7225],[47.9075,13.7595],[48.0185,13.8415],[48.0785,13.7945],[48.1635,13.7695],[48.25,13.7765],[48.3125,13.741],[48.4245,13.731],[48.4985,13.76],[48.6195,13.847],[48.7345,13.8505],[48.837,13.9045],[48.9715,14.0225],[49.03,14.092],[49.1475,14.1895],[49.1905,14.26],[49.2015,14.312],[49.303,14.3575],[49.351,14.4145],[49.433,14.4595],[49.6,14.52],[49.645,14.5505],[49.9425,14.6355],[50.013,14.62],[50.2495,14.6575],[50.339,14.7195],[50.4325,14.746],[50.503,14.8085],[50.5525,14.836],[50.6445,14.8585],[50.7555,14.873],[50.8655,14.8965],[51.089,14.9565],[51.1915,14.976],[51.362,15.034],[51.44,15.047],[51.5075,15.074],[51.603,15.13],[51.715,15.1445],[51.7745,15.1705],[51.8455,15.244],[51.9095,15.2525],[51.9705,15.2775],[52.037,15.345],[52.3045,15.4405],[52.3965,15.5205],[52.4295,15.6],[52.4265,15.683],[52.407,15.7455],[52.41,15.83],[52.371,15.9695],[52.41,16.0795],[52.442,16.131],[52.5555,16.2445],[52.6075,16.269],[52.8935,16.3695],[53.0375,16.4285],[53.189,16.465],[53.1105,16.647],[52.8125,17.2855],[52.746,17.2945],[52.782,17.3495],[52.5005,17.9455],[52.2835,18.404],[52.0,19.0],[51.4245,18.9],[50.7835,18.789],[50.1295,18.7215],[49.713,18.6785],[49.1165,18.6165],[48.588,18.3615],[48.1835,18.1665],[47.849,17.7565],[47.6,17.45],[47.4665,17.1165],[47.1835,16.95],[47.0,16.95],[46.75,17.2835],[46.3665,17.2335],[46.1,17.25],[45.4,17.3335],[45.2165,17.4335],[44.65,17.4335],[44.5665,17.4055],[44.4665,17.4335],[44.366,17.4335],[44.138,17.409],[44.1005,17.366],[44.0665,17.406],[44.0115,17.4025],[43.9665,17.3305],[43.832,17.339],[43.789,17.375],[43.6835,17.3665],[43.5665,17.4835],[43.4845,17.545],[43.4195,17.566],[43.355,17.5565],[43.241,17.4805],[43.228,17.3855],[43.326,17.3285],[43.2015,17.259],[43.2165,17.2105],[43.171,17.1725],[43.158,17.114],[43.227,17.0755],[43.24,17.024],[43.191,17.016],[43.178,16.9635],[43.138,16.9175],[43.18,16.849],[43.2215,16.838],[43.252,16.7795],[43.2305,16.7305],[43.2345,16.643],[43.1285,16.6715],[43.1465,16.6365],[43.1205,16.5285],[42.992,16.5215],[42.945,16.49],[42.95,16.3995],[42.8305,16.3795],[42.772,16.404],[42.15,16.404],[41.7835,16.29],[41.7555,16.29]]],[[[51.8585,12.2235],[51.8735,12.1515],[51.8985,12.1085],[51.9515,12.0585],[52.0035,12.0295],[52.1865,11.9645],[52.274,11.9495],[52.4075,11.9575],[52.4785,11.9815],[52.5525,12.051],[52.589,12.1355],[52.599,12.1975],[52.5655,12.306],[52.518,12.3555],[52.4695,12.383],[52.3405,12.396],[52.3375,12.4985],[52.3005,12.567],[52.2575,12.606],[52.195,12.6345],[52.0965,12.6385],[52.0225,12.609],[51.954,12.537],[51.9285,12.4635],[51.933,12.3915],[51.8855,12.337],[51.8585,12.2235]]],[[[52.7735,12.1585],[52.7925,12.082],[52.86,12.003],[52.984,11.9395],[53.0415,11.9235],[53.1575,11.9395],[53.2035,11.921],[53.289,11.909],[53.3665,11.918],[53.433,11.9515],[53.473,11.991],[53.5075,12.0605],[53.5115,12.143],[53.6565,12.106],[53.768,12.103],[53.963,12.1335],[54.039,12.131],[54.1065,12.1525],[54.182,12.156],[54.236,12.175],[54.3595,12.249],[54.4595,12.2725],[54.553,12.315],[54.673,12.3955],[54.713,12.445],[54.7375,12.517],[54.721,12.6295],[54.679,12.692],[54.617,12.735],[54.5145,12.7565],[54.378,12.8035],[54.282,12.857],[54.1465,12.897],[54.0515,12.8975],[53.951,12.848],[53.8635,12.8465],[53.812,12.8315],[53.7545,12.8735],[53.6955,12.897],[53.555,12.913],[53.4695,12.9095],[53.3965,12.8845],[53.266,12.8075],[53.203,12.834],[53.1035,12.831],[53.048,12.807],[52.9975,12.7625],[52.9695,12.7175],[52.9525,12.6555],[52.96,12.579],[53.0145,12.491],[53.058,12.46],[53.126,12.4375],[53.172,12.3795],[53.159,12.356],[53.056,12.3785],[52.977,12.376],[52.891,12.349],[52.8155,12.289],[52.7775,12.207],[52.7735,12.1585]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/89/Flag_of_Yemen.svg","name:en":"Yemen","wikidata":"Q805","ISO3166-1:alpha2":"YE","ISO3166-1:alpha3":"YEM","ISO3166-1:numeric":"887"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[55.999,41.32],[55.8765,41.332],[55.774,41.284],[55.7435,41.302],[55.613,41.2705],[55.5675,41.2885],[55.4995,41.2515],[55.3155,41.391],[55.2115,41.5145],[55.1155,41.611],[55.066,41.6995],[54.95,41.833],[54.952,41.9065],[54.7795,42.0525],[54.218,42.379],[53.5705,42.289],[52.985,42.121],[52.9345,42.093],[52.497,41.7975],[52.45,41.762],[52.335,41.7195],[52.472,41.626],[52.422,41.491],[52.4735,41.4445],[52.639,41.346],[52.7265,41.163],[52.725,41.048],[52.8125,40.958],[52.7345,40.7515],[52.717,40.6685],[52.63,40.579],[52.57,40.4255],[52.553,40.262],[52.619,40.161],[52.59,40.0305],[52.6335,39.9595],[52.7965,39.7465],[52.997,39.7565],[53.036,39.737],[53.0855,39.596],[52.9835,39.4805],[52.9665,39.375],[53.0445,39.248],[52.9475,39.1145],[52.916,38.9765],[52.924,38.856],[52.9725,38.749],[53.1305,38.753],[53.2855,38.902],[53.5675,39.0065],[53.7495,38.966],[53.869,38.931],[53.865,38.8865],[53.764,38.702],[53.714,38.5415],[53.755,38.3705],[53.739,38.1695],[53.7075,37.896],[53.722,37.708],[53.735,37.6595],[53.8465,37.379],[53.8965,37.3475],[54.2445,37.32],[54.285,37.352],[54.3975,37.3605],[54.4875,37.418],[54.5825,37.4585],[54.6735,37.437],[54.7315,37.488],[54.7985,37.522],[54.819,37.6005],[54.7885,37.647],[54.843,37.745],[54.942,37.79],[55.0395,37.8635],[55.127,37.9455],[55.2735,37.9905],[55.3845,38.042],[55.443,38.086],[55.7485,38.1255],[55.842,38.102],[56.0215,38.0775],[56.173,38.0945],[56.216,38.072],[56.303,38.083],[56.352,38.117],[56.3195,38.1745],[56.333,38.1975],[56.4245,38.2545],[56.5465,38.266],[56.614,38.2405],[56.664,38.2685],[56.7565,38.285],[56.7925,38.2515],[56.91,38.2145],[56.992,38.2145],[57.051,38.1935],[57.1345,38.236],[57.161,38.272],[57.2465,38.2665],[57.373,38.0755],[57.3485,37.999],[57.458,37.938],[57.512,37.9195],[57.5795,37.938],[57.6285,37.922],[57.7205,37.922],[57.796,37.8995],[57.8255,37.863],[57.8915,37.871],[58.028,37.806],[58.155,37.7935],[58.2035,37.7755],[58.229,37.7295],[58.227,37.684],[58.3595,37.661],[58.3885,37.627],[58.498,37.648],[58.55,37.706],[58.6655,37.655],[58.713,37.6485],[58.8045,37.667],[58.836,37.6995],[58.8765,37.669],[58.926,37.67],[59.0605,37.63],[59.229,37.512],[59.3535,37.5285],[59.392,37.479],[59.378,37.4075],[59.397,37.3175],[59.435,37.304],[59.538,37.1855],[59.558,37.1315],[59.6265,37.1185],[59.6535,37.142],[59.772,37.1255],[59.931,37.0425],[59.9815,37.047],[60.043,37.021],[60.085,36.978],[60.0945,36.9365],[60.1695,36.848],[60.215,36.8205],[60.267,36.757],[60.3455,36.6295],[60.6085,36.628],[60.675,36.622],[61.146,36.6465],[61.1855,36.5495],[61.157,36.4865],[61.1665,36.4135],[61.1425,36.393],[61.1615,36.297],[61.2265,36.1665],[61.2285,36.1125],[61.164,36.033],[61.1835,35.943],[61.241,35.8855],[61.262,35.8135],[61.226,35.6505],[61.274,35.605],[61.3605,35.6295],[61.3855,35.569],[61.45,35.5205],[61.588,35.437],[61.7795,35.411],[61.968,35.454],[62.0645,35.4345],[62.1535,35.341],[62.2655,35.2955],[62.291,35.256],[62.2985,35.138],[62.326,35.145],[62.4775,35.279],[62.611,35.2345],[62.713,35.2395],[62.7855,35.301],[62.824,35.3],[62.8775,35.345],[63.016,35.4125],[63.1025,35.4285],[63.13,35.544],[63.095,35.6185],[63.1115,35.6335],[63.249,35.681],[63.195,35.713],[63.109,35.827],[63.121,35.862],[63.299,35.8565],[63.5005,35.8985],[63.5365,35.948],[63.7035,35.9675],[63.989,36.0365],[64.0685,35.9975],[64.0595,36.0985],[64.17,36.163],[64.284,36.1515],[64.3155,36.208],[64.445,36.2425],[64.58,36.3515],[64.6365,36.4425],[64.6185,36.6365],[64.707,36.796],[64.7975,36.922],[64.7555,37.1125],[64.99,37.218],[65.1235,37.244],[65.1905,37.236],[65.2285,37.251],[65.2835,37.228],[65.556,37.2405],[65.6435,37.3295],[65.646,37.4385],[65.706,37.5395],[65.803,37.523],[65.8185,37.5],[65.894,37.4755],[65.974,37.467],[66.085,37.4395],[66.167,37.3695],[66.246,37.356],[66.307,37.32],[66.431,37.319],[66.5515,37.3545],[66.531,37.403],[66.5825,37.431],[66.5725,37.506],[66.5255,37.558],[66.55,37.6965],[66.548,37.792],[66.607,37.8685],[66.6895,37.918],[66.685,37.9685],[66.511,38.032],[66.4275,38.0235],[66.3235,38.0655],[66.2725,38.1075],[66.248,38.1555],[66.1665,38.157],[66.0295,38.227],[65.9565,38.2385],[65.913,38.277],[65.842,38.253],[65.564,38.2885],[65.171,38.5025],[65.0375,38.6055],[64.996,38.6115],[64.897,38.671],[64.8205,38.683],[64.717,38.752],[64.664,38.771],[64.525,38.847],[64.355,38.9765],[64.3135,38.966],[64.181,38.962],[64.0085,39.0535],[63.705,39.224],[63.694,39.2725],[63.565,39.3375],[63.2775,39.5035],[62.985,39.6635],[62.798,39.776],[62.488,39.9515],[62.4425,39.991],[62.427,40.065],[62.3965,40.0995],[62.414,40.1735],[62.3895,40.2445],[62.3915,40.318],[62.333,40.3835],[62.3495,40.4385],[62.2075,40.5085],[62.144,40.5545],[62.091,40.657],[62.0455,40.712],[62.042,40.7575],[61.9855,40.837],[62.0,40.8925],[61.971,41.019],[61.901,41.0535],[61.8855,41.107],[61.7565,41.1755],[61.713,41.215],[61.609,41.256],[61.481,41.2865],[61.4085,41.288],[61.3995,41.2015],[61.3305,41.148],[61.2405,41.1455],[61.08,41.2165],[61.065,41.2545],[60.999,41.2425],[60.816,41.259],[60.681,41.2555],[60.579,41.2235],[60.476,41.2215],[60.4055,41.253],[60.2765,41.3305],[60.23,41.337],[60.093,41.413],[60.074,41.4575],[60.104,41.542],[60.141,41.556],[60.177,41.607],[60.1455,41.6585],[60.082,41.7035],[60.0465,41.751],[60.0795,41.799],[60.1275,41.807],[60.2375,41.7665],[60.326,41.7685],[60.265,41.8155],[60.1645,41.85],[60.104,41.9035],[60.043,41.909],[60.01,41.9555],[59.97,41.9405],[59.9165,41.9915],[59.9505,42.0195],[60.0105,41.991],[60.041,42.0265],[60.0205,42.118],[59.9715,42.1575],[60.0205,42.1875],[59.955,42.2315],[59.9265,42.2775],[59.775,42.272],[59.717,42.291],[59.609,42.2975],[59.4475,42.29],[59.418,42.325],[59.305,42.361],[59.269,42.431],[59.172,42.531],[59.0765,42.519],[59.0145,42.527],[58.8715,42.6115],[58.747,42.7115],[58.6725,42.7605],[58.612,42.7035],[58.59,42.6445],[58.4675,42.6375],[58.3615,42.6745],[58.281,42.685],[58.1565,42.6215],[58.2275,42.5735],[58.3065,42.5485],[58.364,42.449],[58.426,42.38],[58.523,42.3185],[58.52,42.2735],[58.446,42.2955],[58.4005,42.3395],[58.3625,42.421],[58.3035,42.455],[58.1375,42.4805],[58.04,42.504],[57.904,42.426],[57.9475,42.3715],[57.9285,42.245],[57.847,42.2465],[57.835,42.1695],[57.7645,42.1695],[57.655,42.1375],[57.5525,42.1505],[57.356,42.1435],[57.2655,42.112],[57.214,42.0685],[57.1675,41.975],[57.13,41.9435],[57.0015,41.896],[56.9675,41.8045],[56.972,41.6725],[57.02,41.5865],[57.0315,41.446],[57.0865,41.375],[57.089,41.3345],[57.0425,41.263],[56.7875,41.2805],[56.5595,41.289],[56.4325,41.3],[55.999,41.32]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/1b/Flag_of_Turkmenistan.svg","name:en":"Turkmenistan","wikidata":"Q874","ISO3166-1:alpha2":"TM","ISO3166-1:alpha3":"TKM","ISO3166-1:numeric":"795"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[66.5515,37.3545],[66.5935,37.3685],[66.652,37.3235],[66.6925,37.357],[66.801,37.3635],[66.85,37.354],[66.95,37.3985],[67.045,37.3805],[67.1125,37.327],[67.1065,37.2915],[67.2235,37.244],[67.27,37.182],[67.453,37.2365],[67.517,37.265],[67.558,37.2225],[67.7235,37.219],[67.787,37.1855],[67.842,37.3285],[67.801,37.388],[67.8305,37.5445],[67.8525,37.6115],[67.9265,37.647],[68.0165,37.707],[68.12,37.8715],[68.143,37.933],[68.218,37.9335],[68.2705,37.915],[68.3075,38.029],[68.377,38.0845],[68.4055,38.1805],[68.356,38.2325],[68.3025,38.2555],[68.2875,38.3055],[68.157,38.374],[68.1375,38.41],[68.065,38.41],[68.1165,38.468],[68.064,38.5325],[68.0825,38.6725],[68.058,38.7075],[68.1285,38.7365],[68.095,38.814],[68.1715,38.831],[68.2015,38.867],[68.195,38.94],[68.1345,38.963],[68.0945,39.023],[68.028,39.01],[67.9215,39.0265],[67.869,39.0015],[67.768,39.016],[67.6985,39.003],[67.6685,39.0845],[67.677,39.1465],[67.584,39.1885],[67.464,39.1965],[67.399,39.226],[67.344,39.3085],[67.449,39.3125],[67.4785,39.399],[67.4325,39.53],[67.456,39.5745],[67.629,39.6135],[67.7045,39.658],[67.761,39.64],[67.793,39.657],[67.939,39.599],[67.976,39.605],[68.0385,39.5775],[68.1965,39.5545],[68.2865,39.5595],[68.3695,39.53],[68.391,39.5445],[68.524,39.532],[68.575,39.619],[68.6175,39.6375],[68.626,39.6955],[68.587,39.722],[68.6425,39.7765],[68.63,39.8545],[68.746,39.846],[68.828,39.9035],[68.8855,39.863],[68.928,39.9305],[68.8575,40.0465],[68.9685,40.065],[69.0085,40.099],[69.024,40.1455],[68.9405,40.147],[68.766,40.098],[68.633,40.0765],[68.531,40.118],[68.533,40.144],[68.7795,40.204],[68.7975,40.1725],[68.863,40.21],[69.0355,40.2285],[69.1895,40.215],[69.3055,40.195],[69.3075,40.282],[69.3365,40.349],[69.303,40.3675],[69.2715,40.488],[69.212,40.541],[69.2625,40.5765],[69.347,40.5855],[69.33,40.699],[69.3645,40.744],[69.3475,40.775],[69.4585,40.785],[69.5515,40.7695],[69.5755,40.7185],[69.6695,40.634],[69.7205,40.6285],[69.765,40.6515],[69.793,40.7015],[69.9315,40.7165],[70.068,40.755],[70.1205,40.8165],[70.2015,40.822],[70.2785,40.871],[70.372,40.898],[70.3955,41.027],[70.4695,41.042],[70.556,40.979],[70.6455,40.865],[70.6985,40.8355],[70.7275,40.769],[70.796,40.7325],[70.7375,40.664],[70.64,40.6265],[70.588,40.5665],[70.514,40.5495],[70.483,40.5015],[70.328,40.455],[70.379,40.3865],[70.4765,40.352],[70.552,40.355],[70.5775,40.336],[70.5795,40.2345],[70.6325,40.1775],[70.76,40.188],[70.894,40.2315],[70.897,40.312],[70.9815,40.3215],[71.0325,40.306],[71.1245,40.3355],[71.274,40.3435],[71.308,40.3085],[71.369,40.319],[71.428,40.284],[71.5115,40.268],[71.513,40.231],[71.6165,40.2065],[71.62,40.267],[71.6985,40.2445],[71.6895,40.1875],[71.72,40.1535],[71.8285,40.241],[71.8845,40.2625],[71.9785,40.2565],[71.9665,40.3195],[72.089,40.405],[72.087,40.451],[72.159,40.483],[72.2535,40.479],[72.278,40.434],[72.321,40.446],[72.4105,40.401],[72.441,40.4735],[72.42,40.549],[72.3855,40.604],[72.4095,40.619],[72.476,40.551],[72.5055,40.5605],[72.613,40.5175],[72.6695,40.5235],[72.6925,40.597],[72.757,40.622],[72.8015,40.6775],[72.9465,40.732],[72.9905,40.7645],[73.1395,40.7855],[73.1375,40.8275],[73.0895,40.8495],[73.014,40.845],[72.939,40.8005],[72.832,40.8565],[72.7125,40.8485],[72.5915,40.868],[72.593,40.905],[72.5515,40.962],[72.4895,40.976],[72.444,41.032],[72.3305,41.037],[72.2465,41.004],[72.1715,40.995],[72.2085,41.0595],[72.137,41.1625],[72.074,41.1215],[71.8865,41.168],[71.862,41.201],[71.925,41.294],[71.831,41.3875],[71.7595,41.4355],[71.711,41.4875],[71.6695,41.4975],[71.681,41.422],[71.6365,41.3425],[71.569,41.293],[71.4705,41.297],[71.4425,41.248],[71.4515,41.157],[71.3955,41.1075],[71.3465,41.127],[71.2795,41.102],[71.2725,41.1735],[71.2315,41.1925],[71.127,41.1435],[71.039,41.1905],[70.9625,41.166],[70.841,41.251],[70.776,41.2165],[70.7785,41.3885],[70.721,41.442],[70.666,41.47],[70.488,41.398],[70.4075,41.4705],[70.303,41.5205],[70.2405,41.4915],[70.172,41.5175],[70.213,41.611],[70.263,41.6075],[70.367,41.6475],[70.3965,41.684],[70.4965,41.7195],[70.5275,41.7985],[70.5965,41.818],[70.665,41.907],[70.854,41.9415],[70.838,41.9995],[70.865,42.054],[70.9925,42.0305],[71.029,42.0675],[71.174,42.144],[71.218,42.137],[71.269,42.1965],[71.1335,42.282],[71.025,42.2925],[70.9885,42.2525],[70.9435,42.2635],[70.8835,42.2105],[70.7985,42.2075],[70.687,42.121],[70.6345,42.0155],[70.5595,42.0235],[70.55,42.0675],[70.476,42.1095],[70.32,42.037],[70.3355,41.9745],[70.2615,41.9545],[70.1575,41.8495],[70.077,41.8085],[69.981,41.781],[69.9575,41.734],[69.8825,41.7065],[69.839,41.7205],[69.7455,41.701],[69.696,41.673],[69.6175,41.662],[69.501,41.547],[69.4455,41.5635],[69.4005,41.5035],[69.301,41.438],[69.25,41.4665],[69.1565,41.4345],[69.1665,41.395],[69.0415,41.366],[69.0395,41.255],[68.9915,41.214],[68.804,41.116],[68.714,41.032],[68.7485,40.9815],[68.6435,40.943],[68.6285,40.9975],[68.5895,41.029],[68.5265,41.0205],[68.4905,40.9715],[68.579,40.925],[68.5905,40.865],[68.5625,40.806],[68.586,40.78],[68.584,40.709],[68.644,40.694],[68.652,40.614],[68.6105,40.577],[68.502,40.5795],[68.371,40.6175],[68.218,40.6875],[68.077,40.789],[67.9775,40.831],[68.0125,40.8905],[68.0885,40.9255],[68.088,40.97],[68.0555,41.009],[68.111,41.036],[68.071,41.0805],[68.0205,41.0205],[67.9835,41.025],[67.9885,41.0855],[67.9655,41.149],[67.8665,41.1365],[67.7235,41.197],[67.3125,41.1355],[66.7095,41.1425],[66.6455,41.3475],[66.6085,41.494],[66.5355,41.8785],[65.9995,41.9395],[66.0,42.36],[66.088,42.3465],[66.095,42.566],[66.08,42.933],[65.8655,42.8675],[65.742,43.0],[65.5595,43.2895],[65.4955,43.333],[65.185,43.495],[65.002,43.7155],[64.9325,43.7355],[64.535,43.5705],[63.8575,43.5995],[63.349,43.6505],[62.2425,43.5185],[62.004,43.5055],[61.4255,43.9995],[61.138,44.226],[61.1065,44.3605],[61.068,44.3705],[60.7445,44.644],[59.9745,44.968],[59.5055,45.161],[58.9905,45.3695],[58.5885,45.5905],[57.9045,45.442],[57.0005,45.2375],[55.9985,45.0005],[55.999,44.437],[55.999,43.7535],[55.999,41.32],[56.4325,41.3],[56.5595,41.289],[56.7875,41.2805],[57.0425,41.263],[57.089,41.3345],[57.0865,41.375],[57.0315,41.446],[57.02,41.5865],[56.972,41.6725],[56.9675,41.8045],[57.0015,41.896],[57.13,41.9435],[57.1675,41.975],[57.214,42.0685],[57.2655,42.112],[57.356,42.1435],[57.5525,42.1505],[57.655,42.1375],[57.7645,42.1695],[57.835,42.1695],[57.847,42.2465],[57.9285,42.245],[57.9475,42.3715],[57.904,42.426],[58.04,42.504],[58.1375,42.4805],[58.3035,42.455],[58.3625,42.421],[58.4005,42.3395],[58.446,42.2955],[58.52,42.2735],[58.523,42.3185],[58.426,42.38],[58.364,42.449],[58.3065,42.5485],[58.2275,42.5735],[58.1565,42.6215],[58.281,42.685],[58.3615,42.6745],[58.4675,42.6375],[58.59,42.6445],[58.612,42.7035],[58.6725,42.7605],[58.747,42.7115],[58.8715,42.6115],[59.0145,42.527],[59.0765,42.519],[59.172,42.531],[59.269,42.431],[59.305,42.361],[59.418,42.325],[59.4475,42.29],[59.609,42.2975],[59.717,42.291],[59.775,42.272],[59.9265,42.2775],[59.955,42.2315],[60.0205,42.1875],[59.9715,42.1575],[60.0205,42.118],[60.041,42.0265],[60.0105,41.991],[59.9505,42.0195],[59.9165,41.9915],[59.97,41.9405],[60.01,41.9555],[60.043,41.909],[60.104,41.9035],[60.1645,41.85],[60.265,41.8155],[60.326,41.7685],[60.2375,41.7665],[60.1275,41.807],[60.0795,41.799],[60.0465,41.751],[60.082,41.7035],[60.1455,41.6585],[60.177,41.607],[60.141,41.556],[60.104,41.542],[60.074,41.4575],[60.093,41.413],[60.23,41.337],[60.2765,41.3305],[60.4055,41.253],[60.476,41.2215],[60.579,41.2235],[60.681,41.2555],[60.816,41.259],[60.999,41.2425],[61.065,41.2545],[61.08,41.2165],[61.2405,41.1455],[61.3305,41.148],[61.3995,41.2015],[61.4085,41.288],[61.481,41.2865],[61.609,41.256],[61.713,41.215],[61.7565,41.1755],[61.8855,41.107],[61.901,41.0535],[61.971,41.019],[62.0,40.8925],[61.9855,40.837],[62.042,40.7575],[62.0455,40.712],[62.091,40.657],[62.144,40.5545],[62.2075,40.5085],[62.3495,40.4385],[62.333,40.3835],[62.3915,40.318],[62.3895,40.2445],[62.414,40.1735],[62.3965,40.0995],[62.427,40.065],[62.4425,39.991],[62.488,39.9515],[62.798,39.776],[62.985,39.6635],[63.2775,39.5035],[63.565,39.3375],[63.694,39.2725],[63.705,39.224],[64.0085,39.0535],[64.181,38.962],[64.3135,38.966],[64.355,38.9765],[64.525,38.847],[64.664,38.771],[64.717,38.752],[64.8205,38.683],[64.897,38.671],[64.996,38.6115],[65.0375,38.6055],[65.171,38.5025],[65.564,38.2885],[65.842,38.253],[65.913,38.277],[65.9565,38.2385],[66.0295,38.227],[66.1665,38.157],[66.248,38.1555],[66.2725,38.1075],[66.3235,38.0655],[66.4275,38.0235],[66.511,38.032],[66.685,37.9685],[66.6895,37.918],[66.607,37.8685],[66.548,37.792],[66.55,37.6965],[66.5255,37.558],[66.5725,37.506],[66.5825,37.431],[66.531,37.403],[66.5515,37.3545]]],[[[71.036,40.1805],[71.0535,40.0925],[71.085,40.0755],[71.103,40.026],[71.1145,40.014],[71.0875,39.9885],[71.155,39.933],[71.21,39.9545],[71.115,40.0205],[71.0875,40.07],[71.091,40.1045],[71.076,40.1505],[71.036,40.1805]]],[[[71.7145,39.966],[71.8305,39.955],[71.785,39.999],[71.7145,39.966]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/84/Flag_of_Uzbekistan.svg","name:en":"Uzbekistan","wikidata":"Q265","ISO3166-1:alpha2":"UZ","ISO3166-1:alpha3":"UZB","ISO3166-1:numeric":"860"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[67.787,37.1855],[67.7905,37.086],[67.8895,37.0565],[67.9105,37.0145],[67.972,36.9805],[68.0155,36.9255],[68.0515,36.9285],[68.174,37.0145],[68.253,37.005],[68.2885,37.0315],[68.2905,37.09],[68.3155,37.1105],[68.39,37.098],[68.406,37.145],[68.543,37.167],[68.617,37.1985],[68.6715,37.2755],[68.826,37.2695],[68.8085,37.3065],[68.962,37.325],[68.9995,37.308],[69.0295,37.2565],[69.108,37.1865],[69.2535,37.0935],[69.3235,37.118],[69.37,37.166],[69.4035,37.168],[69.425,37.246],[69.393,37.36],[69.371,37.379],[69.3895,37.4495],[69.457,37.494],[69.511,37.5805],[69.6225,37.5695],[69.7135,37.5745],[69.7625,37.5915],[69.802,37.569],[69.8415,37.6035],[69.9405,37.608],[69.998,37.567],[70.1125,37.5245],[70.145,37.525],[70.266,37.6115],[70.261,37.6395],[70.3005,37.7035],[70.2795,37.816],[70.1855,37.85],[70.171,37.93],[70.262,37.9375],[70.291,37.9875],[70.3285,37.999],[70.4315,38.0995],[70.4925,38.1215],[70.5455,38.2435],[70.6055,38.283],[70.611,38.3465],[70.6845,38.364],[70.674,38.4045],[70.7565,38.428],[70.771,38.4565],[70.856,38.4415],[70.956,38.439],[70.9885,38.491],[71.0315,38.461],[71.0465,38.4105],[71.163,38.388],[71.1835,38.347],[71.252,38.3105],[71.3285,38.306],[71.3745,38.2555],[71.3215,38.0675],[71.2755,38.006],[71.261,37.9215],[71.3135,37.919],[71.3275,37.887],[71.524,37.953],[71.591,37.9235],[71.596,37.8075],[71.532,37.7615],[71.5515,37.7365],[71.526,37.6315],[71.5045,37.607],[71.4955,37.5335],[71.5265,37.48],[71.5035,37.451],[71.4865,37.336],[71.485,37.245],[71.4535,37.207],[71.432,37.0565],[71.4625,37.0235],[71.468,36.9515],[71.513,36.898],[71.563,36.764],[71.635,36.69],[71.6755,36.671],[71.8435,36.6805],[71.903,36.734],[71.958,36.756],[72.0185,36.811],[72.193,36.906],[72.209,36.9245],[72.3255,36.9815],[72.441,37.0065],[72.4735,36.9945],[72.5695,37.0075],[72.622,37.029],[72.6625,37.0175],[72.7395,37.119],[72.7755,37.195],[72.818,37.2325],[72.891,37.243],[72.9525,37.2905],[73.094,37.325],[73.1495,37.4045],[73.21,37.404],[73.3005,37.462],[73.3835,37.4465],[73.452,37.474],[73.5135,37.4745],[73.6405,37.4335],[73.7195,37.447],[73.776,37.44],[73.7705,37.344],[73.7325,37.3155],[73.671,37.31],[73.6305,37.2495],[73.843,37.234],[73.852,37.2575],[73.965,37.299],[74.0165,37.2915],[74.0635,37.3125],[74.185,37.3345],[74.276,37.402],[74.375,37.4245],[74.4015,37.392],[74.482,37.413],[74.5575,37.397],[74.566,37.3725],[74.674,37.389],[74.804,37.3555],[74.887,37.258],[74.89,37.234],[74.9105,37.275],[75.1285,37.323],[75.096,37.368],[75.1485,37.421],[75.0575,37.5245],[75.0315,37.501],[74.932,37.5685],[74.9395,37.603],[74.897,37.6655],[74.967,37.752],[74.952,37.809],[74.913,37.8565],[74.9165,38.0245],[74.8685,38.0255],[74.8205,38.0855],[74.8,38.2025],[74.698,38.228],[74.706,38.2825],[74.6655,38.3805],[74.6955,38.425],[74.6505,38.446],[74.5065,38.4715],[74.2845,38.5985],[74.187,38.6405],[74.1215,38.6415],[74.0745,38.611],[74.0395,38.544],[73.9895,38.5245],[73.9235,38.5425],[73.8985,38.581],[73.8035,38.612],[73.805,38.664],[73.744,38.732],[73.768,38.778],[73.699,38.878],[73.7575,38.9425],[73.8065,38.933],[73.854,38.9525],[73.8125,39.043],[73.751,39.0255],[73.7205,39.112],[73.662,39.165],[73.6135,39.2475],[73.569,39.244],[73.535,39.323],[73.5585,39.355],[73.526,39.3915],[73.592,39.4115],[73.6005,39.4595],[73.505,39.4735],[73.3935,39.4525],[73.353,39.3935],[73.2525,39.381],[73.1605,39.3525],[73.1065,39.3765],[72.959,39.3465],[72.7825,39.362],[72.694,39.396],[72.621,39.399],[72.589,39.3595],[72.493,39.38],[72.4625,39.35],[72.3425,39.332],[72.3,39.2925],[72.271,39.1895],[72.2195,39.1825],[72.202,39.2415],[72.1535,39.2735],[72.089,39.278],[72.0355,39.3665],[71.958,39.3315],[71.919,39.2805],[71.802,39.2735],[71.7525,39.324],[71.804,39.403],[71.761,39.4565],[71.633,39.4455],[71.5655,39.457],[71.544,39.505],[71.565,39.576],[71.5145,39.6115],[71.413,39.571],[71.3355,39.5685],[71.3075,39.5235],[71.2585,39.549],[71.1935,39.5115],[71.0895,39.499],[71.072,39.4255],[71.0165,39.3955],[70.941,39.4335],[70.9125,39.3835],[70.768,39.3995],[70.7435,39.497],[70.6925,39.52],[70.65,39.582],[70.606,39.586],[70.525,39.622],[70.4645,39.583],[70.3895,39.582],[70.3295,39.562],[70.309,39.53],[70.239,39.538],[70.2065,39.5785],[70.168,39.554],[70.127,39.5865],[69.996,39.537],[69.978,39.568],[69.9015,39.576],[69.867,39.5295],[69.8285,39.56],[69.7375,39.595],[69.678,39.5805],[69.6295,39.593],[69.574,39.553],[69.448,39.5285],[69.408,39.5495],[69.3375,39.5425],[69.3265,39.7205],[69.265,39.806],[69.327,39.877],[69.297,39.9205],[69.3945,40.0025],[69.432,39.9885],[69.4575,39.935],[69.5355,39.9525],[69.507,40.034],[69.537,40.117],[69.582,40.1045],[69.6755,40.1225],[69.784,40.1795],[69.9955,40.2345],[70.021,40.2305],[70.1755,40.143],[70.241,40.124],[70.292,40.1295],[70.358,40.081],[70.4245,40.0575],[70.498,40.054],[70.5675,40.0305],[70.6095,40.043],[70.6575,40.11],[70.7685,40.1165],[70.7995,40.1475],[70.8855,40.188],[70.894,40.2315],[70.76,40.188],[70.6325,40.1775],[70.5795,40.2345],[70.5775,40.336],[70.552,40.355],[70.4765,40.352],[70.379,40.3865],[70.328,40.455],[70.483,40.5015],[70.514,40.5495],[70.588,40.5665],[70.64,40.6265],[70.7375,40.664],[70.796,40.7325],[70.7275,40.769],[70.6985,40.8355],[70.6455,40.865],[70.556,40.979],[70.4695,41.042],[70.3955,41.027],[70.372,40.898],[70.2785,40.871],[70.2015,40.822],[70.1205,40.8165],[70.068,40.755],[69.9315,40.7165],[69.793,40.7015],[69.765,40.6515],[69.7205,40.6285],[69.6695,40.634],[69.5755,40.7185],[69.5515,40.7695],[69.4585,40.785],[69.3475,40.775],[69.3645,40.744],[69.33,40.699],[69.347,40.5855],[69.2625,40.5765],[69.212,40.541],[69.2715,40.488],[69.303,40.3675],[69.3365,40.349],[69.3075,40.282],[69.3055,40.195],[69.1895,40.215],[69.0355,40.2285],[68.863,40.21],[68.7975,40.1725],[68.7795,40.204],[68.533,40.144],[68.531,40.118],[68.633,40.0765],[68.766,40.098],[68.9405,40.147],[69.024,40.1455],[69.0085,40.099],[68.9685,40.065],[68.8575,40.0465],[68.928,39.9305],[68.8855,39.863],[68.828,39.9035],[68.746,39.846],[68.63,39.8545],[68.6425,39.7765],[68.587,39.722],[68.626,39.6955],[68.6175,39.6375],[68.575,39.619],[68.524,39.532],[68.391,39.5445],[68.3695,39.53],[68.2865,39.5595],[68.1965,39.5545],[68.0385,39.5775],[67.976,39.605],[67.939,39.599],[67.793,39.657],[67.761,39.64],[67.7045,39.658],[67.629,39.6135],[67.456,39.5745],[67.4325,39.53],[67.4785,39.399],[67.449,39.3125],[67.344,39.3085],[67.399,39.226],[67.464,39.1965],[67.584,39.1885],[67.677,39.1465],[67.6685,39.0845],[67.6985,39.003],[67.768,39.016],[67.869,39.0015],[67.9215,39.0265],[68.028,39.01],[68.0945,39.023],[68.1345,38.963],[68.195,38.94],[68.2015,38.867],[68.1715,38.831],[68.095,38.814],[68.1285,38.7365],[68.058,38.7075],[68.0825,38.6725],[68.064,38.5325],[68.1165,38.468],[68.065,38.41],[68.1375,38.41],[68.157,38.374],[68.2875,38.3055],[68.3025,38.2555],[68.356,38.2325],[68.4055,38.1805],[68.377,38.0845],[68.3075,38.029],[68.2705,37.915],[68.218,37.9335],[68.143,37.933],[68.12,37.8715],[68.0165,37.707],[67.9265,37.647],[67.8525,37.6115],[67.8305,37.5445],[67.801,37.388],[67.842,37.3285],[67.787,37.1855]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/d0/Flag_of_Tajikistan.svg","name:en":"Tajikistan","wikidata":"Q863","ISO3166-1:alpha2":"TJ","ISO3166-1:alpha3":"TJK","ISO3166-1:numeric":"762"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[10.593,58.761],[10.6365,58.5175],[10.672,58.4505],[10.845,58.258],[10.962,58.0375],[11.1605,57.7005],[11.4065,57.4525],[11.636,57.152],[11.9265,56.9575],[12.022,56.838],[12.0915,56.7805],[12.227,56.707],[12.2995,56.637],[12.1775,56.4795],[12.1075,56.369],[12.088,56.304],[12.368,56.214],[12.642,56.057],[12.6525,55.9265],[12.7085,55.827],[12.896,55.6435],[12.8815,55.614],[12.7295,55.541],[12.7155,55.489],[12.6105,55.4315],[12.642,55.3375],[12.677,55.25],[12.795,55.1665],[12.876,55.135],[13.013,55.168],[13.3435,55.1335],[13.4585,55.141],[13.6105,55.181],[13.7915,55.2165],[13.848,55.215],[13.99,55.18],[14.178,55.173],[14.2895,55.1845],[14.6985,55.4675],[14.7195,55.5385],[14.7015,55.619],[14.5915,55.7555],[14.8045,55.7945],[14.959,55.808],[15.1135,55.861],[15.153,55.898],[15.299,55.889],[15.4915,55.783],[15.6255,55.7485],[15.7655,55.7475],[15.855,55.7635],[15.9565,55.8025],[16.032,55.854],[16.6065,56.028],[16.783,56.124],[16.8755,56.2185],[16.9345,56.3625],[16.989,56.463],[17.066,56.5685],[17.098,56.6545],[17.214,56.782],[17.4225,57.1125],[17.443,57.177],[17.499,57.241],[17.5205,57.3115],[17.5055,57.366],[17.4425,57.458],[17.261,57.615],[17.279,57.7215],[17.2435,57.8265],[17.528,58.241],[17.577,58.397],[18.1305,58.5265],[18.193,58.545],[18.829,58.798],[19.188,58.982],[19.4635,59.1565],[19.7295,59.253],[19.843,59.3155],[20.014,59.5425],[19.9405,59.595],[19.6585,59.7915],[19.083,60.1915],[19.161,60.375],[19.1965,60.517],[19.0985,60.5805],[19.0275,60.605],[18.242,60.8135],[17.8895,60.941],[17.7755,61.172],[17.818,61.2525],[17.8885,61.507],[17.9815,61.695],[18.069,61.979],[18.296,62.4175],[18.41,62.479],[18.9705,62.8195],[19.4325,63.0735],[19.821,63.13],[20.276,63.2435],[20.401,63.332],[20.6965,63.483],[20.9385,63.5195],[21.376,63.633],[21.457,63.753],[21.476,63.8165],[21.4045,63.957],[21.5095,64.041],[21.8515,64.194],[21.9455,64.2545],[22.071,64.386],[22.0895,64.4465],[22.065,64.5205],[21.825,64.8365],[21.91,64.888],[22.1365,64.9555],[22.8335,65.1025],[23.018,65.1715],[23.13,65.2855],[23.6405,65.3215],[24.085,65.3915],[24.1445,65.3955],[24.132,65.5155],[24.1775,65.6605],[24.172,65.7255],[24.132,65.7715],[24.153,65.8625],[24.042,65.9635],[24.0375,66.009],[23.9365,66.0795],[23.916,66.162],[23.7335,66.206],[23.646,66.3005],[23.689,66.3875],[23.65,66.454],[23.8605,66.5595],[23.8685,66.657],[23.908,66.7215],[23.8795,66.762],[23.978,66.784],[23.9945,66.8235],[23.864,66.922],[23.8565,66.956],[23.674,67.065],[23.6535,67.104],[23.557,67.166],[23.596,67.207],[23.5835,67.2695],[23.731,67.2875],[23.775,67.3395],[23.718,67.385],[23.7635,67.426],[23.5365,67.46],[23.4105,67.4675],[23.408,67.5015],[23.545,67.583],[23.559,67.6195],[23.493,67.664],[23.51,67.88],[23.641,67.915],[23.663,67.942],[23.531,68.0065],[23.3965,68.044],[23.2785,68.1575],[23.1415,68.1545],[23.153,68.231],[23.0705,68.2995],[22.918,68.3335],[22.804,68.393],[22.466,68.4415],[22.351,68.4805],[22.153,68.47],[22.018,68.496],[21.89,68.5845],[21.7015,68.5965],[21.7015,68.6305],[21.565,68.6755],[21.43,68.6915],[21.3895,68.765],[21.3195,68.7595],[21.234,68.814],[20.997,68.8965],[20.844,68.9365],[20.9135,68.9605],[20.775,69.0325],[20.5485,69.06],[20.06,69.046],[20.3065,68.926],[20.336,68.8025],[20.203,68.666],[20.0525,68.591],[19.9375,68.558],[20.2265,68.491],[19.9215,68.356],[18.984,68.517],[18.621,68.507],[18.4055,68.582],[18.126,68.5365],[18.101,68.406],[18.1515,68.199],[17.9,67.9695],[17.6645,68.0385],[17.2815,68.119],[17.1805,68.0505],[16.738,67.914],[16.556,67.647],[16.4075,67.534],[16.158,67.519],[16.09,67.4355],[16.404,67.205],[16.3875,67.0455],[16.194,66.9825],[16.039,66.9125],[15.6215,66.5945],[15.377,66.4845],[15.4845,66.2825],[15.0355,66.1535],[14.5165,66.1325],[14.5845,65.9015],[14.6255,65.812],[14.5415,65.7005],[14.499,65.5215],[14.507,65.3095],[14.379,65.2475],[14.326,65.119],[14.13,64.9785],[13.7055,64.64],[13.6545,64.5805],[13.891,64.507],[14.114,64.4625],[14.157,64.195],[13.9675,64.008],[13.7155,64.0465],[13.211,64.0955],[12.9265,64.058],[12.6835,63.974],[12.48,63.819],[12.3305,63.715],[12.2995,63.672],[12.15,63.594],[12.213,63.4785],[12.084,63.3555],[11.9745,63.269],[12.218,63.0005],[12.0745,62.9025],[12.1365,62.748],[12.056,62.612],[12.2995,62.2675],[12.1375,61.724],[12.4195,61.563],[12.5695,61.5685],[12.871,61.3565],[12.834,61.2585],[12.7905,61.197],[12.707,61.1435],[12.6825,61.061],[12.6105,61.0465],[12.4475,61.0505],[12.224,61.013],[12.333,60.89],[12.3345,60.8525],[12.3955,60.734],[12.511,60.6425],[12.516,60.6],[12.607,60.5125],[12.606,60.406],[12.499,60.3235],[12.542,60.1935],[12.5005,60.099],[12.4485,60.039],[12.341,59.9655],[12.231,59.9275],[12.1745,59.89],[11.9415,59.89],[11.8395,59.841],[11.926,59.794],[11.94,59.6945],[11.8555,59.6485],[11.7205,59.6255],[11.691,59.5895],[11.816,59.3445],[11.83,59.2425],[11.783,59.206],[11.775,59.0865],[11.7105,59.0335],[11.688,58.9555],[11.63,58.9085],[11.4555,58.8895],[11.4645,58.991],[11.3685,59.0985],[11.1535,59.0795],[11.117,59.015],[11.0665,58.9775],[10.918,58.9425],[10.639,58.8925],[10.593,58.761]]],[[[17.679,57.3085],[17.7325,57.202],[17.7825,57.0505],[17.756,56.9035],[17.796,56.8275],[17.924,56.75],[18.104,56.7105],[18.271,56.7085],[18.392,56.7275],[18.5345,56.7705],[18.659,56.8435],[19.002,57.1035],[19.287,57.308],[19.356,57.39],[19.3645,57.4725],[19.2935,57.5675],[19.6615,57.8395],[19.72,57.9045],[19.7345,57.9565],[19.7155,58.022],[19.6725,58.0695],[19.562,58.138],[19.4875,58.1655],[19.5745,58.204],[19.666,58.2715],[19.7085,58.3765],[19.671,58.453],[19.5985,58.507],[19.504,58.5495],[19.346,58.587],[19.1555,58.599],[18.9825,58.572],[18.8385,58.4965],[18.8,58.4475],[18.8,58.3395],[18.859,58.2595],[18.9755,58.1785],[18.623,58.1265],[18.362,58.0415],[18.3005,57.9495],[18.1765,57.8495],[17.958,57.7365],[17.8725,57.7095],[17.7795,57.6345],[17.743,57.5845],[17.679,57.3085]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/4c/Flag_of_Sweden.svg","name:en":"Sweden","wikidata":"Q34","ISO3166-1:alpha2":"SE","ISO3166-1:alpha3":"SWE","ISO3166-1:numeric":"752"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[22.5655,49.088],[22.5455,49.007],[22.4775,48.991],[22.4285,48.9315],[22.421,48.8845],[22.376,48.834],[22.3505,48.7715],[22.3395,48.684],[22.1895,48.61],[22.161,48.5675],[22.1375,48.4325],[22.1555,48.4035],[22.2155,48.4245],[22.2645,48.404],[22.2675,48.361],[22.315,48.3285],[22.369,48.245],[22.49,48.253],[22.566,48.179],[22.603,48.104],[22.6755,48.092],[22.7205,48.1155],[22.827,48.1155],[22.8815,48.055],[22.8365,47.99],[22.8975,47.954],[23.091,48.006],[23.1055,48.066],[23.1465,48.0995],[23.2695,48.086],[23.295,48.0445],[23.495,47.968],[23.539,48.0115],[23.6375,48.0025],[23.6655,47.9835],[23.751,47.9985],[23.8195,47.983],[23.882,47.9435],[24.01,47.9665],[24.217,47.903],[24.345,47.9145],[24.436,47.9705],[24.502,47.9525],[24.58,47.967],[24.674,47.8965],[24.6725,47.8635],[24.753,47.83],[24.8275,47.8205],[24.836,47.7795],[24.883,47.7245],[25.0405,47.7305],[25.113,47.756],[25.2215,47.859],[25.237,47.8955],[25.311,47.9145],[25.5925,47.9385],[25.6255,47.949],[25.775,47.9395],[25.861,47.9705],[25.952,47.971],[26.1845,47.9945],[26.214,48.0525],[26.2725,48.082],[26.335,48.1835],[26.46,48.2145],[26.529,48.21],[26.63,48.2595],[26.6485,48.305],[26.696,48.327],[26.7945,48.291],[26.824,48.3445],[26.765,48.3535],[26.775,48.418],[26.8515,48.413],[26.8945,48.3835],[26.9955,48.3595],[27.087,48.413],[27.124,48.379],[27.1925,48.395],[27.2865,48.3715],[27.3195,48.4435],[27.3825,48.411],[27.447,48.409],[27.465,48.4475],[27.581,48.491],[27.6435,48.442],[27.7475,48.458],[27.869,48.407],[27.882,48.373],[27.964,48.325],[28.042,48.326],[28.0935,48.2935],[28.0825,48.2375],[28.1825,48.2555],[28.2315,48.21],[28.303,48.2415],[28.361,48.2415],[28.383,48.175],[28.4635,48.074],[28.5445,48.169],[28.6775,48.143],[28.8335,48.129],[28.8555,48.108],[28.8395,48.035],[28.926,47.96],[28.9615,47.979],[29.026,47.9455],[29.0865,47.9465],[29.093,47.983],[29.1755,47.994],[29.2195,47.7985],[29.2485,47.7515],[29.2045,47.719],[29.231,47.684],[29.2175,47.6125],[29.117,47.5545],[29.182,47.449],[29.2425,47.462],[29.3175,47.449],[29.3375,47.3705],[29.3835,47.345],[29.3985,47.3005],[29.4855,47.306],[29.4875,47.356],[29.574,47.3705],[29.5985,47.2575],[29.552,47.2515],[29.58,47.136],[29.612,47.1],[29.596,46.9635],[29.648,46.9195],[29.731,46.9195],[29.7495,46.861],[29.884,46.886],[29.906,46.8205],[29.9755,46.7555],[29.971,46.685],[29.946,46.6485],[29.9685,46.595],[29.9265,46.502],[29.9925,46.501],[30.0235,46.442],[30.11,46.4315],[30.0915,46.383],[29.9385,46.4005],[29.8865,46.3715],[29.805,46.3855],[29.7765,46.4545],[29.686,46.426],[29.6775,46.361],[29.5805,46.361],[29.566,46.4165],[29.507,46.423],[29.502,46.4615],[29.4485,46.4985],[29.387,46.4465],[29.308,46.465],[29.2965,46.417],[29.2465,46.416],[29.2295,46.4585],[29.236,46.5585],[29.162,46.5445],[29.164,46.5155],[29.0385,46.506],[29.0255,46.4625],[28.931,46.4575],[28.9865,46.343],[28.9525,46.2595],[29.067,46.1955],[28.9505,46.0935],[29.0055,46.0495],[28.979,46.0035],[28.7765,45.9705],[28.755,45.9275],[28.786,45.8325],[28.697,45.818],[28.7095,45.78],[28.6245,45.766],[28.5895,45.729],[28.5195,45.736],[28.4805,45.678],[28.516,45.6655],[28.544,45.58],[28.491,45.571],[28.515,45.5],[28.421,45.513],[28.305,45.547],[28.214,45.467],[28.2865,45.4335],[28.2855,45.3995],[28.349,45.3205],[28.569,45.248],[28.714,45.2235],[28.7925,45.2435],[28.8165,45.3365],[28.9145,45.2875],[29.044,45.3605],[29.179,45.4],[29.238,45.4325],[29.294,45.428],[29.4295,45.4425],[29.589,45.39],[29.651,45.3395],[29.6905,45.1915],[29.952,45.1695],[29.9955,45.1145],[30.0455,45.0865],[30.166,45.055],[30.2405,45.055],[30.378,45.095],[30.4685,45.178],[30.488,45.282],[30.431,45.3785],[30.313,45.442],[30.166,45.4555],[30.073,45.435],[30.0665,45.506],[30.193,45.5675],[30.3445,45.669],[30.4475,45.7275],[30.6385,45.911],[30.6675,45.96],[30.7355,45.986],[30.8275,46.0655],[30.929,46.1375],[30.968,46.2325],[31.03,46.3145],[31.0475,46.377],[31.159,46.4095],[31.2375,46.403],[31.242,46.27],[31.3085,46.1715],[31.3935,46.107],[31.4595,46.0765],[31.597,46.0395],[31.8925,45.997],[32.08,45.9475],[32.2475,45.9205],[32.447,45.8705],[32.528,45.8645],[32.7725,45.8265],[33.5405,46.012],[33.591,46.061],[33.572,46.1025],[33.6355,46.1465],[33.615,46.226],[33.736,46.186],[33.8115,46.204],[34.0525,46.109],[34.1175,46.1075],[34.1885,46.066],[34.248,46.053],[34.3295,46.0605],[34.405,46.0095],[34.443,45.962],[34.4985,45.9425],[34.561,45.9945],[34.67,45.9675],[34.7545,45.9085],[34.802,45.9005],[34.799,45.8105],[34.975,45.762],[35.2335,45.7915],[35.151,45.9315],[35.273,45.956],[35.3275,45.9855],[35.4325,46.091],[35.468,46.1465],[35.582,46.263],[35.6855,46.313],[35.7205,46.3485],[35.8445,46.41],[35.9355,46.336],[36.0795,46.3005],[36.1935,46.3115],[36.262,46.336],[36.3585,46.418],[36.4345,46.455],[36.499,46.528],[36.5455,46.5355],[36.644,46.478],[36.7095,46.463],[36.8125,46.463],[36.8925,46.484],[36.989,46.5505],[37.024,46.639],[37.098,46.69],[37.1685,46.7105],[37.297,46.6875],[37.4375,46.716],[37.62,46.83],[38.141,46.861],[38.338,46.981],[38.23,47.1195],[38.236,47.1985],[38.2605,47.2385],[38.3245,47.257],[38.336,47.3065],[38.221,47.3055],[38.2575,47.373],[38.3025,47.393],[38.2845,47.5445],[38.3505,47.6165],[38.457,47.617],[38.4565,47.644],[38.6165,47.6445],[38.669,47.699],[38.7725,47.6855],[38.789,47.816],[38.8375,47.8645],[38.884,47.875],[39.083,47.8695],[39.1495,47.8425],[39.2415,47.867],[39.3875,47.871],[39.412,47.831],[39.478,47.8605],[39.521,47.8255],[39.5655,47.8365],[39.7385,47.828],[39.7935,47.9195],[39.816,48.0],[39.7765,48.04],[39.8835,48.0415],[39.8765,48.119],[39.937,48.181],[39.942,48.2285],[40.021,48.254],[39.9905,48.317],[39.9365,48.291],[39.841,48.31],[39.8455,48.333],[39.946,48.352],[39.898,48.4475],[39.853,48.4665],[39.8555,48.561],[39.7875,48.5935],[39.688,48.587],[39.668,48.621],[39.7185,48.6875],[39.7255,48.7525],[39.779,48.7855],[39.807,48.8385],[39.9755,48.793],[40.08,48.87],[40.0585,48.904],[39.8525,48.8905],[39.7765,48.9205],[39.7495,48.978],[39.6635,49.001],[39.693,49.0505],[39.7665,49.04],[39.805,49.06],[39.9385,49.083],[40.031,49.18],[40.0775,49.187],[40.186,49.281],[40.196,49.3445],[40.1145,49.3855],[40.0295,49.4535],[40.039,49.5205],[40.1695,49.569],[40.1355,49.617],[39.952,49.597],[39.891,49.5585],[39.806,49.558],[39.7505,49.5975],[39.6605,49.615],[39.5915,49.7185],[39.4785,49.7565],[39.379,49.7385],[39.285,49.7555],[39.2275,49.8075],[39.18,49.889],[39.067,49.8155],[38.9515,49.797],[38.9095,49.8195],[38.901,49.8695],[38.848,49.8645],[38.745,49.8975],[38.724,49.927],[38.5825,49.9775],[38.4885,49.963],[38.3505,50.007],[38.3295,50.0855],[38.178,50.08],[38.186,50.023],[38.222,49.979],[38.171,49.942],[38.056,49.923],[37.962,49.983],[37.9265,50.034],[37.797,50.084],[37.755,50.0785],[37.639,50.1795],[37.615,50.217],[37.6265,50.2935],[37.485,50.357],[37.465,50.431],[37.333,50.437],[37.2925,50.4015],[37.1815,50.363],[37.1055,50.352],[36.9375,50.3505],[36.693,50.269],[36.6485,50.2175],[36.5605,50.251],[36.575,50.275],[36.4735,50.313],[36.3665,50.288],[36.297,50.292],[36.284,50.3355],[36.1605,50.4315],[36.068,50.451],[35.932,50.431],[35.8315,50.434],[35.738,50.3545],[35.6285,50.3545],[35.584,50.3955],[35.5865,50.448],[35.4755,50.489],[35.436,50.53],[35.4255,50.603],[35.392,50.642],[35.4595,50.689],[35.4885,50.777],[35.4105,50.808],[35.419,50.844],[35.388,50.9235],[35.333,50.9345],[35.33,50.996],[35.406,51.048],[35.305,51.076],[35.2135,51.0465],[35.166,51.0775],[35.168,51.1265],[35.1235,51.165],[35.1505,51.2235],[34.951,51.2265],[34.818,51.169],[34.669,51.1975],[34.6625,51.2475],[34.4865,51.2445],[34.384,51.274],[34.3315,51.24],[34.2445,51.2635],[34.2375,51.2925],[34.337,51.3655],[34.2855,51.375],[34.2225,51.4285],[34.308,51.5155],[34.1155,51.6845],[34.4325,51.7295],[34.4155,51.826],[34.2035,51.941],[34.1895,51.969],[34.094,52.011],[34.0625,52.073],[34.1165,52.141],[34.0545,52.1715],[33.875,52.3065],[33.8365,52.3615],[33.7855,52.3665],[33.6065,52.3345],[33.56,52.3025],[33.5045,52.306],[33.519,52.355],[33.289,52.3575],[33.208,52.376],[33.073,52.325],[32.996,52.2725],[32.8335,52.279],[32.763,52.2565],[32.685,52.2665],[32.55,52.327],[32.3515,52.3165],[32.3955,52.2465],[32.3245,52.2235],[32.3445,52.1825],[32.29,52.103],[32.1255,52.046],[31.9175,52.053],[31.954,52.0815],[31.8565,52.111],[31.7815,52.112],[31.722,52.096],[31.6585,52.1175],[31.466,52.1205],[31.4025,52.1425],[31.331,52.107],[31.2975,52.0515],[31.253,52.042],[31.1365,52.103],[30.9915,52.0775],[30.888,51.9685],[30.805,51.947],[30.707,51.8685],[30.6485,51.7505],[30.578,51.6805],[30.529,51.602],[30.5285,51.563],[30.6555,51.376],[30.618,51.288],[30.5385,51.2625],[30.4625,51.3065],[30.424,51.3055],[30.324,51.3605],[30.347,51.4235],[30.18,51.5125],[30.12,51.4875],[30.0355,51.504],[29.9715,51.475],[29.8935,51.4855],[29.7975,51.4465],[29.7495,51.457],[29.7165,51.53],[29.542,51.4825],[29.4955,51.397],[29.4215,51.415],[29.3405,51.3855],[29.309,51.454],[29.251,51.4955],[29.2665,51.531],[29.1775,51.6075],[29.1635,51.6525],[29.106,51.651],[28.9995,51.5735],[28.9125,51.59],[28.807,51.5485],[28.7615,51.4875],[28.772,51.4295],[28.688,51.4445],[28.6355,51.574],[28.559,51.573],[28.4715,51.5935],[28.3975,51.551],[28.3615,51.558],[28.287,51.6235],[28.2645,51.6815],[28.1735,51.644],[28.1175,51.583],[27.946,51.558],[27.9115,51.6125],[27.858,51.6305],[27.807,51.533],[27.742,51.4775],[27.6835,51.541],[27.7275,51.6045],[27.619,51.6055],[27.55,51.637],[27.393,51.605],[27.2675,51.606],[27.2735,51.6465],[27.213,51.6665],[27.207,51.774],[26.9935,51.7685],[26.9505,51.736],[26.8505,51.767],[26.8095,51.7565],[26.755,51.8035],[26.6115,51.8245],[26.5465,51.796],[26.4665,51.7995],[26.371,51.863],[26.1555,51.866],[26.093,51.9125],[25.99,51.932],[25.9205,51.916],[25.819,51.929],[25.708,51.916],[25.596,51.9235],[25.41,51.9215],[25.2635,51.9685],[25.1005,51.9535],[24.934,51.891],[24.81,51.912],[24.7495,51.881],[24.625,51.9025],[24.5675,51.8895],[24.388,51.882],[24.3,51.814],[24.3195,51.751],[24.2685,51.716],[24.1205,51.6665],[24.0755,51.619],[23.9955,51.5805],[23.8805,51.6085],[23.867,51.643],[23.7825,51.6675],[23.6785,51.653],[23.6055,51.617],[23.6645,51.577],[23.618,51.508],[23.6715,51.475],[23.6975,51.403],[23.636,51.319],[23.695,51.287],[23.7265,51.238],[23.8215,51.1645],[23.8765,51.079],[23.9985,50.9275],[24.099,50.877],[24.0945,50.836],[23.99,50.8375],[23.9575,50.795],[24.0095,50.772],[24.0185,50.7255],[24.0715,50.7205],[24.0985,50.5995],[24.07,50.5035],[23.9975,50.412],[23.8035,50.405],[23.703,50.3755],[23.6865,50.3315],[23.639,50.3205],[23.581,50.266],[23.47,50.218],[23.2795,50.0865],[23.0335,49.8815],[22.9705,49.8385],[22.848,49.71],[22.641,49.53],[22.6965,49.495],[22.747,49.36],[22.7475,49.2165],[22.7075,49.175],[22.789,49.158],[22.8645,49.0665],[22.8915,49.008],[22.7655,49.0535],[22.6395,49.0595],[22.5655,49.088]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/49/Flag_of_Ukraine.svg","name:en":"Ukraine","wikidata":"Q212","ISO3166-1:alpha2":"UA","ISO3166-1:alpha3":"UKR","ISO3166-1:numeric":"804"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[100.0845,20.3525],[100.047,20.3915],[99.9905,20.4235],[99.9655,20.4625],[99.862,20.4435],[99.81,20.3365],[99.73,20.35],[99.6815,20.316],[99.647,20.3415],[99.6115,20.3325],[99.5195,20.3615],[99.472,20.394],[99.4555,20.363],[99.507,20.326],[99.523,20.233],[99.5625,20.207],[99.5375,20.147],[99.499,20.118],[99.4,20.086],[99.3445,20.105],[99.242,20.114],[99.159,20.133],[99.1085,20.098],[99.077,20.101],[99.044,20.0355],[99.045,19.9485],[99.0235,19.9195],[99.034,19.8555],[98.9845,19.739],[98.9315,19.774],[98.83,19.796],[98.7775,19.752],[98.6725,19.752],[98.608,19.709],[98.519,19.715],[98.474,19.695],[98.3715,19.69],[98.3205,19.697],[98.2485,19.6765],[98.238,19.708],[98.1355,19.788],[98.0835,19.81],[98.036,19.801],[98.0245,19.722],[98.026,19.6375],[97.983,19.6405],[97.975,19.602],[97.8635,19.577],[97.8555,19.531],[97.876,19.5065],[97.792,19.395],[97.822,19.329],[97.8415,19.225],[97.8355,19.093],[97.77,19.0735],[97.736,19.0405],[97.7385,18.9785],[97.6905,18.9485],[97.697,18.9045],[97.737,18.887],[97.739,18.8285],[97.774,18.689],[97.768,18.578],[97.6505,18.577],[97.605,18.537],[97.5495,18.531],[97.535,18.491],[97.4905,18.51],[97.444,18.495],[97.426,18.5465],[97.393,18.561],[97.346,18.546],[97.387,18.5055],[97.4265,18.408],[97.452,18.39],[97.444,18.3405],[97.502,18.2675],[97.5365,18.286],[97.551,18.334],[97.62,18.318],[97.6395,18.2875],[97.6135,18.225],[97.676,18.1615],[97.677,18.115],[97.7365,17.9865],[97.7315,17.9525],[97.6875,17.925],[97.672,17.8825],[97.718,17.8195],[97.794,17.6795],[97.9065,17.5835],[97.923,17.5395],[97.9925,17.51],[98.0575,17.438],[98.083,17.3905],[98.1105,17.3855],[98.113,17.319],[98.1755,17.2585],[98.248,17.2085],[98.2875,17.1565],[98.2795,17.1155],[98.347,17.048],[98.3935,17.059],[98.4375,17.037],[98.49,16.9685],[98.5345,16.873],[98.536,16.8295],[98.4855,16.7895],[98.464,16.7325],[98.5115,16.701],[98.5115,16.649],[98.574,16.6205],[98.579,16.557],[98.658,16.455],[98.637,16.4255],[98.6575,16.3785],[98.676,16.2805],[98.7355,16.338],[98.817,16.385],[98.8285,16.4135],[98.8825,16.4225],[98.9135,16.393],[98.9315,16.329],[98.9035,16.2545],[98.852,16.214],[98.8515,16.1365],[98.8055,16.1045],[98.7,16.136],[98.625,16.0425],[98.599,16.0735],[98.5605,16.034],[98.6085,15.9725],[98.584,15.9185],[98.609,15.8735],[98.577,15.8],[98.5485,15.685],[98.553,15.6015],[98.5855,15.471],[98.5805,15.3755],[98.5375,15.371],[98.4895,15.3935],[98.471,15.371],[98.3945,15.3425],[98.4175,15.2665],[98.394,15.2625],[98.306,15.3135],[98.252,15.225],[98.198,15.2345],[98.2125,15.178],[98.1835,15.0965],[98.2315,15.0445],[98.2085,14.9805],[98.2335,14.9665],[98.257,14.8635],[98.246,14.831],[98.2945,14.77],[98.3235,14.7105],[98.436,14.6085],[98.487,14.536],[98.524,14.4555],[98.5495,14.4345],[98.597,14.3275],[98.631,14.316],[98.756,14.2145],[98.835,14.172],[98.8785,14.1235],[98.968,14.0825],[98.972,14.033],[98.9985,14.0195],[99.021,13.9455],[99.077,13.895],[99.1215,13.7735],[99.167,13.726],[99.1725,13.563],[99.207,13.3805],[99.187,13.291],[99.2105,13.2075],[99.139,13.2055],[99.1275,13.103],[99.0995,13.0725],[99.18,12.9935],[99.1725,12.943],[99.1885,12.847],[99.218,12.8285],[99.2325,12.74],[99.2895,12.715],[99.2945,12.678],[99.348,12.6395],[99.4125,12.6155],[99.4355,12.566],[99.401,12.46],[99.442,12.4005],[99.434,12.343],[99.4715,12.2345],[99.515,12.1475],[99.5705,12.145],[99.534,12.0655],[99.538,12.014],[99.592,11.9925],[99.58,11.9065],[99.625,11.8315],[99.659,11.829],[99.638,11.7325],[99.5835,11.6795],[99.5655,11.6265],[99.5165,11.637],[99.4675,11.615],[99.4745,11.533],[99.4405,11.4795],[99.3935,11.461],[99.402,11.3885],[99.367,11.3725],[99.3125,11.3165],[99.3245,11.282],[99.2635,11.215],[99.229,11.113],[99.19,11.084],[99.1585,11.034],[99.104,11.013],[99.077,10.954],[99.024,10.9705],[98.9975,10.911],[99.0115,10.8565],[98.959,10.812],[98.913,10.81],[98.8615,10.7785],[98.7795,10.678],[98.774,10.6165],[98.81,10.5815],[98.817,10.4985],[98.795,10.445],[98.7555,10.393],[98.743,10.3245],[98.7075,10.231],[98.6705,10.1705],[98.5795,9.9865],[98.567,9.9435],[98.519,9.926],[98.471,9.9565],[98.3665,9.943],[98.3345,9.891],[98.3215,9.832],[98.275,9.7505],[98.2175,9.5655],[98.1185,9.4415],[98.112,9.3485],[98.077,9.283],[98.0475,9.127],[98.0475,9.017],[98.017,8.9185],[98.0345,8.836],[98.017,8.7405],[98.0315,8.668],[98.004,8.55],[98.019,8.474],[98.0705,8.282],[98.0895,8.1595],[98.07,8.0765],[98.07,8.009],[98.0545,7.9325],[98.0595,7.8845],[98.102,7.6945],[98.1235,7.552],[98.104,7.479],[98.1145,7.399],[98.155,7.332],[98.2155,7.2835],[98.2915,7.261],[98.369,7.272],[98.4855,7.372],[98.568,7.5405],[98.693,7.4665],[98.698,7.361],[98.764,7.267],[98.856,7.2485],[98.8555,7.1685],[98.8835,7.0925],[98.934,7.037],[99.0035,7.0015],[99.083,6.9995],[99.1955,7.0445],[99.215,6.983],[99.288,6.8835],[99.3015,6.775],[99.247,6.7835],[99.1165,6.7625],[99.006,6.6765],[98.95,6.5505],[98.969,6.449],[99.0105,6.3825],[99.068,6.3255],[99.1115,6.3],[99.3215,6.2715],[99.4585,6.3065],[99.5115,6.4815],[99.5565,6.5035],[99.689,6.4715],[99.812,6.5125],[99.917,6.5235],[100.014,6.442],[100.076,6.406],[100.1335,6.429],[100.159,6.4805],[100.154,6.5575],[100.1705,6.6075],[100.1715,6.694],[100.29,6.689],[100.326,6.6595],[100.316,6.604],[100.3665,6.5395],[100.496,6.5215],[100.5255,6.4875],[100.564,6.495],[100.618,6.46],[100.6625,6.451],[100.7395,6.492],[100.8125,6.442],[100.835,6.2965],[100.904,6.234],[100.984,6.279],[101.015,6.247],[101.0945,6.2605],[101.1265,6.1925],[101.0755,6.171],[101.0585,6.1415],[101.119,6.1145],[101.1005,6.0495],[101.107,5.9905],[101.087,5.911],[101.037,5.918],[100.985,5.81],[101.034,5.738],[101.06,5.7445],[101.111,5.681],[101.136,5.613],[101.215,5.6615],[101.26,5.7115],[101.2495,5.7625],[101.276,5.8115],[101.343,5.8095],[101.397,5.8725],[101.4845,5.87],[101.5405,5.919],[101.5815,5.9345],[101.6625,5.8685],[101.658,5.817],[101.691,5.756],[101.7535,5.797],[101.7935,5.7505],[101.88,5.832],[101.944,5.8725],[101.9305,5.9095],[101.9425,5.981],[102.0035,6.0505],[102.057,6.0855],[102.0875,6.141],[102.0805,6.2255],[102.1665,6.4585],[102.2595,6.6535],[102.1985,7.349],[102.1745,7.427],[102.129,7.4835],[101.5025,8.0125],[100.8995,8.521],[100.5955,9.0935],[100.295,9.6585],[100.282,9.786],[100.262,9.846],[100.179,10.026],[100.152,10.069],[99.9815,10.2725],[99.6225,10.5945],[99.703,10.661],[99.7315,10.717],[99.746,10.782],[99.719,10.9435],[99.758,11.011],[99.763,11.1165],[99.786,11.214],[99.7785,11.265],[99.8355,11.4285],[99.886,11.4525],[99.948,11.5145],[99.978,11.616],[100.0225,11.68],[100.0395,11.7515],[100.0385,11.857],[100.074,11.9315],[100.1475,12.009],[100.227,12.1505],[100.233,12.2525],[100.207,12.3085],[100.2045,12.396],[100.792,12.396],[100.8125,12.367],[100.8785,12.3235],[100.9565,12.3085],[101.053,12.3295],[101.119,12.3725],[101.163,12.437],[101.2485,12.446],[101.283,12.3975],[101.3495,12.3425],[101.4405,12.3205],[101.5225,12.3305],[101.57,12.354],[101.649,12.3685],[101.748,12.372],[101.7895,12.3865],[101.846,12.338],[102.051,12.209],[102.038,12.0635],[102.053,11.9755],[102.11,11.8445],[102.2275,11.652],[102.378,11.4675],[102.4775,11.4095],[102.5705,11.388],[102.621,11.3895],[102.914,11.6545],[102.9115,11.7455],[102.8665,11.8065],[102.8195,11.8925],[102.815,11.9335],[102.785,11.9765],[102.769,12.0755],[102.734,12.111],[102.705,12.18],[102.7175,12.2225],[102.726,12.3645],[102.7875,12.4155],[102.7655,12.457],[102.6775,12.543],[102.6435,12.612],[102.567,12.658],[102.511,12.67],[102.5005,12.7385],[102.5325,12.7675],[102.508,12.8975],[102.488,12.944],[102.494,13.014],[102.399,13.1565],[102.386,13.218],[102.3495,13.2775],[102.345,13.347],[102.3625,13.4245],[102.363,13.506],[102.334,13.5405],[102.3665,13.578],[102.439,13.56],[102.5375,13.567],[102.57,13.586],[102.5715,13.635],[102.549,13.6595],[102.5805,13.7005],[102.6885,13.752],[102.7665,13.8565],[102.783,13.933],[102.869,14.005],[102.9085,14.021],[102.9005,14.0835],[102.941,14.1525],[102.952,14.207],[103.022,14.2285],[103.079,14.294],[103.1885,14.3345],[103.219,14.3235],[103.2665,14.3495],[103.402,14.358],[103.435,14.391],[103.4675,14.3645],[103.497,14.4105],[103.578,14.4335],[103.642,14.4145],[103.6555,14.4395],[103.707,14.433],[103.7005,14.392],[103.78,14.3615],[103.837,14.371],[103.9,14.338],[104.0095,14.356],[104.029,14.34],[104.0935,14.3535],[104.108,14.3785],[104.1715,14.359],[104.217,14.3675],[104.2775,14.408],[104.307,14.383],[104.4765,14.361],[104.5,14.3765],[104.5645,14.354],[104.641,14.423],[104.6985,14.4275],[104.7525,14.4055],[104.806,14.4375],[104.8335,14.4025],[104.8795,14.412],[105.0025,14.362],[105.0005,14.305],[105.026,14.238],[105.05,14.215],[105.1025,14.213],[105.154,14.2545],[105.151,14.2835],[105.2065,14.3435],[105.2815,14.3535],[105.322,14.398],[105.36,14.3875],[105.4305,14.4245],[105.5235,14.5495],[105.531,14.6225],[105.512,14.801],[105.5765,14.897],[105.557,14.9245],[105.6195,14.98],[105.573,15.001],[105.481,15.0985],[105.4745,15.1775],[105.54,15.252],[105.591,15.271],[105.576,15.3225],[105.5085,15.3185],[105.4675,15.3475],[105.491,15.3845],[105.5785,15.408],[105.6025,15.4805],[105.5935,15.5125],[105.625,15.5635],[105.6345,15.6625],[105.596,15.7245],[105.497,15.767],[105.4335,15.7555],[105.3905,15.8085],[105.342,15.922],[105.408,16.016],[105.195,16.055],[105.0405,16.11],[105.011,16.202],[105.015,16.244],[104.9205,16.3375],[104.895,16.343],[104.83,16.4645],[104.768,16.5],[104.735,16.5455],[104.744,16.6375],[104.7625,16.6895],[104.738,16.794],[104.759,16.8415],[104.733,16.9365],[104.7295,17.0085],[104.8015,17.1645],[104.804,17.3715],[104.796,17.402],[104.744,17.4605],[104.708,17.521],[104.4965,17.635],[104.457,17.667],[104.355,17.8225],[104.271,17.87],[104.213,17.9995],[104.1055,18.1155],[104.057,18.2235],[103.973,18.337],[103.953,18.3395],[103.856,18.2845],[103.834,18.328],[103.794,18.343],[103.6955,18.344],[103.6035,18.405],[103.524,18.4255],[103.457,18.425],[103.4035,18.4485],[103.313,18.4335],[103.2465,18.3705],[103.281,18.2935],[103.1685,18.2575],[103.136,18.1605],[103.0835,18.129],[103.073,18.0225],[103.042,17.9825],[103.009,17.9765],[102.969,18.004],[102.862,17.974],[102.7805,17.929],[102.766,17.8995],[102.679,17.8565],[102.667,17.8055],[102.589,17.8495],[102.613,17.9075],[102.594,17.96],[102.46,17.971],[102.341,18.0465],[102.3,18.053],[102.1855,18.148],[102.1645,18.2025],[102.0885,18.2205],[102.045,18.1985],[102.0345,18.1615],[101.9455,18.0875],[101.907,18.031],[101.8745,18.0285],[101.786,18.071],[101.766,18.054],[101.7105,17.902],[101.618,17.894],[101.6025,17.857],[101.5645,17.841],[101.548,17.7875],[101.456,17.747],[101.3455,17.659],[101.3065,17.6505],[101.2645,17.6035],[101.2295,17.5365],[101.175,17.5235],[101.161,17.467],[101.08,17.5025],[101.0215,17.557],[100.9675,17.5715],[100.9915,17.619],[101.007,17.732],[100.978,17.7535],[101.0285,17.829],[101.02,17.8925],[101.1165,17.951],[101.1215,18.0],[101.184,18.065],[101.161,18.1245],[101.1925,18.212],[101.166,18.217],[101.161,18.3045],[101.1825,18.34],[101.083,18.3845],[101.0525,18.4265],[101.0915,18.478],[101.1035,18.5215],[101.1835,18.5605],[101.182,18.612],[101.225,18.6235],[101.2725,18.6885],[101.2335,18.72],[101.2585,18.8095],[101.246,18.8895],[101.297,18.943],[101.2925,18.981],[101.3355,19.004],[101.3555,19.051],[101.257,19.124],[101.245,19.181],[101.2595,19.231],[101.187,19.3995],[101.215,19.4315],[101.2105,19.4735],[101.264,19.4705],[101.2805,19.5825],[101.2065,19.605],[101.198,19.577],[101.123,19.572],[101.036,19.6285],[100.9125,19.627],[100.883,19.606],[100.779,19.4925],[100.7405,19.52],[100.6505,19.5565],[100.608,19.547],[100.5805,19.499],[100.4855,19.5435],[100.478,19.6125],[100.428,19.6725],[100.446,19.7065],[100.404,19.7525],[100.438,19.791],[100.4425,19.8355],[100.501,19.8705],[100.57,20.099],[100.5765,20.17],[100.5075,20.151],[100.456,20.225],[100.4185,20.25],[100.374,20.352],[100.3305,20.398],[100.2725,20.4005],[100.227,20.3555],[100.2175,20.3145],[100.181,20.3065],[100.1715,20.246],[100.113,20.25],[100.0845,20.3525]]],[[[97.7245,9.6005],[97.642,9.4965],[97.6265,9.4205],[97.642,9.3445],[97.703,9.25],[97.665,9.2245],[97.621,9.16],[97.6055,9.0685],[97.6205,8.9925],[97.645,8.956],[97.604,8.872],[97.5635,8.864],[97.498,8.821],[97.4545,8.7565],[97.428,8.5765],[97.4525,8.409],[97.4965,8.3445],[97.574,8.2895],[97.651,8.2745],[97.728,8.2895],[97.7935,8.3325],[97.837,8.3975],[97.858,8.516],[97.8455,8.583],[97.856,8.635],[97.9425,8.6835],[97.986,8.7485],[98.0025,8.8285],[97.987,8.9045],[97.9665,8.935],[98.0045,8.991],[98.02,9.067],[98.0045,9.143],[97.969,9.1975],[98.009,9.224],[98.082,9.3195],[98.106,9.44],[98.042,9.4835],[97.8535,9.5815],[97.7245,9.6005]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/a/a9/Flag_of_Thailand.svg","name:en":"Thailand","wikidata":"Q869","ISO3166-1:alpha2":"TH","ISO3166-1:alpha3":"THA","ISO3166-1:numeric":"764"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[102.1445,22.4],[102.182,22.3235],[102.2345,22.2825],[102.2465,22.2365],[102.3125,22.208],[102.434,22.1125],[102.4455,22.0745],[102.5095,22.0365],[102.4875,21.997],[102.514,21.9665],[102.5945,21.925],[102.642,21.849],[102.6615,21.7865],[102.648,21.7355],[102.6665,21.678],[102.7395,21.6595],[102.8265,21.736],[102.817,21.84],[102.8515,21.8425],[102.8565,21.722],[102.8855,21.712],[102.973,21.7365],[102.9885,21.721],[102.9815,21.647],[102.992,21.586],[102.8865,21.4765],[102.88,21.4245],[102.896,21.385],[102.897,21.3045],[102.8515,21.2985],[102.8585,21.2565],[102.912,21.2295],[102.909,21.1805],[102.9495,21.139],[102.962,21.0775],[103.0345,21.0585],[103.1095,20.9005],[103.168,20.9135],[103.2145,20.8995],[103.227,20.8515],[103.261,20.8235],[103.2945,20.835],[103.39,20.784],[103.4415,20.794],[103.463,20.826],[103.5095,20.753],[103.6015,20.7425],[103.6675,20.6985],[103.6835,20.6615],[103.735,20.667],[103.7335,20.7315],[103.791,20.7465],[103.7805,20.8015],[103.9015,20.9035],[103.9615,20.8975],[104.0485,20.9115],[104.054,20.95],[104.1215,20.9705],[104.2815,20.925],[104.3335,20.881],[104.3375,20.856],[104.428,20.79],[104.483,20.767],[104.4935,20.718],[104.552,20.719],[104.5855,20.6805],[104.6415,20.6625],[104.601,20.6055],[104.5415,20.5985],[104.5225,20.549],[104.376,20.467],[104.4135,20.423],[104.421,20.3765],[104.4745,20.369],[104.565,20.4165],[104.611,20.423],[104.6255,20.462],[104.6615,20.4745],[104.7095,20.4105],[104.6175,20.3615],[104.6105,20.275],[104.63,20.2295],[104.719,20.201],[104.7745,20.1985],[104.862,20.1415],[104.9135,20.1555],[104.9765,20.08],[104.907,19.9985],[104.903,19.968],[104.8465,19.9295],[104.835,19.802],[104.796,19.7905],[104.7535,19.75],[104.7125,19.754],[104.6465,19.6545],[104.567,19.6155],[104.506,19.626],[104.49,19.6555],[104.4275,19.673],[104.4125,19.705],[104.3515,19.6925],[104.236,19.7075],[104.105,19.662],[104.072,19.682],[104.0605,19.613],[104.1055,19.568],[104.073,19.4505],[104.0145,19.402],[103.958,19.384],[103.9085,19.3295],[103.924,19.2855],[104.003,19.233],[104.068,19.248],[104.128,19.205],[104.179,19.1975],[104.2125,19.1295],[104.272,19.1215],[104.3045,19.0935],[104.3975,19.055],[104.4455,18.984],[104.496,19.004],[104.545,18.97],[104.581,18.901],[104.63,18.886],[104.739,18.801],[104.7945,18.783],[104.913,18.787],[104.941,18.7395],[105.018,18.7455],[105.052,18.7085],[105.1065,18.7065],[105.198,18.6405],[105.1805,18.6025],[105.136,18.593],[105.115,18.539],[105.1035,18.4475],[105.1715,18.392],[105.192,18.319],[105.2425,18.2965],[105.256,18.255],[105.3315,18.2525],[105.3195,18.2015],[105.3635,18.164],[105.409,18.154],[105.46,18.206],[105.5015,18.1885],[105.5225,18.1255],[105.5805,18.062],[105.6425,17.9625],[105.608,17.877],[105.6605,17.8565],[105.701,17.7615],[105.78,17.675],[105.862,17.6275],[106.0815,17.3715],[106.2355,17.25],[106.305,17.258],[106.328,17.18],[106.373,17.112],[106.416,17.0785],[106.402,17.053],[106.4275,17.008],[106.5155,16.9715],[106.548,16.9285],[106.5145,16.896],[106.5515,16.865],[106.5515,16.6945],[106.565,16.643],[106.672,16.5625],[106.6475,16.5405],[106.6605,16.4745],[106.726,16.425],[106.772,16.4325],[106.8065,16.4785],[106.831,16.549],[106.8865,16.522],[106.8785,16.4685],[106.8975,16.391],[106.964,16.355],[106.9685,16.307],[107.0865,16.3125],[107.157,16.2565],[107.1465,16.22],[107.16,16.1675],[107.1975,16.144],[107.242,16.1475],[107.2835,16.1185],[107.3385,16.0555],[107.3775,16.074],[107.4455,16.054],[107.464,16.016],[107.4155,15.912],[107.393,15.887],[107.347,15.8935],[107.215,15.824],[107.2755,15.704],[107.291,15.624],[107.3365,15.6215],[107.365,15.57],[107.386,15.4925],[107.471,15.4965],[107.513,15.473],[107.5305,15.4055],[107.606,15.3885],[107.6245,15.311],[107.6215,15.2145],[107.6025,15.1835],[107.623,15.1075],[107.598,15.088],[107.583,15.0285],[107.54,15.0495],[107.468,14.9875],[107.4785,14.9575],[107.5895,14.864],[107.5075,14.7925],[107.542,14.7505],[107.5565,14.686],[107.5595,14.623],[107.5225,14.588],[107.532,14.5465],[107.488,14.406],[107.4465,14.403],[107.391,14.3265],[107.4095,14.2645],[107.3775,14.1795],[107.3385,14.128],[107.367,14.0835],[107.3655,14.013],[107.3865,13.9895],[107.4555,13.98],[107.4515,13.7945],[107.536,13.7405],[107.5705,13.6625],[107.5745,13.6205],[107.617,13.5265],[107.6275,13.3665],[107.548,13.17],[107.496,13.028],[107.5045,12.976],[107.4845,12.9445],[107.492,12.8975],[107.562,12.7925],[107.559,12.716],[107.582,12.6795],[107.5695,12.642],[107.5895,12.5595],[107.58,12.4955],[107.5435,12.3995],[107.544,12.351],[107.447,12.291],[107.434,12.246],[107.387,12.271],[107.363,12.3195],[107.268,12.3245],[107.2305,12.296],[107.1555,12.278],[107.14,12.2335],[107.1005,12.2065],[107.054,12.1425],[106.99,12.085],[106.927,12.0635],[106.7915,12.0815],[106.724,11.9755],[106.496,11.969],[106.4555,11.989],[106.412,11.9735],[106.465,11.8725],[106.418,11.77],[106.4535,11.6905],[106.4405,11.669],[106.3685,11.697],[106.3125,11.674],[106.2495,11.7285],[106.19,11.754],[106.1155,11.743],[106.069,11.776],[106.024,11.7745],[106.016,11.7285],[105.9535,11.6405],[105.884,11.677],[105.8525,11.662],[105.8095,11.5965],[105.8625,11.5655],[105.8855,11.5325],[105.874,11.4055],[105.885,11.361],[105.8755,11.2875],[105.9415,11.2055],[106.014,11.1905],[106.023,11.1405],[106.1215,11.0885],[106.154,11.102],[106.188,11.0505],[106.206,10.978],[106.154,10.983],[106.14,10.915],[106.1865,10.842],[106.1655,10.8115],[106.0725,10.811],[105.9725,10.8935],[105.9,10.8445],[105.8485,10.864],[105.8645,10.8995],[105.807,10.9735],[105.7795,11.0315],[105.73,11.0255],[105.6675,10.9875],[105.5365,10.952],[105.4955,10.9485],[105.4335,10.9725],[105.344,10.8665],[105.265,10.897],[105.2385,10.893],[105.1575,10.9225],[105.1075,10.9185],[105.083,10.9565],[105.0295,10.8925],[105.0655,10.7805],[105.0985,10.721],[104.957,10.638],[104.897,10.547],[104.869,10.522],[104.753,10.518],[104.6945,10.537],[104.588,10.5275],[104.5505,10.4555],[104.439,10.423],[104.2275,10.2715],[104.1245,10.232],[104.1105,10.3835],[104.0885,10.4205],[104.011,10.4805],[103.9715,10.48],[103.9265,10.4305],[103.914,10.3905],[103.838,10.402],[103.8005,10.3675],[103.8265,10.291],[103.901,10.2615],[103.935,10.154],[103.86,10.0045],[103.7785,9.949],[103.118,9.4755],[103.125,9.38],[103.1655,9.2775],[103.292,9.125],[103.3445,9.0785],[103.482,8.9945],[104.7675,8.209],[104.8325,8.183],[104.9025,8.181],[105.674,8.291],[106.0555,8.3455],[106.653,8.431],[106.8,8.486],[108.431,9.378],[109.1805,9.7905],[109.26,9.868],[109.284,9.9385],[109.402,10.763],[109.5375,11.7075],[109.666,12.602],[109.671,12.6605],[109.657,12.9165],[109.585,13.623],[109.554,13.926],[109.463,14.605],[109.3555,15.411],[109.3365,15.4725],[109.2985,15.525],[109.0235,15.7975],[108.6565,16.1665],[108.4805,16.334],[107.6885,17.1145],[107.4915,17.3075],[107.4325,17.348],[107.3625,17.3665],[107.2905,17.3605],[107.2245,17.3315],[107.173,17.2825],[106.9465,17.453],[106.8175,17.579],[106.73,17.718],[106.8275,17.775],[106.8665,17.831],[106.884,17.896],[106.882,17.947],[106.839,18.0385],[106.6725,18.217],[106.5285,18.315],[106.34,18.4225],[106.3035,18.4625],[106.23,18.5025],[106.1555,18.512],[106.0815,18.6225],[106.127,18.6605],[106.1635,18.72],[106.177,18.7875],[106.171,18.842],[106.1405,18.9085],[106.0425,18.9875],[105.9335,19.0055],[105.9485,19.121],[106.0145,19.1435],[106.0725,19.1875],[106.114,19.2385],[106.1415,19.3015],[106.149,19.376],[106.1365,19.445],[106.1005,19.5065],[106.046,19.552],[106.048,19.581],[106.1255,19.693],[106.1745,19.7025],[106.244,19.7375],[106.4705,19.9905],[106.5445,19.992],[106.628,20.009],[106.7425,20.069],[106.786,20.127],[106.8055,20.183],[106.839,20.337],[106.8355,20.4655],[106.954,20.5005],[107.0065,20.451],[107.0745,20.421],[107.129,20.412],[107.282,20.4245],[107.574,20.5495],[107.6445,20.615],[107.7205,20.7435],[107.8165,20.756],[107.959,20.8305],[108.048,20.927],[108.1865,21.063],[108.2235,21.1235],[108.2085,21.2095],[108.1345,21.2755],[108.0955,21.4525],[108.1005,21.4735],[108.0335,21.5475],[107.955,21.537],[107.9425,21.57],[107.8965,21.596],[107.872,21.647],[107.8155,21.6585],[107.6885,21.6115],[107.594,21.605],[107.5435,21.5895],[107.4935,21.605],[107.4825,21.657],[107.361,21.612],[107.36,21.6645],[107.301,21.7425],[107.249,21.7055],[107.1965,21.7225],[107.0855,21.808],[107.0045,21.8335],[107.0635,21.896],[107.05,21.928],[106.988,21.9485],[106.9335,21.9295],[106.919,21.9745],[106.8125,21.973],[106.7845,22.004],[106.6825,22.002],[106.71,22.1015],[106.673,22.181],[106.6985,22.2095],[106.69,22.279],[106.6595,22.334],[106.5715,22.3415],[106.5855,22.378],[106.5575,22.459],[106.5825,22.4825],[106.607,22.5985],[106.6485,22.5765],[106.6935,22.5845],[106.753,22.6925],[106.7645,22.7415],[106.833,22.797],[106.783,22.8145],[106.6915,22.8915],[106.6485,22.867],[106.593,22.933],[106.567,22.919],[106.513,22.9485],[106.5005,22.909],[106.4405,22.8895],[106.2865,22.8675],[106.238,22.9515],[106.2,22.9865],[106.001,22.992],[106.003,22.9475],[105.8725,22.9335],[105.825,22.9965],[105.645,23.083],[105.5695,23.0755],[105.5735,23.161],[105.543,23.1935],[105.499,23.2025],[105.445,23.2955],[105.4115,23.288],[105.3515,23.345],[105.322,23.393],[105.2585,23.3195],[105.2275,23.26],[105.179,23.288],[105.107,23.246],[105.082,23.267],[105.025,23.219],[104.9625,23.1985],[104.9275,23.1565],[104.8815,23.166],[104.876,23.1255],[104.802,23.116],[104.8315,23.0035],[104.8655,22.9625],[104.8395,22.9215],[104.771,22.8955],[104.7355,22.8275],[104.6735,22.8185],[104.5785,22.855],[104.478,22.7635],[104.353,22.6935],[104.3395,22.723],[104.269,22.743],[104.256,22.845],[104.115,22.8115],[104.046,22.734],[104.029,22.6875],[104.0125,22.524],[103.962,22.5065],[103.826,22.6155],[103.767,22.6905],[103.6385,22.795],[103.564,22.706],[103.5795,22.664],[103.531,22.595],[103.489,22.6185],[103.4265,22.713],[103.44,22.7535],[103.372,22.7995],[103.3205,22.7805],[103.2875,22.7375],[103.2835,22.684],[103.1855,22.645],[103.14,22.5405],[103.0725,22.4915],[103.0805,22.451],[103.032,22.4425],[102.9235,22.507],[102.88,22.5605],[102.8835,22.589],[102.8255,22.6265],[102.789,22.6255],[102.689,22.703],[102.656,22.6895],[102.6075,22.732],[102.5665,22.722],[102.5105,22.7785],[102.452,22.7525],[102.434,22.7],[102.384,22.6795],[102.4045,22.6335],[102.346,22.583],[102.2495,22.461],[102.1445,22.4]]],[[[107.504,20.143],[107.5255,20.0405],[107.595,19.9635],[107.7065,19.9275],[107.8185,19.944],[107.88,19.9835],[107.9245,20.041],[107.9445,20.091],[107.9455,20.1925],[107.9155,20.2575],[107.8635,20.308],[107.7955,20.3385],[107.721,20.3455],[107.6305,20.318],[107.54,20.242],[107.504,20.143]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/21/Flag_of_Vietnam.svg","name:en":"Vietnam","wikidata":"Q881","ISO3166-1:alpha2":"VN","ISO3166-1:alpha3":"VNM","ISO3166-1:numeric":"704"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[114.288,10.347],[114.336,10.3265],[114.4235,10.349],[114.427,10.399],[114.3985,10.4405],[114.329,10.4365],[114.294,10.4155],[114.288,10.347]]],[[[116.5795,20.697],[116.5895,20.6325],[116.622,20.5755],[116.673,20.532],[116.7375,20.5075],[116.8065,20.5055],[116.8725,20.5255],[116.927,20.565],[116.964,20.62],[116.978,20.6835],[116.9685,20.7475],[116.936,20.805],[116.885,20.848],[116.8205,20.8725],[116.7515,20.8745],[116.6855,20.855],[116.631,20.815],[116.594,20.76],[116.5795,20.697]]],[[[119.103,23.4],[119.115,23.2985],[119.153,23.205],[119.27,23.054],[120.202,22.181],[120.661,21.6295],[120.739,21.573],[120.815,21.5575],[120.861,21.563],[121.648,21.7505],[121.694,21.7655],[121.759,21.8085],[121.803,21.8735],[121.816,21.9775],[121.717,22.698],[121.709,23.454],[122.041,24.412],[122.089,24.5485],[122.196,24.9695],[122.293,25.4395],[122.294,25.514],[122.26,25.7015],[122.216,25.7665],[122.141,25.8145],[122.065,25.83],[121.962,25.8015],[121.408,25.4685],[120.995,25.246],[120.884,25.163],[119.406,23.9405],[119.361,23.8885],[119.118,23.4765],[119.103,23.4]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/7/72/Flag_of_the_Republic_of_China.svg","name:en":"Taiwan","wikidata":"Q865","ISO3166-1:alpha2":"TW","ISO3166-1:alpha3":"TWN","ISO3166-1:numeric":"158"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[124.4165,38.05],[124.3795,38.05],[124.3725,37.91],[124.411,37.84],[124.416,37.7425],[124.4815,37.657],[124.575,37.5975],[124.6595,37.5685],[124.784,37.5665],[124.8775,37.5885],[124.941,37.6325],[124.9775,37.6875],[124.8665,37.7665],[124.85,38.0],[124.6335,38.05],[124.4165,38.05]]],[[[125.4265,37.649],[125.471,37.527],[125.5525,37.4455],[125.718,37.3925],[125.868,37.4095],[125.7525,37.302],[125.713,37.181],[125.635,37.17],[125.561,37.1155],[125.517,37.0595],[125.3045,36.6975],[125.2885,36.5915],[125.339,36.4935],[125.751,36.015],[125.8105,35.8795],[125.836,35.797],[125.848,35.678],[125.8,35.5475],[125.776,35.4495],[125.5695,35.295],[125.0055,34.852],[124.9385,34.7325],[124.8365,34.109],[124.8565,34.003],[124.9015,33.9415],[124.9745,33.8845],[125.061,33.852],[125.417,33.7965],[126.059,33.7],[126.057,33.66],[126.0815,33.581],[126.0355,33.544],[125.925,33.407],[125.906,33.3465],[125.908,33.2725],[125.9255,33.232],[126.01,33.119],[126.072,32.9925],[126.143,32.9385],[126.227,32.911],[126.355,32.9205],[126.414,32.95],[126.4785,33.016],[126.597,33.023],[126.713,33.02],[126.7845,33.046],[126.851,33.098],[126.929,33.119],[127.013,33.1685],[127.1545,33.343],[127.2105,33.4665],[127.215,33.5415],[127.1925,33.597],[127.102,33.6815],[126.992,33.7115],[126.9155,33.759],[127.324,33.8045],[127.5755,33.8245],[127.6625,33.836],[127.7835,33.884],[127.999,34.1235],[128.3065,34.205],[128.8165,34.3435],[128.7925,34.51],[128.9485,34.7255],[129.101,34.9495],[129.174,35.0415],[129.2665,35.1335],[129.4655,35.131],[129.489,35.186],[129.5255,35.2055],[129.5925,35.2845],[129.607,35.3375],[129.669,35.4],[129.7205,35.5465],[129.712,35.627],[129.7435,35.7475],[129.782,35.838],[129.783,35.894],[129.8325,35.9925],[129.8315,36.074],[129.799,36.163],[129.7135,36.2475],[129.63,36.2875],[129.6595,36.322],[129.7025,36.506],[129.687,36.5925],[129.721,36.662],[129.7305,36.776],[129.6705,36.94],[129.6815,37.064],[129.674,37.114],[129.6215,37.1945],[129.6245,37.271],[129.57,37.3615],[129.5025,37.4275],[129.4575,37.5055],[129.3805,37.5875],[129.3375,37.679],[129.2755,37.7825],[129.1405,37.899],[128.942,38.1385],[128.8695,38.2145],[128.8245,38.324],[128.7375,38.4685],[128.6975,38.5065],[128.656,38.6175],[128.3745,38.6235],[128.3065,38.57],[128.3135,38.514],[128.283,38.4365],[128.1575,38.343],[128.0675,38.3085],[127.882,38.331],[127.8205,38.3065],[127.7425,38.341],[127.691,38.3245],[127.5735,38.3335],[127.5055,38.301],[127.3855,38.337],[127.306,38.3175],[127.2235,38.328],[127.1105,38.2955],[127.042,38.259],[126.976,38.199],[126.9645,38.135],[126.87,38.0885],[126.8565,38.041],[126.8125,37.999],[126.7215,37.955],[126.6695,37.9445],[126.6915,37.8395],[126.652,37.781],[126.575,37.7625],[126.4135,37.8445],[126.206,37.823],[126.187,37.749],[126.1605,37.7175],[126.111,37.7125],[126.0165,37.6585],[125.75,37.7145],[125.695,37.6915],[125.5165,37.682],[125.4265,37.649]]],[[[130.5155,37.5225],[130.551,37.4],[130.597,37.347],[130.663,37.305],[130.8275,37.256],[130.9255,37.2565],[131.024,37.285],[131.142,37.367],[131.206,37.474],[131.2165,37.55],[131.1645,37.651],[131.1005,37.702],[130.9645,37.7495],[130.849,37.749],[130.676,37.706],[130.589,37.659],[130.525,37.5735],[130.5155,37.5225]]],[[[131.585,37.2415],[131.608,37.159],[131.666,37.098],[131.7815,37.048],[131.883,37.0385],[132.0075,37.066],[132.0955,37.124],[132.142,37.204],[132.146,37.266],[132.1165,37.335],[132.0185,37.4155],[131.9125,37.447],[131.79,37.443],[131.702,37.413],[131.6465,37.3735],[131.5925,37.2935],[131.585,37.2415]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/09/Flag_of_South_Korea.svg","name:en":"South Korea","wikidata":"Q884","ISO3166-1:alpha2":"KR","ISO3166-1:alpha3":"KOR","ISO3166-1:numeric":"410"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[31.3075,-22.424],[31.3765,-22.3815],[31.858,-21.8905],[32.2775,-21.459],[32.4055,-21.316],[32.476,-21.3115],[32.3995,-21.2065],[32.4,-21.163],[32.3665,-21.1365],[32.388,-21.0985],[32.481,-20.9925],[32.517,-20.9145],[32.498,-20.8075],[32.4945,-20.701],[32.4835,-20.657],[32.514,-20.5985],[32.567,-20.561],[32.668,-20.556],[32.808,-20.339],[32.864,-20.287],[32.8755,-20.1875],[32.8615,-20.1365],[32.9235,-20.1265],[32.943,-20.0425],[33.029,-20.035],[33.0245,-19.966],[33.063,-19.777],[32.9585,-19.723],[32.9755,-19.6515],[32.892,-19.684],[32.8345,-19.6735],[32.857,-19.6185],[32.8585,-19.5465],[32.8455,-19.4835],[32.784,-19.47],[32.7765,-19.3615],[32.85,-19.2935],[32.849,-19.2335],[32.8775,-19.098],[32.8335,-19.0165],[32.7135,-19.025],[32.699,-18.939],[32.7305,-18.9225],[32.7045,-18.857],[32.734,-18.818],[32.827,-18.7775],[32.8775,-18.797],[32.928,-18.7665],[32.954,-18.69],[32.886,-18.579],[32.8845,-18.5225],[32.9085,-18.5],[33.0205,-18.4975],[33.0185,-18.421],[33.0675,-18.3485],[33.0255,-18.3105],[33.0215,-18.2285],[33.003,-18.201],[32.941,-18.011],[32.9735,-17.9385],[32.951,-17.882],[32.9725,-17.8005],[33.0185,-17.786],[33.006,-17.7425],[33.0155,-17.6885],[33.046,-17.637],[33.042,-17.5875],[32.9975,-17.5685],[32.9635,-17.4945],[33.0065,-17.4355],[33.0065,-17.402],[33.0495,-17.3355],[33.0005,-17.314],[32.9865,-17.1795],[32.938,-17.0685],[32.8385,-16.932],[32.914,-16.889],[32.9665,-16.7725],[32.9785,-16.707],[32.9215,-16.6975],[32.888,-16.719],[32.838,-16.6965],[32.761,-16.7055],[32.7025,-16.677],[32.7125,-16.603],[32.6255,-16.5595],[32.412,-16.4695],[32.2855,-16.4345],[32.0375,-16.4425],[31.9135,-16.413],[31.894,-16.3365],[31.8305,-16.3085],[31.771,-16.2365],[31.6925,-16.197],[31.5645,-16.186],[31.412,-16.144],[31.322,-16.0255],[31.1405,-15.9835],[31.0325,-16.0205],[30.982,-16.059],[30.9225,-16.0],[30.4245,-16.0],[30.425,-15.628],[30.421,-15.621],[30.354,-15.6555],[30.2745,-15.6445],[30.2195,-15.667],[30.176,-15.6235],[29.9705,-15.6435],[29.9325,-15.6235],[29.8295,-15.6095],[29.63,-15.6645],[29.571,-15.6445],[29.487,-15.6925],[29.4155,-15.6865],[29.288,-15.7545],[29.222,-15.7685],[29.0465,-15.8985],[29.0305,-15.932],[28.9335,-15.9435],[28.8495,-16.0405],[28.87,-16.1035],[28.8435,-16.1535],[28.836,-16.2125],[28.857,-16.2495],[28.821,-16.303],[28.851,-16.3745],[28.8165,-16.4455],[28.8225,-16.4705],[28.7355,-16.5545],[28.642,-16.5715],[28.269,-16.718],[28.1355,-16.8245],[27.9185,-16.9225],[27.8335,-16.969],[27.801,-17.0055],[27.63,-17.2465],[27.6245,-17.3325],[27.559,-17.4105],[27.424,-17.51],[27.2985,-17.6125],[27.226,-17.6905],[27.144,-17.8065],[27.153,-17.837],[27.0845,-17.901],[27.041,-17.959],[26.9675,-17.965],[26.895,-17.9895],[26.8365,-17.991],[26.803,-18.024],[26.752,-18.021],[26.698,-18.062],[26.602,-18.051],[26.5635,-17.988],[26.51,-17.9905],[26.411,-17.9385],[26.3085,-17.937],[26.245,-17.918],[26.2075,-17.8885],[26.0885,-17.9385],[26.092,-17.981],[26.0015,-17.977],[25.9705,-18.003],[25.863,-17.975],[25.856,-17.918],[25.771,-17.8515],[25.705,-17.8385],[25.682,-17.809],[25.6185,-17.841],[25.5465,-17.8395],[25.5155,-17.8655],[25.453,-17.8435],[25.379,-17.8525],[25.3315,-17.8365],[25.263,-17.7915],[25.2375,-17.9125],[25.2655,-17.9485],[25.2885,-18.027],[25.319,-18.078],[25.3935,-18.121],[25.492,-18.3],[25.5235,-18.384],[25.6105,-18.4835],[25.648,-18.4965],[25.692,-18.573],[25.7825,-18.6245],[25.803,-18.687],[25.7905,-18.72],[25.8255,-18.8375],[25.952,-18.913],[25.985,-18.9735],[25.9965,-19.0315],[25.967,-19.0635],[25.975,-19.1315],[26.042,-19.2105],[26.0435,-19.2365],[26.142,-19.438],[26.1655,-19.5385],[26.2465,-19.585],[26.3125,-19.576],[26.3585,-19.615],[26.3285,-19.6515],[26.388,-19.6695],[26.445,-19.751],[26.5335,-19.77],[26.583,-19.804],[26.622,-19.883],[26.703,-19.8875],[26.7265,-19.94],[26.8515,-19.962],[26.9805,-20.015],[27.046,-20.011],[27.1435,-20.0795],[27.217,-20.0935],[27.285,-20.232],[27.3045,-20.331],[27.2885,-20.499],[27.3625,-20.4685],[27.434,-20.4825],[27.4715,-20.468],[27.5765,-20.4945],[27.622,-20.4795],[27.6955,-20.4905],[27.73,-20.523],[27.7025,-20.604],[27.7035,-20.6575],[27.7325,-20.706],[27.7275,-20.7975],[27.6895,-20.9335],[27.7045,-21.037],[27.693,-21.0875],[27.7515,-21.1545],[27.8055,-21.176],[27.921,-21.335],[28.022,-21.576],[28.0995,-21.5785],[28.199,-21.6035],[28.2925,-21.5895],[28.3665,-21.603],[28.5035,-21.669],[28.5825,-21.6305],[28.6645,-21.6735],[28.7475,-21.701],[28.861,-21.755],[29.065,-21.804],[29.0225,-21.904],[29.0405,-22.0035],[29.075,-22.042],[29.139,-22.072],[29.264,-22.0715],[29.288,-22.1215],[29.3755,-22.1955],[29.472,-22.1655],[29.528,-22.178],[29.541,-22.1525],[29.6055,-22.1555],[29.6545,-22.125],[29.677,-22.139],[29.7735,-22.1415],[29.805,-22.1655],[29.923,-22.189],[29.972,-22.224],[30.0165,-22.229],[30.1215,-22.3085],[30.2275,-22.295],[30.283,-22.354],[30.379,-22.3515],[30.492,-22.3165],[30.626,-22.3365],[30.667,-22.3105],[30.704,-22.317],[30.839,-22.292],[30.9995,-22.3165],[31.094,-22.3485],[31.162,-22.3285],[31.221,-22.37],[31.2735,-22.375],[31.3075,-22.424]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/6a/Flag_of_Zimbabwe.svg","name:en":"Zimbabwe","wikidata":"Q954","ISO3166-1:alpha2":"ZW","ISO3166-1:alpha3":"ZWE","ISO3166-1:numeric":"716"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-180.0,51.794],[-179.93,51.864],[-179.8935,51.928],[-179.8855,51.9975],[-179.9085,52.056],[-180.0,52.1385],[-180.0,52.0895],[-180.0,52.0405],[-180.0,51.991],[-180.0,51.942],[-180.0,51.893],[-180.0,51.8435],[-180.0,51.794]]],[[[-179.4515,51.292],[-179.434,51.184],[-179.3615,51.0915],[-179.285,51.0515],[-179.166,51.025],[-179.078,51.025],[-178.9685,51.048],[-178.8805,51.084],[-178.758,51.1725],[-178.6315,51.239],[-178.5935,51.2815],[-178.5655,51.359],[-178.4635,51.315],[-178.248,51.2885],[-178.124,51.3055],[-178.0445,51.337],[-177.957,51.413],[-177.8765,51.411],[-177.762,51.428],[-177.665,51.4675],[-177.531,51.4775],[-177.376,51.508],[-177.221,51.4955],[-177.089,51.431],[-176.9175,51.407],[-176.6995,51.4325],[-176.561,51.4625],[-176.349,51.543],[-176.277,51.546],[-175.821,51.6445],[-175.6565,51.7115],[-175.555,51.7715],[-175.3475,51.799],[-175.2485,51.823],[-175.0865,51.8135],[-174.949,51.823],[-174.864,51.84],[-174.773,51.8225],[-174.5975,51.831],[-174.4865,51.8235],[-174.2715,51.848],[-174.1195,51.915],[-173.973,51.872],[-173.8545,51.858],[-173.689,51.866],[-173.6,51.8455],[-173.485,51.838],[-173.2985,51.8495],[-173.1605,51.8235],[-173.055,51.83],[-172.9055,51.884],[-172.737,51.9275],[-172.604,52.018],[-172.572,52.0655],[-172.463,52.066],[-172.221,52.1235],[-172.0645,52.1935],[-171.971,52.2815],[-171.9615,52.3845],[-171.995,52.4545],[-172.0965,52.5325],[-172.239,52.5865],[-172.4135,52.6095],[-172.5475,52.5955],[-172.766,52.526],[-172.8515,52.464],[-172.9185,52.378],[-172.9455,52.3155],[-173.0945,52.325],[-173.3025,52.327],[-173.373,52.3545],[-173.494,52.373],[-173.653,52.365],[-173.6735,52.4305],[-173.7235,52.494],[-173.779,52.5305],[-173.9245,52.594],[-174.052,52.6285],[-174.169,52.636],[-174.3625,52.6175],[-174.441,52.599],[-174.581,52.5195],[-174.684,52.472],[-174.762,52.3755],[-174.835,52.3475],[-174.8915,52.3895],[-174.997,52.43],[-175.1485,52.442],[-175.236,52.43],[-175.3565,52.3825],[-175.4905,52.4015],[-175.584,52.3945],[-175.7085,52.3555],[-175.8115,52.273],[-175.9795,52.325],[-176.1545,52.3325],[-176.2385,52.322],[-176.3315,52.2915],[-176.455,52.208],[-176.6445,52.213],[-176.876,52.1665],[-176.959,52.1375],[-177.091,52.157],[-177.238,52.1515],[-177.324,52.131],[-177.451,52.1425],[-177.5975,52.116],[-177.692,52.0645],[-177.7995,52.1145],[-177.896,52.1335],[-178.0895,52.136],[-178.298,52.1105],[-178.4305,52.052],[-178.509,51.9725],[-178.5955,52.0165],[-178.7795,52.0525],[-178.927,52.039],[-179.087,51.966],[-179.15,51.8965],[-179.1785,51.7925],[-179.2855,51.745],[-179.3665,51.6435],[-179.3645,51.5255],[-179.321,51.466],[-179.4275,51.3735],[-179.4515,51.292]]],[[[-178.533,28.3915],[-178.519,28.3235],[-178.4795,28.2635],[-178.42,28.2185],[-178.308,28.189],[-178.2345,28.221],[-178.1795,28.272],[-178.147,28.336],[-178.1405,28.4055],[-178.1605,28.4735],[-178.2045,28.5315],[-178.2685,28.5735],[-178.3445,28.5945],[-178.4575,28.546],[-178.5055,28.4915],[-178.533,28.3915]]],[[[-177.6235,28.213],[-177.6085,28.142],[-177.568,28.0785],[-177.506,28.0305],[-177.43,28.0025],[-177.3475,27.9985],[-177.2505,28.03],[-177.179,28.083],[-177.1325,28.154],[-177.116,28.235],[-177.132,28.316],[-177.1785,28.387],[-177.25,28.44],[-177.3375,28.468],[-177.4415,28.444],[-177.5455,28.3765],[-177.595,28.3185],[-177.6235,28.213]]],[[[-176.824,0.817],[-176.813,0.7485],[-176.7775,0.674],[-176.7075,0.615],[-176.648,0.5955],[-176.539,0.608],[-176.47,0.655],[-176.4275,0.721],[-176.4135,0.7735],[-176.4215,0.8705],[-176.455,0.936],[-176.4885,0.972],[-176.549,1.0075],[-176.632,1.021],[-176.6935,1.008],[-176.759,0.967],[-176.7945,0.923],[-176.824,0.817]]],[[[-176.686,0.1925],[-176.6575,0.088],[-176.5915,0.02],[-176.508,-0.0095],[-176.433,-0.0075],[-176.3785,0.0125],[-176.311,0.0705],[-176.2735,0.155],[-176.2835,0.2685],[-176.317,0.3265],[-176.395,0.386],[-176.456,0.402],[-176.546,0.3925],[-176.593,0.369],[-176.6535,0.3045],[-176.686,0.1925]]],[[[-176.147,27.7575],[-176.1335,27.6915],[-176.0965,27.6335],[-176.0395,27.589],[-175.969,27.564],[-175.8935,27.561],[-175.733,27.6],[-175.6575,27.645],[-175.604,27.71],[-175.579,27.7875],[-175.526,27.8725],[-175.5205,27.937],[-175.5405,27.999],[-175.5825,28.052],[-175.6425,28.089],[-175.713,28.1065],[-175.786,28.1015],[-175.9275,28.0585],[-175.993,28.022],[-176.0435,27.97],[-176.0735,27.907],[-176.12,27.8545],[-176.147,27.7575]]],[[[-174.2355,26.0505],[-174.2195,25.98],[-174.178,25.9185],[-174.116,25.873],[-174.0405,25.8485],[-173.9605,25.8485],[-173.8835,25.869],[-173.816,25.9075],[-173.767,25.9645],[-173.7425,26.0325],[-173.745,26.104],[-173.774,26.171],[-173.8265,26.225],[-173.8965,26.2595],[-173.975,26.2715],[-174.055,26.263],[-174.1285,26.2345],[-174.187,26.1855],[-174.2245,26.122],[-174.2355,26.0505]]],[[[-173.504,60.655],[-173.4485,60.5555],[-173.451,60.4885],[-173.362,60.3855],[-173.2515,60.3375],[-173.136,60.306],[-173.175,60.1935],[-173.1155,60.109],[-173.0385,60.064],[-172.9215,60.029],[-172.801,60.0135],[-172.656,60.0175],[-172.4615,60.0685],[-172.3855,60.119],[-172.19,60.1135],[-172.102,60.124],[-171.9265,60.183],[-171.848,60.2375],[-171.8035,60.3245],[-171.8165,60.381],[-171.8915,60.4555],[-172.0835,60.5485],[-172.249,60.5995],[-172.4755,60.6145],[-172.5315,60.71],[-172.662,60.7845],[-172.75,60.8535],[-172.8645,60.8945],[-172.9725,60.9115],[-173.113,60.912],[-173.285,60.8785],[-173.3835,60.833],[-173.4745,60.7515],[-173.504,60.655]]],[[[-172.2945,63.56],[-172.266,63.433],[-172.1975,63.343],[-172.0855,63.2625],[-171.953,63.21],[-171.66,63.1415],[-171.503,63.1235],[-171.3595,63.1215],[-171.196,63.143],[-170.9955,63.1985],[-170.9165,63.2335],[-170.7125,63.1915],[-170.6645,63.116],[-170.572,63.061],[-170.4635,63.027],[-170.2345,62.9955],[-170.186,62.974],[-170.1765,62.919],[-170.097,62.8405],[-169.9795,62.792],[-169.794,62.7595],[-169.602,62.7525],[-169.3885,62.7835],[-169.1955,62.849],[-169.0975,62.9195],[-168.899,62.882],[-168.7775,62.881],[-168.6205,62.9035],[-168.45,62.964],[-168.348,63.06],[-168.346,63.131],[-168.2365,63.2705],[-168.228,63.331],[-168.2975,63.4235],[-168.45,63.4895],[-168.737,63.539],[-168.9115,63.559],[-169.2635,63.5605],[-169.459,63.62],[-169.5835,63.6355],[-169.6035,63.7385],[-169.6525,63.782],[-169.7735,63.836],[-170.0435,63.891],[-170.1725,63.9055],[-170.4135,63.914],[-170.577,63.9045],[-170.8545,63.853],[-170.9855,63.812],[-171.197,63.841],[-171.319,63.943],[-171.4335,63.98],[-171.609,64.003],[-171.78,64.0075],[-171.9885,63.9775],[-172.0985,63.9365],[-172.1685,63.8905],[-172.211,63.8205],[-172.2145,63.72],[-172.273,63.642],[-172.2945,63.56]]],[[[-171.967,25.771],[-171.9525,25.697],[-171.911,25.6325],[-171.847,25.5845],[-171.7275,25.5555],[-171.647,25.57],[-171.5765,25.608],[-171.5245,25.665],[-171.497,25.7345],[-171.497,25.8085],[-171.525,25.878],[-171.577,25.935],[-171.6475,25.9725],[-171.7285,25.9865],[-171.81,25.9735],[-171.882,25.936],[-171.935,25.8785],[-171.967,25.771]]],[[[-169.016,65.481],[-168.798,65.442],[-168.5705,65.4495],[-168.441,65.476],[-168.2595,65.412],[-167.9725,65.3515],[-167.734,65.2695],[-167.5375,65.2295],[-167.402,65.218],[-167.396,65.128],[-167.3515,65.0775],[-167.2185,64.988],[-167.132,64.9495],[-167.015,64.864],[-166.925,64.8315],[-166.924,64.7345],[-166.8695,64.6435],[-166.805,64.576],[-166.669,64.5015],[-166.6145,64.409],[-166.4425,64.3225],[-166.2995,64.2955],[-166.0855,64.295],[-165.9605,64.3155],[-165.8395,64.357],[-165.4325,64.309],[-165.101,64.2575],[-164.9735,64.252],[-164.7835,64.2615],[-164.568,64.291],[-164.198,64.381],[-163.92,64.3695],[-163.677,64.38],[-163.526,64.294],[-163.3725,64.2385],[-162.885,64.147],[-162.699,64.1435],[-162.467,64.191],[-162.2435,64.284],[-162.1675,64.3525],[-161.728,64.2195],[-161.756,64.121],[-161.7125,64.0485],[-161.6255,63.994],[-161.452,63.9435],[-161.2975,63.9305],[-161.258,63.8965],[-161.233,63.8165],[-161.372,63.7525],[-161.507,63.802],[-161.6355,63.822],[-161.8605,63.8165],[-162.025,63.776],[-162.219,63.8335],[-162.3785,63.8495],[-162.6575,63.845],[-162.859,63.802],[-163.0535,63.718],[-163.128,63.6535],[-163.1465,63.5865],[-163.107,63.5125],[-162.947,63.414],[-163.099,63.3725],[-163.2215,63.303],[-163.4905,63.4015],[-163.8615,63.467],[-164.106,63.48],[-164.237,63.472],[-164.521,63.4205],[-164.6345,63.3885],[-164.863,63.3025],[-165.0215,63.221],[-165.2445,63.214],[-165.348,63.1915],[-165.4595,63.144],[-165.5185,63.095],[-165.5465,63.027],[-165.5045,62.937],[-165.4375,62.891],[-165.313,62.845],[-165.3575,62.7795],[-165.5825,62.7305],[-165.6765,62.6765],[-165.721,62.6215],[-165.77,62.483],[-165.762,62.4385],[-165.974,62.291],[-166.102,62.277],[-166.2715,62.2195],[-166.3445,62.1705],[-166.407,62.0965],[-166.403,61.9805],[-166.536,61.8215],[-166.5775,61.6555],[-166.5775,61.5655],[-166.531,61.464],[-166.436,61.378],[-166.38,61.304],[-166.213,61.2295],[-166.141,61.175],[-166.025,61.123],[-165.9455,61.0075],[-165.7575,60.9165],[-165.5285,60.873],[-165.443,60.7985],[-165.5785,60.758],[-165.708,60.699],[-165.794,60.6055],[-165.841,60.598],[-166.0325,60.6585],[-166.18,60.668],[-166.305,60.655],[-166.451,60.6075],[-166.601,60.59],[-166.712,60.559],[-166.862,60.54],[-166.9785,60.501],[-167.042,60.4615],[-167.388,60.4515],[-167.5295,60.427],[-167.7055,60.368],[-167.767,60.33],[-167.8275,60.242],[-167.827,60.193],[-167.7855,60.127],[-167.7165,60.068],[-167.672,59.9895],[-167.539,59.909],[-167.2315,59.808],[-167.0505,59.788],[-166.788,59.6875],[-166.655,59.663],[-166.5065,59.659],[-166.4385,59.6175],[-166.2815,59.569],[-166.1365,59.557],[-165.994,59.567],[-165.85,59.5975],[-165.744,59.647],[-165.697,59.6875],[-165.571,59.697],[-165.4025,59.73],[-165.3225,59.757],[-165.227,59.813],[-165.1545,59.886],[-165.1125,59.97],[-165.1125,60.015],[-164.943,60.003],[-164.804,60.014],[-164.709,59.9515],[-164.6815,59.8665],[-164.55,59.7425],[-164.4525,59.6695],[-164.26,59.556],[-164.135,59.5105],[-163.858,59.472],[-163.7055,59.4775],[-163.5765,59.509],[-163.4445,59.589],[-163.2395,59.601],[-163.005,59.6375],[-162.8595,59.638],[-162.717,59.6545],[-162.6155,59.6835],[-162.5325,59.603],[-162.4335,59.5605],[-162.2485,59.532],[-162.3925,59.372],[-162.4285,59.3055],[-162.414,59.22],[-162.3005,59.062],[-162.1565,58.938],[-162.152,58.8845],[-162.342,58.8445],[-162.497,58.758],[-162.5345,58.702],[-162.539,58.6425],[-162.4925,58.5665],[-162.408,58.5125],[-162.286,58.4695],[-162.04,58.435],[-161.961,58.3995],[-161.837,58.371],[-161.737,58.365],[-161.5145,58.385],[-161.3595,58.44],[-161.271,58.3965],[-161.076,58.363],[-160.8035,58.382],[-160.6785,58.416],[-160.5745,58.467],[-160.3975,58.4125],[-160.2915,58.4055],[-160.125,58.4275],[-159.9315,58.408],[-159.7455,58.441],[-159.674,58.4725],[-159.5775,58.5545],[-159.4285,58.4035],[-159.387,58.3225],[-159.2855,58.2575],[-159.185,58.224],[-159.073,58.2065],[-158.8235,58.2075],[-158.6465,58.236],[-158.523,58.2785],[-158.377,58.355],[-158.18,58.3985],[-157.9665,58.2365],[-157.9545,58.145],[-158.003,57.9],[-158.058,57.7635],[-158.1355,57.695],[-158.156,57.6455],[-158.2635,57.5705],[-158.3695,57.522],[-158.517,57.476],[-158.6415,57.416],[-158.7495,57.3165],[-158.972,57.1255],[-159.003,57.089],[-159.141,57.039],[-159.2745,56.969],[-159.6255,56.859],[-159.7295,56.8095],[-159.9535,56.745],[-160.062,56.7025],[-160.2145,56.615],[-160.3465,56.575],[-160.649,56.409],[-160.713,56.3385],[-160.768,56.2445],[-161.041,56.2435],[-161.24,56.2205],[-161.3745,56.195],[-161.6645,56.1515],[-161.9265,56.0975],[-162.0495,56.0515],[-162.143,55.9965],[-162.2825,55.9535],[-162.5145,55.835],[-162.751,55.6535],[-162.882,55.6005],[-163.0135,55.6555],[-163.1355,55.6785],[-163.234,55.6785],[-163.351,55.657],[-163.4715,55.597],[-163.5245,55.5345],[-163.534,55.452],[-163.4485,55.318],[-163.6445,55.261],[-163.78,55.2725],[-163.9855,55.247],[-164.132,55.1955],[-164.254,55.1775],[-164.3365,55.147],[-164.465,55.1505],[-164.6415,55.114],[-164.7795,55.0505],[-164.837,55.0095],[-164.9465,54.84],[-165.16,54.756],[-165.2525,54.6715],[-165.2765,54.6115],[-165.2595,54.505],[-165.3405,54.4975],[-165.4855,54.5145],[-165.6665,54.5105],[-165.779,54.4885],[-165.881,54.4405],[-166.092,54.422],[-166.2785,54.349],[-166.356,54.297],[-166.407,54.227],[-166.5345,54.2215],[-166.66,54.2335],[-166.7895,54.2275],[-166.973,54.196],[-167.1505,54.1545],[-167.3445,54.054],[-167.4395,53.969],[-167.469,53.9225],[-167.4725,53.807],[-167.429,53.7415],[-167.4725,53.6865],[-167.521,53.6685],[-167.626,53.717],[-167.7605,53.7385],[-167.8475,53.7665],[-167.7325,53.8285],[-167.686,53.8885],[-167.6735,53.942],[-167.71,54.0345],[-167.834,54.125],[-167.97,54.158],[-168.088,54.158],[-168.2355,54.12],[-168.3065,54.0775],[-168.352,54.025],[-168.3685,53.9335],[-168.2965,53.8255],[-168.193,53.7705],[-168.4045,53.7125],[-168.551,53.648],[-168.6705,53.551],[-168.7185,53.48],[-168.7985,53.4545],[-168.9955,53.3365],[-169.0815,53.267],[-169.123,53.1695],[-169.178,53.129],[-169.3315,53.0985],[-169.422,53.1925],[-169.5325,53.252],[-169.6355,53.287],[-169.7375,53.299],[-169.914,53.2745],[-170.018,53.2275],[-170.0965,53.1405],[-170.1785,53.13],[-170.313,53.077],[-170.4205,52.979],[-170.4475,52.893],[-170.565,52.9125],[-170.6985,52.9165],[-170.813,52.8935],[-170.9265,52.8525],[-171.038,52.7965],[-171.1935,52.8015],[-171.302,52.7775],[-171.5375,52.655],[-171.611,52.568],[-171.626,52.5065],[-171.597,52.396],[-171.5505,52.3435],[-171.437,52.286],[-171.3375,52.2655],[-171.1665,52.2655],[-171.017,52.305],[-170.9185,52.3765],[-170.7505,52.358],[-170.627,52.3795],[-170.535,52.42],[-170.367,52.4745],[-170.2685,52.5455],[-170.1805,52.5345],[-170.018,52.533],[-169.8655,52.571],[-169.8145,52.6],[-169.6485,52.591],[-169.48,52.6345],[-169.359,52.588],[-169.2355,52.576],[-169.146,52.5855],[-169.0235,52.618],[-168.9455,52.6515],[-168.7305,52.722],[-168.576,52.75],[-168.4935,52.7915],[-168.333,52.7985],[-168.1555,52.866],[-168.0885,52.92],[-168.0525,53.029],[-167.959,53.0825],[-167.8675,53.0885],[-167.779,53.0535],[-167.6845,53.038],[-167.525,53.05],[-167.305,53.1015],[-167.221,53.1445],[-167.086,53.1885],[-166.988,53.239],[-166.769,53.244],[-166.673,53.257],[-166.5225,53.3025],[-166.322,53.404],[-166.1985,53.4985],[-166.0125,53.5535],[-165.8655,53.642],[-165.7715,53.6865],[-165.6955,53.776],[-165.6855,53.8595],[-165.592,53.8425],[-165.486,53.842],[-165.365,53.8595],[-165.2195,53.8545],[-165.1,53.88],[-164.8625,53.8935],[-164.695,53.9495],[-164.5985,54.0365],[-164.4715,54.105],[-164.4245,54.157],[-164.403,54.2345],[-164.245,54.2695],[-164.088,54.344],[-163.992,54.4405],[-163.7765,54.4505],[-163.615,54.4165],[-163.49,54.418],[-163.406,54.4355],[-163.3095,54.478],[-163.2375,54.478],[-163.2605,54.3725],[-163.2015,54.2715],[-163.105,54.211],[-162.944,54.176],[-162.8915,54.1485],[-162.7475,54.1125],[-162.607,54.1085],[-162.4225,54.1295],[-162.2195,54.1985],[-162.085,54.253],[-162.0215,54.3045],[-161.983,54.3815],[-161.9865,54.4355],[-161.8665,54.4635],[-161.783,54.508],[-161.738,54.5515],[-161.641,54.5795],[-161.4935,54.6035],[-161.352,54.667],[-161.2895,54.7455],[-161.293,54.839],[-161.1335,54.9185],[-161.089,54.9715],[-161.0135,54.9745],[-160.9065,54.9435],[-160.726,54.94],[-160.584,54.8985],[-160.555,54.8315],[-160.466,54.7465],[-160.37,54.703],[-160.183,54.68],[-160.065,54.697],[-159.955,54.639],[-159.66,54.578],[-159.557,54.569],[-159.3725,54.5875],[-159.264,54.629],[-159.19,54.68],[-159.035,54.718],[-158.9305,54.7805],[-158.8705,54.8355],[-158.8345,54.9345],[-158.8695,55.0265],[-158.924,55.075],[-158.9525,55.153],[-159.062,55.2355],[-159.125,55.258],[-159.13,55.347],[-159.171,55.4015],[-159.2885,55.4675],[-159.231,55.5485],[-159.0515,55.616],[-158.944,55.595],[-158.7955,55.5975],[-158.6425,55.644],[-158.539,55.6625],[-158.3905,55.7355],[-158.334,55.814],[-158.232,55.836],[-158.126,55.8885],[-158.065,55.95],[-157.963,55.9635],[-157.8675,55.9955],[-157.742,56.0885],[-157.6025,56.0965],[-157.507,56.1215],[-157.393,56.1905],[-157.357,56.2425],[-157.3485,56.331],[-157.1005,56.329],[-157.1485,56.2335],[-157.1535,56.152],[-157.0955,56.06],[-157.0715,55.947],[-157.0,55.8705],[-156.846,55.81],[-156.731,55.798],[-156.627,55.806],[-156.478,55.8375],[-156.3455,55.9115],[-156.2675,56.0025],[-156.255,56.061],[-156.2785,56.1425],[-156.367,56.235],[-156.4195,56.328],[-156.5285,56.4025],[-156.6565,56.438],[-156.608,56.493],[-156.5925,56.566],[-156.61,56.6155],[-156.4705,56.6995],[-156.321,56.739],[-156.2555,56.777],[-156.098,56.9325],[-156.035,57.0125],[-155.912,57.105],[-155.8945,57.198],[-155.923,57.2525],[-155.7365,57.3125],[-155.6735,57.36],[-155.5295,57.3855],[-155.424,57.434],[-155.37,57.482],[-155.151,57.437],[-155.192,57.3215],[-155.1385,57.215],[-155.014,57.146],[-154.874,57.103],[-154.877,56.985],[-154.7915,56.879],[-154.6535,56.8205],[-154.7095,56.786],[-154.922,56.687],[-155.01,56.629],[-155.102,56.5425],[-155.137,56.487],[-155.131,56.392],[-155.0355,56.292],[-154.8955,56.2345],[-154.7515,56.2155],[-154.544,56.242],[-154.4095,56.3045],[-154.0215,56.312],[-153.781,56.34],[-153.6435,56.3885],[-153.538,56.4595],[-153.4815,56.538],[-153.482,56.638],[-153.4025,56.726],[-153.2275,56.809],[-153.1155,56.8245],[-152.9535,56.8785],[-152.876,56.938],[-152.7555,56.957],[-152.5805,57.0285],[-152.492,57.1225],[-152.3725,57.182],[-152.2145,57.1815],[-152.019,57.2305],[-151.9445,57.27],[-151.8735,57.3515],[-151.879,57.459],[-151.7955,57.523],[-151.7445,57.613],[-151.743,57.679],[-151.8145,57.7695],[-151.833,57.8555],[-151.9265,57.9445],[-151.9365,57.979],[-151.7165,57.992],[-151.5225,58.059],[-151.4435,58.1195],[-151.396,58.2035],[-151.3875,58.2615],[-151.423,58.429],[-151.5425,58.5195],[-151.6775,58.5565],[-151.7675,58.564],[-151.84,58.648],[-151.9185,58.7005],[-151.821,58.7215],[-151.6285,58.811],[-151.5505,58.917],[-151.406,58.9215],[-151.269,58.9385],[-151.1125,59.0025],[-151.0285,59.0155],[-150.8535,59.0175],[-150.742,59.0415],[-150.62,59.103],[-150.4745,59.1365],[-150.386,59.1335],[-150.23,59.155],[-150.058,59.233],[-149.938,59.332],[-149.894,59.3945],[-149.7805,59.354],[-149.5885,59.334],[-149.4245,59.3555],[-149.3455,59.3825],[-149.2525,59.4425],[-149.157,59.5715],[-149.1475,59.6305],[-148.956,59.7465],[-148.577,59.729],[-148.411,59.7575],[-148.2995,59.7525],[-148.235,59.6805],[-148.149,59.632],[-148.004,59.592],[-147.782,59.5795],[-147.5245,59.6255],[-147.428,59.6525],[-147.2685,59.677],[-147.136,59.7145],[-147.006,59.775],[-146.9315,59.8525],[-146.913,59.981],[-146.8055,59.9755],[-146.6395,59.9935],[-146.4695,60.0615],[-146.386,60.081],[-146.223,60.1465],[-146.0925,60.161],[-145.9715,60.192],[-145.784,60.1675],[-145.698,60.133],[-145.3905,60.064],[-145.2595,60.045],[-144.8215,60.015],[-144.9185,59.942],[-144.9815,59.85],[-144.9915,59.7955],[-144.9595,59.7245],[-144.8965,59.662],[-144.7335,59.5945],[-144.5805,59.5775],[-144.4585,59.586],[-144.3,59.633],[-144.089,59.784],[-143.7795,59.8115],[-143.6175,59.84],[-143.407,59.853],[-143.03,59.8605],[-142.797,59.902],[-142.6425,59.9075],[-142.5295,59.879],[-142.316,59.874],[-142.0255,59.8395],[-141.8395,59.7835],[-141.7375,59.773],[-141.5835,59.712],[-141.325,59.6525],[-141.0395,59.57],[-140.6345,59.5235],[-140.4215,59.519],[-139.6755,59.2455],[-139.475,59.1825],[-139.107,59.093],[-138.8435,58.9835],[-138.754,58.9575],[-138.4585,58.894],[-138.3145,58.8245],[-138.2915,58.749],[-138.174,58.653],[-138.035,58.59],[-137.9365,58.4965],[-137.7475,58.4285],[-137.505,58.323],[-137.4065,58.2915],[-137.3265,58.2445],[-137.1495,58.1995],[-137.0015,58.106],[-136.939,58.081],[-136.933,57.919],[-136.9075,57.86],[-136.737,57.7085],[-136.628,57.6485],[-136.5595,57.5265],[-136.4405,57.4415],[-136.2765,57.379],[-136.2325,57.343],[-136.2275,57.2215],[-136.1885,57.1485],[-136.2115,57.021],[-136.177,56.9295],[-136.0785,56.8595],[-135.9065,56.8115],[-135.85,56.7365],[-135.703,56.633],[-135.5735,56.5635],[-135.4475,56.523],[-135.3805,56.471],[-135.293,56.3715],[-135.2645,56.3175],[-135.11,56.152],[-134.886,56.0215],[-134.9475,55.9395],[-134.9535,55.8945],[-134.9245,55.823],[-134.8415,55.75],[-134.709,55.692],[-134.512,55.6755],[-134.426,55.6465],[-134.2875,55.6305],[-134.1235,55.6535],[-134.0835,55.6025],[-134.15,55.5085],[-134.16,55.4425],[-134.113,55.3535],[-134.0205,55.294],[-133.96,55.1925],[-133.8895,55.1275],[-133.8105,55.0815],[-133.8175,55.013],[-133.888,54.9135],[-133.8635,54.749],[-133.7925,54.6625],[-133.716,54.612],[-133.648,54.632],[-132.9255,54.659],[-132.684,54.662],[-131.7515,54.6825],[-131.435,54.6895],[-130.6155,54.7075],[-130.659,54.763],[-130.568,54.792],[-130.346,54.9175],[-130.2735,54.974],[-130.1875,55.063],[-130.103,55.1925],[-129.974,55.282],[-130.021,55.338],[-130.041,55.4515],[-130.09,55.498],[-130.128,55.581],[-130.1115,55.683],[-130.1525,55.7665],[-130.0835,55.8215],[-130.0175,55.912],[-130.0035,56.008],[-130.104,56.123],[-130.246,56.0965],[-130.426,56.1415],[-130.468,56.243],[-130.6235,56.267],[-130.782,56.367],[-131.0875,56.406],[-131.1735,56.4495],[-131.472,56.5525],[-131.581,56.612],[-131.8355,56.599],[-131.8605,56.703],[-131.901,56.7535],[-131.873,56.806],[-132.1235,56.8735],[-132.045,57.045],[-132.369,57.0915],[-132.248,57.2115],[-132.37,57.3495],[-132.5535,57.4965],[-132.661,57.6165],[-132.751,57.696],[-132.8695,57.8395],[-133.07,58.0005],[-133.1725,58.1535],[-133.3455,58.2765],[-133.4615,58.3875],[-133.3775,58.4305],[-133.558,58.523],[-133.707,58.6125],[-133.8405,58.7295],[-134.258,58.861],[-134.3365,58.9235],[-134.3135,58.962],[-134.407,58.979],[-134.382,59.039],[-134.4835,59.1315],[-134.5655,59.131],[-134.679,59.1925],[-134.7005,59.249],[-134.96,59.281],[-135.0305,59.3465],[-134.9895,59.387],[-135.101,59.4275],[-135.0275,59.4745],[-135.029,59.5635],[-135.1575,59.6255],[-135.253,59.6985],[-135.479,59.798],[-135.9525,59.662],[-136.193,59.64],[-136.3465,59.6005],[-136.24,59.5595],[-136.2385,59.5245],[-136.305,59.4645],[-136.368,59.449],[-136.477,59.466],[-136.469,59.284],[-136.5845,59.166],[-136.8285,59.16],[-136.9695,59.101],[-137.283,59.0],[-137.4515,58.9085],[-137.526,58.9065],[-137.5,58.9855],[-137.542,59.1065],[-137.6075,59.244],[-138.626,59.7685],[-138.6685,59.8095],[-138.7075,59.9065],[-139.0535,59.995],[-139.199,60.0885],[-139.072,60.3195],[-139.075,60.3525],[-139.693,60.335],[-139.981,60.182],[-140.458,60.308],[-140.5205,60.22],[-140.769,60.26],[-141.002,60.3065],[-141.002,60.8185],[-141.002,61.249],[-141.0015,61.597],[-141.0015,62.224],[-141.0015,62.615],[-141.0015,63.022],[-141.0015,63.5185],[-141.0015,63.9315],[-141.0015,64.543],[-141.0015,64.992],[-141.0015,65.494],[-141.0015,66.179],[-141.001,66.8875],[-141.001,67.5985],[-141.001,68.095],[-141.001,68.8115],[-141.0005,69.419],[-141.0025,69.846],[-140.996,69.8885],[-141.126,69.8985],[-141.3175,69.9555],[-141.796,70.046],[-142.3805,70.219],[-142.7405,70.2895],[-142.956,70.3435],[-143.2065,70.3685],[-143.7085,70.357],[-144.1365,70.319],[-144.269,70.29],[-144.758,70.218],[-145.1165,70.2545],[-145.294,70.2855],[-145.5265,70.349],[-145.727,70.3845],[-146.229,70.44],[-146.502,70.449],[-146.7885,70.508],[-146.9565,70.52],[-147.1695,70.582],[-147.4135,70.6105],[-147.6085,70.6785],[-147.7955,70.706],[-148.01,70.711],[-148.1925,70.695],[-148.444,70.6985],[-148.6135,70.681],[-149.3265,70.768],[-149.7205,70.786],[-150.2745,70.7695],[-150.4735,70.7465],[-150.6,70.7155],[-150.999,70.692],[-151.2215,70.757],[-151.3845,70.7755],[-151.5245,70.846],[-151.671,70.9475],[-151.846,71.004],[-152.253,71.0785],[-152.681,71.118],[-153.078,71.1385],[-153.3705,71.131],[-153.5645,71.1045],[-153.8065,71.1065],[-154.102,71.1545],[-154.346,71.243],[-154.7575,71.345],[-155.1875,71.4105],[-155.4645,71.4425],[-155.678,71.501],[-156.206,71.588],[-156.57,71.602],[-156.8675,71.5575],[-157.303,71.4165],[-157.519,71.308],[-157.749,71.1735],[-157.8885,71.1155],[-158.213,71.0365],[-158.428,71.102],[-158.704,71.1275],[-158.9855,71.117],[-159.4835,71.0615],[-159.8255,71.007],[-159.9995,70.9695],[-160.361,70.8365],[-160.6595,70.7055],[-160.897,70.6195],[-161.237,70.536],[-161.4065,70.5115],[-161.705,70.539],[-162.022,70.539],[-162.2185,70.5075],[-162.668,70.372],[-162.923,70.2635],[-163.1865,70.0905],[-163.45,69.9545],[-163.5865,69.841],[-163.6965,69.6725],[-163.7035,69.446],[-163.7455,69.402],[-164.0605,69.2355],[-164.2695,69.1695],[-164.4215,69.136],[-164.738,69.125],[-165.2905,69.0785],[-165.5785,69.0675],[-166.21,69.0975],[-166.3875,69.085],[-166.579,69.0425],[-166.691,68.9905],[-166.7635,68.8985],[-166.7275,68.7935],[-166.764,68.629],[-166.813,68.584],[-167.0405,68.5455],[-167.206,68.499],[-167.3225,68.435],[-167.364,68.3325],[-167.245,68.228],[-167.103,68.1825],[-166.9475,68.1595],[-166.7215,68.158],[-166.484,68.112],[-166.319,68.003],[-166.1625,67.9585],[-165.8015,67.902],[-165.593,67.822],[-165.203,67.697],[-164.972,67.604],[-164.7435,67.5345],[-164.5205,67.49],[-164.383,67.3485],[-164.339,67.2795],[-164.408,67.2135],[-164.4175,67.165],[-164.3795,67.0975],[-164.2085,67.009],[-163.9695,66.938],[-163.7105,66.899],[-163.184,66.8475],[-163.131,66.8355],[-163.1195,66.7625],[-163.0255,66.6745],[-162.782,66.5735],[-162.541,66.5375],[-162.3785,66.4575],[-162.865,66.3205],[-163.155,66.383],[-163.0015,66.4815],[-162.985,66.563],[-163.0285,66.626],[-163.1015,66.674],[-163.2485,66.7305],[-163.4755,66.7815],[-163.6845,66.8055],[-163.9035,66.813],[-164.152,66.8095],[-164.502,66.7925],[-165.0175,66.727],[-165.703,66.6005],[-166.066,66.5195],[-166.6515,66.362],[-167.1,66.226],[-167.6265,66.0495],[-167.786,66.005],[-168.151,65.93],[-168.415,65.846],[-168.5605,65.937],[-168.7645,65.9805],[-168.9245,65.986],[-169.016,65.481]]],[[[-171.295,-11.0535],[-171.2835,-11.1225],[-171.2175,-11.2175],[-171.1575,-11.2545],[-171.055,-11.2675],[-170.976,-11.242],[-170.8985,-11.1725],[-170.862,-11.0765],[-170.8635,-11.023],[-170.884,-10.9615],[-170.9435,-10.8895],[-170.9885,-10.8625],[-171.0695,-10.845],[-171.1615,-10.861],[-171.2145,-10.8905],[-171.2825,-10.9825],[-171.295,-11.0535]]],[[[-171.053,-14.3205],[-171.025,-14.423],[-170.9585,-14.4935],[-170.8555,-14.552],[-170.791,-14.573],[-170.712,-14.57],[-170.6195,-14.528],[-170.5735,-14.4905],[-170.5005,-14.484],[-170.448,-14.464],[-170.3675,-14.3865],[-170.341,-14.309],[-170.345,-14.237],[-170.3775,-14.154],[-170.408,-14.111],[-170.4675,-14.0665],[-170.5205,-14.048],[-170.6715,-14.028],[-170.7615,-14.0485],[-170.8225,-14.0895],[-170.883,-14.1055],[-170.995,-14.1805],[-171.0365,-14.242],[-171.053,-14.3205]]],[[[-170.802,25.4225],[-170.789,25.3545],[-170.751,25.2945],[-170.693,25.2495],[-170.621,25.225],[-170.546,25.224],[-170.476,25.245],[-170.4175,25.286],[-170.377,25.3415],[-170.359,25.406],[-170.365,25.4725],[-170.395,25.5335],[-170.4455,25.5825],[-170.5105,25.6135],[-170.5835,25.624],[-170.6585,25.6105],[-170.7245,25.5755],[-170.773,25.522],[-170.802,25.4225]]],[[[-170.773,57.177],[-170.7505,57.109],[-170.7515,57.019],[-170.7155,56.9665],[-170.6465,56.9165],[-170.4825,56.866],[-170.3845,56.859],[-170.23,56.876],[-170.1435,56.9055],[-169.984,56.998],[-169.835,57.0015],[-169.7405,57.022],[-169.627,57.0775],[-169.5775,57.126],[-169.5515,57.2145],[-169.5795,57.279],[-169.712,57.3665],[-169.949,57.4515],[-170.065,57.465],[-170.1795,57.4605],[-170.2985,57.4345],[-170.4925,57.412],[-170.645,57.3605],[-170.746,57.2755],[-170.773,57.177]]],[[[-170.131,56.6285],[-170.1105,56.5625],[-170.008,56.474],[-169.868,56.406],[-169.7365,56.365],[-169.521,56.3495],[-169.343,56.3865],[-169.1975,56.459],[-169.0995,56.5575],[-169.0865,56.6175],[-169.129,56.7055],[-169.257,56.7815],[-169.3625,56.8105],[-169.509,56.823],[-169.76,56.8305],[-169.892,56.8175],[-170.0545,56.752],[-170.1025,56.7065],[-170.131,56.6285]]],[[[-169.8935,-14.165],[-169.871,-14.258],[-169.834,-14.3125],[-169.778,-14.3595],[-169.6605,-14.389],[-169.5875,-14.451],[-169.523,-14.472],[-169.4675,-14.473],[-169.35,-14.4455],[-169.2965,-14.416],[-169.24,-14.3505],[-169.221,-14.3],[-169.213,-14.206],[-169.235,-14.1275],[-169.281,-14.0695],[-169.359,-14.0215],[-169.468,-14.011],[-169.539,-13.968],[-169.5915,-13.9555],[-169.723,-13.9625],[-169.798,-13.9945],[-169.8755,-14.083],[-169.8935,-14.165]]],[[[-169.7705,16.6975],[-169.753,16.6305],[-169.7135,16.572],[-169.656,16.53],[-169.587,16.508],[-169.5145,16.509],[-169.4085,16.5325],[-169.3485,16.5645],[-169.3025,16.612],[-169.2565,16.738],[-169.2545,16.8095],[-169.2775,16.8775],[-169.3225,16.934],[-169.385,16.9735],[-169.457,16.9905],[-169.5315,16.984],[-169.6395,16.93],[-169.7075,16.8675],[-169.752,16.7995],[-169.7705,16.6975]]],[[[-168.5515,64.9825],[-168.509,64.8995],[-168.4365,64.851],[-168.3295,64.811],[-168.099,64.7775],[-167.9225,64.7825],[-167.799,64.8035],[-167.663,64.8535],[-167.6065,64.892],[-167.5625,64.9625],[-167.5695,65.031],[-167.6245,65.0965],[-167.8065,65.173],[-168.03,65.198],[-168.208,65.186],[-168.33,65.16],[-168.501,65.0735],[-168.5515,64.9825]]],[[[-168.3785,-14.5405],[-168.355,-14.635],[-168.314,-14.693],[-168.2465,-14.742],[-168.187,-14.759],[-168.0965,-14.752],[-168.0295,-14.721],[-167.966,-14.6595],[-167.9345,-14.5765],[-167.938,-14.502],[-167.9585,-14.45],[-168.0295,-14.368],[-168.084,-14.3405],[-168.1635,-14.3295],[-168.214,-14.338],[-168.2955,-14.378],[-168.366,-14.4705],[-168.3785,-14.5405]]],[[[-168.221,24.999],[-168.2075,24.93],[-168.169,24.8695],[-168.11,24.8245],[-167.999,24.797],[-167.9235,24.8095],[-167.8565,24.8445],[-167.807,24.8985],[-167.781,24.964],[-167.781,25.034],[-167.8075,25.1],[-167.857,25.1535],[-167.9235,25.1885],[-167.9995,25.201],[-168.075,25.1885],[-168.142,25.1535],[-168.191,25.0995],[-168.221,24.999]]],[[[-166.5445,23.8495],[-166.531,23.783],[-166.4455,23.654],[-166.386,23.6025],[-166.3555,23.534],[-166.302,23.479],[-166.2315,23.4435],[-166.157,23.427],[-166.0845,23.428],[-166.016,23.4495],[-165.923,23.534],[-165.867,23.643],[-165.855,23.7625],[-165.8875,23.8785],[-165.962,23.977],[-166.0685,24.047],[-166.1945,24.0795],[-166.325,24.071],[-166.445,24.022],[-166.499,23.976],[-166.5335,23.9165],[-166.5445,23.8495]]],[[[-164.923,23.5765],[-164.9095,23.5075],[-164.8715,23.4465],[-164.8125,23.401],[-164.7405,23.3765],[-164.6655,23.3755],[-164.564,23.415],[-164.5135,23.4645],[-164.4835,23.5265],[-164.4775,23.594],[-164.4955,23.6595],[-164.5365,23.7155],[-164.5955,23.7565],[-164.6655,23.7775],[-164.741,23.7765],[-164.813,23.752],[-164.8715,23.707],[-164.9095,23.646],[-164.923,23.5765]]],[[[-162.6815,6.3775],[-162.664,6.306],[-162.622,6.2455],[-162.5615,6.204],[-162.4695,6.1795],[-162.3485,6.1795],[-162.2775,6.191],[-162.217,6.222],[-162.1705,6.2715],[-162.134,6.3725],[-162.141,6.445],[-162.1685,6.5075],[-162.2185,6.563],[-162.3105,6.629],[-162.369,6.6485],[-162.446,6.649],[-162.5115,6.626],[-162.6195,6.54],[-162.669,6.4595],[-162.6815,6.3775]]],[[[-162.329,5.8885],[-162.307,5.797],[-162.2635,5.7375],[-162.2205,5.702],[-162.1605,5.6745],[-162.014,5.664],[-161.973,5.672],[-161.8985,5.7115],[-161.8555,5.7625],[-161.8265,5.853],[-161.8385,5.937],[-161.8665,5.995],[-161.9555,6.076],[-162.021,6.098],[-162.1715,6.087],[-162.2345,6.06],[-162.282,6.0185],[-162.3145,5.9645],[-162.329,5.8885]]],[[[-162.1455,23.071],[-162.1365,23.003],[-162.1045,22.9415],[-162.052,22.8935],[-161.9855,22.8635],[-161.912,22.8555],[-161.8365,22.8705],[-161.7715,22.908],[-161.724,22.964],[-161.7,23.0315],[-161.7025,23.1025],[-161.731,23.1685],[-161.7825,23.2215],[-161.8505,23.255],[-161.927,23.2655],[-161.9995,23.253],[-162.064,23.219],[-162.1125,23.168],[-162.1455,23.071]]],[[[-160.7615,21.6615],[-160.7505,21.592],[-160.715,21.53],[-160.6585,21.4825],[-160.551,21.451],[-160.4755,21.46],[-160.408,21.4925],[-160.3565,21.544],[-160.3265,21.6085],[-160.262,21.582],[-160.1925,21.576],[-160.092,21.605],[-160.0385,21.647],[-160.0015,21.7025],[-159.916,21.7575],[-159.878,21.812],[-159.7925,21.777],[-159.7455,21.7365],[-159.6365,21.6925],[-159.44,21.667],[-159.3815,21.6775],[-159.268,21.7325],[-159.177,21.8155],[-159.1195,21.9185],[-159.1145,21.985],[-159.078,22.1025],[-159.078,22.1645],[-159.124,22.279],[-159.219,22.3765],[-159.336,22.428],[-159.3985,22.4345],[-159.589,22.4305],[-159.705,22.3945],[-159.755,22.357],[-159.84,22.319],[-159.909,22.2605],[-159.957,22.1855],[-160.0615,22.228],[-160.138,22.227],[-160.21,22.202],[-160.268,22.156],[-160.306,22.0945],[-160.3885,22.031],[-160.4435,21.9455],[-160.464,21.848],[-160.5765,21.8585],[-160.648,21.835],[-160.707,21.791],[-160.7465,21.7305],[-160.7615,21.6615]]],[[[-160.2135,-0.3785],[-160.2005,-0.451],[-160.1475,-0.5285],[-160.0875,-0.5665],[-159.9755,-0.5815],[-159.879,-0.5505],[-159.825,-0.501],[-159.8005,-0.458],[-159.785,-0.3565],[-159.798,-0.295],[-159.8565,-0.2125],[-159.9225,-0.1745],[-159.9895,-0.1625],[-160.076,-0.176],[-160.1505,-0.227],[-160.207,-0.326],[-160.2135,-0.3785]]],[[[-158.4945,21.565],[-158.479,21.498],[-158.3715,21.3095],[-158.323,21.2525],[-158.285,21.181],[-158.227,21.129],[-158.112,21.092],[-157.991,21.1065],[-157.8905,21.065],[-157.8145,21.051],[-157.697,21.059],[-157.6195,21.0745],[-157.5505,21.1115],[-157.528,21.1055],[-157.523,21.04],[-157.494,20.9805],[-157.4455,20.933],[-157.3825,20.904],[-157.2785,20.885],[-157.2495,20.798],[-157.1975,20.7235],[-157.1475,20.6265],[-157.0845,20.573],[-157.008,20.5395],[-156.9165,20.533],[-156.9,20.456],[-156.8575,20.388],[-156.7945,20.336],[-156.6755,20.3],[-156.489,20.316],[-156.3895,20.373],[-156.3135,20.379],[-156.1665,20.4175],[-156.119,20.4215],[-155.929,20.474],[-155.8465,20.5315],[-155.789,20.6105],[-155.763,20.7035],[-155.771,20.799],[-155.8125,20.8865],[-155.883,20.956],[-155.974,21.0],[-156.132,21.1075],[-156.23,21.143],[-156.335,21.1495],[-156.387,21.142],[-156.503,21.2155],[-156.5605,21.2925],[-156.641,21.348],[-156.737,21.3765],[-156.8375,21.3745],[-156.933,21.413],[-157.003,21.4145],[-157.0715,21.3955],[-157.178,21.4065],[-157.3135,21.39],[-157.4355,21.3345],[-157.4575,21.4105],[-157.503,21.4775],[-157.5165,21.5415],[-157.551,21.598],[-157.603,21.642],[-157.6675,21.6675],[-157.744,21.785],[-157.848,21.8805],[-157.9375,21.9095],[-158.0345,21.908],[-158.126,21.877],[-158.201,21.82],[-158.2295,21.7835],[-158.303,21.784],[-158.373,21.763],[-158.432,21.722],[-158.474,21.6655],[-158.4945,21.565]]],[[[-157.747,55.7925],[-157.736,55.744],[-157.663,55.664],[-157.578,55.622],[-157.422,55.5925],[-157.317,55.5965],[-157.176,55.633],[-157.092,55.6835],[-157.0535,55.727],[-157.035,55.81],[-157.0935,55.9045],[-157.1845,55.9565],[-157.321,55.9895],[-157.4445,55.9905],[-157.6015,55.954],[-157.68,55.91],[-157.738,55.837],[-157.747,55.7925]]],[[[-156.2695,19.757],[-156.259,19.645],[-156.21,19.543],[-156.1725,19.4995],[-156.146,19.403],[-156.1035,19.3115],[-156.1245,19.192],[-156.1225,19.07],[-156.0765,18.956],[-155.9915,18.8635],[-155.7725,18.7295],[-155.6765,18.7085],[-155.6115,18.718],[-155.491,18.7875],[-155.438,18.839],[-155.3865,18.9305],[-155.3385,18.98],[-155.215,19.056],[-155.0905,19.075],[-154.871,19.1735],[-154.778,19.2405],[-154.6565,19.3485],[-154.604,19.453],[-154.593,19.53],[-154.635,19.641],[-154.693,19.6975],[-154.7675,19.733],[-154.841,19.8785],[-154.9395,20.01],[-155.0605,20.124],[-155.201,20.2165],[-155.356,20.285],[-155.521,20.328],[-155.6625,20.4235],[-155.8065,20.4665],[-155.9095,20.465],[-156.004,20.422],[-156.044,20.3895],[-156.1,20.306],[-156.119,20.2115],[-156.1095,20.1175],[-156.078,20.025],[-156.1735,19.958],[-156.2395,19.865],[-156.2695,19.757]]],[[[-156.129,55.8455],[-156.106,55.768],[-155.9675,55.652],[-155.8445,55.601],[-155.6685,55.5715],[-155.4745,55.578],[-155.3725,55.609],[-155.2785,55.663],[-155.2125,55.7395],[-155.178,55.819],[-155.193,55.9415],[-155.27,56.0455],[-155.4285,56.1115],[-155.606,56.127],[-155.776,56.0975],[-156.0165,55.9935],[-156.11,55.9105],[-156.129,55.8455]]],[[[-146.7845,59.405],[-146.7705,59.3535],[-146.7165,59.294],[-146.588,59.233],[-146.456,59.2055],[-146.3145,59.202],[-146.0785,59.247],[-145.936,59.314],[-145.872,59.363],[-145.8345,59.447],[-145.878,59.5505],[-145.973,59.65],[-146.0585,59.704],[-146.222,59.747],[-146.3655,59.7515],[-146.497,59.731],[-146.5765,59.704],[-146.662,59.65],[-146.6975,59.6045],[-146.708,59.533],[-146.746,59.496],[-146.7845,59.405]]],[[[-125.0035,48.495],[-125.034,48.45],[-125.0435,48.3635],[-125.021,48.308],[-125.074,48.2365],[-125.084,48.1845],[-125.06,48.1065],[-125.017,48.048],[-125.028,47.998],[-125.004,47.9125],[-124.9415,47.83],[-124.8625,47.7505],[-124.7895,47.697],[-124.7605,47.5905],[-124.6805,47.5225],[-124.699,47.471],[-124.6885,47.395],[-124.5485,47.2075],[-124.4935,47.156],[-124.4685,47.067],[-124.4725,46.937],[-124.4625,46.8745],[-124.3945,46.7895],[-124.38,46.6405],[-124.3595,46.5855],[-124.3465,46.431],[-124.3745,46.301],[-124.3755,46.242],[-124.32,46.136],[-124.234,46.07],[-124.2855,46.0115],[-124.3055,45.9265],[-124.2725,45.844],[-124.2845,45.7605],[-124.2345,45.6515],[-124.277,45.467],[-124.289,45.299],[-124.267,45.252],[-124.266,45.1685],[-124.3015,45.0735],[-124.3125,44.9325],[-124.3425,44.8765],[-124.359,44.7805],[-124.357,44.5735],[-124.374,44.5115],[-124.3645,44.432],[-124.392,44.3185],[-124.408,44.0895],[-124.4215,43.983],[-124.4615,43.764],[-124.4885,43.711],[-124.504,43.6055],[-124.5455,43.5075],[-124.5935,43.474],[-124.6635,43.394],[-124.6845,43.2985],[-124.6765,43.232],[-124.708,43.1915],[-124.729,43.1205],[-124.721,43.065],[-124.74,43.021],[-124.8555,42.8935],[-124.896,42.8265],[-124.9075,42.768],[-124.891,42.6995],[-124.817,42.6195],[-124.721,42.5785],[-124.7695,42.483],[-124.7615,42.4105],[-124.7035,42.323],[-124.68,42.19],[-124.636,42.1165],[-124.6085,42.02],[-124.5715,41.974],[-124.623,41.915],[-124.642,41.861],[-124.632,41.778],[-124.5415,41.6705],[-124.4015,41.5925],[-124.361,41.486],[-124.399,41.4525],[-124.4415,41.3685],[-124.4405,41.309],[-124.409,41.242],[-124.45,41.138],[-124.444,41.064],[-124.399,40.964],[-124.4725,40.865],[-124.503,40.801],[-124.5995,40.6435],[-124.692,40.5545],[-124.7315,40.445],[-124.694,40.3455],[-124.628,40.2895],[-124.618,40.1905],[-124.546,40.103],[-124.326,39.9595],[-124.261,39.8825],[-124.2,39.846],[-124.0975,39.723],[-124.0515,39.6135],[-124.048,39.5645],[-124.077,39.4725],[-124.082,39.308],[-124.016,39.127],[-123.9735,39.0525],[-124.0005,38.987],[-123.994,38.907],[-123.9375,38.806],[-123.84,38.711],[-123.705,38.6045],[-123.6505,38.5705],[-123.542,38.449],[-123.423,38.359],[-123.3325,38.308],[-123.3155,38.25],[-123.2195,38.136],[-123.274,38.0305],[-123.2635,37.93],[-123.3175,37.884],[-123.348,37.8335],[-123.358,37.746],[-123.3365,37.686],[-123.292,37.634],[-123.13,37.52],[-123.0565,37.4975],[-122.9515,37.4975],[-122.8655,37.526],[-122.777,37.6025],[-122.7665,37.482],[-122.736,37.414],[-122.6595,37.318],[-122.672,37.2215],[-122.6225,37.09],[-122.544,36.9935],[-122.442,36.9255],[-122.3915,36.8755],[-122.3005,36.814],[-122.2325,36.782],[-122.2015,36.676],[-122.2275,36.6075],[-122.2245,36.545],[-122.1565,36.356],[-122.131,36.227],[-122.078,36.157],[-121.9785,36.0825],[-121.8595,36.0215],[-121.7745,35.903],[-121.718,35.857],[-121.666,35.7645],[-121.5565,35.6685],[-121.499,35.5615],[-121.443,35.5085],[-121.3295,35.4625],[-121.2675,35.3955],[-121.143,35.295],[-121.1425,35.213],[-121.0915,35.1205],[-121.0415,35.0715],[-120.8995,34.989],[-120.9145,34.92],[-120.905,34.8405],[-120.8795,34.794],[-120.8695,34.687],[-120.894,34.569],[-120.8795,34.5075],[-120.8375,34.446],[-120.764,34.388],[-120.691,34.3605],[-120.617,34.286],[-120.702,34.2335],[-120.756,34.1435],[-120.7565,34.0635],[-120.7345,34.011],[-120.623,33.886],[-120.499,33.83],[-120.3925,33.8155],[-120.3335,33.7685],[-120.2305,33.7165],[-120.1445,33.695],[-120.0785,33.696],[-119.882,33.755],[-119.8085,33.75],[-119.663,33.7645],[-119.595,33.787],[-119.4745,33.808],[-119.328,33.809],[-119.239,33.8405],[-119.162,33.8975],[-119.04,33.8585],[-118.961,33.844],[-118.8935,33.811],[-118.7825,33.799],[-118.6595,33.8305],[-118.669,33.7815],[-118.642,33.6775],[-118.764,33.6305],[-118.8145,33.579],[-118.85,33.6225],[-118.923,33.6685],[-119.021,33.6895],[-119.149,33.6655],[-119.211,33.6305],[-119.261,33.5745],[-119.283,33.5215],[-119.2795,33.408],[-119.4495,33.477],[-119.509,33.4885],[-119.558,33.527],[-119.6295,33.5555],[-119.7575,33.5565],[-119.8525,33.514],[-119.903,33.4625],[-119.9345,33.362],[-119.9255,33.3065],[-119.886,33.2415],[-119.819,33.1905],[-119.7775,33.1395],[-119.6995,33.079],[-119.639,33.048],[-119.4865,33.0145],[-119.3495,33.034],[-119.236,33.102],[-119.1945,33.166],[-119.184,33.2105],[-119.193,33.287],[-119.0535,33.2625],[-118.982,33.2695],[-118.8855,33.308],[-118.8055,33.363],[-118.7065,33.2725],[-118.677,33.2275],[-118.7545,33.1965],[-118.814,33.143],[-118.8395,33.0995],[-118.8485,32.999],[-118.816,32.9205],[-118.75,32.812],[-118.6755,32.7145],[-118.5625,32.633],[-118.4565,32.5995],[-118.3745,32.603],[-118.243,32.639],[-118.1635,32.694],[-118.1185,32.768],[-118.1185,32.872],[-118.153,32.935],[-118.319,33.0715],[-118.2065,33.123],[-118.1345,33.1675],[-118.082,33.236],[-118.068,33.284],[-118.0705,33.365],[-118.1035,33.4365],[-118.0685,33.444],[-117.938,33.378],[-117.8505,33.2925],[-117.7915,33.267],[-117.674,33.1885],[-117.544,33.0325],[-117.5025,32.9195],[-117.521,32.8395],[-117.4865,32.654],[-117.465,32.5905],[-117.264,32.5535],[-117.239,32.5275],[-117.1245,32.5345],[-116.3375,32.6],[-115.718,32.6485],[-115.1805,32.6875],[-114.72,32.7185],[-114.765,32.643],[-114.8105,32.61],[-114.8135,32.494],[-114.4385,32.381],[-113.924,32.2235],[-113.1485,31.9805],[-112.3995,31.752],[-111.864,31.5845],[-111.075,31.332],[-110.456,31.333],[-109.7465,31.334],[-109.2785,31.334],[-108.851,31.3325],[-108.2085,31.3335],[-108.2085,31.7835],[-107.8655,31.7835],[-107.2905,31.7835],[-106.529,31.784],[-106.49,31.7485],[-106.455,31.7645],[-106.382,31.7325],[-106.308,31.6295],[-106.2795,31.561],[-106.245,31.539],[-106.219,31.4795],[-106.0775,31.398],[-106.0055,31.3925],[-105.955,31.3655],[-105.9315,31.313],[-105.8705,31.29],[-105.7695,31.165],[-105.649,31.116],[-105.606,31.085],[-105.556,30.989],[-105.4,30.8895],[-105.387,30.8535],[-105.2665,30.8085],[-105.196,30.792],[-105.13,30.7505],[-105.0525,30.6815],[-105.007,30.6865],[-104.9715,30.61],[-104.8995,30.571],[-104.872,30.5105],[-104.8595,30.3905],[-104.811,30.363],[-104.812,30.333],[-104.761,30.3],[-104.687,30.179],[-104.6905,30.016],[-104.68,29.9205],[-104.6335,29.8705],[-104.5655,29.7695],[-104.5445,29.681],[-104.5125,29.6465],[-104.3985,29.5715],[-104.3375,29.5195],[-104.262,29.5135],[-104.209,29.481],[-104.1605,29.39],[-103.975,29.296],[-103.783,29.264],[-103.719,29.181],[-103.5925,29.15],[-103.557,29.1555],[-103.5005,29.116],[-103.474,29.0705],[-103.416,29.038],[-103.3115,29.0135],[-103.2505,28.9805],[-103.1525,28.972],[-103.098,29.0265],[-103.08,29.0875],[-103.032,29.104],[-102.99,29.1835],[-102.955,29.1775],[-102.868,29.223],[-102.9065,29.2615],[-102.877,29.355],[-102.8395,29.359],[-102.8085,29.523],[-102.7785,29.5435],[-102.742,29.633],[-102.6935,29.6765],[-102.677,29.7415],[-102.548,29.7445],[-102.4875,29.7865],[-102.404,29.7655],[-102.34,29.8695],[-102.3005,29.8775],[-102.144,29.8035],[-102.0735,29.7865],[-101.9815,29.815],[-101.9545,29.796],[-101.8035,29.78],[-101.774,29.789],[-101.71,29.7615],[-101.6615,29.771],[-101.3995,29.76],[-101.3945,29.711],[-101.3645,29.6655],[-101.3005,29.638],[-101.312,29.5865],[-101.2415,29.5645],[-101.2505,29.5195],[-101.193,29.5205],[-101.1485,29.4755],[-101.06,29.4585],[-101.005,29.3655],[-100.8865,29.3075],[-100.8785,29.281],[-100.795,29.2435],[-100.76,29.1575],[-100.685,29.1115],[-100.664,29.075],[-100.6455,28.988],[-100.6515,28.946],[-100.5465,28.825],[-100.5145,28.752],[-100.5005,28.662],[-100.447,28.609],[-100.3985,28.5855],[-100.411,28.5495],[-100.336,28.43],[-100.3495,28.404],[-100.288,28.316],[-100.294,28.2845],[-100.212,28.1945],[-100.0885,28.148],[-100.0525,28.0845],[-100.018,28.065],[-99.9905,27.9935],[-99.9335,27.9815],[-99.9375,27.9415],[-99.8935,27.899],[-99.875,27.7965],[-99.8135,27.7745],[-99.7215,27.666],[-99.6005,27.6415],[-99.539,27.603],[-99.511,27.565],[-99.528,27.499],[-99.4785,27.4795],[-99.504,27.339],[-99.4965,27.2735],[-99.442,27.251],[-99.426,27.1755],[-99.4285,27.092],[-99.453,27.063],[-99.445,27.02],[-99.3835,26.9775],[-99.388,26.9425],[-99.3305,26.9205],[-99.3285,26.8785],[-99.2685,26.8435],[-99.24,26.746],[-99.209,26.725],[-99.2,26.656],[-99.178,26.6205],[-99.1675,26.5365],[-99.1275,26.525],[-99.0915,26.476],[-99.111,26.427],[-99.0835,26.3975],[-99.04,26.413],[-98.9785,26.4],[-98.889,26.357],[-98.825,26.3705],[-98.789,26.3305],[-98.7445,26.3155],[-98.678,26.2435],[-98.4805,26.22],[-98.3845,26.157],[-98.3385,26.153],[-98.3225,26.1195],[-98.249,26.072],[-98.1585,26.0535],[-98.105,26.0675],[-98.0385,26.0415],[-98.0005,26.0655],[-97.9645,26.052],[-97.875,26.0635],[-97.793,26.0535],[-97.779,26.03],[-97.6675,26.0245],[-97.556,25.937],[-97.5105,25.8875],[-97.456,25.884],[-97.4435,25.848],[-97.3715,25.842],[-97.367,25.9035],[-97.2755,25.952],[-97.178,25.962],[-96.924,25.9755],[-96.9225,26.0645],[-96.9465,26.158],[-96.9595,26.258],[-97.0,26.4325],[-97.1095,26.764],[-97.1445,26.909],[-97.153,26.987],[-97.144,27.171],[-97.0975,27.3285],[-96.9845,27.5555],[-96.915,27.6595],[-96.8575,27.706],[-96.812,27.8005],[-96.7115,27.9025],[-96.605,27.9885],[-96.4955,28.062],[-96.2805,28.1695],[-96.125,28.3055],[-95.939,28.3925],[-95.702,28.4895],[-95.3685,28.662],[-95.238,28.7065],[-95.1275,28.7895],[-95.0875,28.839],[-94.951,28.9345],[-94.887,28.989],[-94.646,29.1305],[-94.556,29.165],[-94.5035,29.2125],[-94.454,29.305],[-94.0215,29.469],[-93.9635,29.4815],[-93.868,29.446],[-93.8,29.4445],[-93.719,29.466],[-93.6665,29.498],[-93.6195,29.5515],[-93.453,29.5695],[-93.3585,29.545],[-93.2795,29.552],[-93.2235,29.573],[-93.0505,29.5265],[-92.8245,29.431],[-92.721,29.398],[-92.6155,29.377],[-92.36,29.3365],[-92.268,29.3325],[-92.143,29.362],[-92.0555,29.3105],[-92.0185,29.267],[-91.9575,29.228],[-91.838,29.2055],[-91.7685,29.2185],[-91.6525,29.2145],[-91.521,29.176],[-91.471,29.127],[-91.3935,29.075],[-91.184,29.0035],[-91.1495,28.9425],[-91.1005,28.8985],[-90.982,28.8485],[-90.9105,28.8385],[-90.7435,28.8385],[-90.567,28.875],[-90.5115,28.8595],[-90.3965,28.8495],[-90.2945,28.8605],[-90.122,28.9005],[-89.961,28.996],[-89.635,29.0435],[-89.663,28.898],[-89.651,28.8435],[-89.602,28.772],[-89.533,28.7255],[-89.481,28.709],[-89.398,28.706],[-89.328,28.725],[-89.245,28.7845],[-89.1645,28.7665],[-89.052,28.785],[-88.993,28.82],[-88.851,28.9755],[-88.7965,29.0205],[-88.746,29.115],[-88.737,29.208],[-88.7595,29.296],[-88.8475,29.3805],[-88.905,29.403],[-88.788,29.5185],[-88.7395,29.585],[-88.6835,29.637],[-88.6445,29.693],[-88.6095,29.7765],[-88.5875,29.894],[-88.6015,30.02],[-88.4585,29.995],[-88.383,30.002],[-88.2985,30.028],[-88.2095,30.0395],[-88.08,30.008],[-87.9335,30.0305],[-87.8275,30.026],[-87.597,30.056],[-87.299,30.117],[-87.1175,30.13],[-86.8745,30.174],[-86.644,30.196],[-86.511,30.1805],[-86.4525,30.1825],[-86.3245,30.1615],[-86.1705,30.1155],[-86.0525,30.0705],[-85.9215,30.001],[-85.8665,29.9555],[-85.745,29.894],[-85.6465,29.8105],[-85.6295,29.721],[-85.5925,29.6235],[-85.5055,29.511],[-85.4435,29.474],[-85.342,29.455],[-85.269,29.4665],[-85.1155,29.3935],[-85.0235,29.387],[-84.868,29.427],[-84.7685,29.4785],[-84.6975,29.5015],[-84.6145,29.548],[-84.558,29.5955],[-84.4605,29.635],[-84.3885,29.693],[-84.3165,29.697],[-84.22,29.729],[-84.174,29.764],[-84.12,29.84],[-84.055,29.863],[-83.9485,29.7985],[-83.828,29.754],[-83.7705,29.6375],[-83.734,29.5955],[-83.6355,29.5265],[-83.6235,29.4535],[-83.5845,29.381],[-83.517,29.314],[-83.4105,29.233],[-83.3805,29.1605],[-83.3355,29.113],[-83.3275,29.067],[-83.2895,28.989],[-83.231,28.929],[-83.1805,28.8995],[-83.065,28.8715],[-82.99,28.874],[-82.985,28.7815],[-82.9425,28.6285],[-82.912,28.5655],[-82.927,28.466],[-82.9605,28.404],[-83.022,28.355],[-83.05,28.313],[-83.0785,28.214],[-83.0725,28.071],[-83.0555,28.0045],[-83.0755,27.9085],[-83.0725,27.8335],[-83.035,27.7375],[-82.976,27.669],[-82.992,27.5955],[-82.9855,27.539],[-82.945,27.4425],[-82.878,27.325],[-82.7875,27.2245],[-82.7615,27.1715],[-82.7155,27.1235],[-82.6455,26.969],[-82.4895,26.7295],[-82.493,26.6505],[-82.384,26.3945],[-82.3505,26.346],[-82.25,26.269],[-82.161,26.2325],[-82.0455,26.2235],[-82.0235,26.067],[-81.9795,25.957],[-81.96,25.8755],[-81.918,25.8],[-81.8445,25.694],[-81.7385,25.6305],[-81.638,25.616],[-81.574,25.6245],[-81.508,25.5445],[-81.435,25.477],[-81.373,25.351],[-81.395,25.2215],[-81.3765,25.1475],[-81.3355,25.0615],[-81.446,25.052],[-81.722,24.9045],[-81.912,24.8135],[-82.033,24.7805],[-82.1185,24.7985],[-82.2455,24.7725],[-82.3085,24.7265],[-82.375,24.6245],[-82.3825,24.518],[-82.3645,24.466],[-82.2805,24.378],[-82.1955,24.349],[-82.1075,24.347],[-82.051,24.329],[-81.964,24.268],[-81.901,24.253],[-81.7935,24.2635],[-81.743,24.2815],[-81.6765,24.284],[-81.56,24.312],[-81.464,24.3515],[-81.398,24.3455],[-81.3015,24.3695],[-81.2125,24.449],[-81.127,24.427],[-81.012,24.4485],[-80.9645,24.4785],[-80.913,24.542],[-80.7725,24.61],[-80.677,24.6395],[-80.535,24.723],[-80.389,24.821],[-80.297,24.831],[-80.2075,24.8835],[-80.1725,24.9295],[-80.148,25.021],[-80.072,25.062],[-80.007,25.144],[-79.993,25.247],[-80.0145,25.3105],[-79.9515,25.3915],[-79.9285,25.5005],[-79.939,25.547],[-79.9315,25.664],[-79.9045,25.744],[-79.8895,26.044],[-79.8595,26.23],[-79.841,26.403],[-79.8135,26.5865],[-79.8065,26.7845],[-79.832,26.919],[-79.881,27.082],[-79.9255,27.1795],[-79.937,27.233],[-80.0605,27.489],[-80.1745,27.817],[-80.2965,28.042],[-80.35,28.1545],[-80.38,28.2985],[-80.323,28.362],[-80.297,28.464],[-80.3055,28.5135],[-80.3705,28.6715],[-80.512,28.857],[-80.684,29.118],[-80.7205,29.193],[-80.7545,29.227],[-80.842,29.4005],[-80.952,29.6335],[-81.032,29.831],[-81.0445,29.9355],[-81.081,30.007],[-81.16,30.3255],[-81.15,30.438],[-81.21,30.5845],[-81.171,30.711],[-81.1965,30.8045],[-81.1335,30.909],[-81.133,31.0265],[-81.118,31.066],[-81.0475,31.1485],[-81.0005,31.37],[-80.9415,31.4425],[-80.895,31.575],[-80.8885,31.622],[-80.811,31.7255],[-80.776,31.7455],[-80.6475,31.878],[-80.5765,32.0],[-80.496,32.033],[-80.4305,32.0745],[-80.3965,32.1145],[-80.3185,32.14],[-80.226,32.224],[-80.2055,32.2725],[-80.117,32.344],[-80.0375,32.367],[-79.977,32.4045],[-79.899,32.423],[-79.807,32.4855],[-79.646,32.5775],[-79.6,32.6325],[-79.5115,32.7025],[-79.4435,32.7385],[-79.374,32.7985],[-79.278,32.8095],[-79.206,32.843],[-79.1655,32.878],[-79.1275,32.941],[-78.9595,33.0565],[-78.901,33.159],[-78.919,33.2725],[-78.912,33.33],[-78.8175,33.4275],[-78.7585,33.506],[-78.665,33.585],[-78.5495,33.6415],[-78.4665,33.653],[-78.396,33.6855],[-78.29,33.7095],[-78.174,33.7135],[-78.061,33.637],[-77.974,33.6185],[-77.9095,33.6225],[-77.79,33.677],[-77.742,33.734],[-77.7165,33.844],[-77.627,34.044],[-77.5725,34.124],[-77.5135,34.1815],[-77.406,34.2605],[-77.214,34.3545],[-77.1125,34.4165],[-76.968,34.467],[-76.762,34.4965],[-76.7165,34.4315],[-76.612,34.3735],[-76.52,34.363],[-76.458,34.3725],[-76.3735,34.412],[-76.3315,34.451],[-76.2865,34.5585],[-76.1555,34.7005],[-75.979,34.839],[-75.7955,34.951],[-75.597,35.0225],[-75.528,35.0145],[-75.445,35.0265],[-75.368,35.064],[-75.328,35.1],[-75.291,35.1665],[-75.2415,35.383],[-75.215,35.5625],[-75.239,35.723],[-75.271,35.812],[-75.4405,36.116],[-75.4905,36.1935],[-75.542,36.3025],[-75.576,36.398],[-75.645,36.669],[-75.718,36.8405],[-75.7395,36.9235],[-75.723,36.974],[-75.608,37.073],[-75.575,37.118],[-75.554,37.1905],[-75.4945,37.254],[-75.4375,37.355],[-75.411,37.4295],[-75.374,37.4725],[-75.343,37.542],[-75.343,37.6065],[-75.3195,37.6625],[-75.217,37.6975],[-75.162,37.7385],[-74.9825,37.9815],[-74.9155,38.126],[-74.846,38.2555],[-74.8075,38.3655],[-74.794,38.467],[-74.82,38.734],[-74.7005,38.781],[-74.592,38.8625],[-74.532,38.9525],[-74.4655,39.027],[-74.416,39.113],[-74.347,39.163],[-74.251,39.205],[-74.1205,39.318],[-74.0125,39.46],[-73.8515,39.6855],[-73.8395,39.7155],[-73.819,39.883],[-73.771,40.0885],[-73.7375,40.1915],[-73.7115,40.319],[-73.711,40.3825],[-73.589,40.3735],[-73.4905,40.384],[-73.3335,40.4215],[-73.2095,40.425],[-72.9725,40.4765],[-72.81,40.532],[-72.3795,40.652],[-72.1235,40.746],[-71.7435,40.878],[-71.645,40.9495],[-71.5255,40.9505],[-71.414,40.98],[-71.3315,41.035],[-71.2975,41.0805],[-71.278,41.152],[-71.285,41.2065],[-71.1495,41.2505],[-71.094,41.222],[-71.0785,41.1835],[-70.9985,41.1005],[-70.898,41.059],[-70.8005,41.049],[-70.676,41.074],[-70.582,41.1395],[-70.4605,41.1135],[-70.3985,41.1175],[-70.2465,41.064],[-70.145,41.043],[-70.03,41.039],[-69.883,41.059],[-69.783,41.107],[-69.706,41.209],[-69.6955,41.29],[-69.717,41.3575],[-69.7695,41.439],[-69.683,41.593],[-69.6625,41.6705],[-69.6665,41.816],[-69.7035,41.9515],[-69.7585,42.062],[-69.832,42.153],[-69.9045,42.2065],[-69.99,42.2475],[-70.1565,42.283],[-70.3135,42.269],[-70.4625,42.28],[-70.476,42.302],[-70.419,42.47],[-70.3545,42.519],[-70.3085,42.595],[-70.296,42.664],[-70.312,42.7415],[-70.398,42.83],[-70.3645,42.865],[-70.328,42.951],[-70.2645,42.9915],[-70.215,43.055],[-70.2,43.1275],[-70.23,43.2125],[-70.0125,43.411],[-69.804,43.496],[-69.686,43.5105],[-69.578,43.5515],[-69.4485,43.5765],[-69.302,43.5545],[-69.1625,43.589],[-69.0805,43.648],[-69.006,43.611],[-68.9035,43.585],[-68.812,43.5845],[-68.701,43.6165],[-68.647,43.651],[-68.5945,43.714],[-68.5275,43.755],[-68.4685,43.828],[-68.3795,43.881],[-68.3185,43.821],[-68.215,43.777],[-68.1195,43.767],[-68.0115,43.786],[-67.895,43.859],[-67.849,43.9555],[-67.859,44.025],[-67.885,44.0695],[-67.9585,44.13],[-67.8675,44.1625],[-67.7565,44.1785],[-67.654,44.232],[-67.5565,44.2405],[-67.376,44.304],[-67.301,44.3595],[-67.304,44.3935],[-67.2525,44.4965],[-67.157,44.5825],[-67.039,44.6245],[-66.987,44.6955],[-66.8855,44.794],[-66.9655,44.829],[-66.9665,44.91],[-67.0215,44.954],[-67.1125,45.1125],[-67.159,45.162],[-67.2275,45.1635],[-67.291,45.1875],[-67.321,45.1315],[-67.3805,45.152],[-67.464,45.245],[-67.4765,45.2755],[-67.429,45.3445],[-67.427,45.39],[-67.4725,45.423],[-67.5,45.491],[-67.4275,45.501],[-67.4205,45.5495],[-67.4565,45.6045],[-67.499,45.5865],[-67.675,45.6305],[-67.713,45.681],[-67.8035,45.6775],[-67.802,45.803],[-67.7555,45.8235],[-67.8045,45.869],[-67.751,45.918],[-67.7815,45.9435],[-67.782,46.263],[-67.7885,46.6015],[-67.79,47.067],[-67.883,47.1045],[-67.952,47.1945],[-68.2235,47.3445],[-68.3355,47.3595],[-68.3845,47.324],[-68.378,47.2875],[-68.517,47.296],[-68.58,47.287],[-68.6075,47.247],[-68.687,47.2445],[-68.8115,47.215],[-68.905,47.1805],[-69.041,47.245],[-69.0545,47.3765],[-69.0355,47.415],[-69.176,47.457],[-69.2245,47.46],[-69.587,47.1045],[-69.997,46.6955],[-70.0565,46.4165],[-70.095,46.41],[-70.149,46.359],[-70.209,46.3295],[-70.2925,46.1915],[-70.2395,46.149],[-70.2895,46.0945],[-70.3135,46.0225],[-70.3125,45.962],[-70.2395,45.94],[-70.254,45.9025],[-70.417,45.7955],[-70.4005,45.7195],[-70.553,45.668],[-70.6455,45.6065],[-70.7225,45.5135],[-70.681,45.452],[-70.6245,45.406],[-70.6505,45.377],[-70.712,45.3905],[-70.7815,45.431],[-70.8255,45.4005],[-70.806,45.3215],[-70.8845,45.235],[-70.918,45.3115],[-70.989,45.334],[-71.098,45.3015],[-71.133,45.2445],[-71.2305,45.2495],[-71.288,45.301],[-71.3565,45.254],[-71.3975,45.2055],[-71.4295,45.1225],[-71.4955,45.065],[-71.501,45.0135],[-71.914,45.0075],[-72.312,45.004],[-72.6345,45.0145],[-73.0655,45.016],[-73.65,45.003],[-73.883,45.001],[-74.15,44.9915],[-74.6835,44.9995],[-74.731,44.9905],[-74.8265,45.016],[-74.908,44.9835],[-74.9725,44.9835],[-75.14,44.897],[-75.2185,44.878],[-75.505,44.7055],[-75.767,44.5155],[-75.8215,44.432],[-75.913,44.368],[-76.001,44.348],[-76.162,44.2805],[-76.1645,44.24],[-76.2455,44.204],[-76.3125,44.199],[-76.353,44.1345],[-76.439,44.094],[-76.7965,43.631],[-77.442,43.631],[-77.928,43.631],[-78.6905,43.631],[-79.2005,43.4505],[-79.0775,43.2725],[-79.056,43.2545],[-79.0425,43.1435],[-79.074,43.078],[-79.011,43.066],[-79.0165,42.984],[-78.9325,42.956],[-78.906,42.9],[-78.9355,42.8285],[-79.5705,42.5875],[-80.08,42.3935],[-80.521,42.323],[-81.2455,42.2075],[-81.799,41.953],[-81.8545,41.933],[-82.269,41.7415],[-82.3975,41.6765],[-82.6795,41.6765],[-83.069,41.8635],[-83.1495,42.041],[-83.1215,42.1255],[-83.128,42.2385],[-83.0635,42.318],[-82.83,42.3735],[-82.668,42.5335],[-82.6055,42.5485],[-82.5235,42.6075],[-82.4675,42.7625],[-82.482,42.8085],[-82.4555,42.927],[-82.413,42.9775],[-82.414,43.011],[-82.123,43.591],[-82.25,44.165],[-82.4085,44.8585],[-82.5185,45.3385],[-82.757,45.4455],[-83.597,45.8215],[-83.434,45.998],[-83.572,46.106],[-83.655,46.1215],[-83.76,46.1025],[-83.8265,46.119],[-83.9035,46.0605],[-83.9555,46.057],[-84.006,46.1495],[-84.077,46.1875],[-84.108,46.2415],[-84.146,46.419],[-84.111,46.504],[-84.129,46.5305],[-84.226,46.534],[-84.2935,46.493],[-84.374,46.509],[-84.445,46.489],[-84.4755,46.453],[-84.557,46.461],[-84.763,46.6345],[-84.86,46.889],[-85.319,47.0795],[-87.1125,47.818],[-87.6475,48.029],[-88.37,48.306],[-88.6775,48.2455],[-89.3375,47.9745],[-89.489,48.0145],[-89.5855,48.002],[-89.7675,48.023],[-89.899,47.988],[-89.994,48.028],[-90.0235,48.085],[-90.1325,48.1115],[-90.306,48.105],[-90.375,48.091],[-90.6415,48.1035],[-90.7615,48.0985],[-90.8325,48.1735],[-90.8395,48.2395],[-90.8855,48.246],[-91.0825,48.181],[-91.2495,48.084],[-91.371,48.0695],[-91.4295,48.0485],[-91.488,48.0685],[-91.5755,48.049],[-91.5695,48.0935],[-91.7115,48.1145],[-91.7155,48.1995],[-91.8645,48.207],[-91.893,48.238],[-91.9585,48.233],[-92.0065,48.2655],[-92.0,48.321],[-92.055,48.3595],[-92.289,48.343],[-92.3015,48.2885],[-92.2805,48.2445],[-92.375,48.226],[-92.47,48.352],[-92.4565,48.401],[-92.5075,48.448],[-92.656,48.4365],[-92.7125,48.463],[-92.637,48.4995],[-92.635,48.5425],[-92.7285,48.5395],[-92.9845,48.624],[-93.1785,48.6235],[-93.2075,48.6425],[-93.3485,48.6265],[-93.467,48.5885],[-93.4675,48.5465],[-93.6475,48.5175],[-93.7935,48.5165],[-93.804,48.57],[-93.848,48.631],[-94.2445,48.6535],[-94.261,48.6965],[-94.416,48.711],[-94.439,48.695],[-94.5875,48.7175],[-94.691,48.778],[-94.7045,48.824],[-94.6835,48.884],[-94.7495,49.099],[-94.773,49.1205],[-94.8255,49.2945],[-94.854,49.3245],[-94.9575,49.37],[-95.0585,49.3535],[-95.1535,49.3845],[-95.153,48.999],[-95.633,48.9995],[-96.6525,49.0],[-97.4815,49.0005],[-98.2105,49.0005],[-98.98,49.0],[-99.5405,48.9995],[-100.471,48.9995],[-101.17,48.9995],[-101.981,48.999],[-102.4565,48.999],[-103.3775,48.999],[-103.807,48.9995],[-104.685,48.999],[-105.561,48.9995],[-106.2295,48.9995],[-106.986,49.0],[-107.886,49.0],[-108.8355,48.9995],[-109.4205,49.0005],[-110.326,48.999],[-110.88,48.998],[-111.5755,48.9965],[-112.393,48.9985],[-112.924,48.9985],[-113.6945,48.9975],[-114.362,49.001],[-115.2625,48.9995],[-115.8615,49.001],[-116.499,49.0],[-117.135,48.999],[-117.992,49.0005],[-118.3895,49.0],[-119.047,49.0],[-120.0025,48.9995],[-120.6695,49.0],[-121.335,49.001],[-121.7595,48.9975],[-122.098,49.0025],[-122.787,49.002],[-123.322,49.002],[-123.0085,48.831],[-123.0085,48.767],[-123.268,48.694],[-123.219,48.5485],[-123.16,48.4535],[-123.115,48.423],[-123.2485,48.284],[-123.541,48.2245],[-123.679,48.24],[-124.012,48.2965],[-124.727,48.4935],[-124.8405,48.506],[-125.0035,48.495]]],[[[-83.1625,24.619],[-83.149,24.55],[-83.1005,24.4795],[-83.046,24.442],[-82.981,24.4215],[-82.8655,24.412],[-82.777,24.432],[-82.676,24.4865],[-82.6025,24.5705],[-82.5855,24.639],[-82.5915,24.6985],[-82.6345,24.777],[-82.695,24.8245],[-82.782,24.8505],[-82.8985,24.8445],[-82.984,24.828],[-83.087,24.771],[-83.1295,24.7255],[-83.1625,24.619]]],[[[-75.2385,18.3985],[-75.219,18.3255],[-75.172,18.258],[-75.122,18.2195],[-75.0375,18.1905],[-74.95,18.1965],[-74.848,18.255],[-74.805,18.3205],[-74.7905,18.418],[-74.8085,18.4855],[-74.8455,18.541],[-74.8935,18.58],[-74.9525,18.6045],[-75.02,18.6135],[-75.088,18.6055],[-75.1765,18.5545],[-75.2175,18.5],[-75.2385,18.3985]]],[[[-68.1615,18.159],[-68.155,18.063],[-68.1155,17.9645],[-68.0725,17.9215],[-67.9725,17.865],[-67.9155,17.8525],[-67.8415,17.8545],[-67.756,17.8875],[-67.669,17.974],[-67.6375,18.051],[-67.64,18.1445],[-67.6595,18.197],[-67.741,18.2865],[-67.852,18.3405],[-67.912,18.3595],[-67.9925,18.3585],[-68.0445,18.3415],[-68.132,18.2625],[-68.1615,18.159]]],[[[-64.956,18.6115],[-64.99,18.602],[-65.088,18.607],[-65.156,18.5855],[-65.2115,18.547],[-65.2705,18.546],[-65.3675,18.572],[-65.46,18.5555],[-65.5215,18.5855],[-65.6055,18.603],[-65.6675,18.597],[-65.873,18.653],[-66.212,18.686],[-66.4295,18.694],[-66.4965,18.684],[-66.6225,18.695],[-66.7265,18.685],[-66.7825,18.694],[-66.911,18.69],[-67.0345,18.7155],[-67.1335,18.715],[-67.225,18.692],[-67.272,18.665],[-67.336,18.604],[-67.3625,18.558],[-67.457,18.5905],[-67.5375,18.585],[-67.6035,18.5555],[-67.672,18.488],[-67.6965,18.4295],[-67.69,18.3215],[-67.6405,18.245],[-67.5705,18.197],[-67.5135,18.1795],[-67.4105,18.188],[-67.4005,18.1645],[-67.4185,18.0935],[-67.425,17.9405],[-67.4145,17.889],[-67.3705,17.8165],[-67.2765,17.747],[-67.19,17.729],[-67.1095,17.7425],[-66.9705,17.726],[-66.8965,17.728],[-66.7465,17.7595],[-66.6925,17.7495],[-66.608,17.693],[-66.519,17.6805],[-66.405,17.7185],[-66.3185,17.726],[-66.219,17.7115],[-66.1485,17.7255],[-65.9755,17.743],[-65.9035,17.7735],[-65.768,17.8135],[-65.7165,17.846],[-65.655,17.907],[-65.529,17.8795],[-65.4225,17.8875],[-65.207,17.938],[-65.1515,17.964],[-65.091,18.023],[-65.063,18.085],[-65.0125,18.1005],[-64.915,18.0385],[-64.861,18.0295],[-64.7775,18.042],[-64.6935,18.0975],[-64.64,18.1065],[-64.6605,18.29],[-64.6395,18.364],[-64.756,18.377],[-64.799,18.408],[-64.872,18.4085],[-64.897,18.4895],[-64.956,18.6115]]],[[[-65.114,17.68],[-65.1045,17.6205],[-65.054,17.537],[-65.021,17.5095],[-64.944,17.4775],[-64.742,17.477],[-64.5605,17.5305],[-64.459,17.5775],[-64.413,17.615],[-64.376,17.668],[-64.3555,17.7555],[-64.367,17.8215],[-64.4275,17.908],[-64.5255,17.974],[-64.6395,17.996],[-64.708,17.984],[-64.811,17.983],[-64.9495,17.9585],[-64.999,17.934],[-65.0645,17.8705],[-65.0985,17.7925],[-65.114,17.68]]],[[[144.413,13.4475],[144.4415,13.2655],[144.441,13.206],[144.4825,13.11],[144.545,13.058],[144.6405,13.033],[144.7665,13.0475],[144.8155,13.063],[144.877,13.104],[144.926,13.16],[144.9705,13.247],[144.979,13.3055],[145.081,13.389],[145.1105,13.4315],[145.152,13.53],[145.163,13.583],[145.1565,13.65],[145.1095,13.7345],[145.075,13.7645],[144.952,13.8385],[144.8565,13.857],[144.7625,13.8335],[144.71,13.796],[144.6615,13.732],[144.6355,13.67],[144.564,13.6535],[144.471,13.589],[144.4335,13.536],[144.413,13.4475]]],[[[144.673,20.54],[144.684,20.477],[144.7105,20.426],[144.781,20.364],[144.856,20.3385],[144.9785,20.3505],[145.0595,20.405],[145.0985,20.4655],[145.1135,20.578],[145.0905,20.643],[145.05,20.694],[144.974,20.74],[144.8565,20.7515],[144.7885,20.729],[144.7105,20.6625],[144.681,20.6015],[144.673,20.54]]],[[[144.9155,14.12],[144.938,14.0275],[144.962,13.991],[145.026,13.9395],[145.087,13.9195],[145.1805,13.9095],[145.2845,13.927],[145.418,14.0085],[145.478,14.0945],[145.497,14.174],[145.484,14.2605],[145.457,14.309],[145.366,14.379],[145.2865,14.3995],[145.1805,14.393],[145.0635,14.347],[145.006,14.303],[144.9325,14.204],[144.9155,14.12]]],[[[144.9955,20.0165],[145.011,19.941],[145.05,19.88],[145.0915,19.845],[145.2145,19.81],[145.1885,19.759],[145.1765,19.6885],[145.203,19.5855],[145.2715,19.5135],[145.386,19.475],[145.4885,19.4905],[145.5395,19.5185],[145.6145,19.612],[145.6305,19.6875],[145.6225,19.7475],[145.591,19.8145],[145.5025,19.886],[145.416,19.908],[145.4515,20.013],[145.447,20.063],[145.419,20.13],[145.3675,20.187],[145.2685,20.2315],[145.1975,20.2355],[145.113,20.2095],[145.039,20.1485],[145.0055,20.0865],[144.9955,20.0165]]],[[[145.326,14.8345],[145.3485,14.7425],[145.4,14.68],[145.449,14.65],[145.529,14.633],[145.579,14.638],[145.676,14.6755],[145.7265,14.7145],[145.8285,14.8245],[145.893,14.9465],[145.98,15.061],[146.0385,15.2635],[146.03,15.3285],[146.0065,15.3805],[145.9415,15.4495],[145.887,15.478],[145.811,15.4915],[145.7565,15.4845],[145.609,15.4235],[145.549,15.376],[145.5,15.2955],[145.491,15.238],[145.438,15.1825],[145.39,15.097],[145.379,14.9785],[145.345,14.92],[145.326,14.8345]]],[[[145.424,16.3645],[145.4305,16.3035],[145.462,16.233],[145.532,16.163],[145.645,16.13],[145.7285,16.1335],[145.809,16.1585],[145.88,16.215],[145.9285,16.313],[145.931,16.3755],[145.9085,16.4505],[145.8665,16.5055],[145.935,16.55],[145.982,16.62],[145.9985,16.722],[145.979,16.792],[145.9515,16.8375],[145.886,16.8915],[145.828,16.9135],[145.728,16.9125],[145.6465,16.875],[145.573,16.7825],[145.559,16.684],[145.578,16.6175],[145.611,16.5695],[145.5685,16.56],[145.488,16.512],[145.4455,16.4555],[145.424,16.3645]]],[[[145.425,18.7765],[145.4375,18.698],[145.5005,18.5955],[145.6025,18.534],[145.664,18.524],[145.7335,18.534],[145.786,18.5585],[145.858,18.6145],[145.889,18.662],[145.91,18.741],[145.9085,18.8085],[145.8785,18.8935],[145.823,18.9555],[145.726,19.005],[145.6645,19.0145],[145.597,19.006],[145.5235,18.971],[145.4705,18.9175],[145.4455,18.8705],[145.425,18.7765]]],[[[145.498,18.0475],[145.5145,17.9665],[145.5545,17.9085],[145.648,17.852],[145.733,17.8445],[145.811,17.864],[145.9285,17.9425],[145.98,18.0005],[146.0095,18.067],[146.021,18.1355],[145.9915,18.254],[145.9385,18.316],[145.899,18.342],[145.8165,18.3685],[145.6995,18.358],[145.6105,18.303],[145.57,18.251],[145.523,18.155],[145.498,18.0475]]],[[[145.6045,17.602],[145.6135,17.538],[145.67,17.4435],[145.631,17.37],[145.623,17.307],[145.645,17.215],[145.713,17.1385],[145.8265,17.096],[145.906,17.104],[145.9555,17.1255],[146.024,17.192],[146.0555,17.2605],[146.062,17.325],[146.044,17.393],[146.004,17.454],[146.055,17.546],[146.0565,17.6435],[146.0335,17.703],[145.9625,17.7815],[145.8615,17.821],[145.761,17.8115],[145.6925,17.777],[145.646,17.729],[145.62,17.6805],[145.6045,17.602]]],[[[145.844,16.0055],[145.8605,15.927],[145.888,15.882],[145.945,15.833],[146.0555,15.8045],[146.144,15.825],[146.202,15.8655],[146.2655,15.9685],[146.268,16.0695],[146.2165,16.164],[146.1605,16.2055],[146.0735,16.229],[145.9905,16.217],[145.9305,16.184],[145.891,16.143],[145.8545,16.0705],[145.844,16.0055]]],[[[166.383,19.309],[166.3895,19.2585],[166.426,19.182],[166.5275,19.1025],[166.6565,19.0685],[166.7475,19.0875],[166.7995,19.12],[166.8495,19.1845],[166.8695,19.2815],[166.8525,19.3685],[166.8185,19.432],[166.7205,19.501],[166.614,19.525],[166.501,19.4975],[166.4345,19.443],[166.3935,19.3735],[166.383,19.309]]],[[[172.1155,52.9425],[172.147,52.8545],[172.205,52.803],[172.3045,52.753],[172.413,52.7265],[172.5155,52.6635],[172.6035,52.6255],[172.876,52.56],[173.1285,52.565],[173.0755,52.507],[173.042,52.434],[173.0495,52.37],[173.094,52.306],[173.225,52.2355],[173.3635,52.206],[173.487,52.1955],[173.5805,52.17],[173.7795,52.1685],[173.8865,52.1905],[173.9705,52.2295],[174.049,52.3005],[174.0675,52.4135],[174.12,52.521],[174.2855,52.523],[174.367,52.4795],[174.4895,52.452],[174.5915,52.452],[174.7135,52.4795],[174.772,52.5075],[174.8585,52.6005],[174.865,52.68],[174.8345,52.7395],[174.746,52.8075],[174.6185,52.846],[174.4625,52.8465],[174.409,52.892],[174.295,52.9385],[174.097,52.9595],[173.9435,52.989],[173.8365,52.9895],[173.7455,52.974],[173.4665,53.1295],[173.274,53.191],[173.175,53.206],[172.9725,53.209],[172.76,53.226],[172.552,53.211],[172.4875,53.195],[172.2465,53.0985],[172.151,53.0295],[172.1155,52.9425]]],[[[175.5315,52.3985],[175.56,52.3175],[175.691,52.207],[175.7955,52.1655],[175.9665,52.1495],[176.1155,52.1745],[176.193,52.2095],[176.294,52.292],[176.321,52.3555],[176.3015,52.445],[176.239,52.5075],[176.0955,52.5695],[175.9525,52.598],[175.862,52.605],[175.7305,52.588],[175.594,52.5215],[175.5415,52.452],[175.5315,52.3985]]],[[[176.8875,51.893],[176.9185,51.8085],[177.0085,51.7365],[177.228,51.639],[177.344,51.623],[177.427,51.628],[177.549,51.663],[177.6425,51.732],[177.7705,51.754],[177.9035,51.705],[178.0005,51.696],[178.144,51.6115],[178.34,51.571],[178.437,51.49],[178.714,51.3705],[178.803,51.356],[178.9365,51.277],[179.007,51.223],[179.1705,51.1695],[179.2585,51.163],[179.4285,51.1715],[179.5985,51.191],[179.6695,51.211],[179.76,51.262],[179.809,51.3205],[179.825,51.386],[179.8065,51.4505],[179.751,51.511],[179.574,51.604],[179.4255,51.6305],[179.3295,51.6685],[179.2745,51.732],[179.1675,51.7865],[178.878,51.8525],[178.9255,51.9265],[178.9285,51.989],[178.89,52.065],[178.8285,52.1175],[178.662,52.187],[178.553,52.2075],[178.4135,52.1995],[178.2755,52.256],[178.085,52.265],[177.956,52.235],[177.8835,52.2845],[177.7765,52.327],[177.6875,52.3465],[177.5535,52.3485],[177.4595,52.33],[177.346,52.335],[177.1795,52.2935],[177.117,52.2535],[177.0645,52.184],[177.0645,52.0895],[176.937,52.012],[176.901,51.9575],[176.8875,51.893]]],[[[179.167,51.9555],[179.22,51.8365],[179.29,51.7795],[179.3675,51.74],[179.51,51.7005],[179.602,51.687],[179.7315,51.6935],[179.8055,51.7105],[180.0,51.794],[180.0,51.8435],[180.0,51.8925],[180.0,51.942],[180.0,51.991],[180.0,52.0405],[180.0,52.0895],[180.0,52.1385],[179.8985,52.19],[179.754,52.234],[179.584,52.242],[179.459,52.2165],[179.315,52.1655],[179.2355,52.1185],[179.19,52.0665],[179.167,51.9555]]]]},"properties":{"flag":"https://upload.wikimedia.org/wikipedia/commons/a/a4/Flag_of_the_United_States.svg","name:en":"United States","wikidata":"Q30","ISO3166-1:alpha2":"US","ISO3166-1:alpha3":"USA","ISO3166-1:numeric":"840"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[79.4965,8.8975],[79.576,8.873],[79.6925,8.873],[79.7155,8.855],[79.715,8.781],[79.737,8.713],[79.6635,8.678],[79.626,8.641],[79.5815,8.548],[79.5835,8.434],[79.5605,8.362],[79.5245,8.321],[79.4965,8.257],[79.4905,8.207],[79.5075,8.021],[79.55,7.881],[79.597,7.675],[79.585,7.603],[79.5905,7.507],[79.635,7.289],[79.6175,7.227],[79.6235,7.143],[79.6555,7.025],[79.6385,6.939],[79.6425,6.897],[79.6835,6.723],[79.76,6.537],[79.7845,6.397],[79.8315,6.277],[79.8455,6.197],[79.883,6.101],[79.937,6.014],[80.0115,5.933],[80.136,5.836],[80.214,5.805],[80.4085,5.746],[80.594,5.719],[80.6315,5.723],[80.7195,5.759],[80.7905,5.772],[80.9045,5.849],[81.0635,5.908],[81.1745,5.926],[81.263,5.969],[81.4285,6.029],[81.5055,6.08],[81.6365,6.184],[81.753,6.267],[81.8675,6.384],[81.954,6.533],[81.977,6.613],[82.021,6.71],[82.0285,6.766],[82.0785,6.992],[82.0775,7.062],[82.061,7.124],[82.0695,7.304],[82.06,7.382],[82.0155,7.512],[81.9925,7.62],[81.9355,7.755],[81.874,7.854],[81.783,7.947],[81.7265,8.093],[81.6605,8.162],[81.6045,8.294],[81.5935,8.388],[81.5415,8.569],[81.507,8.626],[81.4225,8.698],[81.398,8.786],[81.352,8.861],[81.2795,8.919],[81.2215,9.011],[81.18,9.042],[81.118,9.124],[81.0505,9.245],[81.03,9.313],[80.9845,9.398],[80.9355,9.454],[80.7975,9.576],[80.677,9.668],[80.504,9.808],[80.3905,9.971],[80.34,10.006],[80.2355,10.034],[80.0775,10.015],[79.999,10.016],[79.893,9.99],[79.7635,9.936],[79.6285,9.819],[79.577,9.738],[79.5015,9.683],[79.451,9.58],[79.396,9.549],[79.4205,9.3535],[79.5665,9.258],[79.5715,9.087],[79.4965,8.8975]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/11/Flag_of_Sri_Lanka.svg","name:en":"Sri Lanka","ISO3166-1:alpha2":"LK","ISO3166-1:alpha3":"LKA","ISO3166-1:numeric":"144"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[7.589,47.59],[7.5055,47.5445],[7.511,47.497],[7.3865,47.4325],[7.3385,47.441],[7.255,47.4245],[7.17,47.443],[7.2015,47.4925],[7.139,47.502],[6.986,47.4935],[7.002,47.454],[6.9405,47.4335],[6.924,47.355],[7.05,47.3615],[7.0455,47.3265],[6.9405,47.286],[6.9555,47.244],[6.8805,47.2005],[6.85,47.1565],[6.7565,47.117],[6.6335,46.998],[6.505,46.9655],[6.4325,46.9285],[6.4645,46.8905],[6.435,46.8015],[6.438,46.7615],[6.283,46.6915],[6.1105,46.5765],[6.1565,46.5455],[6.073,46.4655],[6.0975,46.409],[6.17,46.366],[6.1025,46.285],[6.1245,46.2515],[5.979,46.217],[5.995,46.183],[6.0525,46.1515],[6.1365,46.1415],[6.2325,46.206],[6.2945,46.225],[6.2195,46.312],[6.253,46.3605],[6.335,46.4035],[6.4255,46.416],[6.519,46.4565],[6.682,46.4545],[6.821,46.427],[6.7705,46.3555],[6.8645,46.283],[6.804,46.2025],[6.798,46.136],[6.898,46.122],[6.8825,46.095],[7.0105,45.997],[7.0455,45.9225],[7.118,45.859],[7.1535,45.8795],[7.3445,45.915],[7.383,45.8965],[7.4785,45.9525],[7.658,45.9765],[7.735,45.924],[7.7695,45.937],[7.8635,45.9165],[7.9085,45.997],[7.9885,45.996],[8.034,46.0435],[8.0345,46.101],[8.108,46.1115],[8.1655,46.177],[8.139,46.226],[8.081,46.2585],[8.138,46.302],[8.222,46.33],[8.313,46.377],[8.291,46.409],[8.367,46.452],[8.438,46.464],[8.466,46.4425],[8.4655,46.334],[8.428,46.2985],[8.469,46.233],[8.5325,46.2185],[8.6125,46.1215],[8.852,46.0755],[8.787,45.9915],[8.8305,45.988],[8.925,45.904],[8.949,45.8435],[9.031,45.8245],[9.0745,45.9125],[9.0195,45.93],[9.017,46.05],[9.077,46.064],[9.0725,46.118],[9.194,46.1785],[9.2995,46.3265],[9.28,46.4145],[9.2495,46.431],[9.282,46.496],[9.3735,46.504],[9.3905,46.4735],[9.4625,46.498],[9.4545,46.419],[9.534,46.312],[9.6185,46.2875],[9.7145,46.293],[9.77,46.336],[9.9095,46.3795],[9.996,46.3425],[9.996,46.285],[10.0555,46.266],[10.0715,46.218],[10.175,46.2545],[10.1165,46.314],[10.108,46.3515],[10.164,46.3905],[10.143,46.4285],[10.087,46.4215],[10.0545,46.4645],[10.044,46.54],[10.1275,46.605],[10.224,46.629],[10.2415,46.589],[10.296,46.55],[10.364,46.5555],[10.472,46.5435],[10.4915,46.6115],[10.4015,46.637],[10.3845,46.683],[10.444,46.76],[10.4695,46.855],[10.488,46.9385],[10.3555,46.9925],[10.3095,46.95],[10.2415,46.9315],[10.232,46.8665],[10.123,46.8485],[10.0595,46.861],[10.0265,46.896],[9.88,46.935],[9.8735,47.0065],[9.68,47.062],[9.607,47.061],[9.56,47.0485],[9.5195,47.0985],[9.486,47.1805],[9.5305,47.2705],[9.5835,47.3125],[9.652,47.4085],[9.6545,47.4545],[9.593,47.466],[9.5505,47.537],[9.5145,47.537],[9.445,47.595],[9.256,47.659],[9.0265,47.6865],[8.899,47.648],[8.824,47.711],[8.7925,47.675],[8.728,47.6925],[8.7235,47.7455],[8.6825,47.7835],[8.6115,47.802],[8.473,47.764],[8.4055,47.674],[8.467,47.6415],[8.4315,47.5665],[8.325,47.5725],[8.288,47.6105],[8.1845,47.6045],[8.099,47.562],[7.9165,47.548],[7.892,47.5875],[7.8225,47.588],[7.7955,47.5575],[7.6975,47.533],[7.589,47.59]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/f3/Flag_of_Switzerland.svg","name:en":"Switzerland","wikidata":"Q39","ISO3166-1:alpha2":"CH","ISO3166-1:alpha3":"CHE","ISO3166-1:numeric":"756"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-61.7295,10.948],[-62.3235,11.2905],[-62.918,11.633],[-62.968,11.6545],[-63.7455,11.895],[-64.523,12.1345],[-64.625,12.151],[-65.361,12.1365],[-66.0785,12.1225],[-66.602,12.216],[-67.129,12.2695],[-67.678,12.3245],[-67.7335,12.32],[-67.8085,12.2925],[-67.9895,12.1935],[-67.9895,11.6665],[-68.6,11.6665],[-68.829,11.7415],[-68.9545,11.758],[-69.079,11.8795],[-69.7365,12.263],[-70.1405,12.365],[-70.164,12.35],[-70.4165,12.35],[-70.4165,12.5585],[-70.85,12.7045],[-70.926,12.7165],[-70.973,12.7115],[-71.055,12.675],[-71.122,12.6005],[-71.147,12.5235],[-71.08,12.402],[-71.0615,12.315],[-71.0135,12.2345],[-70.927,12.1575],[-70.927,11.961],[-71.345,11.848],[-71.3835,11.8105],[-71.644,11.734],[-71.7825,11.687],[-71.9715,11.6465],[-72.2455,11.145],[-72.3495,11.1515],[-72.4845,11.099],[-72.485,11.0615],[-72.575,10.915],[-72.64,10.8845],[-72.674,10.8215],[-72.689,10.757],[-72.735,10.6515],[-72.8205,10.57],[-72.8455,10.486],[-72.8935,10.4465],[-72.9065,10.353],[-72.8975,10.2175],[-72.9215,10.138],[-72.9115,10.1125],[-72.9545,10.065],[-72.953,10.0265],[-72.999,9.924],[-72.971,9.855],[-72.9455,9.8375],[-72.994,9.783],[-73.0055,9.741],[-73.055,9.6785],[-73.0855,9.556],[-73.128,9.5545],[-73.2035,9.4675],[-73.19,9.4445],[-73.241,9.403],[-73.2655,9.3265],[-73.3475,9.1735],[-73.248,9.1595],[-73.1775,9.1765],[-73.1315,9.2285],[-73.0735,9.243],[-73.011,9.2915],[-72.962,9.1845],[-72.973,9.1365],[-72.9475,9.0915],[-72.8865,9.1035],[-72.881,9.133],[-72.767,9.1065],[-72.719,8.9345],[-72.698,8.8065],[-72.655,8.6145],[-72.6105,8.5785],[-72.4275,8.3815],[-72.393,8.3585],[-72.382,8.3045],[-72.392,8.256],[-72.367,8.185],[-72.371,8.094],[-72.351,8.0805],[-72.3505,8.004],[-72.411,8.0345],[-72.425,7.99],[-72.487,7.945],[-72.4445,7.858],[-72.47,7.789],[-72.476,7.629],[-72.4525,7.563],[-72.4765,7.4895],[-72.442,7.446],[-72.4395,7.4035],[-72.1965,7.382],[-72.156,7.33],[-72.174,7.252],[-72.0475,7.039],[-71.941,7.0095],[-71.835,7.0255],[-71.811,7.0635],[-71.746,7.0655],[-71.7145,7.0345],[-71.656,7.0365],[-71.633,7.056],[-71.593,7.031],[-71.4915,7.031],[-71.459,7.0135],[-71.4295,7.038],[-71.379,7.018],[-71.2675,7.0325],[-71.1915,7.019],[-71.131,7.033],[-71.1115,6.99],[-70.995,6.983],[-70.927,7.0465],[-70.8395,7.079],[-70.697,7.094],[-70.6085,7.064],[-70.549,7.0745],[-70.503,7.006],[-70.4305,7.007],[-70.3715,6.98],[-70.344,6.9445],[-70.2935,6.934],[-70.2245,6.9745],[-70.118,6.9795],[-69.763,6.528],[-69.4305,6.108],[-69.3355,6.1375],[-69.312,6.0905],[-69.2375,6.08],[-69.1775,6.1475],[-69.123,6.1915],[-69.0435,6.2215],[-69.017,6.194],[-68.974,6.1965],[-68.886,6.168],[-68.8345,6.18],[-68.7925,6.1475],[-68.7065,6.152],[-68.6445,6.129],[-68.597,6.1635],[-68.5335,6.1515],[-68.5135,6.176],[-68.446,6.1875],[-68.3735,6.186],[-68.2975,6.1655],[-68.2545,6.1975],[-68.101,6.232],[-68.0415,6.198],[-67.9775,6.2085],[-67.9245,6.2405],[-67.845,6.3125],[-67.811,6.324],[-67.769,6.294],[-67.7215,6.3005],[-67.6255,6.2915],[-67.584,6.262],[-67.535,6.26],[-67.457,6.1935],[-67.4945,6.131],[-67.456,6.0585],[-67.4275,6.038],[-67.412,5.9885],[-67.527,5.9085],[-67.597,5.828],[-67.631,5.7325],[-67.639,5.653],[-67.619,5.564],[-67.599,5.544],[-67.625,5.476],[-67.683,5.427],[-67.797,5.3605],[-67.8495,5.304],[-67.8235,5.247],[-67.8265,5.1915],[-67.8545,5.138],[-67.806,5.055],[-67.8375,4.947],[-67.8235,4.84],[-67.818,4.707],[-67.845,4.645],[-67.839,4.562],[-67.857,4.5245],[-67.8035,4.4895],[-67.798,4.437],[-67.773,4.419],[-67.8055,4.315],[-67.797,4.2295],[-67.7725,4.1655],[-67.742,4.139],[-67.7035,4.0395],[-67.69,3.9365],[-67.6445,3.8525],[-67.644,3.813],[-67.61,3.754],[-67.5015,3.7675],[-67.483,3.712],[-67.439,3.6325],[-67.444,3.585],[-67.412,3.539],[-67.4015,3.48],[-67.339,3.451],[-67.312,3.391],[-67.3345,3.3355],[-67.3815,3.2925],[-67.3825,3.2455],[-67.435,3.2485],[-67.8645,2.866],[-67.864,2.7895],[-67.824,2.826],[-67.7505,2.8375],[-67.735,2.817],[-67.6585,2.7965],[-67.6215,2.814],[-67.584,2.7735],[-67.563,2.723],[-67.5685,2.666],[-67.5195,2.673],[-67.4705,2.624],[-67.3935,2.5745],[-67.352,2.5295],[-67.2975,2.4425],[-67.216,2.3925],[-67.188,2.3505],[-67.2135,2.3095],[-67.2205,2.2505],[-67.1615,2.133],[-67.1145,2.1335],[-67.097,2.0515],[-67.123,1.977],[-67.0655,1.9205],[-67.0355,1.8455],[-67.033,1.7865],[-66.959,1.625],[-66.9075,1.4875],[-66.913,1.4335],[-66.854,1.3675],[-66.8555,1.3215],[-66.881,1.2905],[-66.851,1.229],[-66.598,1.0],[-66.3105,0.745],[-66.1975,0.7815],[-66.1455,0.7475],[-66.077,0.762],[-66.07,0.8125],[-66.0145,0.804],[-65.9435,0.8635],[-65.941,0.891],[-65.888,0.91],[-65.788,0.965],[-65.743,1.001],[-65.627,1.0145],[-65.5575,0.9915],[-65.512,0.896],[-65.502,0.849],[-65.6045,0.715],[-65.556,0.654],[-65.445,0.689],[-65.3965,0.7775],[-65.396,0.822],[-65.356,0.865],[-65.3255,0.936],[-65.265,0.9205],[-65.1755,0.941],[-65.1755,1.0155],[-65.1515,1.109],[-65.1055,1.156],[-65.0105,1.1115],[-64.9715,1.18],[-64.8955,1.251],[-64.8555,1.266],[-64.8025,1.314],[-64.756,1.228],[-64.721,1.2395],[-64.6955,1.284],[-64.6455,1.3005],[-64.581,1.3595],[-64.537,1.4155],[-64.4665,1.4735],[-64.436,1.47],[-64.3945,1.5285],[-64.348,1.495],[-64.41,1.403],[-64.3435,1.382],[-64.3135,1.456],[-64.2435,1.507],[-64.1965,1.5215],[-64.173,1.5735],[-64.1315,1.576],[-64.077,1.645],[-64.061,1.7025],[-64.076,1.782],[-64.0545,1.803],[-64.067,1.8535],[-64.061,1.925],[-63.972,1.992],[-63.893,1.9895],[-63.8355,1.9665],[-63.741,2.0035],[-63.7115,2.0465],[-63.664,2.065],[-63.6355,2.099],[-63.564,2.134],[-63.511,2.1115],[-63.401,2.1505],[-63.3675,2.2685],[-63.384,2.352],[-63.3635,2.376],[-63.3795,2.4195],[-63.4385,2.436],[-63.523,2.417],[-63.5925,2.4475],[-63.6555,2.4365],[-63.703,2.4535],[-63.7725,2.4415],[-63.8425,2.491],[-63.931,2.4555],[-64.0305,2.481],[-64.057,2.5065],[-63.9905,2.6365],[-63.9825,2.715],[-64.0405,2.829],[-64.0715,2.9215],[-64.124,2.9905],[-64.1695,3.072],[-64.2255,3.1365],[-64.198,3.201],[-64.2285,3.3155],[-64.222,3.3875],[-64.2425,3.4355],[-64.1755,3.515],[-64.172,3.559],[-64.201,3.605],[-64.2675,3.6685],[-64.281,3.7095],[-64.3675,3.76],[-64.4775,3.7935],[-64.5435,3.857],[-64.587,3.9325],[-64.6335,3.962],[-64.7225,4.1175],[-64.802,4.174],[-64.8195,4.235],[-64.78,4.287],[-64.695,4.253],[-64.659,4.22],[-64.623,4.135],[-64.592,4.114],[-64.5,4.113],[-64.431,4.135],[-64.335,4.129],[-64.274,4.143],[-64.218,4.116],[-64.171,4.129],[-64.112,4.092],[-64.097,4.026],[-64.035,3.935],[-63.959,3.888],[-63.928,3.925],[-63.85,3.95],[-63.796,3.933],[-63.7,3.945],[-63.685,4.009],[-63.652,4.002],[-63.592,3.929],[-63.593,3.906],[-63.512,3.848],[-63.489,3.874],[-63.452,3.859],[-63.411,3.912],[-63.452,3.956],[-63.393,3.981],[-63.338,3.957],[-63.204,3.952],[-63.233,3.882],[-63.204,3.812],[-63.123,3.805],[-63.06,3.752],[-63.072,3.686],[-63.032,3.666],[-62.984,3.61],[-62.952,3.612],[-62.919,3.673],[-62.886,3.684],[-62.835,3.739],[-62.804,3.73],[-62.748,3.673],[-62.731,3.708],[-62.729,3.805],[-62.788,3.894],[-62.782,3.935],[-62.743,3.975],[-62.768,4.007],[-62.736,4.04],[-62.701,4.031],[-62.609,4.044],[-62.572,4.015],[-62.534,4.052],[-62.552,4.109],[-62.46,4.143],[-62.462,4.178],[-62.389,4.178],[-62.329,4.135],[-62.252,4.13],[-62.148,4.079],[-62.064,4.159],[-61.993,4.175],[-61.9265,4.1245],[-61.922,4.1615],[-61.818,4.168],[-61.802,4.229],[-61.769,4.249],[-61.658,4.262],[-61.631,4.241],[-61.56,4.252],[-61.508,4.322],[-61.513,4.406],[-61.462,4.437],[-61.351,4.419],[-61.278,4.478],[-61.322,4.504],[-61.323,4.535],[-61.269,4.54],[-61.188,4.521],[-61.1475,4.481],[-61.1195,4.5105],[-61.065,4.524],[-60.994,4.519],[-60.964,4.544],[-60.899,4.717],[-60.852,4.704],[-60.806,4.749],[-60.751,4.756],[-60.726,4.792],[-60.659,4.849],[-60.584,4.956],[-60.599,5.0],[-60.644,5.057],[-60.661,5.164],[-60.694,5.197],[-60.7375,5.202],[-60.749,5.2225],[-61.0845,5.599],[-61.392,5.944],[-61.331,5.999],[-61.312,6.052],[-61.2745,6.105],[-61.2095,6.112],[-61.1795,6.187],[-61.142,6.215],[-61.126,6.262],[-61.1755,6.327],[-61.148,6.413],[-61.1525,6.4575],[-61.1825,6.472],[-61.1725,6.5195],[-61.2195,6.566],[-61.183,6.671],[-61.1385,6.7215],[-61.0855,6.7045],[-61.013,6.7285],[-60.9555,6.7155],[-60.9095,6.747],[-60.9235,6.807],[-60.895,6.811],[-60.846,6.7805],[-60.8095,6.794],[-60.7185,6.7555],[-60.6635,6.8295],[-60.5555,6.856],[-60.5005,6.882],[-60.461,6.9245],[-60.4015,6.948],[-60.3665,6.998],[-60.3205,7.0215],[-60.2875,7.0875],[-60.2935,7.1335],[-60.367,7.185],[-60.4205,7.1765],[-60.4495,7.205],[-60.5585,7.1545],[-60.6245,7.211],[-60.638,7.246],[-60.6155,7.2985],[-60.588,7.3145],[-60.614,7.395],[-60.7055,7.4955],[-60.7045,7.56],[-60.6605,7.5645],[-60.618,7.6425],[-60.57,7.7035],[-60.563,7.761],[-60.4995,7.834],[-60.4375,7.836],[-60.405,7.821],[-60.333,7.8415],[-60.2455,7.913],[-60.219,7.9575],[-60.1835,7.9645],[-60.1005,8.0355],[-60.066,8.024],[-60.006,8.06],[-59.995,8.154],[-59.946,8.2135],[-59.8485,8.225],[-59.8015,8.275],[-59.815,8.3115],[-59.981,8.5185],[-59.955,8.5405],[-59.7705,8.604],[-59.5425,8.686],[-60.7295,9.628],[-60.81,9.672],[-60.8535,9.7175],[-60.9755,9.783],[-61.109,9.806],[-61.2075,9.8745],[-61.2235,9.876],[-61.5,9.97],[-61.6305,9.9865],[-61.855,9.9865],[-61.9735,10.008],[-62.083,10.046],[-61.8625,10.5885],[-61.803,10.589],[-61.803,10.7145],[-61.731,10.904],[-61.7295,10.948]]],[[[-63.8575,15.687],[-63.8315,15.586],[-63.796,15.5375],[-63.741,15.494],[-63.6895,15.4725],[-63.613,15.4645],[-63.5325,15.4835],[-63.48,15.515],[-63.4235,15.5825],[-63.3985,15.671],[-63.4055,15.7505],[-63.4495,15.8355],[-63.5165,15.8895],[-63.6075,15.915],[-63.6755,15.91],[-63.7415,15.884],[-63.823,15.806],[-63.8475,15.754],[-63.8575,15.687]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/06/Flag_of_Venezuela.svg","name:en":"Venezuela","wikidata":"Q717","ISO3166-1:alpha2":"VE","ISO3166-1:alpha3":"VEN","ISO3166-1:numeric":"862"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-72.55,21.9485],[-72.4555,22.2505],[-72.4555,22.3625],[-72.5265,22.47],[-73.4415,23.218],[-74.27,24.2415],[-74.3235,24.305],[-74.3855,24.344],[-75.497,24.8055],[-75.514,24.821],[-75.949,25.2765],[-76.7415,26.6025],[-76.7935,26.6915],[-76.8905,26.7785],[-77.2505,27.0065],[-77.338,27.0695],[-77.4615,27.1405],[-77.68,27.2265],[-77.9065,27.275],[-78.0865,27.3845],[-78.183,27.4245],[-78.285,27.4535],[-78.3825,27.4705],[-78.456,27.471],[-78.5395,27.444],[-79.21,27.1285],[-79.274,27.0835],[-79.3155,27.021],[-79.329,26.949],[-79.316,26.0915],[-79.4475,25.9135],[-79.505,25.811],[-79.524,25.7555],[-79.536,25.639],[-79.528,25.563],[-79.4705,25.4285],[-79.407,25.3225],[-79.371,25.2045],[-79.363,25.0045],[-80.0035,24.248],[-80.4825,24.156],[-80.5825,24.111],[-80.654,24.038],[-80.695,23.9495],[-80.6855,23.834],[-80.596,23.6205],[-80.557,23.5605],[-80.484,23.5065],[-80.437,23.4905],[-79.596,23.301],[-79.295,23.143],[-78.791,22.8755],[-78.773,22.8685],[-78.4825,22.7535],[-78.213,22.6425],[-78.1155,22.596],[-77.8015,22.42],[-77.6295,22.292],[-77.5715,22.2585],[-77.215,22.033],[-75.8345,21.5315],[-73.8395,20.8055],[-73.8085,20.7715],[-73.7095,20.7145],[-73.6295,20.706],[-73.159,20.7405],[-73.0815,20.7605],[-72.993,20.836],[-72.8465,21.06],[-72.814,21.134],[-72.6775,21.54],[-72.6725,21.6405],[-72.63,21.804],[-72.6095,21.858],[-72.55,21.9485]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/93/Flag_of_the_Bahamas.svg","name:en":"The Bahamas","wikidata":"Q778","ISO3166-1:alpha2":"BS","ISO3166-1:alpha3":"BHS","ISO3166-1:numeric":"044"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-16.858,13.603],[-16.9805,13.512],[-17.0205,13.439],[-17.026,13.351],[-17.01,13.247],[-16.991,13.187],[-16.976,13.061],[-16.7485,13.061],[-16.735,13.1125],[-16.679,13.1685],[-16.2335,13.165],[-15.8035,13.167],[-15.805,13.3405],[-15.7335,13.35],[-15.683,13.371],[-15.6295,13.354],[-15.5575,13.3595],[-15.4945,13.395],[-15.3795,13.356],[-15.2995,13.3665],[-15.229,13.419],[-15.1975,13.5295],[-15.1415,13.583],[-15.09,13.6005],[-15.051,13.535],[-14.999,13.4915],[-14.8995,13.4475],[-14.85,13.4445],[-14.814,13.418],[-14.7605,13.4175],[-14.7275,13.3715],[-14.6725,13.3445],[-14.578,13.3585],[-14.517,13.3055],[-14.4595,13.3],[-14.4385,13.271],[-14.359,13.2295],[-14.2665,13.247],[-14.1935,13.2295],[-14.129,13.2605],[-14.114,13.2865],[-13.987,13.3045],[-13.9485,13.3235],[-13.867,13.323],[-13.801,13.389],[-13.7995,13.4335],[-13.886,13.5455],[-13.9735,13.583],[-14.0305,13.556],[-14.0705,13.563],[-14.218,13.504],[-14.241,13.4785],[-14.338,13.454],[-14.472,13.535],[-14.4855,13.599],[-14.5355,13.6505],[-14.6115,13.6575],[-14.664,13.6455],[-14.7185,13.612],[-14.792,13.6535],[-14.8185,13.745],[-14.883,13.793],[-14.938,13.8055],[-14.986,13.794],[-15.067,13.825],[-15.1265,13.8065],[-15.2055,13.7545],[-15.265,13.741],[-15.3075,13.791],[-15.3645,13.7815],[-15.412,13.743],[-15.452,13.674],[-15.4775,13.584],[-15.6055,13.5915],[-16.147,13.5925],[-16.817,13.587],[-16.858,13.603]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/7/77/Flag_of_The_Gambia.svg","name:en":"The Gambia","wikidata":"Q1005","ISO3166-1:alpha2":"GM","ISO3166-1:alpha3":"GMB","ISO3166-1:numeric":"270"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-180.0,-9.585],[-179.938,-9.488],[-179.926,-9.415],[-179.938,-9.3385],[-180.0,-9.228],[-180.0,-9.585]]],[[[175.853,-5.6395],[175.863,-5.7015],[175.8925,-5.7635],[175.9375,-5.8105],[176.0205,-5.8715],[176.114,-5.9085],[176.1705,-5.908],[176.2685,-5.8645],[176.334,-5.771],[176.3445,-5.6875],[176.3305,-5.6265],[176.2965,-5.556],[176.2555,-5.5075],[176.198,-5.47],[176.074,-5.438],[175.962,-5.4595],[175.906,-5.5025],[175.876,-5.5455],[175.853,-5.6395]]],[[[176.1115,-6.29],[176.1185,-6.3435],[176.156,-6.42],[176.243,-6.4885],[176.318,-6.504],[176.3845,-6.494],[176.434,-6.4695],[176.4935,-6.4075],[176.5185,-6.354],[176.528,-6.268],[176.498,-6.1705],[176.4545,-6.119],[176.387,-6.0795],[176.3275,-6.069],[176.264,-6.0775],[176.213,-6.101],[176.1575,-6.153],[176.123,-6.22],[176.1115,-6.29]]],[[[176.9365,-7.194],[176.949,-7.307],[176.9955,-7.3865],[177.029,-7.416],[177.1225,-7.454],[177.2295,-7.4455],[177.2905,-7.4115],[177.35,-7.3335],[177.369,-7.235],[177.3605,-7.163],[177.3295,-7.0875],[177.2835,-7.036],[177.2015,-6.9925],[177.143,-6.9845],[177.0485,-7.007],[177.003,-7.039],[176.9585,-7.098],[176.9365,-7.194]]],[[[177.129,-6.105],[177.138,-6.166],[177.1935,-6.2555],[177.268,-6.303],[177.328,-6.316],[177.391,-6.311],[177.469,-6.2775],[177.517,-6.2295],[177.547,-6.168],[177.555,-6.111],[177.536,-6.022],[177.4955,-5.963],[177.453,-5.93],[177.384,-5.9045],[177.333,-5.9005],[177.225,-5.9325],[177.1645,-5.991],[177.1405,-6.0385],[177.129,-6.105]]],[[[178.102,-8.03],[178.122,-8.1175],[178.18,-8.1905],[178.5775,-8.5065],[178.9375,-8.7925],[179.2605,-9.1225],[179.698,-9.569],[179.7875,-9.624],[179.898,-9.634],[180.0,-9.585],[180.0,-9.228],[179.668,-8.7745],[179.3345,-8.3165],[179.2805,-8.2655],[178.902,-8.021],[178.5295,-7.7805],[178.4375,-7.735],[178.368,-7.726],[178.2715,-7.755],[178.204,-7.8115],[178.17,-7.857],[178.1115,-7.9695],[178.102,-8.03]]],[[[178.4605,-7.4605],[178.477,-7.5445],[178.5205,-7.622],[178.582,-7.6745],[178.6495,-7.6985],[178.732,-7.6955],[178.7785,-7.679],[178.845,-7.6275],[178.882,-7.571],[178.9005,-7.4715],[178.8755,-7.3855],[178.783,-7.2905],[178.7155,-7.2615],[178.6555,-7.2555],[178.58,-7.2745],[178.5365,-7.3015],[178.4855,-7.3625],[178.4605,-7.4605]]],[[[179.264,-10.787],[179.2935,-10.8935],[179.3735,-10.9685],[179.4375,-10.991],[179.509,-10.991],[179.5845,-10.9625],[179.627,-10.9275],[179.6685,-10.862],[179.679,-10.7515],[179.65,-10.679],[179.608,-10.632],[179.533,-10.5925],[179.454,-10.586],[179.3565,-10.619],[179.2875,-10.6945],[179.264,-10.787]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/38/Flag_of_Tuvalu.svg","name:en":"Tuvalu","wikidata":"Q672","ISO3166-1:alpha2":"TV","ISO3166-1:alpha3":"TUV","ISO3166-1:numeric":"798"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[12.4455,41.902],[12.4545,41.9],[12.4575,41.906],[12.4515,41.9065],[12.4455,41.902]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/00/Flag_of_the_Vatican_City.svg","name:en":"Vatican City","wikidata":"Q237","ISO3166-1:alpha2":"VA","ISO3166-1:alpha3":"VAT","ISO3166-1:numeric":"336"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-14.6225,-7.941],[-14.598,-8.061],[-14.565,-8.111],[-14.49,-8.17],[-14.4395,-8.188],[-14.373,-8.192],[-14.2605,-8.166],[-14.2,-8.133],[-14.13,-8.067],[-14.098,-7.993],[-14.0955,-7.917],[-14.1165,-7.854],[-14.2035,-7.759],[-14.2975,-7.705],[-14.355,-7.691],[-14.422,-7.694],[-14.4975,-7.722],[-14.565,-7.784],[-14.6015,-7.843],[-14.6225,-7.941]]],[[[-12.957,-37.299],[-12.94,-37.377],[-12.8575,-37.471],[-12.7165,-37.52],[-12.6735,-37.569],[-12.5865,-37.616],[-12.4805,-37.633],[-12.3945,-37.622],[-12.336,-37.599],[-12.258,-37.535],[-12.223,-37.468],[-12.229,-37.365],[-12.1465,-37.341],[-12.095,-37.31],[-11.9885,-37.201],[-11.9655,-37.133],[-11.97,-37.073],[-12.0095,-36.99],[-12.048,-36.946],[-12.1245,-36.895],[-12.1905,-36.871],[-12.306,-36.863],[-12.3675,-36.873],[-12.466,-36.909],[-12.5165,-36.948],[-12.577,-37.032],[-12.5985,-37.091],[-12.672,-37.082],[-12.774,-37.095],[-12.8995,-37.167],[-12.939,-37.221],[-12.957,-37.299]]],[[[-10.2805,-40.313],[-10.2435,-40.413],[-10.1845,-40.467],[-10.049,-40.544],[-9.9225,-40.57],[-9.7855,-40.553],[-9.698,-40.505],[-9.645,-40.445],[-9.612,-40.349],[-9.621,-40.291],[-9.694,-40.171],[-9.8195,-40.096],[-9.905,-40.076],[-9.9845,-40.073],[-10.0925,-40.092],[-10.1775,-40.132],[-10.2365,-40.189],[-10.2805,-40.313]]],[[[-5.9975,-15.999],[-5.9695,-16.097],[-5.875,-16.193],[-5.8225,-16.219],[-5.757,-16.23],[-5.6845,-16.219],[-5.525,-16.153],[-5.462,-16.097],[-5.4315,-16.037],[-5.4235,-15.977],[-5.4315,-15.905],[-5.468,-15.825],[-5.508,-15.772],[-5.568,-15.731],[-5.705,-15.704],[-5.757,-15.711],[-5.8375,-15.751],[-5.9325,-15.839],[-5.982,-15.921],[-5.9975,-15.999]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/00/Flag_of_Saint_Helena.svg","name:en":"Saint Helena, Ascension and Tristan da Cunha","wikidata":"Q192184","ISO3166-1:alpha2":"SH","ISO3166-1:alpha3":"SHN","ISO3166-1:numeric":"654"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-82.506,9.654],[-82.565,9.572],[-82.6355,9.494],[-82.6845,9.5065],[-82.7595,9.587],[-82.857,9.62],[-82.885,9.5705],[-82.8445,9.5],[-82.936,9.473],[-82.936,9.0785],[-82.887,9.088],[-82.874,9.0575],[-82.7505,8.9925],[-82.712,8.9225],[-82.7605,8.885],[-82.855,8.856],[-82.8665,8.8055],[-82.9145,8.7695],[-82.916,8.7415],[-82.8705,8.6985],[-82.83,8.636],[-82.822,8.567],[-82.832,8.5045],[-82.8685,8.4395],[-82.9355,8.424],[-83.046,8.318],[-82.975,8.2895],[-82.9295,8.2455],[-82.8875,8.077],[-82.9455,7.9355],[-82.3235,7.4125],[-82.1035,7.3575],[-82.016,7.304],[-81.976,7.195],[-81.8925,7.053],[-81.716,7.0945],[-81.566,7.183],[-81.292,7.3315],[-81.2065,7.311],[-81.027,7.1135],[-80.8975,7.034],[-80.3495,7.1085],[-80.2295,7.1895],[-80.17,7.219],[-79.9485,7.292],[-79.809,7.389],[-79.7635,7.5255],[-79.779,7.669],[-79.882,7.8335],[-80.1195,8.084],[-79.568,8.4275],[-79.3395,8.349],[-79.343,8.085],[-79.175,7.9525],[-78.748,7.926],[-78.63,7.775],[-78.3705,7.4045],[-78.1835,7.206],[-78.1235,7.1495],[-78.0365,7.051],[-77.889,7.2285],[-77.818,7.4725],[-77.7745,7.46],[-77.7015,7.507],[-77.7485,7.6165],[-77.742,7.6795],[-77.692,7.693],[-77.645,7.6515],[-77.63,7.5945],[-77.5835,7.5135],[-77.548,7.522],[-77.519,7.5745],[-77.491,7.567],[-77.461,7.6565],[-77.401,7.722],[-77.391,7.76],[-77.3365,7.78],[-77.364,7.825],[-77.3125,7.8975],[-77.2535,7.92],[-77.1795,7.917],[-77.164,7.9705],[-77.2135,8.0095],[-77.218,8.085],[-77.247,8.1755],[-77.3495,8.296],[-77.3555,8.387],[-77.412,8.475],[-77.4475,8.4725],[-77.448,8.5465],[-77.3705,8.661],[-77.3245,8.8105],[-77.5245,9.123],[-77.8465,9.3815],[-78.212,9.5505],[-78.571,9.797],[-79.0065,9.8355],[-79.533,9.87],[-79.9035,9.6485],[-80.025,9.5085],[-80.1925,9.3755],[-80.6045,9.2215],[-80.797,9.1125],[-80.8925,9.026],[-81.037,8.963],[-81.292,8.918],[-81.3675,8.956],[-81.4235,9.1075],[-81.535,9.1795],[-81.6855,9.202],[-81.8145,9.265],[-82.236,9.551],[-82.335,9.539],[-82.4775,9.6505],[-82.506,9.654]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/a/ab/Flag_of_Panama.svg","name:en":"Panama","wikidata":"Q804","ISO3166-1:alpha2":"PA","ISO3166-1:alpha3":"PAN","ISO3166-1:numeric":"591"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-83.046,15.033],[-82.8815,15.0905],[-82.8655,15.006],[-82.834,14.9535],[-82.5555,14.943],[-82.483,14.8735],[-82.4205,14.852],[-82.352,14.8485],[-82.2805,14.871],[-82.218,14.92],[-82.1815,14.982],[-82.1775,15.081],[-82.219,15.1725],[-82.257,15.2075],[-82.3655,15.269],[-82.4055,15.3355],[-82.516,15.4185],[-82.581,15.4455],[-82.667,15.4475],[-82.796,15.41],[-82.8625,15.463],[-82.844,15.5195],[-82.7755,15.548],[-82.7345,15.5825],[-82.6925,15.651],[-82.6825,15.6945],[-82.695,15.7915],[-82.728,15.8475],[-82.7715,15.8865],[-82.8425,15.9265],[-82.9055,15.9445],[-83.0065,15.9325],[-83.0475,15.9125],[-83.061,15.988],[-83.1525,16.155],[-83.1895,16.198],[-83.2685,16.242],[-83.3835,16.2445],[-83.4845,16.1865],[-83.5275,16.1215],[-83.539,16.011],[-83.5055,15.925],[-83.5125,15.811],[-83.483,15.7255],[-83.408,15.6545],[-83.3285,15.6295],[-83.262,15.6325],[-83.2735,15.5865],[-83.268,15.506],[-83.2295,15.433],[-83.155,15.375],[-83.1735,15.3215],[-83.28,15.4225],[-84.194,15.9845],[-84.256,16.01],[-84.94,16.171],[-85.229,16.359],[-85.6845,16.6545],[-85.7315,16.687],[-85.814,16.7135],[-85.8795,16.7155],[-86.195,16.6405],[-86.2715,16.627],[-86.73,16.485],[-86.8005,16.4235],[-87.3035,16.2145],[-87.7005,16.164],[-88.1755,15.9075],[-88.2215,15.7235],[-88.2475,15.69],[-88.3255,15.6705],[-88.3455,15.6175],[-88.5525,15.4465],[-88.605,15.413],[-88.678,15.3425],[-88.8455,15.243],[-88.974,15.136],[-89.1535,15.0685],[-89.1845,15.0025],[-89.1565,14.98],[-89.1815,14.911],[-89.228,14.8825],[-89.224,14.8345],[-89.169,14.775],[-89.1655,14.731],[-89.1315,14.7125],[-89.1575,14.67],[-89.1595,14.5745],[-89.2385,14.585],[-89.303,14.4965],[-89.355,14.47],[-89.356,14.4205],[-89.216,14.389],[-89.1685,14.366],[-89.109,14.4085],[-89.083,14.3415],[-89.0355,14.332],[-89.026,14.2725],[-88.9925,14.259],[-88.97,14.212],[-88.9025,14.2055],[-88.8665,14.1785],[-88.831,14.108],[-88.799,14.1645],[-88.7375,14.131],[-88.709,14.0465],[-88.6075,14.0055],[-88.569,13.978],[-88.5,13.967],[-88.5055,13.9085],[-88.4925,13.8625],[-88.452,13.859],[-88.417,13.8845],[-88.3175,13.89],[-88.2655,13.937],[-88.227,13.938],[-88.23,14.0],[-88.16,13.9835],[-88.0725,13.9925],[-88.063,13.9435],[-88.0125,13.8715],[-87.9625,13.8975],[-87.854,13.8945],[-87.831,13.9185],[-87.7465,13.854],[-87.7085,13.804],[-87.7545,13.691],[-87.7555,13.603],[-87.792,13.5265],[-87.722,13.506],[-87.723,13.4435],[-87.7905,13.414],[-87.799,13.3815],[-87.7435,13.349],[-87.739,13.3245],[-87.678,13.235],[-87.635,13.1975],[-87.663,13.1275],[-87.543,13.1675],[-87.4795,13.078],[-87.3945,13.004],[-87.3085,12.9875],[-87.0275,13.003],[-86.955,13.039],[-86.9255,13.083],[-86.931,13.19],[-86.9085,13.269],[-86.829,13.3135],[-86.7545,13.2675],[-86.706,13.303],[-86.7105,13.359],[-86.744,13.4065],[-86.722,13.4325],[-86.741,13.4865],[-86.7495,13.5655],[-86.7695,13.582],[-86.749,13.6395],[-86.786,13.662],[-86.7605,13.7255],[-86.7655,13.7665],[-86.723,13.787],[-86.5225,13.781],[-86.417,13.759],[-86.3325,13.769],[-86.2785,13.8755],[-86.227,13.9065],[-86.1405,14.006],[-86.1525,14.0355],[-86.076,14.07],[-86.0085,14.0555],[-86.042,13.996],[-85.9125,13.926],[-85.8455,13.9175],[-85.8265,13.859],[-85.7665,13.8495],[-85.7535,13.968],[-85.6645,14.011],[-85.626,14.0085],[-85.592,14.0425],[-85.536,14.046],[-85.4985,14.0855],[-85.404,14.123],[-85.3415,14.247],[-85.1985,14.2565],[-85.159,14.288],[-85.1985,14.3475],[-85.2055,14.3865],[-85.181,14.4285],[-85.183,14.4695],[-85.1385,14.519],[-85.147,14.5765],[-85.096,14.5525],[-85.0425,14.575],[-85.0215,14.6075],[-85.0275,14.696],[-84.987,14.74],[-84.9425,14.754],[-84.9005,14.8145],[-84.7995,14.822],[-84.752,14.7735],[-84.745,14.7155],[-84.7035,14.6665],[-84.6295,14.6745],[-84.5435,14.6545],[-84.496,14.6195],[-84.434,14.632],[-84.3755,14.6995],[-84.297,14.663],[-84.2585,14.675],[-84.2735,14.7235],[-84.2355,14.7605],[-84.1885,14.716],[-84.0955,14.7315],[-84.0395,14.7655],[-83.9715,14.7475],[-83.9285,14.7785],[-83.8895,14.765],[-83.7,14.858],[-83.5775,14.912],[-83.529,14.951],[-83.541,14.975],[-83.5015,15.011],[-83.459,14.981],[-83.385,15.0165],[-83.2355,14.9825],[-83.1415,14.998],[-83.046,15.033]]],[[[-84.1545,17.41],[-84.1445,17.3455],[-84.119,17.295],[-84.0585,17.238],[-84.0035,17.213],[-83.895,17.205],[-83.816,17.223],[-83.771,17.25],[-83.7145,17.3185],[-83.6945,17.383],[-83.712,17.493],[-83.747,17.5445],[-83.8365,17.6015],[-83.951,17.619],[-84.0155,17.6035],[-84.075,17.5685],[-84.1375,17.4895],[-84.1545,17.41]]],[[[-82.6035,15.8695],[-82.5975,15.8225],[-82.568,15.7575],[-82.488,15.689],[-82.3895,15.6675],[-82.2845,15.6955],[-82.219,15.7545],[-82.1825,15.8515],[-82.1855,15.9095],[-82.2215,15.9895],[-82.2555,16.025],[-82.3225,16.0625],[-82.4075,16.0735],[-82.4565,16.065],[-82.5395,16.0175],[-82.5815,15.962],[-82.6035,15.8695]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/82/Flag_of_Honduras.svg","name:en":"Honduras","wikidata":"Q783","ISO3166-1:alpha2":"HN","ISO3166-1:alpha3":"HND","ISO3166-1:numeric":"340"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[12.4035,43.9525],[12.4155,43.9],[12.4875,43.8965],[12.516,43.941],[12.5065,43.9915],[12.4035,43.9525]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/b1/Flag_of_San_Marino.svg","name:en":"San Marino","wikidata":"Q238","ISO3166-1:alpha2":"SM","ISO3166-1:alpha3":"SMR","ISO3166-1:numeric":"674"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-60.9865,13.5115],[-60.901,13.513],[-60.823,13.545],[-60.7765,13.588],[-60.728,13.663],[-60.687,13.762],[-60.6735,13.834],[-60.6685,13.996],[-60.68,14.084],[-60.7095,14.158],[-60.753,14.2215],[-60.892,14.2435],[-61.004,14.2725],[-61.097,14.2485],[-61.1495,14.185],[-61.258,13.99],[-61.281,13.922],[-61.2835,13.79],[-61.2705,13.736],[-61.197,13.631],[-61.1305,13.58],[-60.9865,13.5115]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9f/Flag_of_Saint_Lucia.svg","name:en":"Saint Lucia","wikidata":"Q760","ISO3166-1:alpha2":"LC","ISO3166-1:alpha3":"LCA","ISO3166-1:numeric":"662"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-10.28,8.485],[-10.322,8.506],[-10.386,8.488],[-10.3995,8.4495],[-10.478,8.3765],[-10.491,8.35],[-10.556,8.3055],[-10.5775,8.334],[-10.6425,8.3545],[-10.641,8.4745],[-10.616,8.542],[-10.5765,8.596],[-10.4925,8.6255],[-10.466,8.674],[-10.511,8.7425],[-10.52,8.7825],[-10.562,8.818],[-10.559,8.8445],[-10.5905,8.9775],[-10.574,9.0445],[-10.6675,9.0855],[-10.731,9.0815],[-10.722,9.187],[-10.667,9.1995],[-10.6635,9.3105],[-10.7085,9.332],[-10.7315,9.3795],[-10.815,9.39],[-10.8365,9.4395],[-10.881,9.5915],[-10.911,9.602],[-10.918,9.655],[-10.964,9.664],[-10.993,9.7525],[-11.039,9.7875],[-11.096,9.8575],[-11.1575,9.868],[-11.1725,9.961],[-11.208,10.0],[-11.8945,10.0],[-11.907,9.94],[-12.12,9.8725],[-12.2175,9.909],[-12.2225,9.933],[-12.4355,9.881],[-12.471,9.85],[-12.5285,9.717],[-12.5645,9.7025],[-12.5875,9.6015],[-12.6175,9.604],[-12.654,9.54],[-12.684,9.417],[-12.7555,9.392],[-12.7855,9.3035],[-12.807,9.29],[-12.8795,9.2935],[-12.907,9.262],[-12.9415,9.2905],[-12.9715,9.227],[-13.0015,9.1165],[-13.0735,9.08],[-13.082,9.0485],[-13.141,9.0565],[-13.185,9.095],[-13.2755,9.063],[-13.301,9.036],[-13.496,8.966],[-13.488,8.91],[-13.4495,8.836],[-13.444,8.636],[-13.4925,8.55],[-13.5,8.502],[-13.491,8.38],[-13.462,8.313],[-13.399,8.23],[-13.438,8.168],[-13.4515,8.11],[-13.443,8.034],[-13.3975,7.957],[-13.307,7.902],[-13.211,7.896],[-13.1955,7.831],[-13.2335,7.793],[-13.265,7.734],[-13.2755,7.668],[-13.27,7.592],[-13.245,7.52],[-13.2085,7.47],[-13.152,7.428],[-13.0265,7.37],[-12.9505,7.367],[-12.759,7.313],[-12.724,7.252],[-12.687,7.217],[-12.612,7.183],[-12.5055,7.18],[-12.4365,7.16],[-12.182,7.064],[-11.9995,6.991],[-11.792,6.884],[-11.712,6.807],[-11.608,6.755],[-11.5065,6.9285],[-11.4175,6.9415],[-11.4145,6.9735],[-11.369,7.0225],[-11.376,7.0645],[-11.334,7.077],[-11.352,7.14],[-11.2675,7.2365],[-11.182,7.265],[-11.1705,7.306],[-11.1025,7.3865],[-11.0565,7.4065],[-10.933,7.5135],[-10.9175,7.5035],[-10.843,7.55],[-10.773,7.648],[-10.6965,7.7405],[-10.6045,7.7745],[-10.605,8.0405],[-10.576,8.048],[-10.525,8.1285],[-10.463,8.1565],[-10.354,8.15],[-10.2955,8.2195],[-10.32,8.285],[-10.2885,8.3405],[-10.273,8.44],[-10.28,8.485]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/17/Flag_of_Sierra_Leone.svg","name:en":"Sierra Leone","wikidata":"Q1044","ISO3166-1:alpha2":"SL","ISO3166-1:alpha3":"SLE","ISO3166-1:numeric":"694"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-11.608,6.755],[-11.5865,6.7355],[-11.572,6.668],[-11.519,6.5825],[-11.4665,6.537],[-11.189,6.416],[-11.079,6.363],[-11.0185,6.324],[-11.0155,6.2755],[-10.9715,6.1835],[-10.912,6.1315],[-10.753,6.042],[-10.518,5.976],[-10.436,5.9185],[-10.3755,5.896],[-10.3405,5.849],[-10.25,5.791],[-10.2135,5.728],[-10.132,5.6395],[-10.0795,5.612],[-9.997,5.5445],[-9.914,5.4555],[-9.811,5.3785],[-9.727,5.284],[-9.6655,5.2465],[-9.5775,5.1385],[-9.4695,5.048],[-9.433,5.003],[-9.32,4.94],[-9.109,4.794],[-8.9955,4.763],[-8.903,4.6855],[-8.6915,4.5675],[-8.607,4.5455],[-8.5545,4.503],[-8.4275,4.4525],[-8.3275,4.3875],[-8.262,4.3665],[-8.1655,4.3545],[-8.05,4.33],[-7.985,4.296],[-7.933,4.249],[-7.7825,4.173],[-7.6175,4.1555],[-7.527,4.162],[-7.5295,4.3625],[-7.5655,4.3905],[-7.567,4.4565],[-7.5525,4.4885],[-7.5725,4.5815],[-7.548,4.612],[-7.5625,4.649],[-7.5605,4.783],[-7.5835,4.8335],[-7.592,4.908],[-7.55,4.924],[-7.5355,4.9585],[-7.557,5.0755],[-7.4835,5.1265],[-7.4705,5.1645],[-7.4825,5.2125],[-7.468,5.281],[-7.368,5.33],[-7.424,5.385],[-7.4195,5.4835],[-7.384,5.522],[-7.3975,5.546],[-7.3755,5.613],[-7.431,5.696],[-7.4305,5.8395],[-7.476,5.812],[-7.5865,5.8995],[-7.688,5.898],[-7.7845,5.979],[-7.803,6.0935],[-7.852,6.1025],[-7.836,6.2045],[-7.9035,6.278],[-8.006,6.3225],[-8.0925,6.307],[-8.1665,6.2795],[-8.334,6.373],[-8.385,6.386],[-8.4055,6.447],[-8.4565,6.471],[-8.482,6.434],[-8.5715,6.523],[-8.5695,6.5575],[-8.534,6.6],[-8.419,6.676],[-8.3105,6.855],[-8.3335,6.8915],[-8.326,6.972],[-8.2935,7.0255],[-8.303,7.1355],[-8.288,7.1875],[-8.3315,7.203],[-8.365,7.2405],[-8.36,7.278],[-8.396,7.3285],[-8.3975,7.397],[-8.423,7.528],[-8.471,7.557],[-8.559,7.626],[-8.554,7.696],[-8.6765,7.6955],[-8.7065,7.6445],[-8.723,7.5575],[-8.7095,7.5135],[-8.81,7.4045],[-8.8535,7.347],[-8.8375,7.2765],[-8.872,7.257],[-8.93,7.2885],[-8.9705,7.253],[-9.026,7.2465],[-9.072,7.202],[-9.203,7.3185],[-9.2025,7.386],[-9.286,7.377],[-9.2955,7.4275],[-9.3605,7.4335],[-9.3845,7.394],[-9.468,7.43],[-9.4205,7.484],[-9.3785,7.5885],[-9.359,7.613],[-9.3745,7.6915],[-9.349,7.7465],[-9.3785,7.809],[-9.432,7.8595],[-9.4375,7.988],[-9.4055,8.0495],[-9.441,8.084],[-9.494,8.1755],[-9.512,8.2415],[-9.489,8.2655],[-9.507,8.3295],[-9.497,8.3735],[-9.5525,8.382],[-9.5675,8.4095],[-9.6575,8.405],[-9.62,8.453],[-9.6635,8.5015],[-9.734,8.472],[-9.725,8.5255],[-9.7755,8.55],[-9.806,8.5015],[-9.9235,8.496],[-9.9895,8.4455],[-10.038,8.4285],[-10.043,8.489],[-10.12,8.5345],[-10.2265,8.4805],[-10.28,8.485],[-10.273,8.44],[-10.2885,8.3405],[-10.32,8.285],[-10.2955,8.2195],[-10.354,8.15],[-10.463,8.1565],[-10.525,8.1285],[-10.576,8.048],[-10.605,8.0405],[-10.6045,7.7745],[-10.6965,7.7405],[-10.773,7.648],[-10.843,7.55],[-10.9175,7.5035],[-10.933,7.5135],[-11.0565,7.4065],[-11.1025,7.3865],[-11.1705,7.306],[-11.182,7.265],[-11.2675,7.2365],[-11.352,7.14],[-11.334,7.077],[-11.376,7.0645],[-11.369,7.0225],[-11.4145,6.9735],[-11.4175,6.9415],[-11.5065,6.9285],[-11.608,6.755]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/b8/Flag_of_Liberia.svg","name:en":"Liberia","wikidata":"Q1014","ISO3166-1:alpha2":"LR","ISO3166-1:alpha3":"LBR","ISO3166-1:numeric":"430"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-16.976,13.061],[-16.951,12.981],[-16.9955,12.779],[-16.994,12.671],[-16.973,12.577],[-16.994,12.513],[-16.991,12.423],[-16.951,12.309],[-16.8945,12.2375],[-16.6895,12.359],[-16.609,12.3475],[-16.545,12.3605],[-16.5145,12.3505],[-16.3755,12.376],[-16.203,12.4615],[-16.1625,12.4495],[-16.039,12.4725],[-15.9535,12.443],[-15.89,12.4505],[-15.683,12.425],[-15.429,12.537],[-15.3375,12.6135],[-15.184,12.682],[-15.1225,12.686],[-14.913,12.6785],[-14.3235,12.6765],[-13.708,12.6755],[-13.4835,12.674],[-13.345,12.6585],[-13.332,12.645],[-13.2185,12.6515],[-13.1385,12.645],[-13.0515,12.6255],[-13.0465,12.5755],[-13.0615,12.485],[-12.9445,12.4755],[-12.942,12.5375],[-12.895,12.554],[-12.845,12.495],[-12.752,12.467],[-12.765,12.4335],[-12.6265,12.436],[-12.565,12.3665],[-12.486,12.4045],[-12.403,12.385],[-12.3565,12.315],[-12.302,12.3505],[-12.1775,12.3605],[-12.118,12.4135],[-12.0595,12.433],[-12.0105,12.4015],[-11.968,12.4055],[-11.9,12.449],[-11.8445,12.3925],[-11.805,12.4035],[-11.77,12.382],[-11.686,12.405],[-11.668,12.426],[-11.476,12.4525],[-11.377,12.4125],[-11.352,12.4675],[-11.3585,12.508],[-11.4105,12.537],[-11.4035,12.5875],[-11.4235,12.664],[-11.4235,12.729],[-11.383,12.743],[-11.3805,12.8035],[-11.4105,12.8485],[-11.3975,12.93],[-11.346,12.9435],[-11.355,12.976],[-11.396,13.0055],[-11.4355,13.0625],[-11.5185,13.157],[-11.5415,13.2325],[-11.525,13.2595],[-11.591,13.314],[-11.596,13.365],[-11.6275,13.3945],[-11.742,13.39],[-11.7665,13.342],[-11.8285,13.309],[-11.8875,13.394],[-11.868,13.4585],[-11.9535,13.522],[-12.0315,13.6165],[-12.04,13.6665],[-12.072,13.721],[-12.026,13.743],[-11.949,13.8115],[-11.933,13.9245],[-12.009,13.986],[-12.0145,14.0285],[-11.9825,14.09],[-11.989,14.195],[-12.024,14.2835],[-12.092,14.3045],[-12.1025,14.375],[-12.2005,14.4065],[-12.19,14.443],[-12.22,14.49],[-12.2165,14.55],[-12.189,14.5545],[-12.146,14.6525],[-12.2145,14.7055],[-12.2405,14.7645],[-12.277,14.771],[-12.3275,14.8265],[-12.362,14.826],[-12.4545,14.895],[-12.4625,14.984],[-12.4925,15.0145],[-12.5725,15.0425],[-12.612,15.0855],[-12.6655,15.1095],[-12.687,15.09],[-12.7945,15.1595],[-12.809,15.2165],[-12.8495,15.199],[-12.852,15.317],[-12.9235,15.337],[-12.9445,15.358],[-12.9665,15.501],[-13.061,15.479],[-13.105,15.5015],[-13.088,15.582],[-13.1865,15.6265],[-13.215,15.609],[-13.25,15.651],[-13.2075,15.6935],[-13.2935,15.7695],[-13.289,15.7885],[-13.3135,15.9165],[-13.3475,15.9415],[-13.378,16.014],[-13.3745,16.0525],[-13.4435,16.0835],[-13.497,16.078],[-13.524,16.1245],[-13.581,16.132],[-13.6755,16.0955],[-13.72,16.1445],[-13.798,16.143],[-13.843,16.107],[-13.877,16.152],[-13.8675,16.1825],[-13.917,16.2025],[-14.0405,16.3715],[-14.219,16.543],[-14.3335,16.5695],[-14.3275,16.6325],[-14.4095,16.634],[-14.5,16.614],[-14.5495,16.639],[-14.641,16.6175],[-14.652,16.6495],[-14.7535,16.6285],[-14.809,16.6505],[-14.895,16.632],[-14.9455,16.635],[-14.952,16.676],[-14.99,16.6905],[-15.0055,16.6405],[-15.0545,16.6285],[-15.076,16.6705],[-15.1155,16.634],[-15.085,16.6045],[-15.12,16.578],[-15.164,16.5895],[-15.2265,16.553],[-15.301,16.5745],[-15.4065,16.535],[-15.4725,16.5895],[-15.5085,16.567],[-15.5145,16.521],[-15.5445,16.5095],[-15.62,16.525],[-15.626,16.4935],[-15.7045,16.4705],[-15.8115,16.507],[-15.863,16.4945],[-15.9155,16.511],[-15.9645,16.483],[-16.0085,16.4995],[-16.057,16.479],[-16.1035,16.5255],[-16.15,16.5485],[-16.18,16.519],[-16.2605,16.5245],[-16.3045,16.462],[-16.3305,16.3575],[-16.368,16.307],[-16.354,16.27],[-16.399,16.2125],[-16.4545,16.182],[-16.4515,16.0875],[-16.5085,16.0665],[-16.741,16.0805],[-16.79,15.827],[-17.123,15.3795],[-17.3575,15.095],[-17.6975,14.9585],[-17.776,14.8105],[-17.786,14.686],[-17.716,14.5525],[-17.576,14.4685],[-17.3835,14.559],[-17.2535,14.3465],[-17.144,14.195],[-17.0255,14.0495],[-17.0305,13.8035],[-16.959,13.645],[-16.858,13.603],[-16.817,13.587],[-16.147,13.5925],[-15.6055,13.5915],[-15.4775,13.584],[-15.452,13.674],[-15.412,13.743],[-15.3645,13.7815],[-15.3075,13.791],[-15.265,13.741],[-15.2055,13.7545],[-15.1265,13.8065],[-15.067,13.825],[-14.986,13.794],[-14.938,13.8055],[-14.883,13.793],[-14.8185,13.745],[-14.792,13.6535],[-14.7185,13.612],[-14.664,13.6455],[-14.6115,13.6575],[-14.5355,13.6505],[-14.4855,13.599],[-14.472,13.535],[-14.338,13.454],[-14.241,13.4785],[-14.218,13.504],[-14.0705,13.563],[-14.0305,13.556],[-13.9735,13.583],[-13.886,13.5455],[-13.7995,13.4335],[-13.801,13.389],[-13.867,13.323],[-13.9485,13.3235],[-13.987,13.3045],[-14.114,13.2865],[-14.129,13.2605],[-14.1935,13.2295],[-14.2665,13.247],[-14.359,13.2295],[-14.4385,13.271],[-14.4595,13.3],[-14.517,13.3055],[-14.578,13.3585],[-14.6725,13.3445],[-14.7275,13.3715],[-14.7605,13.4175],[-14.814,13.418],[-14.85,13.4445],[-14.8995,13.4475],[-14.999,13.4915],[-15.051,13.535],[-15.09,13.6005],[-15.1415,13.583],[-15.1975,13.5295],[-15.229,13.419],[-15.2995,13.3665],[-15.3795,13.356],[-15.4945,13.395],[-15.5575,13.3595],[-15.6295,13.354],[-15.683,13.371],[-15.7335,13.35],[-15.805,13.3405],[-15.8035,13.167],[-16.2335,13.165],[-16.679,13.1685],[-16.735,13.1125],[-16.7485,13.061],[-16.976,13.061]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/fd/Flag_of_Senegal.svg","name:en":"Senegal","wikidata":"Q1041","ISO3166-1:alpha2":"SN","ISO3166-1:alpha3":"SEN","ISO3166-1:numeric":"686"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-12.2405,14.7645],[-12.119,14.7545],[-12.0555,14.721],[-12.025,14.7635],[-11.9375,14.7805],[-11.9355,14.8125],[-11.8395,14.858],[-11.789,15.03],[-11.8445,15.096],[-11.812,15.1315],[-11.836,15.1845],[-11.7995,15.2325],[-11.806,15.278],[-11.767,15.336],[-11.7435,15.461],[-11.7045,15.492],[-11.71,15.533],[-11.64,15.521],[-11.581,15.55],[-11.5605,15.5835],[-11.517,15.5935],[-11.4925,15.6415],[-11.411,15.637],[-11.3395,15.526],[-11.2515,15.4195],[-11.2045,15.399],[-10.993,15.232],[-10.954,15.16],[-10.882,15.12],[-10.867,15.1985],[-10.833,15.2155],[-10.829,15.2705],[-10.8,15.307],[-10.732,15.3435],[-10.7155,15.375],[-10.7285,15.4275],[-10.705,15.4435],[-10.639,15.42],[-10.519,15.451],[-10.3325,15.4345],[-10.3205,15.443],[-10.1675,15.402],[-10.1375,15.3765],[-10.065,15.3615],[-9.9225,15.4],[-9.799,15.389],[-9.781,15.414],[-9.722,15.4075],[-9.685,15.427],[-9.401,15.439],[-9.447,15.6055],[-9.331,15.703],[-9.3095,15.6935],[-9.3315,15.5655],[-9.3315,15.5015],[-9.0,15.5005],[-8.509,15.5005],[-8.0,15.5],[-7.429,15.5],[-6.731,15.5],[-6.189,15.5],[-5.5,15.5],[-5.3885,16.057],[-5.3335,16.3335],[-5.609,16.5],[-5.6615,17.0005],[-5.705,17.3975],[-5.7715,18.0],[-5.8265,18.4875],[-5.9075,19.187],[-5.943,19.511],[-6.0005,20.041],[-6.0595,20.569],[-6.1045,20.969],[-6.178,21.618],[-6.2175,21.9615],[-6.2805,22.5],[-6.3345,22.9635],[-6.3585,23.201],[-6.4055,23.568],[-6.4565,23.972],[-6.4845,24.222],[-6.5485,24.354],[-6.4995,24.356],[-6.572,25.0],[-6.0,25.0005],[-5.553,25.001],[-4.8335,25.0],[-5.3905,25.344],[-6.0345,25.736],[-6.434,25.9805],[-6.833,26.2235],[-7.266,26.483],[-7.5785,26.67],[-8.2315,27.057],[-8.668,27.315],[-8.667,26.766],[-8.667,26.3335],[-8.667,26.0005],[-9.067,25.9995],[-9.4335,26.0],[-9.9335,25.9995],[-10.367,25.9995],[-10.881,26.0],[-11.2935,25.999],[-11.6725,25.999],[-12.0005,26.0],[-12.0,25.7515],[-12.0005,25.349],[-12.0005,25.3485],[-12.001,24.766],[-12.0,24.366],[-12.001,23.8335],[-12.0005,23.4545],[-12.156,23.4165],[-12.366,23.3185],[-12.5715,23.2915],[-12.9985,23.0245],[-13.1055,22.893],[-13.1505,22.7575],[-13.084,22.5365],[-13.0755,22.4575],[-13.0515,22.086],[-12.9995,21.3365],[-13.5415,21.341],[-14.2855,21.342],[-14.687,21.3385],[-15.0405,21.337],[-15.6105,21.338],[-15.992,21.339],[-16.568,21.339],[-16.9485,21.334],[-16.9935,21.138],[-17.032,21.058],[-17.068,20.8855],[-17.01,20.5625],[-16.932,20.5695],[-16.8445,20.542],[-16.733,20.445],[-16.604,20.3485],[-16.529,20.2775],[-16.487,20.195],[-16.508,20.087],[-16.5705,19.9715],[-16.631,19.906],[-16.668,19.8145],[-16.659,19.6295],[-16.663,19.5605],[-16.6845,19.5095],[-16.7715,19.467],[-16.7935,19.408],[-16.7785,19.3525],[-16.706,19.188],[-16.6125,19.064],[-16.4515,18.868],[-16.335,18.624],[-16.2665,18.4315],[-16.2455,18.2345],[-16.2335,18.0065],[-16.243,17.788],[-16.267,17.612],[-16.298,17.4805],[-16.362,17.34],[-16.637,16.706],[-16.6505,16.6775],[-16.6735,16.509],[-16.7085,16.397],[-16.7285,16.29],[-16.7295,16.1665],[-16.741,16.0805],[-16.5085,16.0665],[-16.4515,16.0875],[-16.4545,16.182],[-16.399,16.2125],[-16.354,16.27],[-16.368,16.307],[-16.3305,16.3575],[-16.3045,16.462],[-16.2605,16.5245],[-16.18,16.519],[-16.15,16.5485],[-16.1035,16.5255],[-16.057,16.479],[-16.0085,16.4995],[-15.9645,16.483],[-15.9155,16.511],[-15.863,16.4945],[-15.8115,16.507],[-15.7045,16.4705],[-15.626,16.4935],[-15.62,16.525],[-15.5445,16.5095],[-15.5145,16.521],[-15.5085,16.567],[-15.4725,16.5895],[-15.4065,16.535],[-15.301,16.5745],[-15.2265,16.553],[-15.164,16.5895],[-15.12,16.578],[-15.085,16.6045],[-15.1155,16.634],[-15.076,16.6705],[-15.0545,16.6285],[-15.0055,16.6405],[-14.99,16.6905],[-14.952,16.676],[-14.9455,16.635],[-14.895,16.632],[-14.809,16.6505],[-14.7535,16.6285],[-14.652,16.6495],[-14.641,16.6175],[-14.5495,16.639],[-14.5,16.614],[-14.4095,16.634],[-14.3275,16.6325],[-14.3335,16.5695],[-14.219,16.543],[-14.0405,16.3715],[-13.917,16.2025],[-13.8675,16.1825],[-13.877,16.152],[-13.843,16.107],[-13.798,16.143],[-13.72,16.1445],[-13.6755,16.0955],[-13.581,16.132],[-13.524,16.1245],[-13.497,16.078],[-13.4435,16.0835],[-13.3745,16.0525],[-13.378,16.014],[-13.3475,15.9415],[-13.3135,15.9165],[-13.289,15.7885],[-13.2935,15.7695],[-13.2075,15.6935],[-13.25,15.651],[-13.215,15.609],[-13.1865,15.6265],[-13.088,15.582],[-13.105,15.5015],[-13.061,15.479],[-12.9665,15.501],[-12.9445,15.358],[-12.9235,15.337],[-12.852,15.317],[-12.8495,15.199],[-12.809,15.2165],[-12.7945,15.1595],[-12.687,15.09],[-12.6655,15.1095],[-12.612,15.0855],[-12.5725,15.0425],[-12.4925,15.0145],[-12.4625,14.984],[-12.4545,14.895],[-12.362,14.826],[-12.3275,14.8265],[-12.277,14.771],[-12.2405,14.7645]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/43/Flag_of_Mauritania.svg","name:en":"Mauritania","wikidata":"Q1025","ISO3166-1:alpha2":"MR","ISO3166-1:alpha3":"MRT","ISO3166-1:numeric":"478"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-69.7365,12.263],[-69.687,12.32],[-69.6615,12.408],[-69.691,12.542],[-69.7225,12.6],[-69.814,12.692],[-69.962,12.802],[-70.0585,12.823],[-70.12,12.813],[-70.1815,12.781],[-70.251,12.69],[-70.2635,12.64],[-70.268,12.518],[-70.2455,12.447],[-70.164,12.35],[-70.1405,12.365],[-69.7365,12.263]]],[[[-69.3675,12.381],[-69.3605,12.281],[-69.345,12.217],[-69.3155,12.165],[-69.2395,12.072],[-69.186,12.025],[-69.055,11.935],[-68.9055,11.861],[-68.7855,11.834],[-68.6835,11.781],[-68.602,11.781],[-68.5215,11.816],[-68.468,11.871],[-68.4405,11.932],[-68.364,11.859],[-68.3225,11.838],[-68.2265,11.826],[-68.156,11.844],[-68.0935,11.885],[-68.0445,11.952],[-67.9945,12.092],[-67.991,12.206],[-68.0165,12.315],[-68.0595,12.369],[-68.1035,12.399],[-68.2,12.426],[-68.287,12.49],[-68.3665,12.511],[-68.4455,12.504],[-68.5035,12.478],[-68.554,12.437],[-68.604,12.363],[-68.6255,12.249],[-68.698,12.313],[-68.787,12.364],[-68.857,12.376],[-68.8895,12.444],[-68.944,12.508],[-69.0695,12.576],[-69.175,12.591],[-69.25,12.569],[-69.3235,12.506],[-69.3595,12.435],[-69.3675,12.381]]],[[[-62.7865,17.616],[-62.847,17.674],[-63.0195,17.736],[-63.0655,17.783],[-63.0545,17.806],[-62.9695,17.9865],[-62.9495,18.017],[-63.063,18.064],[-63.139,18.053],[-63.268,17.8965],[-63.278,17.847],[-63.367,17.813],[-63.415,17.772],[-63.457,17.7],[-63.4675,17.654],[-63.4625,17.572],[-63.446,17.529],[-63.396,17.468],[-63.324,17.428],[-63.262,17.415],[-63.1935,17.418],[-63.1515,17.352],[-63.051,17.279],[-62.7865,17.616]]],[[[3.08,51.551],[3.295,51.449],[3.3855,51.334],[3.3585,51.315],[3.3945,51.2655],[3.4485,51.2415],[3.5275,51.246],[3.5155,51.287],[3.591,51.3045],[3.7955,51.256],[3.7915,51.214],[3.8865,51.2],[4.0115,51.244],[4.064,51.2475],[4.1665,51.293],[4.242,51.354],[4.3915,51.408],[4.4425,51.4685],[4.538,51.4825],[4.5355,51.423],[4.6665,51.4445],[4.774,51.505],[4.8405,51.4785],[4.83,51.421],[4.9285,51.396],[5.079,51.4715],[5.1045,51.4315],[5.071,51.3935],[5.1315,51.347],[5.242,51.305],[5.226,51.2685],[5.4175,51.2625],[5.4875,51.2995],[5.558,51.2625],[5.5605,51.2225],[5.658,51.1845],[5.767,51.1835],[5.847,51.1415],[5.8225,51.0925],[5.758,51.0335],[5.756,50.9575],[5.7145,50.9085],[5.6515,50.875],[5.654,50.82],[5.694,50.8115],[5.695,50.755],[5.7765,50.782],[5.8075,50.756],[5.8865,50.77],[6.021,50.7545],[6.019,50.8465],[6.074,50.8465],[6.0925,50.9175],[6.018,50.9345],[6.0175,50.9835],[5.955,50.9885],[5.938,51.035],[6.0915,51.1345],[6.0725,51.2425],[6.1695,51.3295],[6.2265,51.3605],[6.2055,51.3995],[6.2235,51.475],[6.212,51.5135],[6.0915,51.606],[6.1095,51.647],[6.0365,51.673],[6.029,51.726],[5.945,51.8235],[6.0555,51.8525],[6.1665,51.8405],[6.2795,51.874],[6.407,51.829],[6.4645,51.855],[6.675,51.916],[6.722,51.896],[6.8285,51.964],[6.8265,51.9935],[6.688,52.04],[6.751,52.085],[6.7605,52.119],[6.8555,52.1205],[6.9815,52.2215],[7.0615,52.2345],[7.0265,52.292],[7.072,52.352],[6.994,52.4655],[6.9415,52.4355],[6.8545,52.4595],[6.7745,52.4595],[6.6975,52.4865],[6.7265,52.563],[6.715,52.626],[6.742,52.6455],[6.897,52.6515],[6.94,52.638],[7.055,52.6445],[7.0715,52.8105],[7.1815,52.9415],[7.213,53.011],[7.203,53.1135],[7.179,53.1385],[7.2175,53.198],[7.1915,53.315],[7.0525,53.3065],[6.9025,53.3535],[6.8825,53.4475],[6.699,53.4935],[6.5515,53.5825],[6.4125,53.6045],[6.346,53.7245],[6.3325,53.744],[6.205,53.707],[6.099,53.7245],[5.9935,53.7215],[5.824,53.6665],[5.6335,53.685],[5.4685,53.6705],[5.353,53.63],[5.0785,53.5855],[4.965,53.553],[4.826,53.491],[4.7585,53.433],[4.623,53.382],[4.5405,53.3225],[4.4945,53.231],[4.419,53.15],[4.3375,53.028],[4.332,52.935],[4.364,52.8755],[4.3085,52.7605],[4.2805,52.5915],[4.2145,52.512],[4.209,52.4345],[4.0955,52.2925],[3.934,52.1835],[3.772,52.1365],[3.7035,52.09],[3.638,51.9805],[3.521,51.917],[3.422,51.8835],[3.3065,51.823],[3.2235,51.7325],[3.2135,51.689],[3.1215,51.625],[3.08,51.551]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/20/Flag_of_the_Netherlands.svg","name:en":"Netherlands","wikidata":"Q29999","ISO3166-1:alpha2":"NL","ISO3166-1:alpha3":"NLD","ISO3166-1:numeric":"528"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-6.0565,35.9595],[-6.117,35.9135],[-6.179,35.808],[-6.2335,35.6415],[-6.4485,35.151],[-6.512,34.9745],[-6.581,34.8425],[-6.7875,34.5045],[-6.873,34.388],[-7.002,34.176],[-7.1005,34.09],[-7.167,34.044],[-7.3505,33.9725],[-7.4965,33.8995],[-7.756,33.786],[-8.3975,33.548],[-8.629,33.447],[-8.7105,33.389],[-8.822,33.2625],[-8.8835,33.176],[-8.9305,33.129],[-9.239,32.8665],[-9.379,32.7555],[-9.4915,32.6395],[-9.523,32.5555],[-9.5245,32.364],[-9.5515,32.1515],[-9.6345,32.077],[-9.843,31.8665],[-10.001,31.5855],[-10.058,31.4555],[-10.0725,31.384],[-10.0715,31.1075],[-10.0895,30.8845],[-10.1095,30.771],[-10.12,30.6515],[-10.1095,30.5905],[-10.058,30.481],[-9.9465,30.448],[-9.8605,30.381],[-9.816,30.312],[-9.818,30.2845],[-9.9785,30.007],[-10.0245,29.9475],[-10.187,29.786],[-10.36,29.52],[-10.5055,29.3705],[-10.6105,29.25],[-10.672,29.196],[-10.7675,29.1335],[-11.0395,29.0045],[-11.196,28.9205],[-11.2835,28.864],[-11.416,28.724],[-11.491,28.6655],[-11.619,28.491],[-11.6715,28.466],[-11.885,28.406],[-12.1035,28.322],[-12.2055,28.29],[-12.49,28.211],[-12.6155,28.194],[-12.801,28.189],[-13.008,28.146],[-13.0665,28.1005],[-13.216,27.907],[-13.306,27.8625],[-13.358,27.803],[-13.4335,27.627],[-13.5805,27.4035],[-13.6685,27.2395],[-13.715,27.1185],[-13.751,26.9585],[-13.8175,26.8545],[-13.882,26.8035],[-14.0305,26.7075],[-14.1465,26.6815],[-14.332,26.6095],[-14.467,26.4705],[-14.5685,26.412],[-14.6285,26.3575],[-14.6765,26.266],[-14.742,26.0725],[-14.834,25.882],[-14.91,25.6915],[-14.976,25.55],[-15.0555,25.3425],[-15.0745,25.267],[-15.085,25.153],[-15.0735,25.061],[-15.0485,24.9945],[-15.075,24.8465],[-15.0985,24.778],[-15.2215,24.704],[-15.3225,24.6585],[-15.424,24.5595],[-15.51,24.4495],[-15.678,24.3115],[-15.7945,24.1985],[-15.9205,24.1045],[-16.056,23.982],[-16.176,23.8365],[-16.2215,23.7725],[-16.2365,23.716],[-16.2505,23.541],[-16.2775,23.4205],[-16.307,23.357],[-16.397,23.2105],[-16.468,23.0745],[-16.5275,22.935],[-16.616,22.6905],[-16.6915,22.577],[-16.7505,22.5395],[-16.8275,22.467],[-16.9355,22.385],[-16.973,22.346],[-17.046,22.222],[-17.104,22.081],[-17.141,22.014],[-17.1965,21.875],[-17.2105,21.8075],[-17.221,21.5445],[-17.255,21.3525],[-17.029,21.3415],[-16.9915,21.364],[-16.8715,21.363],[-16.8325,21.3785],[-16.6595,21.392],[-16.4585,21.3895],[-16.2755,21.347],[-16.1385,21.3515],[-15.992,21.339],[-15.6105,21.338],[-15.0405,21.337],[-14.964,21.36],[-14.815,21.3725],[-14.776,21.4065],[-14.713,21.4335],[-14.605,21.5505],[-14.542,21.591],[-14.495,21.6765],[-14.482,21.747],[-14.5045,22.0085],[-14.4925,22.0415],[-14.446,22.0615],[-14.394,22.132],[-14.2785,22.243],[-14.16,22.418],[-14.1155,22.5765],[-14.116,22.7855],[-14.0745,22.9175],[-14.0395,22.9955],[-14.002,23.016],[-14.023,23.1005],[-14.008,23.173],[-13.953,23.29],[-13.9315,23.378],[-13.825,23.6375],[-13.825,23.6635],[-13.773,23.7585],[-13.7165,23.7815],[-13.689,23.8335],[-13.5775,23.8625],[-13.5305,23.886],[-13.471,23.875],[-13.395,23.9275],[-13.274,23.967],[-13.224,23.964],[-13.115,24.0095],[-13.0615,23.9835],[-13.021,24.03],[-13.0095,24.1765],[-12.971,24.257],[-12.9635,24.3415],[-12.9155,24.4295],[-12.8615,24.457],[-12.7965,24.548],[-12.703,24.5915],[-12.6605,24.67],[-12.602,24.697],[-12.5455,24.769],[-12.5435,24.802],[-12.454,24.858],[-12.388,24.847],[-12.3565,24.884],[-12.325,24.963],[-12.2725,24.9815],[-12.253,25.0405],[-12.119,25.1875],[-12.0495,25.2865],[-12.0315,25.353],[-12.0005,25.3485],[-12.0005,25.349],[-12.0,25.7515],[-12.0005,26.0],[-11.6725,25.999],[-11.636,26.063],[-11.627,26.117],[-11.5645,26.215],[-11.546,26.3495],[-11.4825,26.415],[-11.487,26.4525],[-11.464,26.515],[-11.4345,26.538],[-11.378,26.636],[-11.273,26.7075],[-11.272,26.735],[-11.3395,26.8005],[-11.343,26.841],[-11.2535,26.878],[-11.1485,26.9],[-10.9195,26.9195],[-10.8465,26.8985],[-10.7445,26.908],[-10.683,26.8945],[-10.583,26.9035],[-10.5145,26.8895],[-10.4145,26.8395],[-10.359,26.843],[-10.2575,26.8165],[-10.236,26.783],[-10.132,26.776],[-10.086,26.785],[-9.988,26.745],[-9.9135,26.7325],[-9.846,26.7475],[-9.792,26.7405],[-9.692,26.8015],[-9.6325,26.8785],[-9.4695,26.961],[-9.4045,26.955],[-9.3505,26.977],[-9.2875,26.9815],[-9.141,26.966],[-9.094,26.9705],[-9.047,27.014],[-8.805,26.9975],[-8.7665,26.987],[-8.7325,27.0535],[-8.737,27.1395],[-8.774,27.194],[-8.78,27.258],[-8.762,27.4225],[-8.779,27.547],[-8.8115,27.6665],[-8.668,27.6665],[-8.669,28.241],[-8.6685,28.667],[-8.5735,28.7475],[-8.458,28.792],[-8.3515,28.8855],[-8.202,28.9845],[-8.04,29.08],[-7.958,29.1215],[-7.8735,29.1935],[-7.822,29.211],[-7.773,29.255],[-7.6345,29.301],[-7.6135,29.3655],[-7.4885,29.36],[-7.345,29.392],[-7.257,29.474],[-7.15,29.5225],[-7.0225,29.4935],[-6.9085,29.4955],[-6.834,29.468],[-6.777,29.462],[-6.721,29.5055],[-6.6185,29.53],[-6.5275,29.5215],[-6.468,29.56],[-6.2895,29.5705],[-6.2475,29.5655],[-6.1655,29.5825],[-6.07,29.562],[-5.9365,29.5935],[-5.8765,29.5905],[-5.8135,29.6075],[-5.7275,29.591],[-5.7505,29.53],[-5.686,29.541],[-5.651,29.5045],[-5.5655,29.4765],[-5.445,29.6335],[-5.3175,29.789],[-5.3235,29.815],[-5.289,29.881],[-5.2395,29.933],[-5.124,30.003],[-4.9365,30.1405],[-4.6075,30.2825],[-4.488,30.372],[-4.427,30.4395],[-4.3295,30.5215],[-4.1485,30.585],[-4.001,30.593],[-3.8865,30.6105],[-3.817,30.5905],[-3.768,30.626],[-3.6445,30.6905],[-3.6295,30.7445],[-3.6515,30.8425],[-3.5565,30.932],[-3.5365,31.0135],[-3.606,31.0765],[-3.674,31.097],[-3.681,31.165],[-3.778,31.124],[-3.7595,31.176],[-3.7905,31.236],[-3.759,31.2635],[-3.7645,31.334],[-3.661,31.378],[-3.6645,31.6335],[-3.252,31.7135],[-2.8205,31.7935],[-2.844,31.832],[-2.8415,31.8805],[-2.931,32.035],[-2.8735,32.1115],[-2.6,32.113],[-2.5425,32.145],[-2.2775,32.1685],[-2.18,32.142],[-2.1325,32.1465],[-2.015,32.182],[-1.9685,32.1575],[-1.9035,32.1645],[-1.749,32.121],[-1.5765,32.092],[-1.509,32.104],[-1.41,32.0875],[-1.2215,32.08],[-1.154,32.11],[-1.183,32.1635],[-1.241,32.2055],[-1.235,32.2895],[-1.2485,32.3205],[-1.188,32.407],[-1.1285,32.41],[-1.063,32.453],[-1.0005,32.5195],[-1.2715,32.6955],[-1.399,32.7625],[-1.544,32.958],[-1.486,32.9755],[-1.462,33.042],[-1.576,33.149],[-1.6065,33.213],[-1.6705,33.284],[-1.6635,33.378],[-1.6215,33.448],[-1.62,33.49],[-1.588,33.529],[-1.5995,33.6155],[-1.6465,33.676],[-1.7325,33.701],[-1.721,33.7405],[-1.6765,33.759],[-1.672,33.806],[-1.6985,33.8695],[-1.646,34.1025],[-1.692,34.194],[-1.712,34.2615],[-1.7055,34.307],[-1.782,34.3915],[-1.687,34.4905],[-1.7415,34.508],[-1.839,34.628],[-1.771,34.7235],[-1.7395,34.7435],[-1.8885,34.8065],[-1.8935,34.8415],[-1.9745,34.8875],[-1.973,34.9355],[-2.035,34.9245],[-2.1305,34.997],[-2.1705,35.0095],[-2.211,35.0585],[-2.2065,35.337],[-2.508,35.426],[-2.605,35.44],[-2.696,35.4895],[-2.752,35.5545],[-2.816,35.5945],[-2.9135,35.6285],[-2.9775,35.6375],[-3.0735,35.6245],[-3.1775,35.563],[-3.302,35.439],[-3.63,35.484],[-3.9715,35.45],[-4.298,35.391],[-4.5825,35.4145],[-4.843,35.5525],[-5.019,35.75],[-5.019,35.886],[-5.037,35.9615],[-5.112,36.047],[-5.213,36.0475],[-5.3,36.033],[-5.6215,35.9405],[-5.6665,35.9355],[-5.8855,35.965],[-6.0565,35.9595]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/2c/Flag_of_Morocco.svg","name:en":"Morocco","wikidata":"Q1028","ISO3166-1:alpha2":"MA","ISO3166-1:alpha3":"MAR","ISO3166-1:numeric":"504"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-31.5575,39.4455],[-31.5445,39.3625],[-31.469,39.234],[-31.353,39.1635],[-31.2705,39.1475],[-31.075,39.17],[-30.977,39.2145],[-30.931,39.2535],[-30.868,39.365],[-30.8575,39.421],[-30.8545,39.7225],[-30.8785,39.8095],[-30.9525,39.882],[-31.027,39.9145],[-31.0945,39.926],[-31.1965,39.9175],[-31.2995,39.8705],[-31.3505,39.8175],[-31.5045,39.5875],[-31.543,39.509],[-31.5575,39.4455]]],[[[-29.0955,38.593],[-29.08,38.528],[-29.0325,38.4645],[-28.9495,38.3895],[-28.8785,38.344],[-28.572,38.2105],[-28.4565,38.185],[-28.2045,38.1805],[-28.045,38.1975],[-27.929,38.2235],[-27.6295,38.366],[-27.549,38.4275],[-27.508,38.5165],[-27.388,38.4645],[-27.189,38.418],[-27.0945,38.409],[-26.982,38.436],[-26.8845,38.4935],[-26.84,38.533],[-26.769,38.642],[-26.76,38.6945],[-26.7825,38.792],[-26.8125,38.8395],[-26.898,38.911],[-26.9615,38.9465],[-27.1375,38.9925],[-27.2455,39.0055],[-27.3975,38.993],[-27.4995,38.9605],[-27.612,38.8705],[-27.6375,38.8215],[-27.6415,38.718],[-27.878,38.8105],[-27.805,38.8335],[-27.7105,38.9085],[-27.6785,38.9835],[-27.699,39.1065],[-27.7475,39.1845],[-27.8385,39.2525],[-27.9215,39.288],[-28.0195,39.307],[-28.0875,39.303],[-28.2015,39.265],[-28.2725,39.208],[-28.331,39.1075],[-28.33,39.0285],[-28.2955,38.959],[-28.4085,38.9485],[-28.806,38.8355],[-28.9985,38.756],[-29.055,38.707],[-29.0955,38.593]]],[[[-26.097,37.829],[-26.0595,37.721],[-25.745,37.314],[-25.3735,36.821],[-25.3295,36.7845],[-25.228,36.7435],[-25.064,36.7255],[-24.9555,36.732],[-24.851,36.7755],[-24.806,36.8185],[-24.5625,37.1695],[-24.5315,37.2415],[-24.5515,37.3565],[-24.8405,37.8045],[-24.9115,37.9215],[-24.985,37.994],[-25.0425,38.0315],[-25.1485,38.0595],[-25.767,38.1085],[-25.8385,38.106],[-25.9455,38.069],[-26.0225,37.9955],[-26.0875,37.8815],[-26.097,37.829]]],[[[-17.5045,32.8065],[-17.4895,32.742],[-17.4235,32.638],[-17.329,32.561],[-17.208,32.4915],[-16.5745,32.2215],[-16.508,32.2025],[-16.43,32.202],[-16.317,32.244],[-16.2735,32.282],[-16.238,32.341],[-16.227,32.393],[-16.24,32.469],[-16.3295,32.6825],[-16.415,32.7935],[-16.2995,32.8035],[-16.1475,32.8795],[-16.066,32.9525],[-16.0395,33.015],[-16.0405,33.135],[-16.0745,33.229],[-16.1255,33.2795],[-16.1785,33.308],[-16.2545,33.326],[-16.3175,33.325],[-16.443,33.293],[-16.505,33.267],[-16.5805,33.195],[-16.643,33.0735],[-16.6405,32.9865],[-16.626,32.949],[-16.7975,33.0175],[-16.8565,33.0335],[-17.1365,33.076],[-17.248,33.071],[-17.3385,33.0285],[-17.424,32.965],[-17.476,32.909],[-17.5045,32.8065]]],[[[-16.2815,30.0175],[-16.2645,29.953],[-16.223,29.8955],[-16.161,29.853],[-16.0865,29.831],[-15.972,29.8345],[-15.896,29.862],[-15.814,29.941],[-15.7555,29.9575],[-15.693,29.9955],[-15.6345,30.078],[-15.624,30.1575],[-15.638,30.215],[-15.6875,30.2875],[-15.7895,30.347],[-15.874,30.3615],[-15.945,30.3525],[-16.009,30.327],[-16.089,30.2515],[-16.1805,30.2175],[-16.252,30.1465],[-16.276,30.0875],[-16.2815,30.0175]]],[[[-9.1565,41.8725],[-9.1565,41.7215],[-9.1285,41.6335],[-9.0815,41.5405],[-9.071,41.415],[-9.04,40.673],[-9.17,40.2755],[-9.571,39.83],[-9.7595,39.619],[-9.827,39.526],[-9.835,39.4735],[-9.814,39.3915],[-9.7785,38.7785],[-9.755,38.675],[-9.713,38.598],[-9.4565,38.312],[-9.1665,37.9],[-9.228,37.379],[-9.265,37.0635],[-9.2555,36.9865],[-9.2075,36.8575],[-9.142,36.7705],[-9.0745,36.7325],[-8.949,36.713],[-8.352,36.741],[-7.8845,36.7635],[-7.757,36.799],[-7.459,36.9645],[-7.3865,36.9745],[-7.397,37.1575],[-7.422,37.275],[-7.441,37.3075],[-7.4405,37.391],[-7.4905,37.5185],[-7.5225,37.553],[-7.445,37.664],[-7.419,37.7435],[-7.3215,37.8185],[-7.255,37.9235],[-7.2455,37.992],[-7.1285,38.0015],[-7.1085,38.041],[-7.0445,38.014],[-7.007,38.021],[-6.969,38.1605],[-7.0285,38.1825],[-7.097,38.179],[-7.143,38.2615],[-7.318,38.44],[-7.3035,38.543],[-7.264,38.588],[-7.2725,38.6385],[-7.26,38.723],[-7.203,38.752],[-7.1255,38.8155],[-7.0965,38.816],[-7.033,38.879],[-7.052,38.907],[-6.951,39.0235],[-6.981,39.088],[-7.028,39.1155],[-7.144,39.1085],[-7.132,39.1645],[-7.2215,39.1935],[-7.248,39.2535],[-7.2315,39.2785],[-7.3105,39.341],[-7.323,39.382],[-7.2945,39.457],[-7.377,39.489],[-7.5,39.591],[-7.534,39.667],[-7.331,39.641],[-7.2515,39.667],[-7.1515,39.653],[-7.0155,39.6705],[-6.977,39.772],[-6.987,39.81],[-6.9035,39.8705],[-6.8855,39.94],[-6.881,40.0415],[-6.954,40.1155],[-7.019,40.1425],[-7.009,40.2275],[-6.9515,40.2575],[-6.868,40.2645],[-6.864,40.296],[-6.7905,40.334],[-6.781,40.364],[-6.8385,40.4145],[-6.8495,40.4515],[-6.801,40.5505],[-6.8455,40.566],[-6.799,40.6555],[-6.8305,40.743],[-6.8035,40.846],[-6.86,40.951],[-6.9315,41.017],[-6.809,41.0365],[-6.754,41.104],[-6.768,41.135],[-6.7015,41.1805],[-6.6485,41.2475],[-6.5805,41.239],[-6.469,41.3015],[-6.4155,41.348],[-6.3155,41.39],[-6.3055,41.4495],[-6.189,41.575],[-6.2545,41.633],[-6.3545,41.6765],[-6.4525,41.681],[-6.5125,41.661],[-6.5485,41.6855],[-6.5645,41.7515],[-6.5175,41.875],[-6.571,41.8835],[-6.546,41.931],[-6.5995,41.9485],[-6.7,41.9335],[-6.7505,41.9435],[-7.077,41.952],[-7.1415,41.991],[-7.1865,41.9695],[-7.1735,41.919],[-7.1965,41.88],[-7.3155,41.8425],[-7.39,41.8425],[-7.4525,41.865],[-7.574,41.8295],[-7.704,41.9075],[-7.7335,41.8925],[-7.9215,41.882],[-7.9885,41.8675],[-8.0125,41.8335],[-8.094,41.808],[-8.165,41.818],[-8.162,41.861],[-8.217,41.913],[-8.1305,42.0035],[-8.086,42.0165],[-8.1185,42.0825],[-8.186,42.0725],[-8.1955,42.148],[-8.2535,42.1365],[-8.332,42.084],[-8.429,42.0725],[-8.518,42.0795],[-8.547,42.054],[-8.637,42.0475],[-8.6615,42.0035],[-8.746,41.9645],[-8.871,41.864],[-9.1565,41.8725]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/5/5c/Flag_of_Portugal.svg","name:en":"Portugal","wikidata":"Q45","ISO3166-1:alpha2":"PT","ISO3166-1:alpha3":"PRT","ISO3166-1:numeric":"620"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-2.5605,49.22],[-2.5265,49.0585],[-2.5265,48.927],[-2.243,48.871],[-2.0845,48.871],[-1.9845,48.8825],[-1.9845,48.9405],[-1.944,48.9635],[-1.8605,49.065],[-1.8345,49.1825],[-1.8345,49.25],[-1.893,49.3155],[-1.994,49.3635],[-2.099,49.4595],[-2.1335,49.4075],[-2.295,49.326],[-2.48,49.2645],[-2.5605,49.22]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/1c/Flag_of_Jersey.svg","name:en":"Jersey","wikidata":"Q785","ISO3166-1:alpha2":"JE","ISO3166-1:alpha3":"JEY","ISO3166-1:numeric":"832"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[13.9325,36.0715],[13.948,35.9705],[13.998,35.9],[14.085,35.8485],[14.129,35.7675],[14.244,35.677],[14.387,35.622],[14.5145,35.603],[14.5965,35.6105],[14.6995,35.65],[14.7485,35.685],[14.8085,35.775],[14.825,35.8885],[14.7795,35.9865],[14.6435,36.0925],[14.551,36.14],[14.489,36.2025],[14.4225,36.241],[14.333,36.273],[14.19,36.2835],[14.0735,36.2565],[13.996,36.208],[13.9405,36.1235],[13.9325,36.0715]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/7/73/Flag_of_Malta.svg","name:en":"Malta","wikidata":"Q233","ISO3166-1:alpha2":"MT","ISO3166-1:alpha3":"MLT","ISO3166-1:numeric":"470"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-6.7445,55.415],[-6.869,55.45],[-6.8885,55.502],[-6.965,55.572],[-7.0905,55.62],[-7.1995,55.635],[-7.3375,55.628],[-7.4335,55.603],[-7.6575,55.514],[-7.706,55.477],[-7.972,55.426],[-8.1305,55.465],[-8.3095,55.472],[-8.425,55.448],[-8.5455,55.383],[-8.588,55.331],[-8.6025,55.262],[-8.6495,55.226],[-8.826,55.145],[-8.898,55.068],[-8.9225,54.976],[-8.907,54.921],[-9.097,54.807],[-9.1665,54.721],[-9.1765,54.633],[-9.133,54.563],[-9.0255,54.497],[-9.116,54.491],[-9.251,54.521],[-9.4465,54.519],[-9.5745,54.526],[-9.6445,54.55],[-9.8225,54.566],[-9.9575,54.541],[-10.03,54.509],[-10.2495,54.462],[-10.357,54.411],[-10.4295,54.318],[-10.5165,54.232],[-10.622,54.162],[-10.661,54.05],[-10.5925,53.904],[-10.5035,53.774],[-10.5925,53.709],[-10.6315,53.647],[-10.634,53.571],[-10.564,53.448],[-10.5545,53.336],[-10.478,53.261],[-10.3315,53.207],[-10.2825,53.143],[-10.1755,53.084],[-10.138,53.039],[-10.04,52.979],[-9.8565,52.928],[-9.8445,52.884],[-9.935,52.811],[-10.1135,52.734],[-10.2175,52.665],[-10.261,52.596],[-10.2495,52.498],[-10.541,52.402],[-10.7045,52.32],[-10.7925,52.286],[-10.917,52.204],[-10.9705,52.15],[-11.0065,52.066],[-11.0055,51.98],[-10.9605,51.915],[-10.8425,51.848],[-10.866,51.788],[-10.843,51.694],[-10.783,51.634],[-10.723,51.602],[-10.6215,51.574],[-10.5665,51.479],[-10.411,51.398],[-10.243,51.37],[-10.121,51.382],[-10.037,51.303],[-9.9145,51.259],[-9.7755,51.248],[-9.691,51.253],[-9.575,51.225],[-9.413,51.232],[-9.294,51.271],[-9.1925,51.268],[-9.0505,51.299],[-8.9895,51.331],[-8.9185,51.331],[-8.7445,51.37],[-8.6215,51.378],[-8.5345,51.403],[-8.3855,51.426],[-8.288,51.474],[-8.2345,51.527],[-8.08,51.593],[-7.868,51.638],[-7.663,51.719],[-7.6045,51.752],[-7.378,51.838],[-7.274,51.932],[-7.0285,51.932],[-6.8935,51.924],[-6.7985,51.939],[-6.6275,51.909],[-6.5305,51.917],[-6.3805,51.973],[-6.2605,51.983],[-6.109,52.012],[-6.0,52.048],[-5.8945,52.144],[-5.887,52.246],[-5.934,52.314],[-6.008,52.363],[-5.9145,52.448],[-5.8645,52.56],[-5.875,52.614],[-5.811,52.724],[-5.7625,52.766],[-5.686,52.895],[-5.666,52.973],[-5.702,53.057],[-5.7125,53.151],[-5.749,53.231],[-5.7085,53.389],[-5.6715,53.439],[-5.6605,53.517],[-5.6695,53.631],[-5.6935,53.679],[-5.764,53.74],[-5.8775,53.784],[-5.888,53.844],[-5.826,53.87],[-5.951,53.9315],[-6.1135,54.033],[-6.2805,54.111],[-6.368,54.1115],[-6.3675,54.07],[-6.48,54.067],[-6.623,54.039],[-6.661,54.0625],[-6.6615,54.1225],[-6.6315,54.147],[-6.664,54.1925],[-6.746,54.189],[-6.8025,54.215],[-6.8775,54.347],[-6.982,54.4095],[-7.0535,54.412],[-7.104,54.3555],[-7.1525,54.3355],[-7.1735,54.286],[-7.147,54.2255],[-7.248,54.2045],[-7.31,54.1675],[-7.347,54.1175],[-7.442,54.154],[-7.4905,54.123],[-7.566,54.1265],[-7.702,54.208],[-7.862,54.2185],[-7.8885,54.3005],[-7.9465,54.3045],[-7.9865,54.344],[-8.056,54.3655],[-8.1605,54.4405],[-8.042,54.506],[-8.006,54.546],[-7.8505,54.533],[-7.7715,54.6215],[-7.9135,54.6765],[-7.855,54.727],[-7.746,54.7045],[-7.6365,54.7515],[-7.5785,54.742],[-7.549,54.7895],[-7.484,54.824],[-7.442,54.8755],[-7.4455,54.9365],[-7.405,54.942],[-7.3915,55.0225],[-7.345,55.051],[-7.218,55.0795],[-6.942,55.2045],[-6.8215,55.2165],[-6.7195,55.28],[-6.7445,55.415]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/45/Flag_of_Ireland.svg","name:en":"Ireland","wikidata":"Q27","ISO3166-1:alpha2":"IE","ISO3166-1:alpha3":"IRL","ISO3166-1:numeric":"372"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[27.0115,-29.649],[27.0965,-29.73],[27.223,-29.997],[27.2965,-30.056],[27.327,-30.148],[27.394,-30.1425],[27.3655,-30.219],[27.3765,-30.3255],[27.4645,-30.314],[27.475,-30.3565],[27.534,-30.3845],[27.6015,-30.4465],[27.6215,-30.5045],[27.693,-30.545],[27.7415,-30.604],[27.7815,-30.6175],[27.918,-30.6025],[27.94,-30.644],[28.004,-30.659],[28.123,-30.6635],[28.114,-30.599],[28.1505,-30.5845],[28.1775,-30.5225],[28.1555,-30.472],[28.1795,-30.439],[28.229,-30.43],[28.271,-30.371],[28.253,-30.3235],[28.2155,-30.307],[28.2365,-30.26],[28.3055,-30.255],[28.3405,-30.2345],[28.365,-30.1685],[28.4,-30.1435],[28.452,-30.158],[28.5685,-30.123],[28.6675,-30.1405],[28.69,-30.1245],[28.859,-30.088],[28.879,-30.07],[28.9855,-30.0315],[29.006,-30.0045],[29.109,-29.937],[29.1695,-29.9165],[29.16,-29.883],[29.1025,-29.85],[29.1315,-29.8255],[29.145,-29.7165],[29.1835,-29.668],[29.236,-29.64],[29.279,-29.6445],[29.285,-29.5865],[29.3195,-29.5815],[29.297,-29.5225],[29.3295,-29.47],[29.4035,-29.444],[29.4555,-29.341],[29.437,-29.2645],[29.408,-29.212],[29.3565,-29.2015],[29.3555,-29.127],[29.308,-29.0765],[29.259,-29.0905],[29.2155,-29.0265],[29.1515,-28.9875],[29.075,-28.919],[28.975,-28.893],[28.939,-28.86],[28.944,-28.7825],[28.905,-28.759],[28.808,-28.771],[28.795,-28.6995],[28.7045,-28.6715],[28.7035,-28.619],[28.648,-28.5715],[28.613,-28.5965],[28.507,-28.618],[28.4715,-28.6055],[28.414,-28.6275],[28.357,-28.6925],[28.2795,-28.714],[28.233,-28.695],[28.166,-28.713],[28.073,-28.8155],[27.9905,-28.883],[27.948,-28.8525],[27.896,-28.9085],[27.8325,-28.906],[27.7295,-28.947],[27.7155,-29.007],[27.6825,-29.024],[27.652,-29.1005],[27.617,-29.153],[27.515,-29.224],[27.548,-29.2475],[27.5115,-29.283],[27.466,-29.294],[27.4365,-29.334],[27.4195,-29.4105],[27.392,-29.4155],[27.363,-29.476],[27.206,-29.559],[27.12,-29.5775],[27.0595,-29.635],[27.0115,-29.649]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/4a/Flag_of_Lesotho.svg","name:en":"Lesotho","wikidata":"Q1013","ISO3166-1:alpha2":"LS","ISO3166-1:alpha3":"LSO","ISO3166-1:numeric":"426"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-25.0135,65.5045],[-24.9885,65.438],[-24.4825,64.793],[-23.716,63.616],[-23.653,63.556],[-23.5495,63.5085],[-23.417,63.4785],[-23.196,63.473],[-22.9865,63.5055],[-20.774,63.102],[-20.5305,63.0885],[-19.0875,63.1855],[-18.704,63.185],[-18.578,63.193],[-18.0645,63.259],[-17.71,63.345],[-17.591,63.399],[-17.3175,63.5465],[-16.581,63.5875],[-16.384,63.62],[-15.935,63.7525],[-15.695,63.8555],[-14.77,64.054],[-14.2055,64.222],[-13.793,64.393],[-13.6425,64.469],[-13.441,64.4005],[-13.178,64.39],[-12.9635,64.4355],[-12.8775,64.479],[-12.817,64.5405],[-12.822,64.64],[-12.8885,64.7005],[-13.0445,64.7605],[-13.2055,64.794],[-13.083,64.877],[-13.032,64.9545],[-13.0135,65.0825],[-13.031,65.19],[-13.1235,65.525],[-13.157,65.5785],[-14.063,66.4485],[-14.224,66.5295],[-14.38,66.56],[-15.89,66.7265],[-16.015,66.7335],[-16.2975,66.7285],[-16.7325,66.685],[-16.879,66.6465],[-17.376,66.4565],[-17.4975,66.476],[-17.481,66.559],[-17.519,66.6195],[-17.6305,66.6925],[-17.7305,66.729],[-17.896,66.7595],[-18.078,66.7645],[-18.3295,66.7235],[-18.4485,66.671],[-18.5135,66.605],[-18.528,66.5385],[-18.458,66.4425],[-18.317,66.377],[-18.8605,66.3845],[-20.119,66.337],[-22.1605,66.629],[-22.296,66.6545],[-22.456,66.6655],[-22.597,66.657],[-22.977,66.6655],[-23.164,66.641],[-23.3815,66.592],[-23.5395,66.535],[-24.1865,66.1665],[-24.5265,65.8975],[-24.9485,65.6015],[-25.0135,65.5045]]],[[[-19.1995,67.151],[-19.177,67.093],[-19.0955,67.029],[-18.8895,66.965],[-18.63,66.949],[-18.4475,66.97],[-18.33,67.002],[-18.203,67.071],[-18.162,67.135],[-18.212,67.239],[-18.3155,67.295],[-18.503,67.341],[-18.7335,67.352],[-18.995,67.312],[-19.111,67.264],[-19.1795,67.207],[-19.1995,67.151]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/ce/Flag_of_Iceland.svg","name:en":"Iceland","wikidata":"Q189","ISO3166-1:alpha2":"IS","ISO3166-1:alpha3":"ISL","ISO3166-1:numeric":"352"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-179.059,-31.3545],[-179.0485,-31.414],[-178.9805,-31.505],[-178.884,-31.55],[-178.801,-31.556],[-178.7045,-31.5285],[-178.639,-31.4785],[-178.6095,-31.437],[-178.5895,-31.3675],[-178.6095,-31.2725],[-178.6795,-31.1955],[-178.7535,-31.162],[-178.884,-31.1595],[-178.9735,-31.199],[-179.0425,-31.2805],[-179.059,-31.3545]]],[[[-178.802,-30.5355],[-178.7945,-30.5885],[-178.754,-30.6595],[-178.6445,-30.73],[-178.551,-30.7455],[-178.434,-30.716],[-178.3785,-30.6755],[-178.334,-30.6075],[-178.3225,-30.526],[-178.358,-30.4325],[-178.2775,-30.397],[-178.2285,-30.356],[-178.191,-30.2935],[-178.182,-30.208],[-178.1955,-30.161],[-178.238,-30.1],[-178.28,-30.068],[-178.3715,-30.03],[-178.452,-30.025],[-178.564,-30.0595],[-178.6415,-30.132],[-178.6675,-30.195],[-178.67,-30.2515],[-178.635,-30.341],[-178.6965,-30.3655],[-178.7675,-30.4295],[-178.802,-30.5355]]],[[[-178.211,-29.245],[-178.1715,-29.3705],[-178.123,-29.436],[-178.0695,-29.472],[-177.9855,-29.4955],[-177.897,-29.498],[-177.84,-29.4855],[-177.7595,-29.447],[-177.696,-29.4025],[-177.6445,-29.337],[-177.626,-29.279],[-177.631,-29.2045],[-177.6755,-29.121],[-177.7735,-29.049],[-177.874,-29.0305],[-178.027,-29.0425],[-178.103,-29.072],[-178.1855,-29.1505],[-178.211,-29.245]]],[[[-177.2445,-43.9045],[-177.233,-43.9605],[-177.1915,-44.021],[-177.1025,-44.078],[-177.029,-44.098],[-176.946,-44.1025],[-176.9105,-44.1775],[-176.852,-44.252],[-176.7815,-44.296],[-176.6675,-44.3255],[-176.636,-44.3875],[-176.539,-44.5045],[-176.444,-44.5735],[-176.3675,-44.6135],[-176.213,-44.634],[-176.0715,-44.5955],[-175.9835,-44.5205],[-175.834,-44.5385],[-175.7195,-44.511],[-175.6235,-44.442],[-175.5935,-44.3895],[-175.5875,-44.308],[-175.6115,-44.2515],[-175.6795,-44.186],[-175.737,-44.1535],[-175.6615,-44.1275],[-175.58,-44.0645],[-175.5425,-43.982],[-175.5495,-43.9145],[-175.6165,-43.8255],[-175.6865,-43.7865],[-175.77,-43.7655],[-175.915,-43.7695],[-175.93,-43.6685],[-175.957,-43.6285],[-176.0765,-43.548],[-176.18,-43.526],[-176.3395,-43.5335],[-176.4825,-43.516],[-176.5385,-43.4975],[-176.59,-43.4295],[-176.6555,-43.3885],[-176.8185,-43.3265],[-176.9295,-43.311],[-177.063,-43.3375],[-177.1345,-43.3805],[-177.193,-43.464],[-177.186,-43.576],[-177.0975,-43.6675],[-177.2175,-43.817],[-177.2445,-43.9045]]],[[[165.5535,-50.802],[165.5985,-50.9295],[165.6945,-51.024],[165.804,-51.08],[165.982,-51.1205],[166.145,-51.1255],[166.2735,-51.0975],[166.4,-51.042],[166.518,-50.945],[166.561,-50.837],[166.532,-50.7445],[166.6435,-50.656],[166.6725,-50.5985],[166.6655,-50.5125],[166.6,-50.401],[166.542,-50.35],[166.424,-50.3005],[166.2625,-50.287],[166.0145,-50.323],[165.841,-50.381],[165.691,-50.49],[165.635,-50.5755],[165.636,-50.643],[165.576,-50.714],[165.5535,-50.802]]],[[[166.1385,-45.907],[166.167,-46.0415],[166.2035,-46.1205],[166.2875,-46.2185],[166.363,-46.2655],[166.4515,-46.3465],[166.565,-46.396],[166.6705,-46.4185],[166.5815,-46.514],[166.576,-46.611],[166.624,-46.6865],[166.672,-46.7225],[166.784,-46.768],[166.8745,-46.7815],[167.019,-46.765],[167.097,-46.7315],[167.171,-46.6625],[167.195,-46.602],[167.1815,-46.5065],[167.1545,-46.465],[167.2925,-46.459],[167.5335,-46.513],[167.541,-46.5305],[167.4045,-46.598],[167.3235,-46.673],[167.3005,-46.761],[167.3655,-46.9345],[167.2105,-46.9865],[167.1435,-47.043],[167.05,-47.146],[167.0285,-47.1995],[167.039,-47.284],[167.099,-47.3585],[167.201,-47.4225],[167.3105,-47.4625],[167.431,-47.484],[167.531,-47.4895],[167.5375,-47.579],[167.5715,-47.6305],[167.6335,-47.6785],[167.731,-47.7145],[167.8025,-47.7235],[167.918,-47.713],[168.0065,-47.682],[168.0895,-47.621],[168.1305,-47.509],[168.193,-47.431],[168.1955,-47.328],[168.3265,-47.3065],[168.464,-47.245],[168.533,-47.1865],[168.562,-47.13],[168.544,-47.015],[168.7345,-46.95],[168.838,-46.869],[169.0405,-46.876],[169.249,-46.8615],[169.342,-46.8395],[169.442,-46.83],[169.603,-46.778],[169.745,-46.7455],[170.048,-46.5815],[170.0955,-46.527],[170.116,-46.4535],[170.3835,-46.2925],[170.4385,-46.2375],[170.482,-46.141],[170.7805,-46.091],[170.9135,-46.038],[170.9845,-45.987],[171.0345,-45.8925],[171.0375,-45.7895],[170.988,-45.676],[171.0075,-45.636],[171.0835,-45.57],[171.1345,-45.466],[171.152,-45.36],[171.1395,-45.31],[171.2515,-45.1855],[171.324,-45.1265],[171.4075,-45.0145],[171.4465,-44.9085],[171.456,-44.814],[171.4405,-44.6345],[171.519,-44.52],[171.5445,-44.426],[171.616,-44.376],[171.7345,-44.315],[172.0585,-44.173],[172.2565,-44.0995],[172.401,-44.0575],[172.623,-44.032],[172.6775,-44.06],[172.825,-44.096],[172.9275,-44.103],[173.0335,-44.092],[173.131,-44.067],[173.2765,-43.994],[173.3485,-43.9265],[173.39,-43.8465],[173.407,-43.78],[173.4035,-43.715],[173.338,-43.587],[173.242,-43.5085],[173.167,-43.47],[172.989,-43.4245],[172.9845,-43.362],[173.0065,-43.296],[173.084,-43.2635],[173.207,-43.2405],[173.296,-43.1855],[173.3235,-43.1535],[173.4225,-43.1065],[173.555,-42.9815],[173.716,-42.6965],[173.7705,-42.63],[173.894,-42.58],[173.978,-42.4925],[173.995,-42.4115],[174.17,-42.2675],[174.207,-42.1875],[174.208,-42.1465],[174.3825,-41.9915],[174.4475,-41.914],[174.516,-41.862],[174.562,-41.7845],[174.5645,-41.7075],[174.5065,-41.603],[174.42,-41.5435],[174.395,-41.4805],[174.4295,-41.4575],[174.5365,-41.5265],[174.735,-41.5875],[174.813,-41.625],[174.9825,-41.6785],[175.0195,-41.731],[175.114,-41.791],[175.269,-41.815],[175.3815,-41.8055],[175.5545,-41.7515],[175.67,-41.6825],[175.741,-41.6565],[175.84,-41.584],[175.982,-41.5365],[176.039,-41.5055],[176.1095,-41.4195],[176.2435,-41.325],[176.3065,-41.2575],[176.3625,-41.0965],[176.4745,-40.9805],[176.522,-40.857],[176.6175,-40.7525],[176.6915,-40.6855],[176.76,-40.6635],[176.8275,-40.619],[176.864,-40.574],[176.918,-40.3995],[176.9755,-40.3655],[177.0885,-40.2485],[177.1305,-40.186],[177.1625,-40.0555],[177.203,-39.986],[177.2815,-39.897],[177.288,-39.7895],[177.3495,-39.6925],[177.3545,-39.613],[177.2955,-39.3095],[177.431,-39.266],[177.59,-39.2545],[177.6225,-39.3805],[177.7125,-39.469],[177.81,-39.503],[177.94,-39.501],[178.0805,-39.443],[178.137,-39.4075],[178.1895,-39.3405],[178.202,-39.2405],[178.2575,-39.1475],[178.247,-39.036],[178.1665,-38.9465],[178.1735,-38.8945],[178.357,-38.785],[178.412,-38.728],[178.501,-38.662],[178.5435,-38.591],[178.555,-38.5355],[178.592,-38.4795],[178.6315,-38.279],[178.6165,-38.2245],[178.634,-38.0705],[178.63,-38.03],[178.6545,-37.961],[178.704,-37.8775],[178.8125,-37.77],[178.8355,-37.6705],[178.8065,-37.5905],[178.757,-37.5395],[178.628,-37.4725],[178.5235,-37.4385],[178.4815,-37.403],[178.401,-37.367],[178.2405,-37.334],[177.9245,-37.338],[177.831,-37.3725],[177.7025,-37.476],[177.6205,-37.4945],[177.5445,-37.539],[177.463,-37.619],[177.349,-37.766],[177.3115,-37.7895],[177.2235,-37.7835],[177.1905,-37.7365],[177.265,-37.7265],[177.3515,-37.6875],[177.4115,-37.6295],[177.4475,-37.534],[177.4335,-37.4485],[177.389,-37.386],[177.2685,-37.307],[177.139,-37.2755],[177.06,-37.2845],[176.977,-37.318],[176.9275,-37.358],[176.8835,-37.432],[176.8765,-37.4955],[176.9055,-37.5745],[176.9505,-37.6225],[176.8085,-37.623],[176.7525,-37.519],[176.6995,-37.4615],[176.5765,-37.38],[176.5145,-37.353],[176.5285,-37.244],[176.5125,-37.197],[176.46,-37.132],[176.411,-37.0985],[176.3135,-37.067],[176.3455,-37.0095],[176.351,-36.9015],[176.3045,-36.8195],[176.2315,-36.7605],[176.1665,-36.731],[176.1935,-36.663],[176.192,-36.583],[176.1375,-36.47],[176.033,-36.4025],[175.972,-36.3055],[175.906,-36.2595],[175.779,-36.228],[175.755,-36.1855],[175.763,-36.1045],[175.7115,-35.9985],[175.639,-35.9475],[175.5545,-35.863],[175.48,-35.8325],[175.3785,-35.8255],[175.319,-35.768],[175.2295,-35.7215],[175.155,-35.702],[175.0225,-35.7],[174.932,-35.7245],[174.8855,-35.702],[174.9415,-35.648],[174.99,-35.5195],[174.9745,-35.3835],[174.9005,-35.295],[174.8045,-35.2515],[174.718,-35.244],[174.6215,-35.2675],[174.5855,-35.2105],[174.584,-35.1435],[174.562,-35.079],[174.5065,-35.016],[174.4265,-34.9755],[174.232,-34.956],[174.148,-34.8395],[174.0915,-34.8015],[173.9955,-34.772],[173.8755,-34.772],[173.8285,-34.7575],[173.695,-34.742],[173.5725,-34.6355],[173.5155,-34.599],[173.4485,-34.5775],[173.2455,-34.5665],[173.279,-34.49],[173.298,-34.401],[173.2795,-34.335],[173.1985,-34.25],[173.117,-34.209],[172.979,-34.1955],[172.8965,-34.216],[172.7585,-34.231],[172.7005,-34.2205],[172.6145,-34.227],[172.5155,-34.2725],[172.4365,-34.3505],[172.3995,-34.419],[172.402,-34.5275],[172.4565,-34.609],[172.581,-34.6975],[172.7405,-34.846],[172.8915,-35.0225],[172.8505,-35.0665],[172.814,-35.1445],[172.827,-35.2665],[172.8605,-35.316],[172.934,-35.3855],[173.027,-35.507],[173.133,-35.6135],[173.1585,-35.6595],[173.2415,-35.76],[173.2895,-35.7985],[173.359,-35.884],[173.4085,-35.9245],[173.5585,-36.0865],[173.7195,-36.272],[173.7745,-36.351],[173.7975,-36.445],[173.8395,-36.5105],[173.9675,-36.6105],[174.059,-36.71],[174.17,-36.867],[174.2155,-36.998],[174.2335,-37.083],[174.271,-37.159],[174.339,-37.2145],[174.4475,-37.41],[174.4915,-37.618],[174.562,-37.728],[174.532,-37.7735],[174.481,-37.7835],[174.396,-37.824],[174.3415,-37.881],[174.3145,-37.957],[174.324,-38.028],[174.3795,-38.1065],[174.4265,-38.1385],[174.4515,-38.2475],[174.4135,-38.2855],[174.3775,-38.3775],[174.3755,-38.582],[174.349,-38.732],[174.283,-38.782],[174.193,-38.782],[174.1105,-38.7985],[174.0005,-38.845],[173.886,-38.8715],[173.791,-38.9405],[173.6545,-39.017],[173.5715,-39.0885],[173.505,-39.217],[173.4925,-39.304],[173.533,-39.4555],[173.5735,-39.5195],[173.7395,-39.674],[173.8875,-39.74],[174.0005,-39.768],[174.1175,-39.7855],[174.2855,-39.91],[174.417,-39.9845],[174.6495,-40.0605],[174.7705,-40.067],[174.86,-40.127],[174.9465,-40.2285],[174.9665,-40.368],[174.9415,-40.501],[174.894,-40.6225],[174.809,-40.6405],[174.7165,-40.696],[174.643,-40.7715],[174.612,-40.826],[174.6035,-40.896],[174.474,-40.815],[174.373,-40.7855],[174.3145,-40.7305],[174.2375,-40.5705],[174.164,-40.505],[174.086,-40.472],[173.9785,-40.4615],[173.8575,-40.4925],[173.717,-40.5645],[173.5975,-40.656],[173.5255,-40.7775],[173.5005,-40.863],[173.456,-40.8795],[173.289,-40.749],[173.34,-40.621],[173.331,-40.533],[173.275,-40.4525],[173.148,-40.368],[173.0,-40.321],[172.837,-40.3015],[172.6135,-40.3045],[172.494,-40.342],[172.281,-40.4715],[172.1345,-40.582],[172.0355,-40.625],[171.9115,-40.7365],[171.852,-40.825],[171.826,-40.925],[171.8425,-41.025],[171.8385,-41.1595],[171.8235,-41.2805],[171.764,-41.3315],[171.6805,-41.4625],[171.598,-41.527],[171.4295,-41.5235],[171.349,-41.543],[171.281,-41.581],[171.2175,-41.6545],[171.182,-41.746],[171.186,-41.812],[171.145,-41.914],[171.1165,-41.953],[171.059,-42.085],[171.046,-42.1965],[170.9715,-42.293],[170.9205,-42.424],[170.8575,-42.5055],[170.73,-42.6025],[170.6465,-42.7025],[170.562,-42.765],[170.4625,-42.8165],[170.3695,-42.834],[170.2715,-42.868],[170.2035,-42.9115],[170.0625,-42.9695],[169.975,-43.067],[169.844,-43.155],[169.8015,-43.1965],[169.68,-43.233],[169.6015,-43.2795],[169.5,-43.3865],[169.2205,-43.475],[169.0045,-43.581],[168.923,-43.6425],[168.839,-43.657],[168.6645,-43.722],[168.6205,-43.7545],[168.555,-43.7615],[168.422,-43.801],[168.3515,-43.802],[168.2355,-43.8285],[168.169,-43.863],[168.031,-44.0105],[167.8635,-44.1075],[167.8165,-44.147],[167.7385,-44.2415],[167.6285,-44.33],[167.528,-44.4505],[167.403,-44.5175],[167.312,-44.598],[167.194,-44.657],[167.0545,-44.741],[166.881,-44.8915],[166.7825,-44.989],[166.725,-45.0285],[166.6335,-45.117],[166.51,-45.276],[166.414,-45.439],[166.323,-45.4935],[166.193,-45.6255],[166.1525,-45.7095],[166.1385,-45.907]]],[[[166.192,-48.066],[166.207,-48.129],[166.262,-48.1945],[166.3245,-48.232],[166.4115,-48.2585],[166.495,-48.2655],[166.672,-48.245],[166.819,-48.1995],[166.879,-48.155],[166.922,-48.0855],[166.928,-48.0405],[166.903,-47.964],[166.846,-47.893],[166.7155,-47.824],[166.5895,-47.809],[166.466,-47.831],[166.3455,-47.887],[166.2525,-47.944],[166.2165,-47.986],[166.192,-48.066]]],[[[168.6555,-52.5555],[168.6695,-52.615],[168.734,-52.6865],[168.83,-52.7425],[169.003,-52.8065],[169.1055,-52.821],[169.223,-52.813],[169.3805,-52.7715],[169.528,-52.6795],[169.584,-52.604],[169.5875,-52.504],[169.538,-52.3975],[169.482,-52.339],[169.4085,-52.2995],[169.2825,-52.27],[169.0915,-52.269],[168.9595,-52.296],[168.7555,-52.412],[168.687,-52.4725],[168.6555,-52.5555]]],[[[171.7885,-34.184],[171.8025,-34.251],[171.852,-34.321],[171.9295,-34.37],[172.02,-34.3895],[172.0875,-34.3855],[172.2545,-34.3485],[172.3295,-34.303],[172.382,-34.2425],[172.41,-34.1225],[172.3875,-34.0475],[172.308,-33.9675],[172.2045,-33.932],[172.1145,-33.934],[171.932,-33.9975],[171.873,-34.0305],[171.8195,-34.086],[171.7885,-34.184]]],[[[178.4075,-49.6745],[178.4225,-49.7485],[178.4765,-49.8265],[178.537,-49.8665],[178.6645,-49.9095],[178.812,-49.9165],[178.9105,-49.897],[179.0375,-49.8325],[179.1115,-49.736],[179.1315,-49.6515],[179.095,-49.548],[178.9925,-49.474],[178.875,-49.4415],[178.7915,-49.438],[178.6675,-49.461],[178.5105,-49.5245],[178.4355,-49.5905],[178.4075,-49.6745]]],[[[178.7065,-47.7525],[178.741,-47.847],[178.7785,-47.8845],[178.869,-47.9335],[178.951,-47.956],[179.0695,-47.968],[179.1665,-47.955],[179.2655,-47.913],[179.318,-47.8705],[179.355,-47.8125],[179.3515,-47.7045],[179.307,-47.644],[179.2425,-47.599],[179.086,-47.5505],[179.0035,-47.546],[178.877,-47.5715],[178.781,-47.6215],[178.735,-47.669],[178.7065,-47.7525]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/3e/Flag_of_New_Zealand.svg","name:en":"New Zealand","wikidata":"Q664","ISO3166-1:alpha2":"NZ","ISO3166-1:alpha3":"NZL","ISO3166-1:numeric":"554"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[19.999,-24.764],[19.999,-24.434],[19.999,-23.863],[19.999,-23.309],[19.999,-22.281],[19.999,-22.0],[20.58,-22.0005],[20.9985,-22.0005],[20.999,-21.746],[20.999,-21.006],[20.999,-20.5435],[20.999,-19.866],[20.999,-19.166],[20.999,-18.3175],[21.453,-18.3175],[22.048,-18.205],[22.5,-18.1175],[23.0985,-18.001],[23.297,-18.001],[23.324,-18.082],[23.379,-18.135],[23.4105,-18.2035],[23.5205,-18.2695],[23.558,-18.336],[23.5725,-18.482],[23.616,-18.5025],[23.6565,-18.4785],[23.6825,-18.436],[23.722,-18.433],[23.7895,-18.382],[23.806,-18.3415],[23.8965,-18.263],[23.925,-18.2565],[23.9315,-18.2045],[24.091,-18.1205],[24.149,-18.075],[24.1925,-18.02],[24.294,-18.0305],[24.372,-17.949],[24.4265,-17.9535],[24.482,-18.0105],[24.5055,-18.06],[24.579,-18.07],[24.6185,-17.996],[24.6655,-17.95],[24.6965,-17.9445],[24.732,-17.8925],[24.864,-17.8455],[24.9105,-17.8105],[24.954,-17.8005],[25.0075,-17.8385],[25.052,-17.808],[25.0835,-17.837],[25.144,-17.808],[25.1625,-17.7785],[25.262,-17.7905],[25.194,-17.7695],[25.0895,-17.663],[25.032,-17.5865],[24.998,-17.592],[24.975,-17.5535],[24.9075,-17.5545],[24.8835,-17.529],[24.829,-17.52],[24.8025,-17.5365],[24.7085,-17.497],[24.6275,-17.511],[24.559,-17.539],[24.453,-17.48],[24.3815,-17.4715],[24.327,-17.492],[24.2485,-17.474],[23.927,-17.539],[23.434,-17.638],[22.9965,-17.724],[22.5,-17.821],[21.423,-18.026],[21.268,-17.967],[21.21,-17.929],[21.1145,-17.9355],[21.095,-17.9495],[20.977,-17.958],[20.9055,-17.995],[20.8665,-18.0295],[20.8025,-18.0375],[20.749,-18.0035],[20.719,-18.013],[20.6455,-17.977],[20.56,-17.9845],[20.4765,-17.952],[20.4385,-17.9065],[20.368,-17.8965],[20.3325,-17.8665],[20.2755,-17.865],[20.233,-17.8845],[20.1745,-17.877],[20.116,-17.9095],[20.057,-17.8855],[20.028,-17.9055],[19.912,-17.862],[19.863,-17.8835],[19.8065,-17.8685],[19.7425,-17.9075],[19.6735,-17.8495],[19.5665,-17.874],[19.508,-17.8605],[19.4085,-17.8675],[19.331,-17.852],[19.2715,-17.8205],[19.231,-17.828],[19.138,-17.8075],[19.118,-17.8365],[19.0345,-17.835],[18.8945,-17.816],[18.834,-17.772],[18.7905,-17.7665],[18.624,-17.636],[18.598,-17.5835],[18.5685,-17.5845],[18.5335,-17.5205],[18.4215,-17.3895],[17.6265,-17.3895],[16.8945,-17.39],[16.107,-17.3905],[15.578,-17.3905],[15.2015,-17.391],[14.637,-17.3915],[14.2225,-17.3915],[14.2125,-17.41],[14.101,-17.439],[14.017,-17.415],[13.9555,-17.433],[13.9165,-17.378],[13.8685,-17.343],[13.68,-17.247],[13.5415,-17.147],[13.5225,-17.0905],[13.4645,-17.013],[13.352,-16.974],[13.2725,-16.9985],[13.17,-16.964],[13.0905,-16.98],[12.9865,-16.982],[12.9155,-17.021],[12.8725,-17.0645],[12.6965,-17.169],[12.6175,-17.207],[12.5945,-17.235],[12.4505,-17.2545],[12.4235,-17.2075],[12.2835,-17.242],[12.25,-17.2405],[12.184,-17.1965],[12.162,-17.1625],[12.102,-17.161],[12.079,-17.142],[11.9325,-17.19],[11.7985,-17.268],[11.7495,-17.25],[11.542,-17.25],[11.5465,-17.306],[11.5305,-17.4595],[11.528,-17.5895],[11.5605,-17.802],[11.592,-17.9275],[11.5975,-18.0075],[11.6315,-18.1435],[11.6665,-18.23],[11.7475,-18.3225],[11.794,-18.4325],[11.8015,-18.491],[11.838,-18.5745],[11.9035,-18.657],[12.1525,-18.8605],[12.2635,-19.0055],[12.2815,-19.0735],[12.3135,-19.1265],[12.396,-19.2085],[12.43,-19.283],[12.4925,-19.389],[12.505,-19.4485],[12.541,-19.5255],[12.656,-19.7225],[12.6825,-19.7875],[12.739,-19.8765],[12.762,-19.938],[12.83,-20.0625],[12.864,-20.16],[12.9125,-20.2265],[12.997,-20.304],[13.0325,-20.3875],[13.0445,-20.5105],[13.137,-20.687],[13.166,-20.824],[13.2025,-20.9225],[13.2355,-20.9845],[13.321,-21.0895],[13.399,-21.2475],[13.492,-21.351],[13.536,-21.4275],[13.619,-21.527],[13.6535,-21.584],[13.682,-21.6645],[13.7375,-21.7505],[13.737,-21.7985],[13.76,-21.866],[13.806,-21.922],[13.883,-21.984],[14.0785,-22.211],[14.1005,-22.2625],[14.2035,-22.3855],[14.2665,-22.555],[14.2895,-22.5965],[14.3055,-22.7165],[14.2555,-22.7665],[14.197,-22.905],[14.186,-23.016],[14.2185,-23.16],[14.2595,-23.268],[14.216,-23.385],[14.231,-23.4975],[14.2875,-23.6405],[14.28,-23.7515],[14.2875,-23.8305],[14.244,-23.9235],[14.2335,-23.997],[14.253,-24.146],[14.301,-24.2975],[14.3875,-24.4815],[14.34,-24.539],[14.314,-24.6045],[14.316,-24.6825],[14.343,-24.744],[14.395,-24.7975],[14.4635,-24.831],[14.5615,-24.838],[14.5775,-24.948],[14.637,-25.0805],[14.5805,-25.2945],[14.59,-25.4],[14.639,-25.5545],[14.624,-25.606],[14.6075,-25.749],[14.6225,-25.822],[14.684,-25.9195],[14.7075,-26.0145],[14.73,-26.0525],[14.709,-26.1535],[14.7235,-26.231],[14.7145,-26.312],[14.741,-26.413],[14.788,-26.4855],[14.887,-26.546],[14.8555,-26.632],[14.8575,-26.7095],[14.8765,-26.7895],[14.9825,-27.089],[15.013,-27.14],[15.0455,-27.271],[15.0935,-27.412],[15.1795,-27.5465],[15.238,-27.6075],[15.3015,-27.73],[15.3225,-27.7995],[15.371,-27.878],[15.4455,-27.951],[15.476,-28.0395],[15.5475,-28.132],[15.696,-28.2745],[15.897,-28.4315],[16.066,-28.5905],[16.159,-28.6855],[16.238,-28.7455],[16.3335,-28.8005],[16.453,-28.633],[16.48,-28.5655],[16.5925,-28.5355],[16.621,-28.5],[16.6885,-28.4705],[16.734,-28.4945],[16.777,-28.44],[16.7695,-28.396],[16.808,-28.361],[16.755,-28.302],[16.803,-28.222],[16.857,-28.207],[16.888,-28.173],[16.8845,-28.09],[17.0825,-28.033],[17.1445,-28.0955],[17.1965,-28.128],[17.184,-28.209],[17.215,-28.248],[17.334,-28.226],[17.3825,-28.296],[17.376,-28.321],[17.414,-28.376],[17.3965,-28.4275],[17.3555,-28.437],[17.333,-28.475],[17.3655,-28.509],[17.389,-28.571],[17.4295,-28.57],[17.43,-28.7215],[17.4935,-28.693],[17.599,-28.6945],[17.619,-28.765],[17.736,-28.7565],[17.9255,-28.769],[17.972,-28.7915],[18.046,-28.8745],[18.079,-28.87],[18.194,-28.9155],[18.2635,-28.8795],[18.351,-28.8805],[18.4235,-28.901],[18.533,-28.868],[18.7285,-28.8315],[18.9355,-28.857],[18.9835,-28.879],[19.006,-28.9245],[19.1185,-28.9695],[19.1965,-28.947],[19.23,-28.9125],[19.285,-28.9085],[19.24,-28.806],[19.27,-28.742],[19.4055,-28.7365],[19.4895,-28.682],[19.507,-28.598],[19.5485,-28.541],[19.622,-28.511],[19.671,-28.5295],[19.73,-28.488],[19.813,-28.5085],[19.847,-28.46],[19.999,-28.428],[19.999,-27.8885],[19.999,-27.547],[20.0,-26.9125],[19.999,-26.6185],[19.9995,-26.1425],[19.999,-25.7805],[19.999,-25.2205],[19.999,-24.764]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/00/Flag_of_Namibia.svg","name:en":"Namibia","wikidata":"Q1030","ISO3166-1:alpha2":"NA","ISO3166-1:alpha3":"NAM","ISO3166-1:numeric":"516"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[114.095,10.97],[114.12,10.952],[114.1635,10.8865],[114.2185,10.86],[114.2795,10.8515],[114.281,10.827],[114.2355,10.7665],[114.2155,10.694],[114.227,10.612],[114.2845,10.531],[114.4985,10.493],[114.573,10.543],[114.6155,10.6145],[114.6255,10.697],[114.605,10.7685],[114.5595,10.8275],[114.4955,10.867],[114.4215,10.8805],[114.4865,11.006],[114.491,11.0685],[114.474,11.134],[114.4355,11.1905],[114.333,11.2495],[114.2015,11.124],[114.095,10.97]]],[[[115.5995,10.716],[115.6435,10.6055],[115.6915,10.562],[115.7755,10.53],[115.8675,10.537],[115.9625,10.598],[116.0065,10.681],[116.029,10.816],[116.0215,10.8705],[115.9695,10.9595],[115.914,10.9995],[115.8345,11.0205],[115.7805,11.017],[115.6945,10.978],[115.6395,10.9145],[115.62,10.864],[115.5995,10.716]]],[[[118.8375,4.4525],[119.1115,4.2635],[119.2095,4.219],[119.2465,4.216],[119.347,4.2405],[119.955,4.616],[120.786,5.024],[122.077,5.8975],[122.316,6.229],[124.18,5.9645],[124.219,5.937],[125.2055,5.231],[125.298,5.1785],[125.4345,5.166],[125.4905,5.178],[125.577,5.2195],[125.6245,5.257],[126.336,6.127],[126.393,6.222],[126.785,7.195],[126.8075,7.293],[126.799,7.5325],[126.771,7.761],[126.68,8.256],[126.5475,8.9195],[126.3675,9.8735],[126.164,10.814],[125.76,12.173],[125.7075,12.2895],[125.669,12.345],[125.5445,12.4895],[125.375,12.669],[125.237,12.794],[124.461,14.2155],[124.381,14.284],[123.107,14.633],[122.4615,16.318],[122.6355,16.737],[122.7225,17.009],[122.7375,17.127],[122.6025,17.995],[122.5485,18.338],[122.397,19.781],[122.3755,19.9835],[122.168,21.1635],[122.1075,21.2625],[122.0315,21.305],[121.947,21.322],[121.8945,21.3155],[121.7965,21.274],[121.75,21.2125],[121.738,21.17],[121.5775,20.7765],[121.325,20.0865],[121.0355,19.2735],[120.3765,18.5835],[120.3555,18.5365],[120.1475,17.739],[120.133,17.5915],[119.833,16.9405],[119.5925,16.402],[119.5795,16.3635],[119.5445,16.1725],[119.542,15.937],[119.5755,15.7905],[119.812,13.8835],[119.662,12.407],[119.0675,11.2985],[118.452,10.1085],[117.477,9.1845],[117.3235,9.03],[117.192,8.87],[117.077,8.708],[116.719,8.1185],[116.7005,8.036],[116.688,7.9015],[116.719,7.7675],[116.8105,7.68],[116.8375,7.6665],[117.0,7.6665],[117.425,7.4125],[117.967,6.867],[117.9665,6.2835],[118.3335,6.0],[118.833,6.0],[119.5835,5.2665],[119.3335,5.025],[119.0,4.7],[119.0,4.443],[118.8375,4.4525]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/99/Flag_of_the_Philippines.svg","name:en":"Philippines","wikidata":"Q928","ISO3166-1:alpha2":"PH","ISO3166-1:alpha3":"PHL","ISO3166-1:numeric":"608"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[31.975,-25.9525],[32.003,-25.997],[32.0875,-26.0085],[32.1055,-26.1615],[32.0745,-26.3055],[32.0775,-26.4055],[32.135,-26.527],[32.1345,-26.8405],[32.1865,-26.863],[32.2205,-26.833],[32.33,-26.8635],[32.692,-26.868],[32.902,-26.858],[33.1025,-26.921],[33.117,-26.881],[33.1275,-26.692],[33.1205,-26.649],[33.1525,-26.449],[33.1475,-26.4115],[33.183,-26.0885],[33.2055,-26.0345],[33.492,-25.4355],[33.6955,-25.3585],[33.7895,-25.314],[33.9495,-25.2565],[34.062,-25.2245],[34.298,-25.136],[34.3655,-25.12],[34.6355,-25.0195],[34.8965,-24.934],[35.1185,-24.8385],[35.2135,-24.7865],[35.299,-24.728],[35.391,-24.625],[35.4145,-24.572],[35.5805,-24.3775],[35.6515,-24.28],[35.7055,-24.1755],[35.718,-24.1245],[35.7205,-24.0245],[35.7625,-23.9315],[35.7715,-23.842],[35.7495,-23.7425],[35.7225,-23.6855],[35.6485,-23.621],[35.6405,-23.542],[35.701,-23.37],[35.709,-23.324],[35.7115,-23.1765],[35.7655,-23.095],[35.811,-22.993],[35.82,-22.917],[35.793,-22.8275],[35.73,-22.7615],[35.721,-22.595],[35.7555,-22.44],[35.7595,-22.324],[35.7475,-22.238],[35.761,-22.1125],[35.741,-22.0505],[35.6865,-21.9835],[35.606,-21.936],[35.646,-21.8895],[35.676,-21.8215],[35.7095,-21.669],[35.7115,-21.5595],[35.6975,-21.472],[35.674,-21.424],[35.62,-21.361],[35.5685,-21.3305],[35.4545,-21.303],[35.3875,-21.3105],[35.3325,-21.3345],[35.32,-21.203],[35.328,-21.1655],[35.315,-21.067],[35.3425,-20.944],[35.333,-20.8715],[35.2645,-20.7665],[35.23,-20.737],[35.1985,-20.637],[35.129,-20.5395],[35.063,-20.474],[35.0105,-20.443],[34.9315,-20.4185],[34.918,-20.351],[34.9805,-20.2155],[34.989,-20.0985],[34.971,-20.035],[35.097,-19.969],[35.177,-19.9025],[35.2535,-19.8575],[35.4705,-19.6755],[35.563,-19.588],[35.691,-19.433],[35.9075,-19.2035],[36.0515,-19.1315],[36.252,-19.089],[36.3545,-19.072],[36.468,-18.999],[36.5535,-18.907],[36.5875,-18.8485],[36.599,-18.7805],[36.6745,-18.6865],[36.713,-18.622],[36.8225,-18.5185],[36.9765,-18.363],[37.045,-18.308],[37.082,-18.2395],[37.1485,-18.1645],[37.1705,-18.1155],[37.3015,-17.952],[37.389,-17.8825],[37.5225,-17.805],[37.9355,-17.588],[38.06,-17.5345],[38.1085,-17.5275],[38.9015,-17.449],[38.985,-17.423],[39.2165,-17.292],[39.6555,-16.979],[39.8665,-16.806],[40.093,-16.609],[40.226,-16.4615],[40.75,-15.5855],[40.9645,-15.1705],[40.9935,-15.0995],[41.041,-14.861],[41.0545,-14.469],[41.05,-14.419],[40.998,-14.188],[40.956,-14.1035],[40.897,-14.049],[40.822,-13.9215],[40.792,-13.824],[40.774,-13.6745],[40.7955,-13.63],[40.806,-13.557],[40.775,-13.451],[40.789,-13.3715],[40.7675,-13.254],[40.7605,-13.104],[40.8025,-13.008],[40.8405,-12.7685],[40.849,-12.4495],[40.84,-11.8315],[40.856,-11.7145],[40.9335,-11.0365],[40.9305,-10.973],[40.893,-10.7945],[40.8395,-10.6215],[40.735,-10.4665],[40.6895,-10.364],[40.647,-10.325],[40.493,-10.4145],[40.419,-10.483],[40.371,-10.5505],[40.298,-10.566],[40.2155,-10.6105],[40.176,-10.668],[40.1345,-10.69],[39.999,-10.807],[39.876,-10.846],[39.7595,-10.9155],[39.595,-10.9515],[39.522,-10.9815],[39.438,-11.0485],[39.356,-11.083],[39.274,-11.1575],[39.2365,-11.173],[39.123,-11.1435],[39.0785,-11.159],[38.883,-11.172],[38.8495,-11.2085],[38.7675,-11.25],[38.7495,-11.274],[38.6635,-11.273],[38.611,-11.307],[38.5775,-11.3475],[38.5365,-11.3655],[38.489,-11.4165],[38.3705,-11.3745],[38.316,-11.3265],[38.2825,-11.3275],[38.265,-11.2875],[38.1115,-11.2605],[38.064,-11.2775],[37.9705,-11.2725],[37.944,-11.2585],[37.8305,-11.311],[37.8275,-11.3725],[37.7775,-11.4575],[37.7855,-11.505],[37.753,-11.547],[37.6555,-11.5795],[37.581,-11.626],[37.502,-11.614],[37.4455,-11.6365],[37.415,-11.6855],[37.333,-11.678],[37.301,-11.641],[37.2255,-11.6545],[37.1575,-11.6315],[37.08,-11.625],[37.044,-11.593],[36.9865,-11.58],[36.9105,-11.6055],[36.8365,-11.584],[36.794,-11.6085],[36.767,-11.649],[36.6225,-11.737],[36.5735,-11.6985],[36.5195,-11.7615],[36.517,-11.6975],[36.494,-11.6815],[36.3835,-11.6805],[36.3545,-11.7135],[36.2875,-11.7205],[36.27,-11.6905],[36.221,-11.708],[36.183,-11.671],[36.1885,-11.598],[36.132,-11.5555],[36.128,-11.518],[36.063,-11.5405],[36.042,-11.4945],[36.0085,-11.487],[35.95,-11.4315],[35.9135,-11.438],[35.8465,-11.412],[35.8115,-11.4195],[35.766,-11.471],[35.7195,-11.475],[35.708,-11.509],[35.6505,-11.5505],[35.561,-11.566],[35.4155,-11.572],[35.2315,-11.5685],[34.959,-11.5735],[34.637,-11.5735],[34.6435,-11.656],[34.6345,-11.739],[34.591,-11.856],[34.484,-11.9725],[34.378,-12.1715],[34.4175,-12.2655],[34.43,-12.401],[34.4555,-12.571],[34.5205,-12.6825],[34.535,-12.7365],[34.5305,-12.88],[34.576,-13.232],[34.5615,-13.348],[34.607,-13.483],[34.867,-13.483],[34.927,-13.5465],[35.0895,-13.6995],[35.2275,-13.881],[35.487,-14.1705],[35.5205,-14.259],[35.872,-14.6755],[35.872,-14.8955],[35.9185,-14.8955],[35.79,-15.17],[35.853,-15.419],[35.8065,-15.992],[35.8175,-16.0275],[35.704,-16.1025],[35.6615,-16.1],[35.6125,-16.1245],[35.5025,-16.1555],[35.4815,-16.1235],[35.4055,-16.125],[35.3135,-16.2075],[35.2785,-16.326],[35.303,-16.3455],[35.263,-16.399],[35.262,-16.475],[35.213,-16.5],[35.146,-16.557],[35.167,-16.6195],[35.2755,-16.706],[35.3145,-16.831],[35.2635,-16.939],[35.2965,-16.9645],[35.2955,-17.128],[35.0975,-17.1295],[35.0885,-17.0785],[35.0565,-17.0495],[35.063,-16.994],[35.1355,-16.9715],[35.1675,-16.9215],[35.1575,-16.84],[35.113,-16.818],[35.0635,-16.8355],[34.9905,-16.7895],[34.9845,-16.749],[34.919,-16.746],[34.9095,-16.6935],[34.8585,-16.676],[34.8435,-16.6085],[34.7875,-16.5855],[34.775,-16.544],[34.7215,-16.497],[34.6895,-16.505],[34.6525,-16.453],[34.594,-16.4175],[34.5755,-16.3265],[34.52,-16.2805],[34.489,-16.2955],[34.4195,-16.25],[34.3975,-16.1855],[34.4295,-16.0445],[34.389,-16.027],[34.355,-15.9695],[34.259,-15.906],[34.2505,-15.8425],[34.2995,-15.761],[34.3645,-15.7425],[34.388,-15.6925],[34.437,-15.6595],[34.455,-15.611],[34.4255,-15.476],[34.521,-15.3845],[34.519,-15.3535],[34.5985,-15.287],[34.6035,-15.238],[34.578,-15.2005],[34.573,-15.0675],[34.618,-15.015],[34.58,-14.908],[34.5835,-14.809],[34.5205,-14.687],[34.551,-14.649],[34.5155,-14.5545],[34.4755,-14.5325],[34.391,-14.395],[34.301,-14.3985],[34.239,-14.425],[34.085,-14.4585],[34.087,-14.4895],[33.9155,-14.4775],[33.799,-14.5515],[33.7405,-14.501],[33.7165,-14.5015],[33.708,-14.578],[33.6795,-14.616],[33.634,-14.587],[33.6075,-14.4915],[33.566,-14.4815],[33.545,-14.4345],[33.512,-14.4235],[33.4495,-14.365],[33.445,-14.328],[33.3815,-14.2305],[33.3415,-14.2165],[33.2975,-14.146],[33.322,-14.0845],[33.3,-14.0315],[33.2165,-13.9995],[32.6105,-14.2145],[32.4515,-14.2825],[32.2415,-14.3235],[32.0565,-14.3885],[31.9295,-14.42],[31.8265,-14.473],[31.6835,-14.5065],[31.491,-14.612],[31.19,-14.6795],[31.079,-14.7175],[30.799,-14.7835],[30.5175,-14.888],[30.365,-14.9595],[30.2165,-14.9975],[30.234,-15.0355],[30.213,-15.0835],[30.257,-15.164],[30.283,-15.2645],[30.361,-15.3295],[30.383,-15.387],[30.377,-15.437],[30.4015,-15.4765],[30.3665,-15.5405],[30.421,-15.621],[30.425,-15.628],[30.4245,-16.0],[30.9225,-16.0],[30.982,-16.059],[31.0325,-16.0205],[31.1405,-15.9835],[31.322,-16.0255],[31.412,-16.144],[31.5645,-16.186],[31.6925,-16.197],[31.771,-16.2365],[31.8305,-16.3085],[31.894,-16.3365],[31.9135,-16.413],[32.0375,-16.4425],[32.2855,-16.4345],[32.412,-16.4695],[32.6255,-16.5595],[32.7125,-16.603],[32.7025,-16.677],[32.761,-16.7055],[32.838,-16.6965],[32.888,-16.719],[32.9215,-16.6975],[32.9785,-16.707],[32.9665,-16.7725],[32.914,-16.889],[32.8385,-16.932],[32.938,-17.0685],[32.9865,-17.1795],[33.0005,-17.314],[33.0495,-17.3355],[33.0065,-17.402],[33.0065,-17.4355],[32.9635,-17.4945],[32.9975,-17.5685],[33.042,-17.5875],[33.046,-17.637],[33.0155,-17.6885],[33.006,-17.7425],[33.0185,-17.786],[32.9725,-17.8005],[32.951,-17.882],[32.9735,-17.9385],[32.941,-18.011],[33.003,-18.201],[33.0215,-18.2285],[33.0255,-18.3105],[33.0675,-18.3485],[33.0185,-18.421],[33.0205,-18.4975],[32.9085,-18.5],[32.8845,-18.5225],[32.886,-18.579],[32.954,-18.69],[32.928,-18.7665],[32.8775,-18.797],[32.827,-18.7775],[32.734,-18.818],[32.7045,-18.857],[32.7305,-18.9225],[32.699,-18.939],[32.7135,-19.025],[32.8335,-19.0165],[32.8775,-19.098],[32.849,-19.2335],[32.85,-19.2935],[32.7765,-19.3615],[32.784,-19.47],[32.8455,-19.4835],[32.8585,-19.5465],[32.857,-19.6185],[32.8345,-19.6735],[32.892,-19.684],[32.9755,-19.6515],[32.9585,-19.723],[33.063,-19.777],[33.0245,-19.966],[33.029,-20.035],[32.943,-20.0425],[32.9235,-20.1265],[32.8615,-20.1365],[32.8755,-20.1875],[32.864,-20.287],[32.808,-20.339],[32.668,-20.556],[32.567,-20.561],[32.514,-20.5985],[32.4835,-20.657],[32.4945,-20.701],[32.498,-20.8075],[32.517,-20.9145],[32.481,-20.9925],[32.388,-21.0985],[32.3665,-21.1365],[32.4,-21.163],[32.3995,-21.2065],[32.476,-21.3115],[32.4055,-21.316],[32.2775,-21.459],[31.858,-21.8905],[31.3765,-22.3815],[31.3075,-22.424],[31.4755,-22.9255],[31.5635,-23.198],[31.5505,-23.4105],[31.561,-23.482],[31.6625,-23.586],[31.69,-23.6255],[31.6975,-23.722],[31.768,-23.885],[31.8805,-23.9525],[31.908,-24.182],[31.987,-24.302],[32.009,-24.4555],[32.009,-24.5755],[31.998,-24.6895],[32.0335,-25.1325],[32.016,-25.3775],[31.9795,-25.457],[31.996,-25.5265],[32.006,-25.645],[31.9785,-25.6935],[31.9305,-25.841],[31.975,-25.9525]],[[34.5725,-12.014],[34.605,-11.9745],[34.64,-11.982],[34.6625,-12.041],[34.6195,-12.085],[34.5845,-12.069],[34.5725,-12.014]],[[34.675,-12.0845],[34.706,-12.008],[34.742,-11.9995],[34.794,-12.0425],[34.7825,-12.0815],[34.7065,-12.1365],[34.675,-12.0845]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/d0/Flag_of_Mozambique.svg","name:en":"Mozambique","wikidata":"Q1029","ISO3166-1:alpha2":"MZ","ISO3166-1:alpha3":"MOZ","ISO3166-1:numeric":"508"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[30.473,-1.0575],[30.359,-1.0605],[30.307,-1.145],[30.2925,-1.1885],[30.214,-1.269],[30.1695,-1.2745],[30.17,-1.345],[30.014,-1.416],[29.997,-1.446],[29.916,-1.4825],[29.8855,-1.4235],[29.882,-1.357],[29.823,-1.309],[29.777,-1.3665],[29.7115,-1.345],[29.6765,-1.3835],[29.591,-1.3875],[29.526,-1.4115],[29.4505,-1.506],[29.362,-1.509],[29.3105,-1.5995],[29.2685,-1.6295],[29.245,-1.698],[29.156,-1.82],[29.136,-1.861],[29.129,-1.9415],[29.156,-2.0175],[29.1735,-2.129],[29.1155,-2.256],[29.092,-2.2765],[28.9985,-2.2975],[28.948,-2.3765],[28.909,-2.3725],[28.8665,-2.4365],[28.892,-2.476],[28.8625,-2.5325],[28.891,-2.5575],[28.918,-2.681],[29.004,-2.7045],[29.0405,-2.7435],[29.055,-2.7125],[29.0625,-2.6015],[29.1495,-2.5915],[29.2225,-2.632],[29.264,-2.6185],[29.328,-2.653],[29.3505,-2.7005],[29.334,-2.747],[29.3845,-2.821],[29.4385,-2.7975],[29.487,-2.8025],[29.543,-2.8295],[29.6585,-2.7875],[29.708,-2.8195],[29.7455,-2.807],[29.7695,-2.767],[29.8115,-2.771],[29.887,-2.7495],[29.918,-2.7025],[29.9355,-2.642],[29.9205,-2.5565],[29.9675,-2.446],[29.944,-2.373],[29.9595,-2.3275],[30.0465,-2.361],[30.061,-2.39],[30.126,-2.437],[30.185,-2.427],[30.232,-2.3505],[30.2925,-2.3735],[30.3735,-2.3525],[30.4085,-2.31],[30.459,-2.3185],[30.4715,-2.367],[30.5435,-2.413],[30.61,-2.3995],[30.657,-2.4135],[30.717,-2.3555],[30.7765,-2.389],[30.8525,-2.321],[30.8435,-2.2055],[30.899,-2.0775],[30.808,-1.938],[30.832,-1.8145],[30.8215,-1.693],[30.84,-1.651],[30.745,-1.5235],[30.739,-1.454],[30.6825,-1.397],[30.6295,-1.385],[30.6125,-1.35],[30.5685,-1.337],[30.5515,-1.252],[30.5095,-1.172],[30.471,-1.157],[30.453,-1.081],[30.473,-1.0575]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/17/Flag_of_Rwanda.svg","name:en":"Rwanda","wikidata":"Q1037","ISO3166-1:alpha2":"RW","ISO3166-1:alpha3":"RWA","ISO3166-1:numeric":"646"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-63.051,17.279],[-63.0075,17.22],[-62.8975,17.132],[-62.8405,17.106],[-62.81,17.016],[-62.754,16.951],[-62.645,16.899],[-62.5535,16.8995],[-62.3305,17.147],[-62.3425,17.23],[-62.402,17.33],[-62.5135,17.419],[-62.6035,17.528],[-62.7245,17.6],[-62.7865,17.616],[-63.051,17.279]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/fe/Flag_of_Saint_Kitts_and_Nevis.svg","name:en":"Saint Kitts and Nevis","wikidata":"Q763","ISO3166-1:alpha2":"KN","ISO3166-1:alpha3":"KNA","ISO3166-1:numeric":"659"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[166.71,-0.534],[166.728,-0.62],[166.784,-0.697],[166.847,-0.737],[166.956,-0.752],[167.026,-0.732],[167.0805,-0.697],[167.1355,-0.621],[167.157,-0.551],[167.148,-0.449],[167.1045,-0.375],[167.039,-0.325],[166.9675,-0.304],[166.894,-0.307],[166.811,-0.345],[166.7635,-0.39],[166.723,-0.458],[166.71,-0.534]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/30/Flag_of_Nauru.svg","name:en":"Nauru","wikidata":"Q697","ISO3166-1:alpha2":"NR","ISO3166-1:alpha3":"NRU","ISO3166-1:numeric":"520"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[42.968,-22.084],[42.9715,-22.118],[43.04,-22.4805],[43.1395,-22.864],[43.1545,-22.9025],[43.4175,-23.415],[43.448,-24.3395],[43.4705,-24.423],[43.8365,-25.09],[44.037,-25.35],[44.1305,-25.418],[45.048,-25.7685],[45.133,-25.784],[45.517,-25.784],[45.592,-25.772],[46.7935,-25.3715],[47.203,-25.1775],[47.2565,-25.141],[47.3005,-25.083],[47.4165,-24.8495],[47.432,-24.8075],[47.433,-24.733],[47.4935,-24.5935],[47.525,-24.458],[47.5815,-24.3305],[47.6195,-24.2155],[47.6705,-24.138],[47.802,-23.8415],[47.816,-23.737],[47.86,-23.5235],[47.921,-23.381],[47.964,-23.225],[47.9805,-23.123],[48.016,-23.031],[48.0665,-22.7975],[48.076,-22.6845],[48.105,-22.529],[48.1625,-22.3625],[48.237,-22.183],[48.3305,-21.9745],[48.4285,-21.716],[48.522,-21.4405],[48.558,-21.284],[48.644,-21.0625],[48.713,-20.743],[48.808,-20.456],[48.882,-20.2845],[48.9875,-20.0705],[49.0325,-19.9465],[49.028,-19.8555],[49.071,-19.6665],[49.187,-19.3935],[49.197,-19.3065],[49.228,-19.209],[49.29,-19.075],[49.3865,-18.8265],[49.423,-18.718],[49.4955,-18.5465],[49.5335,-18.4825],[49.5495,-18.38],[49.573,-18.3095],[49.616,-18.2545],[49.669,-18.0895],[49.669,-18.0135],[49.653,-17.965],[49.721,-17.7715],[50.22,-16.7875],[50.2405,-16.683],[50.2305,-16.6365],[50.1155,-16.3045],[50.3415,-16.1705],[50.4195,-16.087],[50.529,-15.864],[50.6455,-15.531],[50.6555,-15.4825],[50.672,-15.2825],[50.6675,-15.2215],[50.216,-13.3055],[50.0455,-12.743],[50.0185,-12.687],[49.4185,-11.821],[49.3445,-11.756],[49.242,-11.733],[49.15,-11.759],[48.55,-12.092],[48.4955,-12.136],[48.467,-12.178],[48.446,-12.2735],[48.4595,-12.671],[47.687,-13.4425],[47.6345,-13.5335],[47.399,-14.425],[46.3585,-15.3405],[44.3875,-16.0085],[43.91,-16.14],[43.8445,-16.1705],[43.8,-16.213],[43.7615,-16.3005],[43.56,-17.467],[43.5575,-17.496],[43.54,-18.3125],[43.5465,-18.367],[43.6085,-18.5835],[43.6595,-18.6495],[44.0145,-18.952],[44.009,-19.0875],[44.1475,-19.785],[43.931,-20.3745],[43.5985,-20.692],[43.5585,-20.7445],[43.0745,-21.6605],[43.0575,-21.7045],[42.9735,-22.0375],[42.968,-22.084]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/bc/Flag_of_Madagascar.svg","name:en":"Madagascar","wikidata":"Q1019","ISO3166-1:alpha2":"MG","ISO3166-1:alpha3":"MDG","ISO3166-1:numeric":"450"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[46.5525,29.1005],[46.841,29.068],[47.465,29.0],[47.5845,28.8355],[47.598,28.7565],[47.59,28.716],[47.6055,28.655],[47.709,28.543],[47.7045,28.5245],[48.4305,28.5345],[48.5895,28.639],[48.6695,28.6725],[48.6885,28.697],[49.0035,28.799],[48.9795,28.9095],[48.932,28.965],[48.833,29.013],[48.7125,29.0105],[48.7235,29.0755],[48.7075,29.146],[48.662,29.21],[48.612,29.244],[48.6635,29.326],[48.671,29.3965],[48.623,29.5025],[48.5395,29.5715],[48.5815,29.638],[48.5235,29.707],[48.464,29.757],[48.3835,29.8045],[48.318,29.881],[48.1515,30.017],[48.065,30.021],[48.023,29.9785],[47.7075,30.1035],[47.371,30.1035],[47.2875,30.0585],[47.1895,30.0285],[47.1395,29.987],[47.0815,29.8515],[47.007,29.722],[46.998,29.6635],[46.9045,29.525],[46.867,29.437],[46.7845,29.3555],[46.7675,29.322],[46.6605,29.196],[46.5525,29.1005]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/a/aa/Flag_of_Kuwait.svg","name:en":"Kuwait","wikidata":"Q817","ISO3166-1:alpha2":"KW","ISO3166-1:alpha3":"KWT","ISO3166-1:numeric":"414"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[56.3825,-10.347],[56.391,-10.407],[56.4425,-10.507],[56.5305,-10.62],[56.5995,-10.671],[56.6835,-10.69],[56.763,-10.677],[56.8195,-10.647],[56.8715,-10.593],[56.904,-10.515],[56.899,-10.417],[56.872,-10.358],[56.797,-10.286],[56.765,-10.229],[56.701,-10.169],[56.6275,-10.141],[56.552,-10.141],[56.452,-10.189],[56.4045,-10.251],[56.3825,-10.347]]],[[[57.095,-20.466],[57.118,-20.557],[57.1925,-20.635],[57.335,-20.697],[57.395,-20.711],[57.5525,-20.724],[57.642,-20.706],[57.7385,-20.672],[57.8165,-20.63],[57.917,-20.548],[57.9855,-20.458],[58.023,-20.29],[58.021,-20.208],[58.004,-20.15],[57.9325,-20.008],[57.9825,-19.949],[58.0175,-19.857],[58.016,-19.773],[57.963,-19.679],[57.917,-19.644],[57.851,-19.62],[57.7835,-19.617],[57.669,-19.662],[57.5825,-19.675],[57.525,-19.706],[57.4595,-19.784],[57.4345,-19.834],[57.381,-19.882],[57.3115,-20.009],[57.248,-20.062],[57.188,-20.155],[57.161,-20.222],[57.15,-20.315],[57.1,-20.42],[57.095,-20.466]]],[[[59.2615,-16.8165],[59.2725,-16.8895],[59.3075,-16.9515],[59.361,-16.999],[59.428,-17.0275],[59.556,-17.0275],[59.659,-16.989],[59.732,-16.938],[59.8215,-16.839],[59.883,-16.7525],[59.917,-16.64],[59.9235,-16.477],[59.8915,-16.387],[59.8455,-16.3345],[59.803,-16.2565],[59.7975,-16.1915],[59.7495,-16.1045],[59.695,-16.062],[59.629,-16.039],[59.556,-16.0395],[59.465,-16.0765],[59.416,-16.1255],[59.385,-16.1945],[59.389,-16.299],[59.412,-16.3465],[59.3265,-16.438],[59.299,-16.503],[59.296,-16.573],[59.309,-16.698],[59.279,-16.745],[59.2615,-16.8165]]],[[[63.086,-19.722],[63.0955,-19.784],[63.142,-19.863],[63.2495,-19.945],[63.3105,-19.968],[63.431,-19.985],[63.5365,-19.96],[63.595,-19.915],[63.6825,-19.822],[63.713,-19.741],[63.7005,-19.617],[63.651,-19.543],[63.6075,-19.511],[63.5325,-19.48],[63.444,-19.467],[63.2,-19.526],[63.157,-19.557],[63.1115,-19.62],[63.086,-19.722]]]]},"properties":{"flag":"https://commons.wikimedia.org/wiki/File:Flag_of_Mauritius.svg","name:en":"Mauritius","wikidata":"Q1027","ISO3166-1:alpha2":"MU","ISO3166-1:alpha3":"MUS","ISO3166-1:numeric":"480"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[45.999,-9.401],[46.0055,-9.4565],[46.0455,-9.569],[46.0825,-9.6225],[46.345,-9.894],[46.3985,-9.9335],[46.4615,-9.954],[46.547,-9.953],[46.6135,-9.9275],[46.695,-9.842],[46.7245,-9.7665],[46.73,-9.7095],[46.7235,-9.3715],[46.6945,-9.294],[46.642,-9.2365],[46.568,-9.1975],[46.476,-9.1715],[46.392,-9.1635],[46.2075,-9.17],[46.123,-9.195],[46.066,-9.2355],[46.0055,-9.3385],[45.999,-9.401]]],[[[47.3005,-9.72],[47.31,-9.788],[47.3345,-9.8405],[47.5555,-10.2025],[47.6065,-10.2585],[47.6735,-10.2955],[47.753,-10.306],[47.8255,-10.29],[47.9175,-10.219],[47.9635,-10.108],[47.956,-10.018],[47.857,-9.6625],[47.8265,-9.5995],[47.7565,-9.5265],[47.6815,-9.4825],[47.597,-9.456],[47.5225,-9.462],[47.452,-9.496],[47.3865,-9.546],[47.338,-9.598],[47.316,-9.6435],[47.3005,-9.72]]],[[[50.519,-9.3165],[50.5305,-9.403],[50.604,-9.623],[50.6475,-9.7255],[50.8305,-10.2325],[50.8715,-10.339],[50.915,-10.3985],[50.987,-10.448],[51.0555,-10.465],[51.159,-10.445],[51.276,-10.377],[51.3245,-10.325],[51.359,-10.2675],[51.391,-10.184],[51.3965,-10.115],[51.332,-9.362],[51.2815,-9.2105],[51.1805,-9.07],[51.1215,-9.0255],[51.055,-9.005],[50.952,-9.018],[50.6515,-9.139],[50.6075,-9.162],[50.5545,-9.2155],[50.519,-9.3165]]],[[[52.5185,-7.038],[52.536,-7.2235],[52.5665,-7.286],[52.616,-7.334],[52.679,-7.363],[52.7545,-7.372],[52.879,-7.328],[52.925,-7.287],[52.9665,-7.2165],[52.9795,-7.1455],[52.966,-6.9855],[52.9445,-6.9195],[52.8735,-6.8435],[52.7525,-6.7955],[52.6805,-6.7975],[52.6135,-6.825],[52.5605,-6.874],[52.5285,-6.939],[52.5185,-7.038]]],[[[52.631,-6.099],[52.646,-6.167],[52.6835,-6.2255],[52.739,-6.268],[52.8465,-6.2895],[52.8685,-6.343],[52.913,-6.3935],[52.971,-6.4265],[53.046,-6.439],[53.125,-6.422],[53.179,-6.386],[53.237,-6.3665],[53.292,-6.3235],[53.3325,-6.2605],[53.3485,-6.1935],[53.3425,-6.122],[53.3115,-6.057],[53.217,-5.965],[53.3125,-5.987],[53.421,-5.953],[53.4725,-5.9065],[53.504,-5.848],[53.5435,-5.8805],[53.6085,-5.9055],[53.7235,-5.895],[53.811,-5.8485],[53.863,-5.7955],[53.898,-5.698],[53.892,-5.629],[53.863,-5.566],[53.807,-5.511],[53.704,-5.4745],[53.625,-5.4845],[53.559,-5.52],[53.5705,-5.4445],[53.546,-5.3455],[53.4795,-5.2635],[53.5235,-5.214],[53.5485,-5.1605],[53.5625,-5.069],[53.5535,-5.022],[53.5785,-4.974],[53.593,-4.884],[53.564,-4.775],[53.519,-4.7215],[53.452,-4.6835],[53.3835,-4.6715],[53.315,-4.684],[53.252,-4.7215],[53.2105,-4.7705],[53.1745,-4.8605],[53.1755,-4.9665],[53.1195,-5.0495],[53.1095,-5.1515],[53.1325,-5.217],[53.164,-5.259],[53.124,-5.3025],[53.093,-5.3735],[53.089,-5.443],[53.1015,-5.4915],[53.069,-5.526],[53.035,-5.597],[53.0215,-5.684],[52.9535,-5.6975],[52.894,-5.734],[52.8505,-5.7885],[52.826,-5.8885],[52.772,-5.897],[52.713,-5.927],[52.6695,-5.9705],[52.64,-6.0295],[52.631,-6.099]]],[[[55.0015,-3.725],[55.0225,-3.815],[55.0595,-3.867],[55.1055,-3.902],[55.1625,-3.923],[55.2555,-3.92],[55.322,-3.889],[55.3605,-3.854],[55.3975,-3.792],[55.41,-3.738],[55.4,-3.654],[55.338,-3.561],[55.299,-3.535],[55.226,-3.513],[55.1705,-3.515],[55.1025,-3.54],[55.057,-3.576],[55.013,-3.649],[55.0015,-3.725]]],[[[55.0055,-4.4875],[55.035,-4.5905],[55.0765,-4.6465],[55.2115,-4.7975],[55.3665,-4.9465],[55.4445,-4.9935],[55.5235,-5.008],[55.586,-5.0005],[55.6745,-4.9525],[55.845,-4.793],[55.9315,-4.803],[56.0185,-4.781],[56.1085,-4.717],[56.151,-4.6205],[56.1495,-4.55],[56.0965,-4.449],[56.124,-4.3615],[56.117,-4.283],[56.0705,-4.1995],[56.005,-4.1365],[55.9355,-4.0935],[55.7375,-4.0215],[55.8115,-3.957],[55.8525,-3.9005],[55.8725,-3.8315],[55.8685,-3.7545],[55.8165,-3.659],[55.7135,-3.602],[55.6325,-3.6005],[55.5255,-3.652],[55.4845,-3.704],[55.459,-3.7995],[55.472,-3.8805],[55.507,-3.943],[55.5945,-4.0205],[55.561,-4.0355],[55.293,-4.1895],[55.2395,-4.1815],[55.171,-4.194],[55.111,-4.229],[55.051,-4.3145],[55.016,-4.4125],[55.0055,-4.4875]]],[[[55.148,-5.851],[55.1795,-5.9505],[55.2355,-6.016],[55.2935,-6.0595],[55.3995,-6.08],[55.4745,-6.0605],[55.529,-6.024],[55.569,-5.972],[55.5895,-5.9095],[55.588,-5.805],[55.5595,-5.734],[55.4915,-5.6525],[55.4295,-5.6205],[55.328,-5.6165],[55.264,-5.643],[55.19,-5.7195],[55.1575,-5.7815],[55.148,-5.851]]],[[[56.035,-7.2065],[56.0505,-7.276],[56.1155,-7.3595],[56.179,-7.3915],[56.28,-7.3955],[56.3765,-7.349],[56.4715,-7.227],[56.498,-7.1285],[56.485,-7.0235],[56.4515,-6.9655],[56.401,-6.9215],[56.3385,-6.8965],[56.2715,-6.8935],[56.1955,-6.9175],[56.136,-6.9635],[56.1005,-7.0185],[56.045,-7.136],[56.035,-7.2065]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/fc/Flag_of_Seychelles.svg","name:en":"Seychelles","wikidata":"Q1042","ISO3166-1:alpha2":"SC","ISO3166-1:alpha3":"SYC","ISO3166-1:numeric":"690"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[101.0395,2.8305],[100.6605,3.003],[100.329,3.3005],[99.919,3.669],[99.6225,3.935],[99.595,3.9525],[99.1885,4.1705],[98.873,4.339],[98.4185,4.5825],[98.07,5.018],[98.0465,5.043],[97.681,5.366],[97.602,5.4195],[97.502,5.451],[96.8565,5.4745],[95.9735,5.6875],[95.4605,6.0525],[95.248,6.2285],[95.188,6.2625],[95.1125,6.2745],[95.0065,6.2445],[94.9325,6.1635],[94.7925,5.881],[94.7715,5.797],[94.789,5.712],[95.017,5.1985],[95.1625,4.836],[95.1845,2.98],[95.208,2.886],[95.265,2.81],[95.7835,2.381],[96.7205,1.4585],[96.868,1.313],[96.8815,1.193],[96.9085,1.112],[97.187,0.6395],[97.6635,-0.1695],[97.691,-0.208],[98.2365,-1.0335],[98.4335,-1.332],[98.706,-1.782],[98.74,-1.824],[98.9355,-2.0075],[99.8445,-2.9645],[100.1765,-3.4245],[100.331,-3.5845],[100.879,-4.1515],[101.927,-5.4825],[102.1085,-5.6545],[102.224,-5.715],[102.388,-5.71],[103.507,-5.5135],[103.8335,-5.4565],[104.2855,-6.022],[104.6515,-6.455],[105.085,-6.968],[105.1535,-7.023],[105.4445,-7.2005],[106.051,-7.4565],[106.3555,-7.5825],[107.8015,-7.9375],[108.2725,-8.015],[108.437,-8.0205],[108.8295,-7.989],[109.401,-7.9775],[109.902,-8.133],[110.3725,-8.2895],[110.6385,-8.3875],[110.8815,-8.441],[111.4725,-8.5665],[111.6955,-8.605],[113.2645,-8.706],[114.4925,-8.9835],[115.0935,-9.047],[115.1915,-9.05],[115.57,-9.0205],[115.959,-9.1165],[116.9755,-9.306],[117.0865,-9.3015],[118.371,-9.106],[118.757,-9.6735],[118.912,-9.8365],[118.951,-9.8675],[119.9925,-10.5045],[120.1025,-10.538],[120.401,-10.52],[121.1905,-11.0135],[121.2875,-11.033],[121.3545,-11.0195],[121.838,-10.84],[122.8055,-11.1965],[122.89,-11.2085],[122.972,-11.186],[123.3205,-11.004],[124.4975,-10.344],[124.604,-10.2815],[124.8905,-10.0265],[125.1595,-9.755],[125.2565,-9.575],[125.24,-9.5645],[125.087,-9.463],[125.0795,-9.3925],[125.0065,-9.295],[124.9825,-9.2395],[124.983,-9.191],[125.014,-9.171],[125.0745,-9.1765],[125.098,-9.2005],[125.176,-9.1725],[125.1715,-9.126],[125.1855,-9.0265],[125.1135,-8.9655],[125.0895,-9.011],[124.9845,-9.066],[124.941,-9.047],[124.9345,-8.995],[124.9525,-8.9665],[124.936,-8.7415],[125.098,-8.519],[125.24,-8.444],[125.3215,-8.2915],[125.34,-8.2325],[125.6725,-8.0895],[125.696,-8.101],[125.8275,-8.251],[126.4595,-8.176],[126.7625,-8.232],[126.7995,-8.2285],[127.189,-8.2235],[127.397,-8.2785],[127.5335,-8.419],[127.6195,-8.436],[128.4885,-8.549],[128.534,-8.5495],[129.822,-8.424],[130.749,-8.5475],[130.8565,-8.5405],[130.985,-8.4815],[131.232,-8.339],[131.429,-8.2045],[131.8615,-7.8095],[131.898,-7.7655],[132.1485,-7.3485],[132.8945,-6.285],[134.0905,-7.121],[134.3985,-7.2755],[134.539,-7.3025],[134.6085,-7.283],[134.7865,-7.1985],[134.869,-7.1095],[134.975,-6.9035],[135.031,-6.696],[135.1095,-6.3705],[135.115,-6.3195],[135.107,-5.979],[135.0415,-5.679],[135.2285,-5.037],[136.1485,-4.872],[136.6765,-5.0885],[137.5745,-5.538],[137.882,-6.0775],[137.9075,-6.1125],[138.1695,-6.402],[137.6605,-7.753],[137.495,-8.1625],[137.4595,-8.4185],[137.5065,-8.577],[137.6595,-8.6435],[138.908,-8.634],[138.967,-8.6245],[139.4115,-8.4855],[140.7165,-9.247],[140.7785,-9.3255],[140.8665,-9.3835],[140.915,-9.3045],[141.0195,-9.1355],[141.0195,-8.4525],[141.0195,-8.0455],[141.0195,-7.415],[141.02,-6.8925],[140.9405,-6.892],[140.871,-6.7945],[140.9005,-6.7565],[140.847,-6.7215],[140.886,-6.605],[140.956,-6.491],[140.943,-6.3735],[140.9605,-6.3335],[141.0,-6.3225],[141.0,-5.2945],[141.001,-4.987],[141.0,-4.5345],[141.0,-3.9315],[141.0045,-3.238],[141.001,-2.9005],[141.003,-2.6815],[141.0,-2.3875],[140.663,-2.2465],[140.244,-2.143],[138.808,-1.3965],[138.7455,-1.3765],[137.97,-1.2605],[136.4715,-0.8855],[135.9705,-0.535],[135.9485,-0.522],[135.4095,-0.2395],[135.1785,0.0895],[134.505,1.0475],[134.4465,1.102],[134.3255,1.137],[134.2425,1.132],[134.1685,1.0935],[133.522,0.5605],[132.9785,0.113],[132.651,-0.1575],[132.4305,-0.143],[132.2715,-0.14],[131.814,0.5955],[131.45,1.18],[131.3745,1.2525],[131.3105,1.2815],[131.24,1.2875],[131.172,1.2685],[131.1155,1.227],[130.656,0.746],[129.64,0.8685],[129.275,0.9125],[128.935,1.628],[128.8985,2.4365],[128.8725,2.5265],[128.7475,2.7445],[128.719,2.7825],[128.418,2.9015],[127.8055,3.4465],[127.093,3.8355],[127.353,4.5595],[127.3625,4.6655],[127.341,4.8055],[127.3065,4.885],[126.7555,5.679],[126.697,5.7355],[126.62,5.7625],[126.532,5.76],[126.4615,5.726],[125.37,4.905],[125.3345,4.8775],[125.269,4.7915],[125.2345,4.7205],[125.118,4.256],[124.9625,2.789],[124.554,1.8575],[124.2285,1.348],[123.1165,1.2485],[122.4605,1.3355],[122.2955,1.3645],[121.4725,1.511],[120.9085,1.5765],[120.822,1.5675],[120.691,1.51],[120.2205,1.234],[119.668,1.5835],[119.175,1.9315],[118.823,2.3515],[118.765,2.5325],[118.265,4.097],[117.9585,4.1905],[117.899,4.166],[117.642,4.1655],[117.5625,4.179],[117.5295,4.1615],[117.4415,4.1935],[117.426,4.233],[117.342,4.291],[117.289,4.316],[117.2425,4.374],[117.1965,4.336],[117.1515,4.354],[117.1055,4.3335],[117.044,4.3465],[116.9735,4.345],[116.899,4.367],[116.84,4.327],[116.782,4.3575],[116.6195,4.336],[116.612,4.3765],[116.536,4.3755],[116.5355,4.323],[116.5025,4.3245],[116.441,4.2885],[116.4325,4.3255],[116.3485,4.3915],[116.2595,4.364],[116.1805,4.3825],[116.162,4.342],[116.1195,4.3385],[116.079,4.2765],[116.039,4.295],[116.006,4.348],[115.929,4.355],[115.878,4.391],[115.864,4.3225],[115.8295,4.241],[115.766,4.2505],[115.731,4.1945],[115.7075,4.1995],[115.6755,4.127],[115.6775,4.0905],[115.65,3.9885],[115.616,3.938],[115.581,3.9415],[115.582,3.888],[115.6185,3.8425],[115.5795,3.7475],[115.5765,3.6095],[115.6145,3.5445],[115.6345,3.4555],[115.574,3.422],[115.538,3.362],[115.516,3.261],[115.525,3.188],[115.564,3.171],[115.514,3.093],[115.5195,3.0585],[115.4835,3.0195],[115.429,3.017],[115.3975,2.979],[115.335,2.9735],[115.2855,3.0495],[115.249,2.9665],[115.2095,2.9555],[115.15,2.909],[115.151,2.872],[115.114,2.8335],[115.1425,2.8025],[115.141,2.7445],[115.093,2.694],[115.1165,2.647],[115.088,2.603],[115.128,2.5825],[115.172,2.6055],[115.2375,2.506],[115.1935,2.4715],[115.1395,2.4775],[115.095,2.411],[115.047,2.408],[115.0215,2.368],[114.9505,2.3515],[114.9485,2.3115],[114.906,2.257],[114.864,2.272],[114.7995,2.2495],[114.78,2.1445],[114.8105,2.1005],[114.792,2.06],[114.8065,2.0245],[114.8565,2.0455],[114.8805,2.0175],[114.8485,1.972],[114.8785,1.9145],[114.815,1.889],[114.786,1.8485],[114.7435,1.8695],[114.6945,1.8105],[114.718,1.728],[114.711,1.6715],[114.649,1.5895],[114.615,1.575],[114.611,1.501],[114.586,1.4465],[114.5265,1.442],[114.416,1.511],[114.2495,1.451],[114.213,1.4105],[114.1425,1.466],[113.9745,1.45],[113.8675,1.3875],[113.8145,1.3665],[113.8295,1.3345],[113.8035,1.3005],[113.7035,1.2655],[113.6645,1.2245],[113.5965,1.264],[113.5745,1.3065],[113.5375,1.3225],[113.4275,1.286],[113.37,1.3235],[113.356,1.357],[113.241,1.3925],[113.183,1.377],[113.1335,1.4015],[113.097,1.443],[113.015,1.405],[112.986,1.4525],[113.0315,1.4915],[113.064,1.5525],[112.9895,1.579],[112.9335,1.5675],[112.8845,1.5865],[112.812,1.5405],[112.7745,1.564],[112.677,1.5545],[112.6575,1.5715],[112.544,1.574],[112.501,1.5835],[112.445,1.5395],[112.2875,1.4735],[112.212,1.4495],[112.2325,1.379],[112.2025,1.314],[112.181,1.306],[112.143,1.135],[112.057,1.1355],[111.9355,1.122],[111.887,1.0785],[111.8595,1.004],[111.818,0.9865],[111.772,1.016],[111.7175,1.007],[111.6675,1.043],[111.596,1.009],[111.551,0.9565],[111.4885,1.0355],[111.445,1.014],[111.385,1.015],[111.2315,1.086],[111.1385,1.0505],[111.0695,1.0495],[110.998,1.0295],[110.907,1.029],[110.8855,0.978],[110.762,0.9235],[110.6975,0.884],[110.5955,0.8575],[110.4905,0.8765],[110.4055,0.953],[110.3965,0.9975],[110.2985,0.9955],[110.2795,1.0525],[110.2105,1.1185],[110.2125,1.151],[110.165,1.196],[110.097,1.199],[110.064,1.263],[109.9795,1.299],[109.9635,1.403],[109.9305,1.425],[109.8375,1.422],[109.838,1.4755],[109.8015,1.4695],[109.7805,1.509],[109.662,1.6175],[109.6675,1.733],[109.6855,1.782],[109.623,1.8035],[109.5865,1.792],[109.576,1.844],[109.5515,1.859],[109.54,1.9265],[109.56,1.971],[109.6205,1.983],[109.645,2.0815],[109.7125,2.3145],[109.328,2.765],[109.0875,3.131],[108.596,4.103],[108.2005,4.8855],[108.1115,4.974],[107.9875,4.992],[107.9265,4.975],[107.8835,4.947],[107.7625,4.846],[107.5785,4.6585],[107.5525,4.625],[107.2955,4.218],[106.1865,3.633],[105.8805,3.5175],[105.842,3.498],[105.4745,3.2595],[105.4105,3.1925],[105.2065,2.8415],[105.1795,2.7485],[105.2,2.6535],[105.3685,2.3105],[104.924,1.3555],[104.6345,1.417],[104.5735,1.4005],[104.5215,1.357],[104.4725,1.2955],[104.416,1.256],[104.376,1.252],[104.3155,1.2835],[104.189,1.2725],[104.125,1.276],[104.0335,1.2695],[103.805,1.1715],[103.7405,1.1305],[103.6585,1.185],[103.5665,1.1955],[103.433,1.2365],[103.065,1.325],[102.5835,1.6865],[102.2235,1.92],[101.775,2.2565],[101.2015,2.6915],[101.0395,2.8305]],[[124.273,-9.419],[124.218,-9.3665],[124.133,-9.4255],[124.1005,-9.41],[124.0415,-9.34],[124.048,-9.231],[124.155,-9.178],[124.3295,-9.117],[124.433,-9.113],[124.475,-9.1655],[124.462,-9.2995],[124.404,-9.34],[124.3515,-9.426],[124.3415,-9.4825],[124.2775,-9.5025],[124.273,-9.419]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9f/Flag_of_Indonesia.svg","name:en":"Indonesia","wikidata":"Q252","ISO3166-1:alpha2":"ID","ISO3166-1:alpha3":"IDN","ISO3166-1:numeric":"360"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[7.533,43.537],[7.4525,43.742],[7.4185,43.725],[7.5,43.5165],[7.533,43.537]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/e/ea/Flag_of_Monaco.svg","name:en":"Monaco","wikidata":"Q235","ISO3166-1:alpha2":"MC","ISO3166-1:alpha3":"MCO","ISO3166-1:numeric":"492"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-173.009,-13.5235],[-172.9945,-13.5905],[-172.937,-13.681],[-172.827,-13.7735],[-172.7355,-13.8935],[-172.6595,-13.9635],[-172.606,-13.99],[-172.5315,-14.0035],[-172.3525,-13.9795],[-172.2705,-14.003],[-172.206,-14.04],[-172.038,-14.1675],[-171.9775,-14.1965],[-171.8875,-14.205],[-171.785,-14.244],[-171.6865,-14.2485],[-171.519,-14.2455],[-171.458,-14.271],[-171.3975,-14.277],[-171.327,-14.262],[-171.265,-14.2225],[-171.22,-14.163],[-171.1945,-14.043],[-171.208,-13.937],[-171.2445,-13.879],[-171.319,-13.814],[-171.4875,-13.701],[-171.534,-13.6815],[-171.6285,-13.6635],[-171.7545,-13.6065],[-171.819,-13.5925],[-171.9785,-13.61],[-172.0395,-13.4685],[-172.1505,-13.3285],[-172.2475,-13.2605],[-172.3435,-13.238],[-172.525,-13.265],[-172.6875,-13.301],[-172.763,-13.289],[-172.815,-13.294],[-172.898,-13.3255],[-172.947,-13.3685],[-173.0,-13.4555],[-173.009,-13.5235]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/31/Flag_of_Samoa.svg","name:en":"Samoa","wikidata":"Q683","ISO3166-1:alpha2":"WS","ISO3166-1:alpha3":"WSM","ISO3166-1:numeric":"882"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[72.3555,6.2185],[72.3695,6.066],[72.4585,5.086],[72.499,4.6385],[72.5355,4.2395],[72.503,4.0335],[72.497,3.786],[72.499,3.5975],[72.5345,3.3725],[72.59,2.9835],[72.6235,2.7635],[72.6665,2.54],[72.686,2.3965],[72.716,1.884],[72.7475,1.34],[72.7905,0.626],[72.7865,0.487],[72.804,0.373],[72.8365,-0.0645],[72.877,-0.6075],[72.8965,-0.681],[72.956,-0.795],[72.998,-0.842],[73.061,-0.8855],[73.1285,-0.906],[73.214,-0.9015],[73.286,-0.868],[73.387,-0.7705],[73.612,-0.415],[73.6395,-0.346],[73.7065,-0.004],[73.7605,0.2355],[73.788,0.431],[73.787,1.3855],[73.786,2.1205],[73.8545,2.6485],[73.935,3.191],[73.97,3.467],[73.95,3.782],[73.9225,4.4675],[73.879,5.0915],[73.8585,5.382],[73.821,5.4855],[73.653,6.119],[73.52,6.621],[73.412,7.0215],[73.3865,7.074],[73.2965,7.1515],[72.987,7.2925],[72.897,7.3105],[72.792,7.29],[72.7265,7.2645],[72.645,7.202],[72.6025,7.121],[72.5115,6.8075],[72.3625,6.2925],[72.3555,6.2185]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/0f/Flag_of_Maldives.svg","name:en":"Maldives","wikidata":"Q826","ISO3166-1:alpha2":"MV","ISO3166-1:alpha3":"MDV","ISO3166-1:numeric":"462"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[140.915,-9.3045],[140.9985,-9.387],[141.0755,-9.426],[141.1175,-9.4345],[141.241,-9.426],[141.343,-9.3835],[141.3945,-9.3515],[141.4465,-9.381],[141.593,-9.41],[141.662,-9.41],[141.7805,-9.3875],[141.8115,-9.396],[141.9825,-9.4025],[142.0595,-9.457],[142.0595,-9.261],[142.1435,-9.196],[142.2365,-9.1915],[142.275,-9.23],[142.346,-9.266],[142.4955,-9.366],[142.559,-9.3745],[142.5925,-9.3555],[142.8065,-9.3225],[142.8435,-9.349],[142.851,-9.3915],[142.851,-9.4695],[142.94,-9.3985],[143.039,-9.3415],[143.0845,-9.3025],[143.1985,-9.344],[143.2555,-9.348],[143.324,-9.334],[143.392,-9.2955],[143.442,-9.234],[143.5245,-9.2065],[143.5635,-9.1815],[143.6205,-9.1115],[143.6455,-9.048],[143.6525,-8.9795],[143.6365,-8.9015],[143.6985,-8.888],[143.757,-8.854],[143.797,-8.813],[143.8315,-8.7405],[143.9015,-8.717],[143.9715,-8.6585],[144.0035,-8.605],[144.0205,-8.538],[144.0095,-8.445],[143.981,-8.385],[143.8935,-8.291],[143.9085,-8.241],[143.989,-8.2035],[144.067,-8.135],[144.106,-8.073],[144.123,-7.997],[144.265,-8.0015],[144.3565,-7.9665],[144.489,-8.0055],[144.5915,-7.9895],[144.6475,-7.956],[144.697,-7.8935],[144.7615,-7.9475],[144.849,-7.9805],[144.899,-8.015],[144.99,-8.0425],[145.104,-8.0425],[145.163,-8.061],[145.239,-8.06],[145.307,-8.1215],[145.394,-8.15],[145.5745,-8.141],[145.669,-8.1575],[145.7315,-8.2075],[145.792,-8.2315],[145.9125,-8.2485],[145.9545,-8.311],[146.0235,-8.3825],[146.066,-8.406],[146.0885,-8.499],[146.175,-8.653],[146.24,-8.732],[146.305,-8.7755],[146.3165,-8.8375],[146.3745,-9.0085],[146.4235,-9.1075],[146.512,-9.19],[146.59,-9.2255],[146.6695,-9.2415],[146.6985,-9.3445],[146.682,-9.3945],[146.6845,-9.4715],[146.717,-9.544],[146.782,-9.6025],[146.8735,-9.6285],[146.911,-9.67],[146.982,-9.71],[147.0485,-9.724],[147.132,-9.713],[147.2045,-9.737],[147.253,-9.807],[147.305,-9.8605],[147.321,-9.938],[147.3565,-9.997],[147.4605,-10.113],[147.5295,-10.1645],[147.591,-10.2545],[147.6515,-10.291],[147.7245,-10.305],[147.826,-10.3005],[147.9,-10.35],[147.9685,-10.3635],[148.0695,-10.4245],[148.1385,-10.4305],[148.2175,-10.4075],[148.277,-10.371],[148.341,-10.4],[148.411,-10.4085],[148.571,-10.3895],[148.723,-10.436],[148.7655,-10.4785],[148.8245,-10.5085],[148.886,-10.518],[148.958,-10.506],[149.057,-10.468],[149.0955,-10.4435],[149.1635,-10.466],[149.201,-10.5305],[149.2385,-10.567],[149.3065,-10.601],[149.3815,-10.6075],[149.5,-10.5915],[149.5705,-10.607],[149.632,-10.6],[149.675,-10.664],[149.7785,-10.7455],[150.0395,-10.8595],[150.092,-10.872],[150.138,-10.9055],[150.2215,-10.928],[150.307,-10.9645],[150.3745,-10.972],[150.702,-11.107],[151.0365,-11.281],[151.1755,-11.3405],[151.2565,-11.357],[151.6545,-11.355],[151.7845,-11.375],[151.9295,-11.379],[151.9885,-11.397],[152.087,-11.457],[152.15,-11.463],[152.2275,-11.4995],[152.2925,-11.507],[152.379,-11.492],[153.213,-11.699],[153.247,-11.727],[153.373,-11.7725],[153.4115,-11.809],[153.485,-11.845],[153.597,-11.8515],[153.82,-11.821],[154.441,-11.647],[154.5265,-11.6075],[154.59,-11.5215],[154.6035,-11.4545],[154.592,-11.381],[154.529,-11.291],[154.3425,-11.1395],[154.2865,-11.1065],[153.116,-10.638],[153.046,-10.559],[152.7535,-9.7185],[153.721,-9.502],[153.7865,-9.479],[153.865,-9.4065],[153.896,-9.3335],[153.9005,-9.2915],[153.8815,-9.2035],[153.8045,-9.1065],[153.7465,-9.072],[153.673,-9.057],[153.537,-9.0655],[152.8605,-8.8175],[152.826,-8.808],[152.495,-8.749],[151.988,-8.6085],[151.764,-8.515],[151.1865,-8.212],[150.9465,-8.1525],[150.819,-8.116],[150.7575,-8.126],[150.5725,-8.126],[150.413,-8.1425],[150.233,-8.144],[150.1445,-8.104],[150.07,-8.105],[150.001,-8.1325],[149.2525,-8.738],[148.317,-7.9485],[148.1325,-6.873],[148.61,-6.607],[149.0125,-6.382],[149.0685,-6.3845],[149.129,-6.3685],[149.2525,-6.2925],[149.305,-6.278],[149.31,-6.389],[149.3425,-6.449],[149.393,-6.4945],[149.456,-6.521],[149.5245,-6.5245],[149.6135,-6.492],[149.6795,-6.493],[149.7995,-6.521],[149.9,-6.523],[150.13,-6.506],[150.191,-6.478],[150.2935,-6.5035],[150.3475,-6.5015],[150.4675,-6.4655],[150.5415,-6.46],[150.64,-6.4015],[150.674,-6.35],[150.72,-6.3325],[150.832,-6.3195],[150.888,-6.293],[150.9275,-6.256],[150.9955,-6.234],[151.05,-6.2305],[151.1365,-6.194],[151.1805,-6.1615],[151.24,-6.1505],[151.304,-6.119],[151.3765,-6.0455],[151.4925,-5.9715],[151.57,-5.8765],[151.617,-5.8515],[151.6885,-5.769],[151.81,-5.7885],[151.881,-5.777],[152.071,-5.6855],[152.1135,-5.6485],[152.193,-5.618],[152.879,-5.177],[153.021,-5.086],[153.9125,-5.232],[154.334,-5.3015],[154.3395,-5.353],[154.372,-5.423],[154.399,-5.5315],[154.4045,-5.609],[154.3795,-5.6545],[154.366,-5.7225],[154.377,-5.7925],[154.427,-5.872],[154.534,-5.9315],[154.574,-6.046],[154.6785,-6.169],[154.767,-6.2225],[154.789,-6.2875],[154.858,-6.361],[154.9765,-6.613],[155.0025,-6.6535],[155.2975,-7.0175],[155.336,-7.0975],[155.594,-6.926],[155.6935,-6.926],[155.923,-6.847],[156.0395,-6.6585],[156.036,-6.55],[156.174,-6.445],[156.163,-6.381],[156.136,-6.321],[156.101,-6.281],[156.0435,-6.246],[156.016,-6.188],[155.98,-6.1485],[155.866,-6.078],[155.7845,-6.0125],[155.6845,-5.9495],[155.42,-5.061],[155.4745,-5.059],[155.54,-5.034],[155.622,-4.96],[155.673,-4.847],[155.664,-4.7135],[155.603,-4.5955],[155.531,-4.516],[155.4405,-4.4685],[155.317,-4.4565],[155.2465,-4.4765],[154.866,-3.197],[154.853,-3.1635],[154.7805,-3.084],[154.5465,-2.936],[154.4885,-2.9115],[154.394,-2.911],[153.912,-3.026],[153.387,-3.151],[152.794,-2.62],[152.711,-2.5755],[152.082,-2.412],[150.7875,-1.482],[150.728,-1.453],[150.662,-1.445],[150.0905,-1.472],[149.861,-1.2995],[149.8215,-1.2455],[149.7475,-1.188],[149.64,-1.129],[149.571,-1.115],[149.4675,-1.131],[148.5305,-1.5465],[147.998,-1.782],[147.886,-1.801],[147.658,-1.8565],[147.3705,-1.763],[147.2425,-1.7555],[147.1315,-1.74],[147.0395,-1.738],[146.8745,-1.7055],[146.667,-1.7055],[145.707,-0.733],[145.646,-0.6905],[145.3835,-0.574],[145.2875,-0.5575],[145.224,-0.573],[144.4825,-0.8935],[144.4035,-0.875],[144.3415,-0.8825],[143.5225,-1.1165],[142.983,-1.266],[142.9015,-1.32],[142.8625,-1.3825],[142.8345,-1.51],[142.781,-1.511],[142.714,-1.536],[142.6595,-1.583],[142.6255,-1.647],[142.6155,-1.7185],[142.6415,-1.8285],[142.698,-1.9115],[142.7515,-1.9445],[142.6425,-2.515],[142.3705,-2.917],[142.3395,-2.923],[142.255,-2.898],[142.187,-2.8455],[142.0865,-2.7865],[142.0215,-2.765],[141.954,-2.7625],[141.8985,-2.7285],[141.8385,-2.7105],[141.52,-2.5515],[141.4575,-2.535],[141.3665,-2.4755],[141.2405,-2.434],[141.169,-2.4285],[141.0,-2.3875],[141.003,-2.6815],[141.001,-2.9005],[141.0045,-3.238],[141.0,-3.9315],[141.0,-4.5345],[141.001,-4.987],[141.0,-5.2945],[141.0,-6.3225],[140.9605,-6.3335],[140.943,-6.3735],[140.956,-6.491],[140.886,-6.605],[140.847,-6.7215],[140.9005,-6.7565],[140.871,-6.7945],[140.9405,-6.892],[141.02,-6.8925],[141.0195,-7.415],[141.0195,-8.0455],[141.0195,-8.4525],[141.0195,-9.1355],[140.915,-9.3045]]],[[[156.7155,-4.7585],[156.7205,-4.8005],[156.7585,-4.893],[156.839,-4.9695],[156.935,-4.997],[157.031,-4.9965],[157.113,-4.9685],[157.2015,-4.893],[157.234,-4.8205],[157.235,-4.715],[157.197,-4.621],[157.1445,-4.5635],[157.0405,-4.5045],[156.9965,-4.495],[156.8965,-4.498],[156.802,-4.5455],[156.745,-4.628],[156.7225,-4.689],[156.7155,-4.7585]]],[[[159.1195,-4.557],[159.1505,-4.653],[159.2095,-4.7295],[159.27,-4.771],[159.412,-4.8045],[159.5205,-4.7925],[159.607,-4.744],[159.6565,-4.694],[159.692,-4.6015],[159.686,-4.5235],[159.647,-4.4225],[159.6025,-4.3645],[159.498,-4.2735],[159.388,-4.244],[159.3135,-4.26],[159.2115,-4.33],[159.1615,-4.3835],[159.1345,-4.445],[159.1195,-4.557]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/e/e3/Flag_of_Papua_New_Guinea.svg","name:en":"Papua New Guinea","wikidata":"Q691","ISO3166-1:alpha2":"PG","ISO3166-1:alpha3":"PNG","ISO3166-1:numeric":"598"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[155.336,-7.0975],[155.3255,-7.1045],[155.319,-7.393],[155.347,-7.508],[155.418,-7.6035],[156.3845,-8.457],[156.4265,-8.4855],[157.242,-8.8985],[157.3365,-8.933],[157.5825,-8.9915],[157.7765,-9.012],[158.6735,-9.4405],[159.6,-9.8825],[159.724,-9.973],[159.7895,-9.994],[159.988,-10.0225],[160.841,-10.4665],[161.4025,-10.7585],[161.513,-10.84],[161.675,-10.937],[161.811,-10.9845],[162.4115,-11.1005],[162.4905,-11.1],[162.5415,-11.0865],[162.603,-11.049],[162.647,-10.9925],[162.668,-10.9245],[162.6775,-10.8225],[162.661,-10.7535],[162.3615,-10.067],[162.1775,-9.644],[162.1325,-9.5745],[161.1805,-8.5125],[160.817,-7.784],[160.778,-7.73],[160.7235,-7.692],[160.6325,-7.668],[160.377,-7.65],[159.048,-7.558],[158.9305,-7.4385],[158.7965,-7.3325],[158.7045,-7.284],[158.1505,-7.1185],[157.932,-7.0155],[156.74,-6.454],[156.6,-6.4025],[156.5005,-6.381],[156.434,-6.3795],[156.2195,-6.41],[156.174,-6.445],[156.036,-6.55],[156.0395,-6.6585],[155.923,-6.847],[155.6935,-6.926],[155.594,-6.926],[155.336,-7.0975]]],[[[158.981,-5.374],[158.9905,-5.4455],[159.0275,-5.5165],[159.0725,-5.5665],[159.1805,-5.652],[159.2455,-5.6755],[159.538,-5.726],[159.6875,-5.7265],[159.759,-5.7085],[159.8195,-5.6655],[159.8825,-5.5955],[159.911,-5.5335],[159.9165,-5.4655],[159.908,-5.368],[159.892,-5.3035],[159.8555,-5.2485],[159.532,-4.8985],[159.4765,-4.856],[159.357,-4.816],[159.2655,-4.8155],[159.143,-4.875],[159.091,-4.9365],[159.0395,-5.0305],[159.0165,-5.098],[158.9825,-5.329],[158.981,-5.374]]],[[[159.098,-6.2285],[159.123,-6.336],[159.175,-6.4065],[159.208,-6.4325],[159.31,-6.4735],[159.381,-6.4735],[159.463,-6.4405],[159.551,-6.359],[159.581,-6.2965],[159.594,-6.203],[159.581,-6.1245],[159.538,-6.039],[159.4915,-5.9965],[159.4305,-5.969],[159.356,-5.96],[159.285,-5.9755],[159.1985,-6.0225],[159.139,-6.085],[159.1045,-6.166],[159.098,-6.2285]]],[[[159.5455,-11.2525],[159.5525,-11.323],[159.855,-12.372],[159.8805,-12.427],[160.1215,-12.7865],[160.388,-13.1235],[160.498,-13.216],[160.5695,-13.2405],[160.645,-13.2375],[160.714,-13.2085],[160.8065,-13.1215],[160.836,-13.0655],[160.8465,-13.0035],[160.8555,-11.855],[160.8445,-11.7885],[160.7885,-11.7045],[160.6045,-11.5435],[159.923,-11.1155],[159.8515,-11.084],[159.735,-11.068],[159.665,-11.085],[159.6055,-11.125],[159.564,-11.1835],[159.5455,-11.2525]]],[[[162.6635,-8.4175],[162.688,-8.5225],[162.731,-8.577],[162.79,-8.613],[162.871,-8.628],[163.0245,-8.604],[163.0785,-8.5695],[163.132,-8.498],[163.152,-8.3885],[163.134,-8.3205],[163.095,-8.265],[163.045,-8.227],[162.947,-8.1835],[162.863,-8.1735],[162.7915,-8.192],[162.7495,-8.2175],[162.697,-8.278],[162.6675,-8.3525],[162.6635,-8.4175]]],[[[165.492,-10.109],[165.544,-10.7975],[165.553,-10.8735],[165.5775,-10.934],[165.62,-10.984],[166.7005,-11.8855],[166.7895,-11.9325],[166.8695,-11.9485],[166.954,-11.946],[167.0675,-11.9155],[167.163,-11.858],[167.2095,-11.8],[167.231,-11.729],[167.223,-11.5855],[167.204,-11.5145],[166.561,-10.1725],[166.523,-10.1185],[166.442,-10.036],[166.377,-9.9915],[166.1265,-9.884],[166.0685,-9.8685],[165.7375,-9.832],[165.66,-9.838],[165.582,-9.877],[165.516,-9.964],[165.492,-10.109]]],[[[166.858,-9.7725],[166.892,-9.868],[166.9485,-9.947],[167.027,-10.0305],[167.082,-10.072],[167.2195,-10.129],[167.288,-10.1265],[167.352,-10.1015],[167.404,-10.0565],[167.4375,-9.997],[167.4465,-9.8845],[167.425,-9.8225],[167.3845,-9.7705],[167.2235,-9.6255],[167.1705,-9.5855],[167.103,-9.5595],[167.0345,-9.5565],[166.969,-9.5765],[166.914,-9.6165],[166.8755,-9.6725],[166.858,-9.7725]]],[[[168.607,-12.3035],[168.6255,-12.3885],[168.6995,-12.474],[168.7695,-12.503],[168.881,-12.4995],[168.9625,-12.4625],[169.015,-12.411],[169.045,-12.344],[169.044,-12.2435],[169.012,-12.1755],[168.929,-12.1045],[168.837,-12.0825],[168.767,-12.092],[168.7035,-12.125],[168.631,-12.209],[168.607,-12.3035]]],[[[169.6445,-11.6295],[169.676,-11.7205],[169.726,-11.774],[169.796,-11.8075],[169.894,-11.8105],[169.956,-11.7865],[170.0265,-11.7175],[170.0515,-11.658],[170.051,-11.564],[170.0065,-11.477],[169.956,-11.435],[169.8905,-11.41],[169.82,-11.4085],[169.751,-11.4315],[169.6975,-11.474],[169.6655,-11.5205],[169.6445,-11.6295]]],[[[169.9825,-11.9235],[170.016,-12.0195],[170.07,-12.0765],[170.1235,-12.104],[170.2085,-12.1145],[170.2795,-12.0955],[170.3365,-12.0555],[170.3735,-12.005],[170.394,-11.9425],[170.381,-11.8345],[170.3355,-11.765],[170.286,-11.7285],[170.2195,-11.706],[170.149,-11.7075],[170.063,-11.7455],[170.0185,-11.7915],[169.99,-11.8495],[169.9825,-11.9235]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/7/74/Flag_of_the_Solomon_Islands.svg","name:en":"Solomon Islands","wikidata":"Q685","ISO3166-1:alpha2":"SB","ISO3166-1:alpha3":"SLB","ISO3166-1:numeric":"090"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[51.829,24.716],[51.827,24.8015],[51.802,24.854],[51.857,24.9565],[51.8735,25.024],[51.864,25.093],[51.839,25.1395],[51.8665,25.282],[51.864,25.329],[51.8305,25.4075],[51.7875,25.4515],[51.7475,25.536],[51.7785,25.585],[51.815,25.6995],[51.8105,25.85],[51.827,25.909],[51.8195,25.9785],[51.756,26.0735],[51.6895,26.113],[51.577,26.142],[51.5385,26.22],[51.4905,26.264],[51.388,26.335],[51.2975,26.374],[51.183,26.3815],[51.1055,26.3585],[51.044,26.313],[51.0115,26.267],[50.9195,26.2145],[50.9075,26.077],[50.85,26.011],[50.816,25.895],[50.868,25.7495],[50.8395,25.6385],[50.7985,25.6225],[50.7695,25.547],[50.7345,25.5725],[50.58,25.586],[50.5675,25.576],[50.573,25.5415],[50.615,25.4785],[50.647,25.3205],[50.647,25.256],[50.666,25.1375],[50.7135,25.0425],[50.706,24.923],[50.794,24.8775],[50.8115,24.7445],[50.9285,24.547],[50.9945,24.504],[51.0985,24.471],[51.266,24.5055],[51.302,24.5045],[51.376,24.5785],[51.391,24.6235],[51.586,24.664],[51.829,24.716]]],[[[52.45,24.983],[52.448,25.0855],[52.3845,25.1795],[52.315,25.219],[52.23,25.234],[52.119,25.208],[52.0535,25.1575],[52.017,25.0955],[52.009,25.0015],[52.0315,24.9395],[52.097,24.87],[52.1645,24.8385],[52.2645,24.8315],[52.3475,24.874],[52.3785,24.9005],[52.334,24.967],[52.346,24.9975],[52.3965,25.0195],[52.45,24.983]]],[[[52.1825,25.676],[52.206,25.5815],[52.2475,25.5275],[52.3055,25.489],[52.385,25.468],[52.4625,25.472],[52.5265,25.496],[52.612,25.5775],[52.6345,25.639],[52.6315,25.7245],[52.605,25.7825],[52.5505,25.839],[52.4785,25.8735],[52.403,25.8825],[52.296,25.8535],[52.213,25.7765],[52.1825,25.676]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/65/Flag_of_Qatar.svg","name:en":"Qatar","wikidata":"Q846","ISO3166-1:alpha2":"QA","ISO3166-1:alpha3":"QAT","ISO3166-1:numeric":"634"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[3.6095,11.6935],[3.5765,11.6685],[3.525,11.575],[3.4765,11.438],[3.6935,11.129],[3.7225,11.1285],[3.725,11.0275],[3.751,11.013],[3.7695,10.924],[3.7455,10.817],[3.78,10.736],[3.835,10.696],[3.845,10.5945],[3.8055,10.514],[3.8055,10.4505],[3.785,10.4075],[3.6835,10.4615],[3.602,10.4125],[3.604,10.344],[3.5765,10.2725],[3.608,10.2115],[3.6795,10.177],[3.659,10.109],[3.617,10.084],[3.598,9.957],[3.5635,9.901],[3.515,9.8605],[3.4625,9.8705],[3.3625,9.835],[3.332,9.8055],[3.325,9.761],[3.361,9.708],[3.314,9.6595],[3.267,9.659],[3.252,9.6065],[3.1885,9.5115],[3.1615,9.4975],[3.133,9.441],[3.1555,9.3605],[3.158,9.284],[3.123,9.2325],[3.122,9.1925],[3.0885,9.102],[2.9725,9.075],[2.953,9.0925],[2.8795,9.0645],[2.783,9.0695],[2.7905,8.9895],[2.7595,8.8445],[2.731,8.787],[2.749,8.7405],[2.739,8.683],[2.7555,8.654],[2.7495,8.4485],[2.7085,8.4225],[2.7195,8.3875],[2.696,8.3545],[2.7205,8.25],[2.754,8.2125],[2.733,8.0815],[2.6995,7.9325],[2.6785,7.8745],[2.7255,7.8025],[2.729,7.7555],[2.7165,7.6365],[2.735,7.55],[2.7925,7.4975],[2.794,7.4295],[2.745,7.4245],[2.745,7.2815],[2.7575,7.2515],[2.773,7.133],[2.7405,7.105],[2.7615,7.0435],[2.729,7.017],[2.7125,6.9515],[2.7415,6.9275],[2.7345,6.785],[2.7845,6.764],[2.784,6.699],[2.7295,6.637],[2.748,6.568],[2.706,6.52],[2.7065,6.3775],[2.738,6.178],[2.904,6.196],[3.1915,6.2045],[3.3905,6.194],[3.5005,6.2225],[3.7175,6.228],[3.8155,6.2395],[3.8955,6.238],[4.3425,6.167],[4.413,6.1355],[4.486,6.082],[4.639,5.956],[4.816,5.7765],[4.9575,5.535],[4.9655,5.4815],[5.002,5.411],[5.053,5.344],[5.132,5.2745],[5.1505,5.2085],[5.1615,5.101],[5.235,4.9555],[5.27,4.823],[5.364,4.641],[5.474,4.4805],[5.5565,4.3775],[5.733,4.235],[5.8295,4.1775],[5.8755,4.139],[6.0675,4.07],[6.231,4.0775],[6.2925,4.0915],[6.471,4.1035],[6.539,4.124],[6.6225,4.118],[6.725,4.141],[6.895,4.1605],[6.95,4.176],[7.026,4.177],[7.0775,4.194],[7.1715,4.179],[7.2755,4.1905],[7.4095,4.235],[7.519,4.2515],[7.6415,4.2595],[7.7265,4.3015],[7.9455,4.3355],[8.089,4.345],[8.1865,4.3445],[8.256,4.334],[8.336,4.3435],[8.388,4.3675],[8.403,4.442],[8.4075,4.5335],[8.4525,4.6165],[8.539,4.702],[8.526,4.737],[8.544,4.8015],[8.6255,4.821],[8.607,4.8645],[8.6205,4.9055],[8.653,4.9175],[8.6955,5.013],[8.724,5.041],[8.745,5.098],[8.7835,5.113],[8.821,5.1845],[8.8145,5.284],[8.8415,5.3915],[8.8335,5.4305],[8.9215,5.564],[8.904,5.619],[8.842,5.6795],[8.884,5.775],[8.8505,5.805],[8.8605,5.845],[9.0545,6.0005],[9.1535,6.094],[9.169,6.1335],[9.2115,6.1685],[9.2645,6.1815],[9.307,6.263],[9.3345,6.292],[9.347,6.3535],[9.431,6.3155],[9.4675,6.456],[9.529,6.4425],[9.587,6.4735],[9.5955,6.5285],[9.706,6.512],[9.751,6.6525],[9.774,6.7845],[9.863,6.776],[9.996,6.898],[10.0125,6.904],[10.1505,7.0385],[10.181,6.968],[10.172,6.942],[10.2155,6.8895],[10.462,6.916],[10.4815,6.9015],[10.5415,6.9395],[10.56,7.032],[10.5715,7.162],[10.595,7.1475],[10.5955,7.0785],[10.6265,7.049],[10.6795,7.0385],[10.7205,6.9885],[10.7665,6.9555],[10.7985,6.9625],[10.8415,6.9305],[10.8145,6.8535],[10.8395,6.811],[10.914,6.7575],[10.916,6.7095],[10.9455,6.687],[10.9925,6.687],[11.0305,6.7145],[11.0965,6.6795],[11.097,6.5205],[11.167,6.5],[11.222,6.5395],[11.28,6.538],[11.316,6.5065],[11.422,6.532],[11.4275,6.579],[11.462,6.611],[11.5175,6.613],[11.5465,6.701],[11.585,6.7375],[11.5695,6.773],[11.5795,6.8415],[11.573,6.8995],[11.6035,6.909],[11.631,6.9895],[11.7375,7.05],[11.779,7.046],[11.8025,7.0825],[11.863,7.0775],[11.8805,7.108],[11.8565,7.1685],[11.847,7.2545],[11.879,7.3475],[11.928,7.394],[11.9315,7.4865],[12.019,7.5185],[12.005,7.5805],[12.0115,7.6305],[11.9965,7.667],[12.0525,7.7355],[12.098,7.8475],[12.136,7.862],[12.214,7.9835],[12.201,8.009],[12.1925,8.108],[12.256,8.1765],[12.249,8.216],[12.244,8.3865],[12.2675,8.448],[12.3135,8.4255],[12.342,8.4585],[12.4615,8.537],[12.4465,8.6025],[12.4875,8.643],[12.575,8.614],[12.6985,8.669],[12.7205,8.763],[12.784,8.7455],[12.819,8.8305],[12.8,8.8565],[12.823,8.9715],[12.901,9.114],[12.888,9.1775],[12.9175,9.2485],[12.9025,9.3545],[12.8785,9.394],[12.9455,9.422],[12.9755,9.4645],[13.0345,9.506],[13.1245,9.5265],[13.2095,9.557],[13.234,9.614],[13.2625,9.78],[13.302,9.827],[13.249,9.8575],[13.237,9.911],[13.265,9.927],[13.288,9.9795],[13.2475,10.0055],[13.2865,10.046],[13.299,10.087],[13.3395,10.114],[13.412,10.1215],[13.47,10.161],[13.4835,10.196],[13.466,10.246],[13.5015,10.3375],[13.5005,10.3905],[13.535,10.4],[13.531,10.4575],[13.5785,10.537],[13.547,10.6125],[13.5745,10.635],[13.5885,10.698],[13.6265,10.7115],[13.6505,10.813],[13.717,10.863],[13.73,10.924],[13.7115,10.9635],[13.7355,11.006],[13.7895,11.003],[13.815,11.0645],[13.856,11.0955],[13.9345,11.2065],[13.976,11.311],[14.1785,11.24],[14.239,11.296],[14.3645,11.3595],[14.4325,11.4225],[14.4715,11.428],[14.5175,11.468],[14.618,11.51],[14.647,11.572],[14.644,11.65],[14.6,11.698],[14.5555,11.7055],[14.6065,11.799],[14.6045,11.8695],[14.643,11.912],[14.6445,11.9725],[14.624,12.0495],[14.656,12.1385],[14.659,12.198],[14.6175,12.186],[14.591,12.2295],[14.5255,12.2915],[14.4825,12.3525],[14.439,12.3675],[14.3765,12.3595],[14.334,12.3735],[14.2225,12.362],[14.1895,12.405],[14.1775,12.481],[14.2035,12.538],[14.0835,13.0835],[13.6335,13.708],[13.363,13.708],[13.313,13.6975],[13.2055,13.5415],[13.1195,13.5225],[13.0305,13.531],[12.9695,13.519],[12.917,13.487],[12.8715,13.501],[12.851,13.4445],[12.7625,13.3875],[12.6775,13.2815],[12.644,13.293],[12.5765,13.2715],[12.5535,13.2275],[12.5505,13.1595],[12.514,13.1535],[12.469,13.0675],[12.3215,13.085],[12.257,13.118],[12.1865,13.124],[12.1645,13.0985],[12.0385,13.141],[12.009,13.172],[11.883,13.256],[11.6785,13.299],[11.5905,13.3465],[11.459,13.3805],[11.279,13.379],[10.656,13.3605],[10.4655,13.2875],[10.3365,13.275],[10.204,13.2705],[10.0115,13.1825],[9.919,13.095],[9.889,13.052],[9.841,13.0265],[9.7965,12.9555],[9.6585,12.8075],[9.3865,12.823],[9.331,12.811],[9.182,12.8345],[8.978,12.8335],[8.8115,12.8895],[8.703,12.919],[8.646,12.9435],[8.597,13.0235],[8.502,13.074],[8.416,13.057],[8.2495,13.214],[8.1915,13.2315],[8.1515,13.2735],[8.069,13.314],[7.816,13.3425],[7.7025,13.277],[7.661,13.244],[7.4395,13.115],[7.389,13.0985],[7.2215,13.129],[7.1215,13.0205],[7.053,13.0],[6.942,13.0035],[6.82,13.1435],[6.6965,13.3395],[6.428,13.6005],[6.2775,13.6765],[6.2325,13.6735],[6.1555,13.645],[6.091,13.677],[5.832,13.7615],[5.631,13.8365],[5.53,13.8855],[5.4515,13.871],[5.3505,13.8345],[5.281,13.7555],[5.2055,13.736],[5.077,13.751],[5.0045,13.7355],[4.9095,13.7455],[4.874,13.781],[4.8395,13.768],[4.4655,13.6815],[4.2345,13.478],[4.1415,13.478],[4.1475,13.2925],[4.142,13.162],[4.1035,12.9875],[4.054,12.9],[3.9835,12.8175],[3.942,12.7465],[3.774,12.626],[3.6535,12.5225],[3.6505,12.402],[3.6665,12.259],[3.647,12.2125],[3.6315,12.1195],[3.6715,12.032],[3.6785,11.9765],[3.62,11.9205],[3.6295,11.831],[3.669,11.8105],[3.681,11.7545],[3.6095,11.6935]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/7/79/Flag_of_Nigeria.svg","name:en":"Nigeria","wikidata":"Q1033","ISO3166-1:alpha2":"NG","ISO3166-1:alpha3":"NGA","ISO3166-1:numeric":"566"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-61.1305,13.58],[-61.248,13.57],[-61.3365,13.522],[-61.3755,13.479],[-61.449,13.367],[-61.4755,13.295],[-61.484,13.223],[-61.477,13.151],[-61.458,13.104],[-61.485,13.05],[-61.4945,12.988],[-61.471,12.886],[-61.515,12.83],[-61.6085,12.741],[-61.6415,12.69],[-61.6655,12.5965],[-61.3825,12.53],[-61.173,12.5165],[-61.143,12.6],[-61.063,12.665],[-60.9545,12.83],[-60.9215,12.938],[-60.928,13.02],[-60.955,13.076],[-60.9165,13.188],[-60.9095,13.242],[-60.9165,13.366],[-60.938,13.436],[-60.9865,13.5115],[-61.1305,13.58]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/6d/Flag_of_Saint_Vincent_and_the_Grenadines.svg","name:en":"Saint Vincent and the Grenadines","wikidata":"Q757","ISO3166-1:alpha2":"VC","ISO3166-1:alpha3":"VCT","ISO3166-1:numeric":"670"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[104.125,1.276],[104.0795,1.3575],[104.0765,1.431],[104.041,1.444],[104.003,1.4205],[103.898,1.428],[103.8125,1.4785],[103.7605,1.4485],[103.714,1.4575],[103.674,1.428],[103.618,1.3215],[103.603,1.264],[103.5765,1.2545],[103.5665,1.1955],[103.6585,1.185],[103.7405,1.1305],[103.805,1.1715],[104.0335,1.2695],[104.125,1.276]]],[[[104.508,1.5015],[104.4635,1.4995],[104.3785,1.4105],[104.349,1.333],[104.389,1.317],[104.523,1.3935],[104.5705,1.442],[104.508,1.5015]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/48/Flag_of_Singapore.svg","name:en":"Singapore","wikidata":"Q334","ISO3166-1:alpha2":"SG","ISO3166-1:alpha3":"SGP","ISO3166-1:numeric":"702"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[13.6335,13.708],[13.4855,14.3585],[13.4735,14.443],[13.4935,14.4745],[13.572,14.5055],[13.641,14.5135],[13.696,14.551],[13.6775,14.6365],[13.7455,14.6985],[13.81,14.7215],[13.7895,14.863],[13.8695,15.043],[13.97,15.1565],[14.276,15.588],[14.385,15.7315],[14.6105,15.956],[14.9135,16.2765],[14.9565,16.3255],[15.2585,16.6395],[15.5055,16.898],[15.522,17.333],[15.5435,17.729],[15.573,18.2625],[15.6025,18.782],[15.6665,19.264],[15.754,19.9325],[15.9965,20.353],[15.6755,20.6965],[15.576,20.7665],[15.554,20.8525],[15.5685,20.9105],[15.627,20.9555],[15.2845,21.4455],[15.2025,21.496],[15.1945,21.999],[15.074,22.6135],[14.9985,23.001],[14.6635,22.832],[14.2345,22.6135],[13.6235,23.1165],[13.5435,23.1685],[13.417,23.214],[12.9315,23.3195],[12.576,23.396],[11.9975,23.517],[11.729,23.364],[11.2925,23.116],[11.0015,22.9335],[10.6715,22.7455],[10.2385,22.4965],[9.756,22.211],[9.351,21.976],[9.051,21.8],[8.997,21.7785],[8.4345,21.4395],[8.0135,21.1835],[7.994,21.167],[7.4595,20.8425],[6.999,20.455],[6.4695,20.0085],[6.437,19.9755],[6.1275,19.7125],[5.9875,19.599],[5.8105,19.447],[5.179,19.3205],[4.8495,19.2535],[4.336,19.1495],[4.2665,19.144],[4.267,18.7635],[4.2665,18.2855],[4.2675,17.92],[4.266,17.388],[4.2665,17.0015],[4.2145,17.0],[4.2065,16.837],[4.1975,16.815],[4.2,16.395],[4.1185,16.35],[4.097,16.323],[4.063,16.2225],[3.986,16.081],[3.9935,16.0295],[3.9775,15.935],[3.928,15.8645],[3.901,15.747],[3.856,15.6865],[3.798,15.6635],[3.7225,15.659],[3.645,15.586],[3.5915,15.517],[3.537,15.485],[3.5365,15.4035],[3.493,15.358],[3.0315,15.4285],[3.02,15.338],[2.6365,15.347],[2.166,15.3225],[1.8495,15.3065],[1.3115,15.278],[1.0,15.0],[0.9065,14.972],[0.7335,14.96],[0.6875,14.9445],[0.5725,14.989],[0.5145,14.9975],[0.3945,14.964],[0.232,15.0],[0.2445,14.914],[0.1965,14.8265],[0.236,14.7355],[0.169,14.522],[0.213,14.418],[0.381,14.051],[0.417,14.023],[0.424,13.9835],[0.473,13.951],[0.465,13.9135],[0.526,13.8435],[0.618,13.767],[0.598,13.731],[0.625,13.684],[0.773,13.6885],[0.7745,13.644],[0.833,13.625],[0.902,13.623],[0.977,13.57],[1.019,13.523],[1.0315,13.4625],[1.124,13.4135],[1.2035,13.387],[1.2445,13.393],[1.283,13.3545],[1.1855,13.321],[1.115,13.3315],[0.992,13.3745],[0.992,13.1035],[0.974,13.0075],[1.1595,13.0075],[1.33,12.8315],[1.5665,12.6115],[1.8685,12.6055],[1.928,12.7005],[1.989,12.731],[2.0385,12.7165],[2.096,12.7255],[2.146,12.691],[2.1545,12.6515],[2.201,12.631],[2.221,12.5935],[2.2255,12.5165],[2.264,12.4735],[2.2615,12.4145],[2.1615,12.4155],[2.118,12.387],[2.078,12.386],[2.0655,12.3475],[2.2055,12.1675],[2.3975,11.91],[2.409,11.9025],[2.4065,11.9525],[2.464,11.9855],[2.4035,12.1035],[2.3875,12.2165],[2.4015,12.258],[2.471,12.273],[2.5475,12.274],[2.5925,12.2995],[2.662,12.3065],[2.6945,12.283],[2.7225,12.3525],[2.8415,12.4055],[2.8695,12.3895],[2.9665,12.2865],[3.0145,12.266],[3.0745,12.1815],[3.126,12.156],[3.2205,12.0615],[3.2795,11.942],[3.323,11.8845],[3.3735,11.889],[3.448,11.8585],[3.482,11.86],[3.5615,11.7785],[3.5515,11.7285],[3.6095,11.6935],[3.681,11.7545],[3.669,11.8105],[3.6295,11.831],[3.62,11.9205],[3.6785,11.9765],[3.6715,12.032],[3.6315,12.1195],[3.647,12.2125],[3.6665,12.259],[3.6505,12.402],[3.6535,12.5225],[3.774,12.626],[3.942,12.7465],[3.9835,12.8175],[4.054,12.9],[4.1035,12.9875],[4.142,13.162],[4.1475,13.2925],[4.1415,13.478],[4.2345,13.478],[4.4655,13.6815],[4.8395,13.768],[4.874,13.781],[4.9095,13.7455],[5.0045,13.7355],[5.077,13.751],[5.2055,13.736],[5.281,13.7555],[5.3505,13.8345],[5.4515,13.871],[5.53,13.8855],[5.631,13.8365],[5.832,13.7615],[6.091,13.677],[6.1555,13.645],[6.2325,13.6735],[6.2775,13.6765],[6.428,13.6005],[6.6965,13.3395],[6.82,13.1435],[6.942,13.0035],[7.053,13.0],[7.1215,13.0205],[7.2215,13.129],[7.389,13.0985],[7.4395,13.115],[7.661,13.244],[7.7025,13.277],[7.816,13.3425],[8.069,13.314],[8.1515,13.2735],[8.1915,13.2315],[8.2495,13.214],[8.416,13.057],[8.502,13.074],[8.597,13.0235],[8.646,12.9435],[8.703,12.919],[8.8115,12.8895],[8.978,12.8335],[9.182,12.8345],[9.331,12.811],[9.3865,12.823],[9.6585,12.8075],[9.7965,12.9555],[9.841,13.0265],[9.889,13.052],[9.919,13.095],[10.0115,13.1825],[10.204,13.2705],[10.3365,13.275],[10.4655,13.2875],[10.656,13.3605],[11.279,13.379],[11.459,13.3805],[11.5905,13.3465],[11.6785,13.299],[11.883,13.256],[12.009,13.172],[12.0385,13.141],[12.1645,13.0985],[12.1865,13.124],[12.257,13.118],[12.3215,13.085],[12.469,13.0675],[12.514,13.1535],[12.5505,13.1595],[12.5535,13.2275],[12.5765,13.2715],[12.644,13.293],[12.6775,13.2815],[12.7625,13.3875],[12.851,13.4445],[12.8715,13.501],[12.917,13.487],[12.9695,13.519],[13.0305,13.531],[13.1195,13.5225],[13.2055,13.5415],[13.313,13.6975],[13.363,13.708],[13.6335,13.708]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/f4/Flag_of_Niger.svg","name:en":"Niger","wikidata":"Q1032","ISO3166-1:alpha2":"NE","ISO3166-1:alpha3":"NER","ISO3166-1:numeric":"562"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-9.685,70.868],[-9.6545,70.785],[-9.4995,70.69],[-9.3075,70.6455],[-8.96,70.6265],[-8.681,70.6525],[-8.4485,70.7015],[-8.273,70.768],[-7.8195,70.82],[-7.638,70.855],[-7.493,70.9035],[-7.3865,70.9825],[-7.3155,71.1275],[-7.3185,71.1745],[-7.4215,71.2625],[-7.567,71.3155],[-7.696,71.341],[-7.947,71.36],[-8.219,71.352],[-8.578,71.298],[-8.748,71.255],[-8.968,71.1545],[-9.299,71.0825],[-9.486,71.02],[-9.6275,70.9515],[-9.685,70.868]]],[[[2.9345,-54.406],[2.964,-54.512],[3.0745,-54.599],[3.1895,-54.641],[3.2775,-54.653],[3.4905,-54.642],[3.623,-54.606],[3.7225,-54.539],[3.77,-54.469],[3.762,-54.359],[3.678,-54.269],[3.6,-54.228],[3.481,-54.197],[3.2925,-54.19],[3.158,-54.21],[3.0545,-54.246],[3.0,-54.281],[2.944,-54.354],[2.9345,-54.406]]],[[[20.5485,69.06],[20.7175,69.12],[21.0575,69.0365],[21.1085,69.104],[20.9875,69.192],[21.096,69.261],[21.279,69.312],[21.627,69.2765],[21.7235,69.2145],[22.176,68.9565],[22.192,68.919],[22.341,68.827],[22.3745,68.7165],[22.5355,68.7445],[22.801,68.6875],[23.046,68.6895],[23.1675,68.6285],[23.4405,68.692],[23.6735,68.7055],[23.7755,68.819],[23.9835,68.827],[24.0755,68.78],[24.3025,68.7175],[24.6085,68.682],[24.917,68.605],[25.0765,68.622],[25.157,68.8],[25.2675,68.851],[25.4815,68.905],[25.627,68.8925],[25.7775,69.0195],[25.7205,69.109],[25.742,69.145],[25.694,69.1955],[25.742,69.319],[25.8465,69.394],[25.793,69.421],[25.876,69.529],[25.976,69.61],[25.8925,69.6655],[26.007,69.723],[26.136,69.7385],[26.3605,69.845],[26.4665,69.94],[26.676,69.9645],[26.7325,69.9465],[26.986,69.935],[27.0315,69.911],[27.3055,69.958],[27.437,70.0205],[27.5235,70.023],[27.5745,70.067],[27.9595,70.092],[27.9845,70.014],[28.1605,69.921],[28.3455,69.881],[28.404,69.8185],[29.134,69.6955],[29.1705,69.639],[29.3365,69.4785],[29.2195,69.3975],[28.8315,69.2245],[28.8055,69.111],[28.9295,69.052],[29.0565,69.015],[29.242,69.113],[29.313,69.2295],[29.286,69.294],[29.3905,69.322],[29.573,69.3185],[29.7245,69.3895],[29.8685,69.424],[29.9705,69.408],[30.115,69.4685],[30.1195,69.5135],[30.188,69.566],[30.138,69.6435],[30.224,69.653],[30.4175,69.59],[30.516,69.5405],[30.818,69.529],[30.939,69.5605],[30.9455,69.6775],[30.8175,69.795],[31.1045,69.9795],[31.441,70.0985],[31.5855,70.144],[31.6355,70.2375],[31.7245,70.3185],[31.7615,70.3885],[31.6875,70.4845],[31.5485,70.5455],[30.6095,70.8265],[30.381,70.8825],[29.566,71.0235],[28.5555,71.2625],[28.2995,71.297],[27.718,71.3325],[26.26,71.3745],[25.7105,71.3845],[25.5435,71.3805],[24.6295,71.314],[24.0165,71.301],[23.723,71.2795],[22.4765,71.027],[21.7155,70.8555],[20.4795,70.7035],[18.847,70.487],[18.3595,70.3995],[18.163,70.3405],[17.452,69.993],[17.0555,69.745],[16.677,69.667],[15.79,69.5175],[15.6985,69.498],[14.816,69.2595],[14.7335,69.2315],[13.892,68.8725],[13.7215,68.746],[13.264,68.4635],[12.8325,68.3465],[12.584,68.2355],[12.306,68.0315],[12.1285,67.823],[11.6965,67.696],[11.507,67.631],[11.3925,67.5715],[11.307,67.4555],[11.359,67.331],[11.859,66.8155],[11.654,66.724],[11.566,66.6675],[11.0935,66.1995],[11.0715,66.172],[10.7985,65.702],[10.579,65.471],[10.0895,64.9925],[9.997,64.87],[8.9405,64.3575],[8.1645,64.0665],[8.09,64.031],[7.462,63.6555],[7.358,63.581],[6.839,63.26],[5.996,62.974],[5.671,62.8265],[4.949,62.472],[4.667,62.2705],[4.506,62.106],[4.178,61.7265],[4.1475,61.6615],[4.088,61.084],[4.104,60.976],[4.494,60.272],[4.649,59.775],[4.672,59.665],[4.4835,59.369],[4.4545,59.278],[4.4875,59.1955],[4.6125,59.112],[4.895,59.0005],[5.006,58.923],[5.112,58.701],[5.18,58.5995],[5.3275,58.456],[5.4155,58.3945],[5.623,58.2735],[6.344,57.9355],[6.529,57.872],[6.8635,57.799],[7.1805,57.7625],[7.5575,57.759],[7.693,57.7665],[7.83,57.791],[8.163,57.865],[8.4135,57.928],[8.506,57.961],[8.9425,58.176],[9.7885,58.6725],[10.074,58.748],[10.271,58.775],[10.593,58.761],[10.639,58.8925],[10.918,58.9425],[11.0665,58.9775],[11.117,59.015],[11.1535,59.0795],[11.3685,59.0985],[11.4645,58.991],[11.4555,58.8895],[11.63,58.9085],[11.688,58.9555],[11.7105,59.0335],[11.775,59.0865],[11.783,59.206],[11.83,59.2425],[11.816,59.3445],[11.691,59.5895],[11.7205,59.6255],[11.8555,59.6485],[11.94,59.6945],[11.926,59.794],[11.8395,59.841],[11.9415,59.89],[12.1745,59.89],[12.231,59.9275],[12.341,59.9655],[12.4485,60.039],[12.5005,60.099],[12.542,60.1935],[12.499,60.3235],[12.606,60.406],[12.607,60.5125],[12.516,60.6],[12.511,60.6425],[12.3955,60.734],[12.3345,60.8525],[12.333,60.89],[12.224,61.013],[12.4475,61.0505],[12.6105,61.0465],[12.6825,61.061],[12.707,61.1435],[12.7905,61.197],[12.834,61.2585],[12.871,61.3565],[12.5695,61.5685],[12.4195,61.563],[12.1375,61.724],[12.2995,62.2675],[12.056,62.612],[12.1365,62.748],[12.0745,62.9025],[12.218,63.0005],[11.9745,63.269],[12.084,63.3555],[12.213,63.4785],[12.15,63.594],[12.2995,63.672],[12.3305,63.715],[12.48,63.819],[12.6835,63.974],[12.9265,64.058],[13.211,64.0955],[13.7155,64.0465],[13.9675,64.008],[14.157,64.195],[14.114,64.4625],[13.891,64.507],[13.6545,64.5805],[13.7055,64.64],[14.13,64.9785],[14.326,65.119],[14.379,65.2475],[14.507,65.3095],[14.499,65.5215],[14.5415,65.7005],[14.6255,65.812],[14.5845,65.9015],[14.5165,66.1325],[15.0355,66.1535],[15.4845,66.2825],[15.377,66.4845],[15.6215,66.5945],[16.039,66.9125],[16.194,66.9825],[16.3875,67.0455],[16.404,67.205],[16.09,67.4355],[16.158,67.519],[16.4075,67.534],[16.556,67.647],[16.738,67.914],[17.1805,68.0505],[17.2815,68.119],[17.6645,68.0385],[17.9,67.9695],[18.1515,68.199],[18.101,68.406],[18.126,68.5365],[18.4055,68.582],[18.621,68.507],[18.984,68.517],[19.9215,68.356],[20.2265,68.491],[19.9375,68.558],[20.0525,68.591],[20.203,68.666],[20.336,68.8025],[20.3065,68.926],[20.06,69.046],[20.5485,69.06]]],[[[9.421,78.8965],[9.471,78.7705],[9.6495,78.6395],[10.112,78.385],[10.253,78.3325],[11.058,78.1105],[11.4255,78.037],[11.7845,78.0075],[12.5135,78.0005],[12.581,77.9835],[12.6085,77.8355],[12.7955,77.6975],[13.017,77.3445],[13.383,77.139],[13.5455,77.079],[13.91,76.9855],[14.217,76.9255],[14.658,76.762],[15.165,76.61],[15.554,76.445],[15.8605,76.337],[16.192,76.2695],[16.4745,76.2455],[16.919,76.2565],[17.2915,76.3045],[17.433,76.3355],[17.7325,76.4305],[17.8885,76.517],[18.0035,76.6805],[18.293,77.1485],[18.4465,77.3195],[18.671,77.3175],[19.733,77.3785],[20.172,77.3065],[20.4385,77.2075],[20.5795,77.105],[20.7735,76.8395],[20.8315,76.794],[21.0265,76.7285],[21.398,76.6765],[21.6565,76.667],[22.0515,76.678],[22.4105,76.7285],[23.1665,76.9],[23.632,77.0355],[24.092,77.211],[24.579,77.4495],[25.679,77.625],[25.909,77.675],[26.0455,77.7345],[26.0995,77.816],[25.9825,77.921],[25.682,77.989],[24.8665,78.1005],[24.0365,78.2695],[23.9365,78.315],[22.8605,78.6655],[22.5985,78.8225],[22.637,78.838],[24.4775,79.0225],[25.954,79.2],[26.2165,79.243],[26.675,79.3475],[27.544,79.5735],[28.1335,79.6915],[28.522,79.8085],[29.191,79.9565],[29.333,79.9955],[29.4405,80.101],[29.3255,80.188],[29.119,80.2435],[28.654,80.309],[28.287,80.3365],[27.4935,80.3725],[27.3355,80.523],[27.0855,80.5935],[25.898,80.801],[25.3825,80.8525],[24.8725,80.861],[24.52,80.8465],[23.004,80.74],[22.0845,80.857],[21.1555,80.982],[20.847,81.012],[20.258,81.0275],[19.6285,80.993],[19.202,80.9135],[18.7135,80.742],[17.2545,80.4835],[16.8775,80.369],[16.769,80.293],[16.0435,80.26],[14.4,80.2365],[13.9405,80.213],[13.675,80.18],[13.146,80.0655],[12.5745,80.049],[11.8135,80.1045],[11.2495,80.0945],[10.6505,80.04],[9.8265,79.919],[9.558,79.8575],[9.447,79.753],[9.577,79.495],[9.784,79.306],[10.0065,79.143],[9.563,78.9965],[9.421,78.8965]]],[[[17.996,74.477],[18.0455,74.399],[18.2115,74.3115],[18.5335,74.194],[18.7305,74.156],[18.955,74.137],[19.3025,74.147],[19.6815,74.213],[19.8905,74.305],[19.995,74.41],[20.0055,74.4955],[19.9035,74.571],[19.6945,74.645],[19.4395,74.6935],[19.2015,74.7125],[18.751,74.703],[18.413,74.6665],[18.2665,74.6365],[18.1085,74.5785],[17.996,74.477]]],[[[24.0435,76.4465],[24.1785,76.343],[24.3715,76.2925],[24.7595,76.2485],[25.007,76.245],[25.272,76.2605],[25.5015,76.293],[25.7555,76.367],[26.2765,76.6205],[26.365,76.7015],[26.288,76.7965],[26.1355,76.85],[25.738,76.9065],[25.334,76.911],[25.145,76.8975],[24.859,76.855],[24.6385,76.791],[24.29,76.6495],[24.1365,76.5705],[24.0435,76.4465]]],[[[25.335,78.8145],[25.408,78.7195],[25.749,78.572],[26.071,78.4895],[26.342,78.4555],[26.7185,78.4395],[27.252,78.4665],[27.628,78.5155],[27.9725,78.5755],[28.3115,78.5375],[28.852,78.5285],[29.34,78.576],[30.255,78.7335],[30.8,78.8005],[31.2295,78.8805],[31.448,78.9735],[31.396,79.081],[31.1935,79.146],[30.898,79.193],[30.663,79.212],[30.24,79.2185],[28.226,79.164],[27.8985,79.144],[27.3745,79.0645],[26.362,79.035],[25.8915,78.997],[25.564,78.934],[25.394,78.874],[25.335,78.8145]]],[[[30.2665,80.089],[30.361,80.0045],[30.748,79.9065],[31.123,79.8555],[31.461,79.8345],[32.0795,79.845],[33.766,79.954],[34.196,80.0005],[34.413,80.051],[34.601,80.1305],[34.6725,80.2645],[34.5505,80.3245],[33.996,80.435],[33.6485,80.478],[32.917,80.5155],[32.4425,80.5035],[31.8855,80.4685],[31.2705,80.4015],[30.7755,80.32],[30.5415,80.2665],[30.373,80.1995],[30.2665,80.089]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/d9/Flag_of_Norway.svg","name:en":"Norway","wikidata":"Q20","ISO3166-1:alpha2":"NO","ISO3166-1:alpha3":"NOR","ISO3166-1:numeric":"578"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[25.0,22.0],[25.0015,22.337],[25.001,23.04],[24.9995,23.5665],[24.999,23.899],[24.9985,24.468],[24.997,24.7865],[24.998,25.513],[24.999,25.9845],[24.999,26.4145],[25.0005,27.0665],[25.001,27.524],[25.0025,28.1205],[25.0005,28.4295],[24.9985,28.8885],[24.998,29.249],[24.876,29.512],[24.887,29.664],[24.8125,29.7845],[24.8345,29.8765],[24.7405,30.0985],[24.65,30.1265],[24.698,30.2295],[24.7975,30.348],[24.849,30.393],[24.89,30.452],[24.9455,30.6445],[25.011,30.782],[24.9805,30.9],[24.9035,31.0395],[24.8585,31.155],[24.8635,31.2385],[24.8445,31.3625],[24.8625,31.406],[24.981,31.5],[25.0765,31.551],[25.076,31.599],[25.134,31.67],[25.377,31.722],[25.2495,32.0195],[25.216,32.0645],[25.1425,32.1205],[25.0565,32.161],[24.9305,32.182],[24.8395,32.2085],[24.716,32.2235],[24.344,32.2025],[24.2005,32.2085],[24.1575,32.243],[24.049,32.2955],[23.8415,32.3575],[23.687,32.3825],[23.5005,32.3795],[23.479,32.3865],[23.4395,32.4805],[23.363,32.5825],[23.3635,32.6375],[23.339,32.706],[23.301,32.755],[23.22,32.8115],[23.0985,32.8475],[23.025,32.8575],[22.571,33.0315],[22.4345,33.067],[22.334,33.0775],[22.24,33.123],[22.155,33.139],[21.939,33.1075],[21.754,33.139],[21.667,33.138],[21.546,33.1145],[21.491,33.09],[21.3345,32.9895],[21.058,32.968],[20.963,32.944],[20.8625,32.905],[20.487,32.7345],[20.3955,32.6435],[20.184,32.4905],[19.963,32.2835],[19.7795,32.0475],[19.7745,32.0115],[19.719,31.849],[19.7205,31.7565],[19.7535,31.6355],[19.78,31.4505],[19.827,31.322],[19.9345,31.1495],[19.9535,31.09],[19.788,30.8855],[19.608,30.6775],[19.411,30.5385],[19.2175,30.458],[18.976,30.464],[18.6635,30.6545],[18.3325,30.9045],[18.0385,30.987],[17.9925,31.0505],[17.5835,31.157],[17.4855,31.218],[16.781,31.354],[16.3205,31.368],[16.086,31.4015],[15.863,31.509],[15.736,31.6285],[15.593,31.8555],[15.524,32.0145],[15.5235,32.173],[15.397,32.3985],[15.3105,32.467],[15.23,32.5105],[14.8245,32.577],[14.594,32.7135],[14.486,32.796],[14.3335,32.879],[14.0135,32.965],[13.824,33.002],[13.6105,33.016],[13.493,33.0775],[13.4375,33.0935],[13.2435,33.12],[13.112,33.1025],[12.9265,33.03],[12.684,32.9965],[12.491,33.0175],[12.296,33.0705],[12.039,33.2135],[11.9205,33.27],[11.789,33.315],[11.664,33.349],[11.5615,33.167],[11.527,33.0785],[11.5275,32.986],[11.4955,32.918],[11.5015,32.8305],[11.4875,32.7625],[11.494,32.694],[11.478,32.656],[11.5015,32.612],[11.5515,32.581],[11.6,32.519],[11.595,32.4545],[11.549,32.4085],[11.3845,32.345],[11.029,32.1995],[10.8615,32.1055],[10.861,32.0855],[10.795,31.998],[10.7225,31.9675],[10.658,31.9775],[10.6125,31.9165],[10.635,31.8795],[10.527,31.741],[10.4485,31.7305],[10.386,31.7405],[10.312,31.703],[10.2125,31.566],[10.139,31.49],[10.1665,31.377],[10.294,31.0915],[10.275,31.041],[10.2975,30.8865],[10.272,30.8005],[10.202,30.6935],[10.0695,30.5085],[10.017,30.479],[9.944,30.3835],[9.8775,30.337],[9.832,30.337],[9.559,30.229],[9.4155,30.1875],[9.3915,30.1465],[9.415,30.0425],[9.5385,29.901],[9.78,29.425],[9.8715,29.0275],[9.9025,28.759],[9.833,28.286],[9.962,27.886],[9.943,27.836],[9.9425,27.7325],[9.8885,27.609],[9.863,27.5045],[9.8135,27.463],[9.7945,27.395],[9.7825,27.2565],[9.798,27.1745],[9.818,27.1495],[9.8625,26.9425],[9.9255,26.862],[9.902,26.743],[9.9135,26.647],[9.8635,26.52],[9.5125,26.385],[9.456,26.2535],[9.399,26.1955],[9.5375,26.0025],[9.751,25.725],[10.032,25.3595],[10.038,24.9655],[10.0975,24.881],[10.106,24.846],[10.153,24.784],[10.2165,24.6505],[10.3025,24.599],[10.3565,24.537],[10.542,24.534],[10.6335,24.5665],[10.706,24.573],[10.7665,24.5105],[10.821,24.5675],[10.8965,24.556],[10.9495,24.5325],[10.9815,24.491],[11.0775,24.411],[11.1385,24.391],[11.4225,24.2005],[11.6045,24.2645],[11.846,23.806],[11.9975,23.517],[12.576,23.396],[12.9315,23.3195],[13.417,23.214],[13.5435,23.1685],[13.6235,23.1165],[14.2345,22.6135],[14.6635,22.832],[14.9985,23.001],[16.0,23.4515],[17.7885,22.661],[17.819,22.6505],[18.1465,22.494],[18.63,22.262],[19.186,21.99],[19.6715,21.7505],[20.2605,21.4555],[20.7355,21.216],[21.2735,20.941],[21.6615,20.741],[22.268,20.4255],[22.831,20.129],[23.4995,19.772],[24.0,19.5],[24.0,20.0],[25.0,20.0],[25.0015,20.479],[25.002,21.086],[25.0035,21.6245],[25.004,21.943],[25.0,22.0]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/05/Flag_of_Libya.svg","name:en":"Libya","wikidata":"Q1016","ISO3166-1:alpha2":"LY","ISO3166-1:alpha3":"LBY","ISO3166-1:numeric":"434"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-130.805,-23.9355],[-130.7895,-23.9685],[-130.7345,-23.983],[-130.69,-23.954],[-130.6875,-23.892],[-130.7455,-23.8665],[-130.7945,-23.901],[-130.805,-23.9355]]],[[[-130.1795,-25.069],[-130.166,-25.102],[-130.1185,-25.1285],[-130.053,-25.116],[-130.034,-25.087],[-130.0475,-25.0375],[-130.1215,-25.008],[-130.1625,-25.031],[-130.1795,-25.069]]],[[[-128.4115,-24.3655],[-128.379,-24.4395],[-128.3085,-24.4725],[-128.254,-24.456],[-128.237,-24.4195],[-128.249,-24.3145],[-128.301,-24.2805],[-128.3525,-24.2885],[-128.393,-24.3165],[-128.4115,-24.3655]]],[[[-124.8515,-24.682],[-124.81,-24.7335],[-124.74,-24.7215],[-124.7185,-24.6885],[-124.731,-24.644],[-124.7675,-24.6235],[-124.827,-24.6345],[-124.8515,-24.682]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/88/Flag_of_the_Pitcairn_Islands.svg","name:en":"Pitcairn Islands","wikidata":"Q35672","ISO3166-1:alpha2":"PN","ISO3166-1:alpha3":"PCN","ISO3166-1:numeric":"612"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[7.0455,45.9225],[6.99,45.868],[6.939,45.847],[6.818,45.836],[6.808,45.7275],[6.8465,45.6905],[6.97,45.654],[6.9955,45.5755],[6.9905,45.531],[7.0485,45.4725],[7.1825,45.408],[7.1595,45.3595],[7.1095,45.3185],[7.136,45.28],[7.081,45.2245],[6.966,45.208],[6.9555,45.1805],[6.85,45.1275],[6.768,45.16],[6.6805,45.1405],[6.6275,45.107],[6.6735,45.02],[6.7485,45.016],[6.7635,44.971],[6.75,44.9075],[6.8645,44.8515],[6.932,44.8635],[7.0065,44.8395],[7.0,44.789],[7.041,44.7195],[6.948,44.654],[6.969,44.626],[6.9155,44.56],[6.8545,44.529],[6.876,44.4825],[6.9365,44.44],[6.897,44.3755],[7.0085,44.235],[7.07,44.233],[7.194,44.19],[7.2805,44.141],[7.357,44.1165],[7.575,44.153],[7.667,44.1335],[7.7185,44.0825],[7.652,43.9735],[7.585,43.954],[7.5615,43.899],[7.5115,43.885],[7.5075,43.842],[7.539,43.744],[7.6105,43.656],[7.631,43.5785],[7.733,43.578],[8.051,43.658],[8.2605,43.7395],[8.399,43.832],[8.4625,43.9085],[8.642,44.0655],[8.7105,44.16],[8.751,44.188],[8.8755,44.186],[9.1505,44.088],[9.2855,44.0635],[9.6865,43.858],[9.795,43.823],[9.867,43.819],[9.943,43.704],[9.7005,43.581],[9.6215,43.481],[9.559,43.193],[9.589,43.1755],[9.6415,42.955],[9.7165,42.8485],[9.7645,42.8085],[9.733,42.7035],[9.7825,42.6325],[9.815,42.435],[9.801,42.3815],[9.828,42.261],[9.92,42.19],[10.0,42.1635],[10.233,42.118],[10.3215,42.1095],[10.849,42.1125],[11.0365,42.041],[11.605,41.9215],[11.6465,41.8835],[12.033,41.599],[12.217,41.522],[12.2765,41.4745],[12.377,41.3685],[12.579,40.9225],[12.618,40.814],[12.6745,40.764],[12.872,40.683],[13.0415,40.6425],[13.7835,40.5035],[14.074,40.3555],[14.75,40.0835],[15.105,39.866],[15.168,39.837],[15.332,39.793],[15.5385,39.695],[15.5515,39.635],[15.5915,39.5705],[15.636,39.467],[15.6815,39.4125],[15.7625,39.343],[15.795,39.2505],[15.798,39.126],[15.831,39.04],[15.76,38.8575],[15.6775,38.8155],[15.605,38.74],[15.577,38.6805],[15.526,38.505],[15.2725,38.477],[15.3385,38.5355],[15.372,38.6105],[15.45,38.6755],[15.508,38.776],[15.5055,38.869],[15.4715,38.9295],[15.3835,38.9945],[15.3045,39.0185],[15.2365,39.0225],[15.117,39.001],[15.0575,38.9745],[14.964,38.8985],[14.9295,38.819],[14.876,38.7865],[14.7575,38.7825],[14.69,38.7645],[14.628,38.782],[14.487,38.786],[14.3845,38.757],[14.3145,38.756],[14.2305,38.736],[14.124,38.661],[14.0895,38.6005],[14.0805,38.5405],[14.1025,38.4565],[14.148,38.3995],[14.2315,38.35],[14.298,38.3325],[14.4085,38.3325],[14.4975,38.361],[14.62,38.3525],[14.0195,38.247],[13.636,38.304],[13.4555,38.3945],[13.348,38.425],[13.271,38.423],[13.0765,38.393],[12.8095,38.383],[12.7485,38.391],[12.6425,38.379],[12.5695,38.347],[12.4115,38.247],[12.286,38.2185],[12.0005,38.192],[11.9415,38.181],[11.856,38.1395],[11.791,38.063],[11.776,37.9715],[11.817,37.8615],[11.856,37.8185],[11.927,37.776],[12.223,37.6555],[12.2615,37.588],[12.3415,37.5135],[12.5005,37.4085],[12.618,37.3605],[12.929,37.303],[13.1895,37.189],[13.315,37.12],[13.523,37.015],[13.755,36.922],[14.362,36.613],[14.644,36.5195],[15.018,36.4455],[15.093,36.44],[15.1875,36.46],[15.2695,36.4945],[15.3515,36.5585],[15.3815,36.597],[15.567,36.9145],[15.5895,37.025],[15.5565,37.105],[15.5085,37.282],[15.44,37.57],[15.4615,37.6385],[15.547,37.778],[15.656,37.7315],[15.788,37.713],[15.897,37.7225],[16.0105,37.713],[16.1255,37.7265],[16.2435,37.7785],[16.295,37.823],[16.664,38.2045],[16.7675,38.29],[17.3675,38.8215],[17.414,38.8795],[17.4605,38.974],[17.461,39.0755],[17.4125,39.2295],[17.414,39.262],[17.9405,39.4335],[18.4685,39.6045],[18.5695,39.662],[18.64,39.7505],[18.77,40.0405],[18.784,40.097],[18.762,40.212],[18.6865,40.3515],[18.6405,40.412],[18.4055,40.6045],[18.23,40.769],[18.146,40.826],[18.016,40.879],[17.9,40.9055],[17.8135,40.945],[17.652,40.992],[17.538,41.062],[17.4895,41.1065],[17.3,41.21],[17.1685,41.263],[17.0445,41.296],[16.9915,41.324],[16.717,41.392],[16.5385,41.4675],[16.4695,41.781],[16.473,41.823],[16.44,41.9615],[16.4055,42.008],[16.323,42.0675],[16.2345,42.111],[16.1185,42.147],[16.007,42.166],[16.0175,42.253],[15.9665,42.346],[15.9125,42.3845],[15.8235,42.419],[15.693,42.421],[15.609,42.3995],[15.5285,42.34],[15.4225,42.3305],[15.0565,42.234],[14.8805,42.3375],[14.734,42.3845],[14.6135,42.4995],[14.443,42.5925],[14.306,42.712],[14.2055,42.8675],[14.1905,42.9325],[14.1355,43.055],[14.105,43.167],[14.041,43.3015],[13.962,43.4275],[13.906,43.5415],[13.8665,43.6515],[13.7275,43.764],[13.613,43.818],[13.4815,43.8325],[13.441,43.8485],[13.2425,43.983],[13.073,44.0895],[12.897,44.1545],[12.8325,44.1675],[12.7565,44.24],[12.6965,44.268],[12.6275,44.3295],[12.5735,44.4895],[12.566,44.575],[12.7925,44.8555],[12.832,44.9475],[12.8605,45.3515],[13.046,45.432],[13.173,45.4395],[13.2105,45.453],[13.312,45.546],[13.467,45.5895],[13.639,45.639],[13.7185,45.5945],[13.8515,45.585],[13.9185,45.6335],[13.8575,45.666],[13.784,45.7485],[13.6695,45.7995],[13.596,45.808],[13.5745,45.8435],[13.638,45.9365],[13.643,45.9825],[13.568,45.9685],[13.502,45.9805],[13.516,46.0625],[13.6445,46.1375],[13.6335,46.192],[13.444,46.2255],[13.3925,46.2825],[13.4495,46.335],[13.437,46.3545],[13.5655,46.398],[13.582,46.4305],[13.6935,46.444],[13.714,46.523],[13.5045,46.5665],[13.322,46.553],[13.193,46.5725],[13.0905,46.601],[12.9335,46.6095],[12.6905,46.657],[12.5485,46.659],[12.384,46.7165],[12.3575,46.775],[12.309,46.785],[12.306,46.8335],[12.2665,46.887],[12.211,46.8775],[12.1385,46.9565],[12.126,47.013],[12.2045,47.027],[12.227,47.082],[12.186,47.092],[12.02,47.047],[11.9315,47.037],[11.7645,46.9725],[11.627,47.0135],[11.538,46.984],[11.479,47.011],[11.4425,46.9765],[11.3825,46.9705],[11.3205,46.9925],[11.187,46.9695],[11.072,46.856],[11.021,46.7665],[10.814,46.775],[10.763,46.8205],[10.6625,46.8745],[10.5705,46.8425],[10.4695,46.855],[10.444,46.76],[10.3845,46.683],[10.4015,46.637],[10.4915,46.6115],[10.472,46.5435],[10.364,46.5555],[10.296,46.55],[10.2415,46.589],[10.224,46.629],[10.1275,46.605],[10.044,46.54],[10.0545,46.4645],[10.087,46.4215],[10.143,46.4285],[10.164,46.3905],[10.108,46.3515],[10.1165,46.314],[10.175,46.2545],[10.0715,46.218],[10.0555,46.266],[9.996,46.285],[9.996,46.3425],[9.9095,46.3795],[9.77,46.336],[9.7145,46.293],[9.6185,46.2875],[9.534,46.312],[9.4545,46.419],[9.4625,46.498],[9.3905,46.4735],[9.3735,46.504],[9.282,46.496],[9.2495,46.431],[9.28,46.4145],[9.2995,46.3265],[9.194,46.1785],[9.0725,46.118],[9.077,46.064],[9.017,46.05],[9.0195,45.93],[9.0745,45.9125],[9.031,45.8245],[8.949,45.8435],[8.925,45.904],[8.8305,45.988],[8.787,45.9915],[8.852,46.0755],[8.6125,46.1215],[8.5325,46.2185],[8.469,46.233],[8.428,46.2985],[8.4655,46.334],[8.466,46.4425],[8.438,46.464],[8.367,46.452],[8.291,46.409],[8.313,46.377],[8.222,46.33],[8.138,46.302],[8.081,46.2585],[8.139,46.226],[8.1655,46.177],[8.108,46.1115],[8.0345,46.101],[8.034,46.0435],[7.9885,45.996],[7.9085,45.997],[7.8635,45.9165],[7.7695,45.937],[7.735,45.924],[7.658,45.9765],[7.4785,45.9525],[7.383,45.8965],[7.3445,45.915],[7.1535,45.8795],[7.118,45.859],[7.0455,45.9225]],[[12.4455,41.902],[12.4515,41.9065],[12.4575,41.906],[12.4545,41.9],[12.4455,41.902]],[[12.4035,43.9525],[12.5065,43.9915],[12.516,43.941],[12.4875,43.8965],[12.4155,43.9],[12.4035,43.9525]]],[[[8.831,41.261],[8.789,41.2325],[8.4955,41.2735],[8.436,41.303],[8.3165,41.3235],[8.211,41.3075],[8.0955,41.255],[7.9875,41.141],[7.9075,40.9675],[7.869,40.759],[7.8725,40.5955],[7.905,40.4915],[8.0995,40.2885],[8.022,39.9935],[8.0205,39.84],[8.0465,39.787],[8.165,39.686],[8.119,39.4885],[8.1145,39.4295],[7.9815,39.246],[7.948,39.145],[7.98,39.0495],[8.1805,38.762],[8.252,38.697],[8.3265,38.666],[8.4155,38.656],[8.6525,38.6605],[8.874,38.673],[8.985,38.6995],[9.167,38.816],[9.5865,38.882],[9.7105,38.929],[9.83,39.0295],[9.8675,39.117],[9.894,39.28],[9.939,39.6935],[9.979,39.9075],[9.999,40.062],[10.058,40.404],[10.0865,40.471],[10.0835,40.5875],[10.015,40.78],[10.041,40.833],[10.0335,40.938],[9.9625,41.0385],[9.901,41.098],[9.8445,41.197],[9.784,41.2535],[9.7615,41.3065],[9.658,41.393],[9.631,41.4335],[9.45,41.4065],[9.3165,41.336],[9.27,41.292],[9.135,41.318],[8.831,41.261]]],[[[11.673,36.8045],[11.6895,36.734],[11.737,36.665],[11.82,36.585],[11.953,36.536],[12.079,36.5365],[12.1675,36.567],[12.265,36.6475],[12.3065,36.756],[12.296,36.84],[12.2645,36.8995],[12.1455,36.993],[12.0145,37.034],[11.933,37.0385],[11.815,37.0105],[11.714,36.933],[11.678,36.863],[11.673,36.8045]]],[[[12.072,35.558],[12.095,35.462],[12.1425,35.405],[12.2155,35.3675],[12.294,35.3505],[12.3795,35.3555],[12.5465,35.295],[12.653,35.2905],[12.716,35.3015],[12.8215,35.3615],[12.863,35.4185],[12.8785,35.4695],[12.8645,35.585],[12.828,35.652],[12.93,35.655],[12.991,35.6725],[13.079,35.734],[13.116,35.793],[13.128,35.8465],[13.1155,35.927],[13.0495,36.017],[12.9315,36.071],[12.801,36.072],[12.691,36.0285],[12.6365,35.9795],[12.5975,35.8795],[12.628,35.768],[12.6835,35.713],[12.5085,35.727],[12.4585,35.722],[12.3685,35.751],[12.234,35.736],[12.141,35.689],[12.102,35.6475],[12.072,35.558]]],[[[12.896,38.69],[12.9215,38.6065],[12.964,38.556],[13.0765,38.499],[13.158,38.488],[13.275,38.5045],[13.358,38.546],[13.407,38.588],[13.457,38.6865],[13.447,38.7725],[13.3795,38.857],[13.297,38.902],[13.2245,38.921],[13.142,38.92],[13.0635,38.9],[12.986,38.859],[12.939,38.814],[12.8975,38.724],[12.896,38.69]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/03/Flag_of_Italy.svg","name:en":"Italy","wikidata":"Q38","ISO3166-1:alpha2":"IT","ISO3166-1:alpha3":"ITA","ISO3166-1:numeric":"380"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[20.5945,41.877],[20.5585,41.8675],[20.573,41.788],[20.5205,41.7515],[20.517,41.663],[20.5545,41.5835],[20.4705,41.559],[20.469,41.4975],[20.5135,41.4375],[20.557,41.417],[20.5515,41.377],[20.498,41.322],[20.516,41.2305],[20.596,41.133],[20.596,41.092],[20.675,41.08],[20.7315,40.911],[20.8015,40.898],[20.848,40.9375],[20.9485,40.9225],[20.9775,40.8555],[21.1565,40.8575],[21.2065,40.884],[21.252,40.8625],[21.3635,40.8805],[21.417,40.9175],[21.5325,40.9075],[21.5665,40.8665],[21.649,40.9015],[21.707,40.943],[21.783,40.9285],[21.801,40.9745],[21.914,41.0505],[21.932,41.104],[22.0675,41.1565],[22.1285,41.1235],[22.2145,41.17],[22.416,41.1195],[22.618,41.134],[22.667,41.186],[22.706,41.143],[22.748,41.1665],[22.7645,41.322],[22.812,41.344],[22.9275,41.3385],[22.9655,41.3535],[22.952,41.4175],[22.9795,41.4465],[22.958,41.4945],[22.973,41.56],[22.9515,41.642],[23.0335,41.7225],[23.0085,41.769],[22.965,41.778],[22.928,41.862],[22.9025,41.876],[22.874,41.9535],[22.867,42.022],[22.798,42.0455],[22.6805,42.0635],[22.528,42.14],[22.434,42.258],[22.3605,42.311],[22.2915,42.3525],[22.195,42.34],[22.0655,42.2985],[22.032,42.2985],[21.9465,42.3445],[21.8925,42.3005],[21.8515,42.3255],[21.774,42.2655],[21.6945,42.233],[21.587,42.263],[21.569,42.2505],[21.445,42.278],[21.3605,42.222],[21.3025,42.1415],[21.318,42.107],[21.2215,42.0995],[21.162,42.197],[21.104,42.206],[21.0265,42.1525],[20.945,42.138],[20.8835,42.096],[20.791,42.083],[20.7485,42.0265],[20.7545,41.947],[20.7765,41.9185],[20.728,41.8645],[20.5945,41.877]]]},"properties":{"flag":"https://upload.wikimedia.org/wikipedia/commons/7/79/Flag_of_North_Macedonia.svg","name:en":"North Macedonia","wikidata":"Q221","ISO3166-1:alpha2":"MK","ISO3166-1:alpha3":"MKD","ISO3166-1:numeric":"807"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[19.226,43.528],[19.153,43.5365],[19.062,43.505],[18.9885,43.5555],[18.95,43.5035],[18.961,43.4605],[19.0045,43.443],[19.04,43.3655],[19.0835,43.319],[19.009,43.251],[18.9555,43.2875],[18.96,43.3175],[18.911,43.3605],[18.852,43.324],[18.733,43.281],[18.6675,43.204],[18.6485,43.147],[18.6605,43.0375],[18.5435,43.0325],[18.498,42.9955],[18.4825,42.9285],[18.509,42.8865],[18.458,42.8255],[18.4735,42.757],[18.528,42.724],[18.569,42.656],[18.5,42.588],[18.438,42.5555],[18.434,42.484],[18.524,42.4205],[18.54,42.39],[18.4195,42.2095],[18.6485,42.121],[18.876,41.953],[18.9285,41.8635],[19.2645,41.7495],[19.373,41.8445],[19.347,41.9135],[19.377,41.974],[19.3705,42.037],[19.4025,42.1035],[19.281,42.1805],[19.349,42.2405],[19.414,42.351],[19.468,42.3895],[19.563,42.5015],[19.616,42.5435],[19.61,42.5755],[19.662,42.628],[19.723,42.661],[19.7755,42.591],[19.7435,42.545],[19.7665,42.5015],[19.8315,42.466],[19.9435,42.5175],[20.0035,42.5095],[20.0175,42.5435],[20.0765,42.556],[20.0755,42.621],[20.112,42.6555],[20.033,42.6975],[20.0245,42.765],[20.098,42.7765],[20.1895,42.7465],[20.2505,42.759],[20.298,42.836],[20.353,42.8335],[20.3495,42.895],[20.2845,42.9315],[20.1375,42.98],[20.0595,42.9945],[19.992,43.052],[19.9605,43.1095],[19.84,43.0945],[19.771,43.163],[19.686,43.168],[19.619,43.2295],[19.5465,43.2455],[19.528,43.316],[19.461,43.3445],[19.449,43.3875],[19.35,43.4155],[19.223,43.482],[19.226,43.528]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/64/Flag_of_Montenegro.svg","name:en":"Montenegro","wikidata":"Q236","ISO3166-1:alpha2":"ME","ISO3166-1:alpha3":"MNE","ISO3166-1:numeric":"499"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[21.587,42.263],[21.5255,42.342],[21.547,42.3655],[21.6205,42.3785],[21.646,42.4145],[21.6225,42.453],[21.69,42.502],[21.706,42.5475],[21.7475,42.559],[21.7355,42.604],[21.79,42.651],[21.7535,42.701],[21.6745,42.687],[21.5865,42.704],[21.4795,42.7475],[21.393,42.745],[21.435,42.8725],[21.361,42.8725],[21.283,42.8955],[21.2345,42.96],[21.235,43.01],[21.1525,43.0405],[21.137,43.1135],[21.0505,43.1075],[20.967,43.1245],[20.8635,43.165],[20.8795,43.223],[20.8285,43.266],[20.793,43.245],[20.728,43.2485],[20.6715,43.2085],[20.615,43.2045],[20.6115,43.1695],[20.685,43.123],[20.6715,43.039],[20.5815,43.013],[20.4865,42.929],[20.5355,42.889],[20.4415,42.834],[20.353,42.8335],[20.298,42.836],[20.2505,42.759],[20.1895,42.7465],[20.098,42.7765],[20.0245,42.765],[20.033,42.6975],[20.112,42.6555],[20.0755,42.621],[20.0765,42.556],[20.165,42.5065],[20.2275,42.4195],[20.2575,42.319],[20.327,42.3275],[20.4565,42.2725],[20.524,42.2105],[20.568,42.121],[20.5545,42.0825],[20.5945,42.043],[20.6265,41.961],[20.5765,41.917],[20.5945,41.877],[20.728,41.8645],[20.7765,41.9185],[20.7545,41.947],[20.7485,42.0265],[20.791,42.083],[20.8835,42.096],[20.945,42.138],[21.0265,42.1525],[21.104,42.206],[21.162,42.197],[21.2215,42.0995],[21.318,42.107],[21.3025,42.1415],[21.3605,42.222],[21.445,42.278],[21.569,42.2505],[21.587,42.263]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/1f/Flag_of_Kosovo.svg","name:en":"Kosovo","wikidata":"Q1246","ISO3166-1:alpha2":"XK","ISO3166-1:alpha3":"XKX"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[22.3605,42.311],[22.4555,42.3335],[22.478,42.3935],[22.52,42.3975],[22.559,42.485],[22.5475,42.507],[22.438,42.572],[22.4675,42.641],[22.487,42.749],[22.441,42.806],[22.5355,42.882],[22.6195,42.896],[22.6815,42.872],[22.7445,42.886],[22.78,42.932],[22.7855,42.9825],[22.8985,43.036],[22.919,43.0775],[22.983,43.111],[23.0055,43.186],[22.8965,43.227],[22.8485,43.2755],[22.8275,43.329],[22.7665,43.3775],[22.6795,43.3945],[22.6605,43.426],[22.5975,43.4355],[22.5335,43.471],[22.4875,43.5685],[22.492,43.639],[22.408,43.696],[22.3955,43.7595],[22.357,43.8095],[22.409,43.9395],[22.4095,44.004],[22.5225,44.019],[22.535,44.052],[22.6215,44.0635],[22.6105,44.1065],[22.6475,44.2045],[22.6745,44.216],[22.6835,44.2715],[22.558,44.309],[22.5235,44.3405],[22.475,44.4805],[22.5505,44.4825],[22.5645,44.5355],[22.619,44.552],[22.699,44.5165],[22.7545,44.565],[22.6695,44.619],[22.5695,44.637],[22.4845,44.707],[22.4295,44.71],[22.371,44.6725],[22.333,44.676],[22.2735,44.623],[22.184,44.482],[22.1295,44.474],[22.037,44.542],[21.9955,44.632],[21.842,44.6555],[21.642,44.66],[21.608,44.7335],[21.537,44.7725],[21.425,44.7735],[21.3585,44.8215],[21.3715,44.8665],[21.4855,44.868],[21.56,44.889],[21.5465,44.9305],[21.4065,44.9785],[21.36,45.0205],[21.4475,45.0575],[21.4785,45.1215],[21.5275,45.138],[21.483,45.192],[21.203,45.2655],[21.18,45.3125],[21.0965,45.296],[21.0635,45.332],[21.0165,45.3245],[20.9605,45.367],[20.879,45.4545],[20.769,45.5],[20.8325,45.536],[20.766,45.6125],[20.805,45.657],[20.8025,45.738],[20.7005,45.7505],[20.6605,45.829],[20.516,45.892],[20.4835,45.9535],[20.4055,45.965],[20.3485,45.9995],[20.346,46.0475],[20.273,46.0985],[20.2645,46.1265],[20.182,46.16],[20.1375,46.144],[20.096,46.177],[19.935,46.176],[19.818,46.128],[19.6965,46.1875],[19.6315,46.1695],[19.5675,46.1785],[19.5025,46.142],[19.4155,46.0455],[19.364,46.052],[19.2855,45.997],[19.1475,45.996],[19.1045,46.04],[19.0655,46.0],[19.0795,45.9635],[19.006,45.9585],[18.962,45.926],[18.89,45.922],[18.8855,45.859],[18.9185,45.819],[18.8735,45.7845],[18.894,45.7515],[18.9585,45.7675],[18.9795,45.7395],[18.9285,45.691],[18.936,45.6385],[18.9085,45.5675],[18.984,45.537],[19.096,45.5205],[19.0825,45.4885],[18.997,45.491],[18.987,45.455],[19.0235,45.403],[18.9715,45.377],[19.093,45.335],[19.1045,45.299],[19.26,45.243],[19.4205,45.2335],[19.4475,45.196],[19.418,45.1665],[19.295,45.173],[19.187,45.166],[19.142,45.13],[19.077,45.1135],[19.106,45.079],[19.0925,44.995],[19.143,44.941],[18.989,44.906],[19.019,44.855],[19.065,44.8615],[19.175,44.9215],[19.2255,44.8985],[19.3095,44.908],[19.3695,44.8805],[19.318,44.8215],[19.303,44.688],[19.1835,44.573],[19.19,44.547],[19.1285,44.52],[19.147,44.415],[19.103,44.3715],[19.1325,44.317],[19.2285,44.2645],[19.328,44.269],[19.3605,44.1835],[19.491,44.1165],[19.512,44.081],[19.5995,44.0705],[19.6185,44.0135],[19.5645,43.9995],[19.5265,43.956],[19.3885,43.9605],[19.3105,43.996],[19.235,44.0085],[19.2535,43.951],[19.294,43.92],[19.395,43.798],[19.4655,43.7645],[19.5185,43.7145],[19.532,43.668],[19.481,43.5715],[19.3575,43.606],[19.273,43.5965],[19.226,43.528],[19.223,43.482],[19.35,43.4155],[19.449,43.3875],[19.461,43.3445],[19.528,43.316],[19.5465,43.2455],[19.619,43.2295],[19.686,43.168],[19.771,43.163],[19.84,43.0945],[19.9605,43.1095],[19.992,43.052],[20.0595,42.9945],[20.1375,42.98],[20.2845,42.9315],[20.3495,42.895],[20.353,42.8335],[20.4415,42.834],[20.5355,42.889],[20.4865,42.929],[20.5815,43.013],[20.6715,43.039],[20.685,43.123],[20.6115,43.1695],[20.615,43.2045],[20.6715,43.2085],[20.728,43.2485],[20.793,43.245],[20.8285,43.266],[20.8795,43.223],[20.8635,43.165],[20.967,43.1245],[21.0505,43.1075],[21.137,43.1135],[21.1525,43.0405],[21.235,43.01],[21.2345,42.96],[21.283,42.8955],[21.361,42.8725],[21.435,42.8725],[21.393,42.745],[21.4795,42.7475],[21.5865,42.704],[21.6745,42.687],[21.7535,42.701],[21.79,42.651],[21.7355,42.604],[21.7475,42.559],[21.706,42.5475],[21.69,42.502],[21.6225,42.453],[21.646,42.4145],[21.6205,42.3785],[21.547,42.3655],[21.5255,42.342],[21.587,42.263],[21.6945,42.233],[21.774,42.2655],[21.8515,42.3255],[21.8925,42.3005],[21.9465,42.3445],[22.032,42.2985],[22.0655,42.2985],[22.195,42.34],[22.2915,42.3525],[22.3605,42.311]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/ff/Flag_of_Serbia.svg","name:en":"Serbia","wikidata":"Q403","ISO3166-1:alpha2":"RS","ISO3166-1:alpha3":"SRB","ISO3166-1:numeric":"688"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[35.7565,32.745],[35.633,32.6855],[35.5735,32.641],[35.577,32.5525],[35.554,32.513],[35.555,32.389],[35.555,32.386],[35.5565,32.3685],[35.559,32.3365],[35.5655,32.258],[35.5705,32.1915],[35.533,32.108],[35.519,32.0355],[35.5445,31.97],[35.5245,31.907],[35.549,31.8655],[35.5555,31.7515],[35.5275,31.7215],[35.4915,31.621],[35.475,31.4965],[35.4565,31.3625],[35.4065,31.2815],[35.4,31.239],[35.4495,31.1575],[35.4545,31.1045],[35.4275,31.05],[35.4165,30.951],[35.371,30.927],[35.333,30.867],[35.341,30.8155],[35.296,30.762],[35.2615,30.657],[35.204,30.582],[35.193,30.499],[35.162,30.4415],[35.192,30.346],[35.146,30.282],[35.1445,30.1625],[35.161,30.1345],[35.146,30.063],[35.1125,30.039],[35.0785,29.957],[35.0845,29.8855],[35.03,29.772],[35.012,29.697],[35.0145,29.639],[34.9785,29.577],[34.9665,29.519],[34.921,29.4535],[34.8845,29.375],[34.9495,29.359],[35.737,29.238],[35.823,29.2195],[36.073,29.1835],[36.152,29.232],[36.2125,29.286],[36.371,29.3975],[36.4095,29.4055],[36.5275,29.5145],[36.5485,29.5605],[36.626,29.639],[36.681,29.7495],[36.736,29.789],[36.785,29.868],[36.865,29.8855],[37.5055,30.001],[37.521,30.0425],[37.6655,30.3325],[37.997,30.5005],[37.933,30.5765],[37.5835,30.928],[37.283,31.228],[37.006,31.5005],[37.4035,31.6015],[38.04,31.7635],[38.4785,31.872],[39.0065,32.0005],[39.201,32.1545],[39.3015,32.2305],[39.26,32.355],[39.043,32.3035],[38.9855,32.4775],[39.086,32.502],[38.88,33.119],[38.7935,33.375],[38.7695,33.358],[38.3505,33.1415],[37.8885,32.894],[37.818,32.9055],[37.7695,32.8785],[37.762,32.788],[37.741,32.762],[37.5205,32.7175],[37.444,32.643],[37.4245,32.607],[37.36,32.56],[37.2555,32.572],[37.2065,32.5575],[37.105,32.4545],[37.065,32.4285],[36.9625,32.44],[36.881,32.334],[36.838,32.3115],[36.71,32.3165],[36.6895,32.3345],[36.512,32.357],[36.407,32.377],[36.3055,32.4595],[36.2065,32.5195],[36.1225,32.5245],[36.0785,32.5135],[36.0625,32.576],[36.0295,32.597],[36.027,32.6535],[35.967,32.6625],[35.936,32.718],[35.882,32.7145],[35.7865,32.7475],[35.7565,32.745]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/c0/Flag_of_Jordan.svg","name:en":"Jordan","wikidata":"Q810","ISO3166-1:alpha2":"JO","ISO3166-1:alpha3":"JOR","ISO3166-1:numeric":"400"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[38.7935,33.375],[38.88,33.119],[39.086,32.502],[38.9855,32.4775],[39.043,32.3035],[39.26,32.355],[39.3015,32.2305],[39.201,32.1545],[39.973,32.0245],[40.4135,31.948],[40.796,31.736],[41.4405,31.373],[42.0855,31.1115],[42.6585,30.7065],[43.2445,30.2865],[43.7065,29.9505],[44.0405,29.705],[44.5135,29.3545],[44.727,29.1915],[44.8335,29.187],[45.3745,29.142],[45.725,29.1195],[46.4245,29.0585],[46.5525,29.1005],[46.6605,29.196],[46.7675,29.322],[46.7845,29.3555],[46.867,29.437],[46.9045,29.525],[46.998,29.6635],[47.007,29.722],[47.0815,29.8515],[47.1395,29.987],[47.1895,30.0285],[47.2875,30.0585],[47.371,30.1035],[47.7075,30.1035],[48.023,29.9785],[48.065,30.021],[48.1515,30.017],[48.318,29.881],[48.3835,29.8045],[48.464,29.757],[48.5235,29.707],[48.5815,29.638],[48.634,29.669],[48.7065,29.6855],[48.7885,29.7305],[48.859,29.8165],[48.802,29.8245],[48.68,29.888],[48.611,29.9365],[48.508,29.9675],[48.4515,30.0075],[48.4485,30.0595],[48.386,30.1335],[48.415,30.166],[48.405,30.2165],[48.278,30.3325],[48.1955,30.336],[48.176,30.4155],[48.136,30.444],[48.0285,30.4775],[48.04,30.5445],[48.0435,30.724],[48.0355,30.998],[47.8705,31.01],[47.8,31.0005],[47.6875,31.003],[47.6855,31.395],[47.866,31.7835],[47.8065,31.842],[47.8095,31.8815],[47.7315,31.9395],[47.6975,32.022],[47.646,32.06],[47.5995,32.1165],[47.529,32.142],[47.5655,32.193],[47.4625,32.321],[47.4655,32.3915],[47.378,32.474],[47.282,32.4885],[47.247,32.4635],[47.1685,32.4575],[47.111,32.4895],[46.956,32.5975],[46.887,32.632],[46.7205,32.786],[46.656,32.8075],[46.5185,32.898],[46.4155,32.9415],[46.3125,32.969],[46.244,32.97],[46.1735,32.9535],[46.094,32.985],[46.148,33.0505],[46.0845,33.0915],[46.1235,33.116],[46.1985,33.1915],[46.19,33.264],[46.134,33.292],[46.078,33.3575],[46.008,33.5045],[45.954,33.4905],[45.863,33.493],[45.961,33.5615],[45.858,33.632],[45.753,33.593],[45.7715,33.637],[45.6745,33.699],[45.648,33.7635],[45.501,33.951],[45.451,33.945],[45.4205,33.9875],[45.467,34.019],[45.515,34.1125],[45.5815,34.146],[45.5555,34.198],[45.583,34.248],[45.562,34.3315],[45.4675,34.379],[45.44,34.459],[45.5255,34.493],[45.515,34.555],[45.577,34.5585],[45.714,34.541],[45.7395,34.5865],[45.702,34.6945],[45.658,34.7185],[45.7225,34.838],[45.795,34.856],[45.7885,34.9115],[45.865,34.8965],[45.8925,34.95],[45.8805,35.038],[45.944,35.091],[46.0675,35.043],[46.1915,35.111],[46.157,35.164],[46.194,35.211],[46.1125,35.235],[46.1585,35.2845],[46.1455,35.313],[46.0385,35.4055],[45.9855,35.496],[46.0135,35.574],[46.014,35.6845],[46.0355,35.7055],[46.101,35.6875],[46.165,35.689],[46.2335,35.715],[46.347,35.787],[46.34,35.82],[46.2895,35.827],[46.2125,35.795],[46.1665,35.8005],[46.1375,35.8435],[46.0585,35.856],[45.9555,35.823],[45.896,35.8375],[45.8315,35.8095],[45.763,35.8],[45.7095,35.8825],[45.6655,35.927],[45.5555,35.9995],[45.4535,35.9945],[45.402,35.971],[45.343,36.0095],[45.3815,36.084],[45.327,36.1395],[45.3365,36.204],[45.3025,36.275],[45.261,36.3015],[45.2765,36.3765],[45.2375,36.433],[45.1505,36.4045],[45.0815,36.4255],[45.0265,36.6005],[45.071,36.63],[45.0615,36.695],[45.0305,36.7405],[44.9725,36.7495],[44.9425,36.7845],[44.845,36.7785],[44.8385,36.816],[44.8945,36.8535],[44.9125,36.9165],[44.8825,36.954],[44.904,37.004],[44.8545,37.047],[44.817,37.04],[44.7775,37.0965],[44.7845,37.144],[44.769,37.164],[44.682,37.171],[44.627,37.19],[44.576,37.1625],[44.5115,37.101],[44.392,37.0505],[44.3065,36.97],[44.2675,36.976],[44.235,37.042],[44.185,37.098],[44.222,37.158],[44.2765,37.165],[44.2685,37.2445],[44.1245,37.323],[44.0145,37.322],[43.9165,37.2235],[43.694,37.2355],[43.6205,37.2215],[43.578,37.25],[43.4745,37.253],[43.3275,37.326],[43.3015,37.3035],[43.2405,37.345],[43.151,37.371],[43.072,37.3665],[42.9635,37.3155],[42.8975,37.3285],[42.8245,37.371],[42.78,37.3755],[42.73,37.3175],[42.6175,37.2185],[42.579,37.146],[42.464,37.142],[42.3515,37.1055],[42.3745,37.073],[42.0,36.7385],[41.9705,36.7005],[41.817,36.5875],[41.402,36.524],[41.294,36.365],[41.256,36.06],[41.3695,35.8435],[41.382,35.6255],[41.262,35.456],[41.275,35.385],[41.2425,35.2855],[41.218,35.132],[41.2275,34.974],[41.2285,34.7785],[41.1225,34.6535],[41.0165,34.448],[40.978,34.398],[40.64,34.315],[39.9825,33.985],[39.3045,33.64],[38.7935,33.375]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/f6/Flag_of_Iraq.svg","name:en":"Iraq","wikidata":"Q796","ISO3166-1:alpha2":"IQ","ISO3166-1:alpha3":"IRQ","ISO3166-1:numeric":"368"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[35.6745,34.686],[35.6245,34.665],[35.541,34.5865],[35.518,34.519],[35.5205,34.4675],[35.443,34.3835],[35.414,34.3205],[35.387,34.1735],[35.393,34.091],[35.28,34.0245],[35.2495,33.9835],[35.2275,33.9095],[35.2355,33.84],[35.201,33.7775],[35.1325,33.6145],[35.054,33.5225],[35.0165,33.4185],[34.9615,33.3315],[34.953,33.261],[34.8825,33.172],[35.0795,33.096],[35.193,33.0855],[35.2935,33.108],[35.354,33.0575],[35.4315,33.0655],[35.5035,33.0895],[35.527,33.1415],[35.5465,33.238],[35.5835,33.2675],[35.658,33.2745],[35.7155,33.3255],[35.7735,33.3355],[35.827,33.405],[35.8765,33.426],[35.9535,33.488],[35.952,33.534],[36.029,33.549],[36.059,33.5795],[36.019,33.6135],[35.946,33.6375],[35.9685,33.715],[36.067,33.8245],[36.1525,33.8555],[36.202,33.833],[36.246,33.8595],[36.323,33.833],[36.3965,33.8335],[36.356,33.8815],[36.2835,33.918],[36.328,33.978],[36.4405,34.0585],[36.476,34.0505],[36.564,34.1345],[36.595,34.1895],[36.5805,34.2775],[36.5285,34.37],[36.572,34.405],[36.4635,34.4645],[36.4435,34.5055],[36.3805,34.508],[36.4095,34.6115],[36.3115,34.683],[36.2975,34.6355],[36.1895,34.6375],[36.036,34.6285],[36.0055,34.642],[35.8395,34.6005],[35.754,34.662],[35.6745,34.686]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/5/59/Flag_of_Lebanon.svg","name:en":"Lebanon","wikidata":"Q822","ISO3166-1:alpha2":"LB","ISO3166-1:alpha3":"LBN","ISO3166-1:numeric":"422"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[41.907,3.9825],[41.7165,3.7155],[41.575,3.5245],[41.312,3.141],[41.1465,2.9855],[40.989,2.8285],[40.9915,2.1765],[40.9935,1.231],[40.9945,0.9305],[40.9945,0.5165],[40.9935,-0.1995],[40.9935,-0.834],[41.2765,-1.2165],[41.559,-1.5985],[41.5595,-1.662],[41.718,-1.803],[41.8185,-1.6625],[41.8365,-1.623],[41.9475,-1.464],[41.9965,-1.384],[42.0455,-1.339],[42.1555,-1.2025],[42.198,-1.1385],[42.258,-1.078],[42.4705,-0.819],[42.529,-0.724],[42.604,-0.658],[42.631,-0.6065],[42.752,-0.4605],[42.7815,-0.3895],[43.026,-0.1475],[43.2525,0.0975],[43.5275,0.4015],[43.6855,0.558],[43.796,0.658],[43.8845,0.7265],[43.9135,0.7595],[44.1,0.904],[44.1475,0.9325],[44.209,1.001],[44.2745,1.0465],[44.304,1.0885],[44.484,1.2455],[44.693,1.411],[44.889,1.548],[44.988,1.6125],[45.209,1.743],[45.3135,1.785],[45.4455,1.8525],[45.876,2.1095],[45.9985,2.1765],[46.16,2.294],[46.2475,2.376],[46.3595,2.511],[46.456,2.5905],[46.4945,2.647],[46.585,2.73],[46.7095,2.8295],[46.837,2.9505],[46.939,3.06],[47.0755,3.2255],[47.231,3.3835],[47.3605,3.531],[47.457,3.6215],[47.62,3.788],[47.7355,3.9325],[47.9015,4.1085],[48.003,4.2305],[48.0755,4.302],[48.156,4.4065],[48.3265,4.6965],[48.3555,4.763],[48.4375,4.8915],[48.583,5.084],[48.6995,5.231],[48.814,5.3885],[48.8965,5.5295],[49.088,5.824],[49.1645,5.9715],[49.2365,6.131],[49.279,6.2825],[49.2785,6.3645],[49.335,6.5175],[49.3955,6.662],[49.5405,6.9025],[49.639,7.052],[49.75,7.1985],[49.838,7.328],[49.925,7.495],[49.964,7.593],[50.0035,7.6485],[50.0365,7.781],[50.0285,7.852],[50.1095,7.934],[50.187,7.9775],[50.284,8.0675],[50.32,8.1305],[50.342,8.2085],[50.409,8.3195],[50.4915,8.4155],[50.521,8.48],[50.5365,8.5685],[50.576,8.6385],[50.6095,8.7705],[50.7775,8.9255],[50.821,8.988],[50.847,9.061],[50.8545,9.1235],[50.902,9.165],[51.011,9.33],[51.0465,9.429],[51.046,9.505],[51.014,9.5845],[51.048,9.7865],[51.0955,9.94],[51.1035,9.9955],[51.0925,10.088],[51.1075,10.203],[51.152,10.2145],[51.216,10.1825],[51.2705,10.172],[51.401,10.1645],[51.471,10.1865],[51.5465,10.255],[51.612,10.391],[51.618,10.4605],[51.598,10.5325],[51.527,10.628],[51.4625,10.667],[51.349,10.683],[51.3335,10.742],[51.322,10.95],[51.369,11.058],[51.3865,11.1435],[51.3735,11.214],[51.333,11.283],[51.2975,11.315],[51.3305,11.444],[51.4035,11.529],[51.4405,11.5915],[51.4595,11.703],[51.4905,11.796],[51.475,11.913],[51.4225,11.985],[51.3415,12.032],[51.255,12.043],[51.2035,12.065],[51.1115,12.0725],[51.036,12.112],[50.93,12.1405],[50.882,12.1695],[50.7695,12.189],[50.6965,12.173],[50.646,12.1435],[50.5485,12.1265],[50.475,12.0845],[50.41,12.0295],[50.3585,11.95],[50.3255,11.849],[50.215,11.7995],[50.166,11.7685],[50.012,11.706],[49.946,11.7165],[49.887,11.708],[49.79,11.6615],[49.7035,11.6805],[49.632,11.673],[49.479,11.6355],[49.442,11.616],[49.351,11.533],[49.2695,11.534],[49.178,11.495],[48.9395,11.4425],[48.837,11.4825],[48.688,11.524],[48.4875,11.5075],[48.419,11.485],[48.3635,11.4815],[48.2725,11.453],[48.2015,11.4035],[48.1605,11.3905],[48.074,11.3295],[47.991,11.319],[47.921,11.3275],[47.85,11.316],[47.798,11.323],[47.7095,11.307],[47.6305,11.3605],[47.5615,11.381],[47.3865,11.3755],[47.2935,11.4245],[47.2245,11.428],[47.129,11.3925],[47.068,11.333],[47.032,11.227],[46.9655,11.1575],[46.8205,11.0895],[46.746,11.0275],[46.576,10.929],[46.428,10.892],[46.3375,10.9575],[46.234,10.984],[46.095,10.9655],[46.045,10.975],[45.872,11.0585],[45.7675,11.066],[45.68,11.039],[45.5735,10.964],[45.4845,10.931],[45.3895,10.8615],[45.3345,10.865],[45.235,10.843],[45.1735,10.7995],[45.1075,10.727],[44.9965,10.688],[44.8665,10.611],[44.747,10.6195],[44.582,10.5845],[44.391,10.6055],[44.32,10.6695],[44.2285,10.7295],[44.1735,10.78],[44.088,10.836],[43.9455,10.962],[43.8355,11.0875],[43.702,11.314],[43.707,11.4135],[43.6715,11.4995],[43.666,11.5615],[43.6405,11.62],[43.5785,11.682],[43.469,11.716],[43.4255,11.7115],[43.3445,11.6225],[43.228,11.412],[42.967,10.997],[42.9615,10.9845],[42.93,10.947],[42.766,10.7215],[42.719,10.6475],[42.7085,10.578],[42.747,10.512],[42.792,10.4035],[42.833,10.278],[42.8875,10.1895],[43.036,10.034],[43.086,9.908],[43.15,9.899],[43.257,9.843],[43.298,9.606],[43.33,9.6015],[43.4055,9.545],[43.439,9.447],[43.5155,9.3815],[43.643,9.357],[43.9965,9.0],[44.69,8.7725],[45.2675,8.5795],[45.6265,8.4625],[46.2255,8.2635],[46.993,8.0015],[47.9825,8.0],[47.557,7.561],[47.3375,7.3825],[46.873,6.9075],[46.511,6.5205],[45.845,5.9565],[45.411,5.5365],[44.9985,4.946],[44.978,4.9235],[44.625,4.933],[44.549,4.926],[44.385,4.941],[44.202,4.9425],[44.154,4.9505],[44.0315,4.9435],[43.809,4.902],[43.552,4.8355],[43.4345,4.7945],[43.232,4.695],[43.0795,4.602],[43.026,4.5415],[43.0075,4.468],[42.9695,4.403],[42.8975,4.318],[42.825,4.267],[42.7355,4.2645],[42.669,4.2495],[42.587,4.216],[42.37,4.1895],[42.194,4.179],[42.0875,4.179],[42.0005,4.0935],[41.9465,4.0555],[41.943,4.0165],[41.907,3.9825]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/a/a0/Flag_of_Somalia.svg","name:en":"Somalia","wikidata":"Q1045","ISO3166-1:alpha2":"SO","ISO3166-1:alpha3":"SOM","ISO3166-1:numeric":"706"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[55.2115,22.7055],[55.4815,22.287],[55.6665,22.0],[55.4795,21.438],[55.3355,21.007],[55.1495,20.453],[55.0,20.0],[54.644,19.8815],[54.209,19.737],[53.667,19.5565],[52.917,19.3065],[52.423,19.1415],[52.0,19.0],[52.2835,18.404],[52.5005,17.9455],[52.782,17.3495],[52.746,17.2945],[52.8125,17.2855],[53.1105,16.647],[53.189,16.465],[53.2725,16.5025],[53.3985,16.536],[53.5225,16.5565],[53.6275,16.5525],[53.7705,16.604],[53.8585,16.686],[53.9965,16.7035],[54.065,16.7305],[54.178,16.808],[54.31,16.8275],[54.543,16.8295],[54.5975,16.7895],[54.688,16.751],[54.8295,16.7375],[55.0935,16.8125],[55.138,16.8345],[55.233,16.906],[55.278,16.958],[55.3575,17.0165],[55.458,17.168],[55.472,17.2355],[55.5945,17.262],[55.8045,17.281],[55.8655,17.272],[55.947,17.2885],[56.017,17.2785],[56.126,17.2965],[56.2495,17.3],[56.3135,17.287],[56.387,17.2945],[56.475,17.317],[56.5355,17.351],[56.5805,17.402],[56.606,17.465],[56.608,17.532],[56.5615,17.859],[56.612,17.9185],[56.6925,17.9775],[56.725,18.014],[56.7555,18.0805],[56.7605,18.157],[56.799,18.236],[56.819,18.3485],[56.8435,18.4255],[56.842,18.489],[56.927,18.5865],[56.9735,18.615],[57.1085,18.6675],[57.323,18.721],[57.485,18.7375],[57.682,18.737],[57.757,18.746],[57.912,18.7965],[58.0045,18.8675],[58.05,18.9455],[58.052,19.061],[58.014,19.1315],[58.0125,19.188],[57.959,19.2935],[57.9735,19.403],[57.963,19.4635],[57.922,19.56],[57.939,19.6475],[57.982,19.6975],[58.007,19.7665],[57.992,19.876],[58.017,19.9335],[58.0475,20.123],[58.2705,20.137],[58.525,19.9855],[58.5975,19.958],[58.675,19.9575],[58.748,19.983],[58.8585,20.058],[58.958,20.1595],[59.0885,20.333],[59.1595,20.399],[59.1905,20.498],[59.18,20.5665],[59.0405,20.96],[59.198,21.117],[59.3025,21.194],[59.445,21.2545],[59.513,21.309],[59.5615,21.4045],[59.6625,21.5775],[59.697,21.671],[59.7565,21.731],[59.8555,21.881],[59.884,21.989],[59.989,22.115],[60.0195,22.181],[60.036,22.256],[60.054,22.4435],[60.035,22.5275],[59.9805,22.643],[59.9275,22.697],[59.8385,22.735],[59.755,22.737],[59.6185,22.7645],[59.5685,22.803],[59.4345,22.9505],[59.3755,23.071],[59.332,23.118],[59.259,23.1605],[59.2085,23.2295],[59.1905,23.285],[59.132,23.3595],[59.1085,23.4195],[59.0445,23.4855],[58.9915,23.5195],[58.9645,23.589],[58.9085,23.664],[58.7165,23.7955],[58.571,23.8735],[58.2205,24.046],[58.099,24.068],[57.923,24.039],[57.77,23.9955],[57.688,23.9795],[57.599,24.023],[57.542,24.0325],[57.3675,24.082],[57.2775,24.116],[57.1,24.252],[57.005,24.374],[56.9275,24.491],[56.839,24.5775],[56.791,24.66],[56.7365,24.7015],[56.691,24.7845],[56.6565,24.8785],[56.594,25.009],[56.3235,24.973],[56.349,24.933],[56.3255,24.8985],[56.2595,24.86],[56.2055,24.8505],[56.201,24.785],[56.1195,24.7345],[56.0675,24.7415],[56.036,24.811],[55.9785,24.8775],[56.042,24.8865],[56.059,24.9495],[56.007,24.9945],[55.961,25.006],[55.911,24.9655],[55.8515,24.966],[55.8125,24.911],[55.8145,24.7995],[55.8315,24.78],[55.8365,24.6715],[55.816,24.6155],[55.7675,24.5725],[55.765,24.5295],[55.834,24.4095],[55.834,24.3275],[55.791,24.2795],[55.777,24.2345],[55.8335,24.201],[55.9545,24.2225],[55.9605,24.1705],[56.0175,24.0665],[55.9025,24.047],[55.833,24.0145],[55.782,24.056],[55.731,24.058],[55.633,24.02],[55.495,23.9535],[55.485,23.94],[55.5335,23.8495],[55.533,23.756],[55.569,23.7205],[55.5725,23.6295],[55.447,23.457],[55.437,23.412],[55.4015,23.3925],[55.2805,23.1775],[55.2325,23.1105],[55.2135,22.9355],[55.2275,22.7925],[55.2115,22.7055]]],[[[56.549,25.6925],[56.652,25.8255],[56.6875,25.8965],[56.696,26.016],[56.749,26.0875],[56.7715,26.187],[56.76,26.372],[56.757,26.521],[56.73,26.5875],[56.697,26.6275],[56.629,26.676],[56.546,26.7025],[56.298,26.6035],[56.0365,26.384],[55.984,26.3185],[55.8885,26.1515],[56.0865,26.0505],[56.153,26.0695],[56.1955,25.9795],[56.163,25.942],[56.18,25.91],[56.14,25.827],[56.1675,25.725],[56.1585,25.6615],[56.202,25.612],[56.4185,25.6825],[56.549,25.6925]]],[[[56.208,25.256],[56.2735,25.232],[56.344,25.264],[56.2705,25.328],[56.2455,25.2755],[56.208,25.256]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/dd/Flag_of_Oman.svg","name:en":"Oman","wikidata":"Q842","ISO3166-1:alpha2":"OM","ISO3166-1:alpha3":"OMN","ISO3166-1:numeric":"512"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[79.396,9.549],[79.378,9.6665],[79.56,9.923],[79.6675,9.973],[80.0395,10.0965],[80.226,10.825],[80.221,11.0335],[80.139,11.516],[80.175,11.748],[80.2055,11.843],[80.329,12.14],[80.431,12.333],[80.574,12.7865],[80.5855,12.889],[80.642,13.207],[80.6695,13.565],[80.4985,15.025],[80.486,15.066],[80.474,15.2525],[80.492,15.3415],[80.5475,15.43],[80.653,15.4875],[80.8425,15.5205],[81.6015,16.0475],[81.784,16.0535],[82.2085,16.169],[82.8245,16.927],[83.209,17.1575],[83.779,17.6335],[83.981,17.7975],[84.4435,18.219],[84.9495,18.6765],[85.012,18.692],[85.0545,18.7715],[85.145,18.853],[85.2,18.994],[85.5155,19.2785],[85.6455,19.3995],[85.8125,19.452],[86.0995,19.559],[86.277,19.632],[86.666,19.78],[86.7235,19.8585],[86.781,19.9885],[86.9645,20.162],[87.4865,20.654],[87.5075,20.752],[87.5035,20.8535],[87.441,20.9045],[87.3115,21.0365],[87.2655,21.138],[87.274,21.235],[87.366,21.282],[87.6745,21.34],[88.3755,21.2585],[88.7805,21.3015],[89.0455,21.403],[89.14,21.4265],[89.14,21.6085],[89.0285,21.791],[89.0425,21.867],[89.0275,21.9195],[89.073,21.929],[89.0825,22.003],[89.04,22.1025],[89.07,22.1505],[89.0705,22.197],[89.033,22.2585],[88.996,22.2855],[88.985,22.3255],[89.0005,22.4315],[88.9595,22.552],[88.9425,22.558],[88.931,22.652],[88.96,22.685],[88.9115,22.7575],[88.963,22.819],[88.95,22.876],[88.9105,22.88],[88.8905,22.9275],[88.855,22.9585],[88.884,23.0405],[88.8685,23.101],[88.916,23.13],[88.9415,23.2065],[88.912,23.234],[88.85,23.2305],[88.8095,23.255],[88.734,23.2435],[88.703,23.307],[88.7575,23.3845],[88.753,23.4795],[88.6515,23.556],[88.637,23.605],[88.5905,23.639],[88.5595,23.712],[88.59,23.7995],[88.587,23.873],[88.6695,23.868],[88.737,23.919],[88.723,23.997],[88.7455,24.0325],[88.699,24.0845],[88.7005,24.153],[88.744,24.1875],[88.7395,24.2445],[88.7065,24.303],[88.652,24.294],[88.577,24.3165],[88.498,24.321],[88.3655,24.412],[88.226,24.469],[88.111,24.524],[88.1065,24.573],[88.0755,24.6335],[88.008,24.668],[88.063,24.7255],[88.109,24.8125],[88.165,24.8615],[88.152,24.9065],[88.1695,24.9515],[88.2295,24.958],[88.264,24.8855],[88.3425,24.8705],[88.396,24.9375],[88.3975,24.969],[88.438,25.009],[88.463,25.0795],[88.444,25.198],[88.477,25.213],[88.559,25.192],[88.6205,25.2055],[88.7155,25.207],[88.7995,25.171],[88.8315,25.206],[88.875,25.179],[88.949,25.181],[88.952,25.247],[89.0095,25.2985],[88.9155,25.312],[88.9055,25.338],[88.838,25.3695],[88.8035,25.5245],[88.7595,25.5265],[88.7105,25.4815],[88.6465,25.478],[88.603,25.516],[88.548,25.5175],[88.45,25.6045],[88.454,25.6645],[88.402,25.673],[88.357,25.7215],[88.2365,25.81],[88.172,25.787],[88.102,25.8285],[88.0855,25.9145],[88.111,25.934],[88.1415,26.0145],[88.1775,26.0215],[88.1855,26.0635],[88.1585,26.095],[88.1775,26.148],[88.325,26.2045],[88.3475,26.221],[88.3495,26.2825],[88.434,26.335],[88.524,26.36],[88.4845,26.459],[88.4155,26.4695],[88.35,26.5105],[88.397,26.626],[88.448,26.5355],[88.5605,26.461],[88.65,26.4295],[88.702,26.336],[88.6675,26.272],[88.803,26.3055],[88.8385,26.2325],[88.8755,26.2865],[88.9185,26.288],[88.9535,26.242],[89.0455,26.241],[89.04,26.281],[88.9825,26.309],[88.911,26.3705],[88.9575,26.4575],[89.0375,26.4],[89.09,26.392],[89.105,26.3265],[89.1355,26.3095],[89.125,26.264],[89.148,26.209],[89.155,26.139],[89.2285,26.123],[89.254,26.064],[89.3405,26.0155],[89.4275,26.013],[89.4635,25.998],[89.5165,26.0095],[89.54,25.97],[89.5865,25.9805],[89.589,26.039],[89.6435,26.063],[89.6295,26.1165],[89.601,26.1295],[89.6185,26.1795],[89.6875,26.1815],[89.7655,26.1285],[89.8215,26.01],[89.85,25.99],[89.8255,25.9455],[89.8875,25.945],[89.833,25.8705],[89.8265,25.81],[89.8355,25.7155],[89.8825,25.6215],[89.861,25.5155],[89.8145,25.374],[89.838,25.296],[89.904,25.3105],[90.1105,25.2245],[90.289,25.1955],[90.3835,25.154],[90.4385,25.147],[90.5235,25.1745],[90.741,25.1585],[90.776,25.176],[90.816,25.151],[91.082,25.198],[91.1795,25.1955],[91.269,25.2045],[91.328,25.1765],[91.44,25.151],[91.548,25.1495],[91.5755,25.172],[91.636,25.127],[91.6945,25.134],[91.7575,25.174],[91.791,25.1655],[91.915,25.181],[91.9825,25.1705],[92.0345,25.1885],[92.193,25.14],[92.224,25.0995],[92.347,25.05],[92.428,25.0315],[92.4205,24.967],[92.4845,24.9325],[92.499,24.904],[92.424,24.853],[92.317,24.895],[92.249,24.909],[92.244,24.8425],[92.27,24.832],[92.2975,24.7345],[92.26,24.683],[92.2145,24.503],[92.17,24.5305],[92.1545,24.4795],[92.169,24.4355],[92.091,24.371],[91.996,24.3875],[91.923,24.3335],[91.9475,24.2645],[91.9115,24.144],[91.8235,24.2085],[91.75,24.241],[91.762,24.1545],[91.7255,24.144],[91.6455,24.1705],[91.6435,24.1135],[91.586,24.0715],[91.474,24.099],[91.376,24.1055],[91.398,24.05],[91.361,23.984],[91.3225,23.993],[91.272,23.9605],[91.231,23.8815],[91.2535,23.8345],[91.21,23.747],[91.1695,23.7485],[91.1575,23.69],[91.21,23.6875],[91.2065,23.65],[91.1605,23.639],[91.202,23.523],[91.251,23.4765],[91.2915,23.319],[91.325,23.2385],[91.3255,23.1585],[91.3705,23.0715],[91.412,23.077],[91.3835,23.1555],[91.384,23.193],[91.418,23.2685],[91.449,23.261],[91.503,23.1935],[91.4975,23.147],[91.5515,23.0385],[91.544,23.0],[91.5775,22.9675],[91.627,22.956],[91.7215,22.989],[91.7835,23.037],[91.834,23.094],[91.8085,23.135],[91.7625,23.3095],[91.813,23.349],[91.8535,23.4065],[91.966,23.484],[91.9495,23.617],[91.9295,23.683],[91.978,23.735],[92.0005,23.673],[92.068,23.648],[92.141,23.7325],[92.205,23.705],[92.279,23.7265],[92.291,23.681],[92.273,23.6435],[92.306,23.583],[92.3165,23.4865],[92.3535,23.39],[92.381,23.352],[92.402,23.2365],[92.354,23.236],[92.361,23.0985],[92.3925,23.0565],[92.374,22.971],[92.378,22.9295],[92.4195,22.911],[92.4645,22.8545],[92.4545,22.82],[92.479,22.7535],[92.5165,22.7225],[92.543,22.491],[92.591,22.255],[92.599,22.137],[92.5665,22.1415],[92.601,21.982],[92.6795,22.027],[92.678,22.0995],[92.7185,22.1595],[92.806,22.104],[92.8545,22.0595],[92.8655,22.0255],[92.9225,21.994],[92.9895,22.061],[93.042,22.1365],[93.0385,22.1955],[93.0715,22.2115],[93.1575,22.187],[93.142,22.2445],[93.202,22.2645],[93.1855,22.339],[93.1855,22.428],[93.1315,22.468],[93.113,22.5595],[93.141,22.594],[93.108,22.6355],[93.092,22.7095],[93.1065,22.746],[93.0955,22.807],[93.146,22.9275],[93.123,23.0075],[93.14,23.054],[93.2105,23.0475],[93.235,23.011],[93.2945,23.008],[93.32,23.029],[93.3645,23.121],[93.3875,23.216],[93.3555,23.3535],[93.4025,23.3895],[93.388,23.4205],[93.3975,23.5105],[93.4185,23.5415],[93.4175,23.6365],[93.436,23.6875],[93.3945,23.754],[93.385,23.8765],[93.3925,23.924],[93.352,23.947],[93.3255,24.0465],[93.344,24.092],[93.3985,24.0855],[93.4655,23.972],[93.51,23.9465],[93.564,23.9785],[93.5945,23.962],[93.6265,24.0115],[93.7225,23.999],[93.7565,24.006],[93.815,23.924],[93.894,23.9515],[93.9735,23.9235],[94.022,23.926],[94.0465,23.8925],[94.095,23.8855],[94.117,23.838],[94.156,23.847],[94.169,23.9275],[94.238,24.033],[94.2555,24.081],[94.2605,24.164],[94.4085,24.44],[94.4555,24.5695],[94.5095,24.5925],[94.541,24.6425],[94.5465,24.707],[94.607,24.711],[94.6295,24.754],[94.633,24.835],[94.6845,24.882],[94.7135,24.93],[94.697,24.961],[94.737,25.001],[94.745,25.063],[94.7255,25.134],[94.6035,25.1845],[94.5775,25.216],[94.5855,25.268],[94.6865,25.466],[94.808,25.4955],[94.845,25.5605],[94.918,25.6145],[94.9405,25.672],[95.038,25.74],[95.0515,25.798],[95.02,25.872],[95.029,25.935],[95.081,25.947],[95.1565,26.0195],[95.185,26.075],[95.12,26.0995],[95.1225,26.3065],[95.1325,26.3775],[95.073,26.4725],[95.114,26.518],[95.1085,26.543],[95.154,26.583],[95.149,26.6155],[95.208,26.6475],[95.315,26.6645],[95.4395,26.7025],[95.485,26.7485],[95.5035,26.8065],[95.546,26.8295],[95.6095,26.814],[95.658,26.8915],[95.7135,26.883],[95.7555,26.91],[95.7555,26.951],[95.804,27.0155],[95.831,27.008],[95.946,27.052],[96.0075,27.14],[96.022,27.18],[96.091,27.2235],[96.314,27.2935],[96.4095,27.292],[96.4335,27.305],[96.5265,27.289],[96.582,27.314],[96.606,27.363],[96.6765,27.3355],[96.7155,27.376],[96.7765,27.356],[96.8295,27.312],[96.855,27.267],[96.858,27.215],[96.89,27.1765],[97.0105,27.145],[97.076,27.0955],[97.1455,27.0925],[97.1765,27.14],[97.1015,27.2145],[97.088,27.245],[97.002,27.3455],[96.9145,27.461],[96.9335,27.508],[96.9,27.6085],[96.995,27.671],[97.026,27.7355],[97.1125,27.7695],[97.255,27.894],[97.293,27.9135],[97.36,27.873],[97.379,27.892],[97.3675,27.977],[97.3945,28.0185],[97.3585,28.063],[97.3445,28.117],[97.361,28.1655],[97.346,28.2145],[97.2485,28.264],[97.146,28.353],[97.0785,28.3715],[97.027,28.33],[96.977,28.3295],[96.8895,28.386],[96.893,28.4185],[96.861,28.4855],[96.767,28.515],[96.7455,28.5715],[96.655,28.609],[96.6135,28.6135],[96.538,28.572],[96.4785,28.4905],[96.412,28.517],[96.4815,28.555],[96.451,28.583],[96.537,28.6545],[96.536,28.681],[96.597,28.6965],[96.62,28.7275],[96.5765,28.8185],[96.519,28.8675],[96.508,28.9465],[96.441,28.9525],[96.4345,29.0065],[96.362,29.048],[96.358,29.094],[96.2695,29.0965],[96.23,29.047],[96.183,29.111],[96.235,29.1295],[96.2995,29.191],[96.261,29.2445],[96.196,29.2635],[96.1495,29.295],[96.139,29.343],[96.0535,29.3825],[96.0165,29.3625],[95.9655,29.376],[95.8775,29.3145],[95.8125,29.3475],[95.737,29.298],[95.7525,29.276],[95.7055,29.213],[95.648,29.2105],[95.6055,29.236],[95.589,29.188],[95.5085,29.195],[95.5095,29.1265],[95.458,29.137],[95.419,29.1805],[95.379,29.137],[95.2995,29.1365],[95.273,29.1055],[95.179,29.1045],[95.136,29.0885],[95.097,29.142],[94.9945,29.144],[94.8475,29.1825],[94.8095,29.165],[94.7945,29.2175],[94.7515,29.2295],[94.735,29.287],[94.6935,29.318],[94.5905,29.272],[94.541,29.2195],[94.5105,29.231],[94.452,29.189],[94.3905,29.184],[94.379,29.154],[94.293,29.1525],[94.2845,29.0865],[94.3125,29.079],[94.342,29.002],[94.274,28.968],[94.2605,28.9315],[94.1785,28.936],[94.1315,28.889],[94.0785,28.8825],[93.975,28.8215],[93.8965,28.7575],[93.7875,28.733],[93.7845,28.7135],[93.707,28.6645],[93.643,28.6575],[93.623,28.6885],[93.512,28.6675],[93.4575,28.668],[93.3895,28.5325],[93.3075,28.527],[93.23,28.5915],[93.197,28.545],[93.1485,28.3665],[92.9915,28.273],[92.9325,28.249],[92.9215,28.2005],[92.8265,28.175],[92.791,28.1875],[92.739,28.154],[92.6775,28.151],[92.6645,28.0705],[92.7375,28.0415],[92.7235,27.9735],[92.6505,27.915],[92.5815,27.89],[92.4775,27.8365],[92.422,27.8355],[92.3205,27.8],[92.2905,27.873],[92.2445,27.888],[92.143,27.835],[92.108,27.803],[92.036,27.7755],[91.979,27.7745],[91.925,27.7165],[91.8725,27.72],[91.829,27.788],[91.8015,27.7725],[91.722,27.783],[91.6605,27.829],[91.6125,27.839],[91.5695,27.8175],[91.6145,27.8215],[91.645,27.77],[91.6285,27.6985],[91.573,27.661],[91.566,27.584],[91.6515,27.484],[91.7775,27.4655],[91.925,27.473],[91.9435,27.46],[92.017,27.4805],[92.056,27.4],[92.065,27.3275],[92.1235,27.2865],[92.0465,27.2695],[92.0715,27.238],[92.0275,27.1625],[92.023,27.11],[92.0445,27.052],[92.0815,27.0405],[92.12,26.9715],[92.1035,26.8695],[92.0565,26.8495],[91.987,26.861],[91.894,26.9195],[91.8595,26.9135],[91.825,26.864],[91.7245,26.814],[91.627,26.821],[91.4945,26.7925],[91.41,26.8395],[91.378,26.796],[91.3385,26.7805],[91.235,26.8125],[91.0985,26.8225],[91.0555,26.7815],[90.9955,26.7905],[90.822,26.7765],[90.691,26.7715],[90.5475,26.8165],[90.418,26.9045],[90.3545,26.9015],[90.3,26.8485],[90.248,26.86],[90.2005,26.835],[90.1905,26.768],[90.045,26.73],[89.902,26.723],[89.8625,26.7015],[89.771,26.702],[89.745,26.73],[89.679,26.7395],[89.649,26.7705],[89.557,26.8135],[89.4765,26.802],[89.4395,26.8405],[89.379,26.8625],[89.3175,26.8515],[89.2625,26.8155],[89.141,26.812],[89.102,26.836],[89.0955,26.8915],[89.0155,26.94],[88.9795,26.918],[88.9225,26.993],[88.874,26.954],[88.87,27.11],[88.7465,27.142],[88.7995,27.2085],[88.8025,27.2485],[88.9045,27.273],[88.9215,27.3275],[88.8075,27.4045],[88.783,27.4535],[88.7715,27.558],[88.8065,27.5965],[88.8095,27.6375],[88.8445,27.662],[88.8565,27.717],[88.857,27.8155],[88.888,27.8565],[88.843,27.956],[88.836,28.0155],[88.7545,28.0805],[88.667,28.0765],[88.64,28.116],[88.5575,28.0755],[88.546,28.034],[88.492,28.0485],[88.468,28.017],[88.3225,27.98],[88.2635,27.9555],[88.2375,27.9695],[88.1875,27.9425],[88.1425,27.9655],[88.118,27.918],[88.135,27.8815],[88.201,27.8375],[88.197,27.791],[88.1585,27.741],[88.144,27.665],[88.085,27.5905],[88.044,27.4785],[88.0785,27.432],[88.0415,27.3705],[88.0665,27.3365],[88.0315,27.2865],[88.007,27.1435],[87.991,27.131],[88.0375,27.037],[88.083,27.029],[88.118,26.9875],[88.136,26.899],[88.172,26.869],[88.1895,26.7465],[88.1635,26.646],[88.1055,26.561],[88.1035,26.4665],[88.0775,26.419],[87.992,26.3695],[87.916,26.434],[87.9,26.4775],[87.8485,26.437],[87.793,26.469],[87.7695,26.4215],[87.678,26.416],[87.6515,26.3935],[87.5875,26.393],[87.516,26.431],[87.4665,26.4405],[87.3885,26.419],[87.3135,26.3675],[87.266,26.374],[87.247,26.4145],[87.1615,26.404],[87.0915,26.4505],[87.0725,26.543],[86.932,26.516],[86.894,26.462],[86.8335,26.439],[86.7655,26.4595],[86.737,26.423],[86.694,26.451],[86.57,26.4965],[86.542,26.5385],[86.306,26.62],[86.141,26.617],[86.028,26.6665],[85.974,26.657],[85.861,26.5705],[85.851,26.6085],[85.732,26.654],[85.723,26.687],[85.735,26.7795],[85.7205,26.8205],[85.642,26.853],[85.543,26.8385],[85.4515,26.7815],[85.4075,26.7915],[85.334,26.742],[85.197,26.771],[85.177,26.8145],[85.193,26.8665],[85.099,26.871],[85.0575,26.849],[84.9625,26.9605],[84.855,26.986],[84.8195,27.0215],[84.7575,27.003],[84.6435,27.046],[84.6705,27.091],[84.682,27.2365],[84.6225,27.336],[84.294,27.385],[84.254,27.453],[84.176,27.4745],[84.1055,27.521],[84.052,27.4435],[83.874,27.4345],[83.865,27.371],[83.8295,27.3705],[83.6145,27.469],[83.389,27.48],[83.4075,27.415],[83.388,27.3755],[83.3375,27.3325],[83.2965,27.3335],[83.272,27.3835],[83.188,27.4545],[83.0345,27.449],[82.954,27.468],[82.9295,27.501],[82.7365,27.5025],[82.757,27.5835],[82.7075,27.715],[82.605,27.706],[82.473,27.6765],[82.402,27.7035],[82.368,27.7425],[82.3035,27.773],[82.209,27.843],[82.121,27.866],[82.0625,27.9215],[81.9685,27.929],[81.9,27.8535],[81.805,27.904],[81.6985,27.988],[81.644,27.9935],[81.4785,28.0825],[81.484,28.1185],[81.447,28.161],[81.3745,28.177],[81.368,28.141],[81.313,28.1565],[81.321,28.1975],[81.2325,28.289],[81.211,28.361],[81.0815,28.3845],[81.0335,28.428],[80.9055,28.466],[80.768,28.5655],[80.7145,28.5685],[80.6675,28.642],[80.614,28.639],[80.5395,28.6905],[80.5035,28.665],[80.5225,28.5525],[80.4605,28.622],[80.377,28.629],[80.275,28.711],[80.2565,28.754],[80.216,28.7555],[80.1185,28.828],[80.0645,28.8375],[80.059,28.916],[80.127,29.006],[80.1455,29.1045],[80.1865,29.137],[80.2355,29.1175],[80.2715,29.1465],[80.262,29.206],[80.29,29.2315],[80.318,29.3045],[80.2795,29.3475],[80.246,29.447],[80.3025,29.4545],[80.298,29.49],[80.342,29.5105],[80.3485,29.5555],[80.408,29.597],[80.4165,29.652],[80.385,29.6735],[80.366,29.726],[80.4175,29.796],[80.493,29.795],[80.5535,29.853],[80.574,29.9235],[80.6015,29.958],[80.6745,29.957],[80.7385,29.999],[80.8055,30.09],[80.878,30.1285],[80.8715,30.1605],[81.0345,30.197],[81.031,30.247],[80.981,30.2705],[80.927,30.267],[80.9065,30.3035],[80.8335,30.313],[80.7875,30.3405],[80.715,30.414],[80.693,30.413],[80.6065,30.4715],[80.541,30.449],[80.497,30.488],[80.4195,30.515],[80.3455,30.5205],[80.3155,30.5645],[80.2545,30.5645],[80.2085,30.588],[80.2195,30.643],[80.1925,30.666],[80.249,30.7205],[80.2385,30.7625],[80.1975,30.765],[80.1795,30.806],[80.1085,30.7815],[80.05,30.841],[79.9885,30.877],[79.929,30.8825],[79.889,30.9175],[79.8575,30.9755],[79.776,30.986],[79.663,30.9645],[79.601,30.939],[79.553,30.9575],[79.507,31.0325],[79.427,31.0235],[79.414,31.1065],[79.321,31.1385],[79.301,31.219],[79.2265,31.2605],[79.25,31.2935],[79.2235,31.346],[79.1425,31.432],[79.075,31.459],[79.019,31.4265],[79.0185,31.349],[78.944,31.3655],[78.913,31.31],[78.833,31.294],[78.778,31.3125],[78.753,31.385],[78.795,31.444],[78.7205,31.5075],[78.7445,31.542],[78.8225,31.5785],[78.8465,31.607],[78.761,31.675],[78.702,31.807],[78.7355,31.8325],[78.7425,31.902],[78.779,31.9665],[78.74,32.0015],[78.7065,32.063],[78.597,32.158],[78.4965,32.276],[78.476,32.3325],[78.4725,32.4435],[78.3925,32.538],[78.4145,32.566],[78.502,32.5845],[78.5465,32.619],[78.611,32.6005],[78.635,32.6445],[78.723,32.6745],[78.7815,32.6165],[78.7575,32.567],[78.813,32.434],[78.8685,32.4135],[78.9685,32.3355],[78.9895,32.37],[79.058,32.387],[79.1045,32.3745],[79.1175,32.4545],[79.184,32.498],[79.248,32.5165],[79.311,32.56],[79.41,32.519],[79.399,32.604],[79.4605,32.71],[79.4145,32.737],[79.407,32.7855],[79.303,32.892],[79.3065,32.928],[79.1605,33.015],[79.14,33.106],[79.1625,33.1675],[79.073,33.223],[79.035,33.2725],[79.027,33.32],[78.9625,33.3395],[78.9365,33.387],[78.836,33.4265],[78.8035,33.4895],[78.74,33.554],[78.741,33.601],[78.6785,33.667],[78.731,33.6835],[78.775,33.738],[78.754,33.7845],[78.7655,33.836],[78.7315,33.9275],[78.7425,34.0],[78.6575,34.0315],[78.6575,34.0745],[78.7425,34.0925],[78.826,34.1245],[78.862,34.1655],[78.9255,34.1545],[78.944,34.225],[78.9855,34.314],[78.982,34.357],[78.947,34.3895],[78.902,34.381],[78.851,34.4155],[78.7425,34.453],[78.7565,34.4845],[78.7095,34.526],[78.634,34.544],[78.5635,34.5095],[78.552,34.5715],[78.4825,34.5785],[78.3855,34.6065],[78.29,34.615],[78.2625,34.6635],[78.272,34.7015],[78.2085,34.7205],[78.237,34.868],[78.1785,34.9285],[78.2015,34.973],[78.1145,35.032],[78.1275,35.1005],[78.0495,35.114],[78.0565,35.175],[78.003,35.243],[78.023,35.359],[78.101,35.4305],[78.098,35.4995],[78.025,35.4685],[77.968,35.4945],[77.911,35.462],[77.812,35.523],[77.7425,35.4955],[77.719,35.4615],[77.6295,35.4625],[77.5595,35.487],[77.501,35.4895],[77.4425,35.462],[77.3815,35.4735],[77.3025,35.5455],[77.194,35.522],[77.011,35.611],[76.9575,35.5965],[76.815,35.67],[76.776,35.658],[76.755,35.6295],[76.7935,35.588],[76.7495,35.555],[76.759,35.5185],[76.8385,35.443],[76.863,35.3895],[76.948,35.393],[77.0065,35.2945],[76.975,35.2515],[77.0175,35.183],[77.0855,35.169],[77.0825,35.099],[77.1105,35.049],[77.047,35.0515],[76.961,35.0175],[76.898,34.926],[76.8615,34.9485],[76.792,34.954],[76.7455,34.8885],[76.737,34.8065],[76.7015,34.796],[76.697,34.7505],[76.642,34.734],[76.541,34.762],[76.4865,34.796],[76.4195,34.7375],[76.328,34.7195],[76.2825,34.7235],[76.2505,34.6765],[76.1635,34.6325],[76.116,34.6395],[76.063,34.688],[75.9455,34.6255],[75.785,34.5135],[75.6705,34.54],[75.463,34.5345],[75.365,34.538],[75.301,34.5865],[75.2475,34.6035],[75.267,34.6365],[75.163,34.6565],[75.026,34.6295],[74.936,34.673],[74.7305,34.681],[74.651,34.706],[74.58,34.7615],[74.4485,34.7825],[74.3095,34.7825],[74.2415,34.727],[74.158,34.6885],[74.142,34.6605],[73.969,34.6855],[73.932,34.6415],[73.9535,34.5605],[73.905,34.528],[73.88,34.4535],[73.803,34.42],[73.7505,34.369],[73.774,34.3325],[73.859,34.324],[73.939,34.3365],[73.9455,34.276],[73.9905,34.2705],[74.0035,34.1905],[73.927,34.1275],[73.896,34.06],[73.965,34.0135],[74.016,34.0395],[74.1325,34.047],[74.1975,34.017],[74.233,34.0235],[74.277,33.9695],[74.2815,33.901],[74.1895,33.839],[74.06,33.824],[74.01,33.7765],[73.9815,33.707],[73.981,33.6415],[74.0315,33.5785],[74.081,33.585],[74.1405,33.5575],[74.1925,33.4785],[74.1885,33.4085],[74.1665,33.3375],[74.1265,33.3045],[74.018,33.2705],[74.017,33.205],[74.0705,33.194],[74.154,33.1365],[74.2015,33.0665],[74.318,33.032],[74.3385,32.9555],[74.42,32.8855],[74.4195,32.84],[74.4485,32.7935],[74.5185,32.7485],[74.6305,32.7675],[74.6585,32.83],[74.7045,32.817],[74.6535,32.697],[74.695,32.6605],[74.657,32.6305],[74.6515,32.563],[74.69,32.5345],[74.6855,32.4995],[74.7295,32.481],[74.8125,32.48],[74.859,32.4935],[74.943,32.452],[75.0155,32.4645],[75.0265,32.4975],[75.109,32.46],[75.137,32.41],[75.192,32.426],[75.238,32.387],[75.2895,32.3695],[75.3715,32.2795],[75.373,32.2285],[75.3315,32.2195],[75.314,32.172],[75.261,32.1015],[75.2205,32.1075],[75.1795,32.0765],[75.123,32.0815],[75.0125,32.0355],[74.9265,32.0665],[74.8285,31.998],[74.819,31.9585],[74.677,31.926],[74.6155,31.89],[74.5705,31.837],[74.5595,31.758],[74.4865,31.715],[74.535,31.6775],[74.5555,31.608],[74.616,31.5575],[74.5875,31.504],[74.635,31.4845],[74.6435,31.416],[74.5965,31.4165],[74.537,31.33],[74.5105,31.132],[74.5515,31.0865],[74.689,31.128],[74.7025,31.0915],[74.671,31.0535],[74.548,31.032],[74.5455,30.992],[74.48,30.974],[74.366,30.893],[74.38,30.862],[74.3205,30.8465],[74.2745,30.7355],[74.149,30.6315],[74.1285,30.6325],[74.0725,30.523],[73.993,30.514],[73.946,30.468],[73.9025,30.349],[73.9595,30.27],[73.9725,30.1985],[73.83,30.0935],[73.8065,30.068],[73.597,30.019],[73.397,29.946],[73.2825,29.572],[73.0855,29.238],[73.0045,29.153],[72.946,29.028],[72.733,28.948],[72.4795,28.812],[72.404,28.783],[72.2995,28.6695],[72.206,28.394],[72.1325,28.313],[72.0045,28.2185],[71.9275,28.1215],[71.8985,27.961],[71.6665,27.878],[71.383,27.8725],[71.2055,27.8355],[70.906,27.7095],[70.7595,27.721],[70.6845,27.828],[70.6775,27.922],[70.5895,28.0105],[70.5055,28.037],[70.372,28.012],[70.296,27.936],[70.227,27.9015],[70.1325,27.806],[70.026,27.563],[69.934,27.4975],[69.863,27.402],[69.703,27.2845],[69.587,27.1835],[69.5135,27.01],[69.4845,26.805],[69.5105,26.7435],[69.7255,26.652],[69.792,26.598],[69.886,26.5785],[70.0565,26.6005],[70.1175,26.587],[70.1745,26.5515],[70.1855,26.374],[70.1635,26.295],[70.175,26.2515],[70.141,26.156],[70.0835,26.0835],[70.1,25.938],[70.1745,25.8285],[70.2225,25.793],[70.2685,25.7135],[70.387,25.6735],[70.53,25.6835],[70.6085,25.715],[70.645,25.713],[70.674,25.676],[70.667,25.5315],[70.6785,25.5255],[70.665,25.397],[70.737,25.3325],[70.7515,25.2775],[70.8885,25.148],[70.9375,24.9385],[71.0265,24.809],[71.0655,24.7175],[71.0745,24.662],[71.009,24.6355],[70.9865,24.5955],[71.005,24.523],[70.9985,24.4445],[71.103,24.4355],[71.0495,24.356],[70.986,24.3655],[70.8785,24.302],[70.8515,24.245],[70.8055,24.221],[70.714,24.2155],[70.6445,24.225],[70.5715,24.252],[70.585,24.278],[70.5625,24.351],[70.6025,24.408],[70.573,24.4225],[70.327,24.352],[70.254,24.3255],[70.11,24.295],[70.0665,24.199],[70.025,24.171],[69.7315,24.171],[69.5945,24.2925],[69.5035,24.2685],[69.4445,24.2805],[69.367,24.27],[69.313,24.2815],[69.194,24.2365],[69.095,24.2745],[69.013,24.224],[68.985,24.2275],[68.9455,24.3025],[68.907,24.28],[68.88,24.216],[68.8565,24.214],[68.831,24.3115],[68.7645,24.296],[68.7695,24.2655],[68.753,23.9715],[68.3795,23.971],[68.32,23.9135],[68.2905,23.9445],[68.207,23.8445],[68.186,23.6885],[68.1355,23.6485],[68.1115,23.6015],[68.115,23.5395],[68.247,23.4475],[68.2765,23.2945],[68.372,23.1015],[68.661,22.9105],[68.98,22.7365],[68.983,22.677],[68.8425,22.592],[68.743,22.4535],[68.6825,22.276],[68.79,22.0165],[69.0395,21.7155],[69.2905,21.487],[69.4985,21.29],[69.807,20.95],[70.0075,20.78],[70.4175,20.576],[70.7395,20.4505],[70.909,20.443],[71.325,20.5605],[71.661,20.639],[71.9185,20.755],[72.079,20.8455],[72.226,20.8985],[72.383,20.9175],[72.47,20.811],[72.5,20.595],[72.48,20.376],[72.538,20.15],[72.6095,19.2635],[72.713,17.971],[72.9885,16.5755],[73.3285,15.608],[73.531,15.229],[73.8725,14.753],[74.324,13.822],[74.5185,12.9955],[74.6405,12.659],[74.7125,12.494],[74.971,11.945],[75.251,11.5245],[75.5525,11.043],[75.5875,10.892],[75.683,10.559],[75.9115,10.046],[76.0185,9.676],[76.2255,8.9565],[76.465,8.593],[76.673,8.343],[76.9215,8.096],[77.6675,7.8585],[78.1035,8.041],[78.361,8.1605],[78.463,8.351],[78.545,8.8475],[78.7395,8.9325],[79.069,9.0225],[79.374,8.979],[79.411,8.9405],[79.4965,8.8975],[79.5715,9.087],[79.5665,9.258],[79.4205,9.3535],[79.396,9.549]]],[[[71.5625,11.888],[71.5875,11.787],[71.666,11.701],[71.7465,11.669],[71.8295,11.6675],[71.88,11.682],[71.9545,11.731],[72.0025,11.8005],[72.02,11.906],[72.005,11.9705],[71.953,12.048],[71.864,12.1015],[71.781,12.113],[71.713,12.0995],[71.6295,12.0475],[71.572,11.9535],[71.5625,11.888]]],[[[71.6765,12.3525],[71.6945,12.2665],[71.745,12.1935],[71.805,12.152],[71.8905,12.13],[71.99,12.145],[72.046,12.1765],[72.0885,12.218],[72.12,12.275],[72.134,12.3335],[72.123,12.424],[72.095,12.4795],[72.018,12.5485],[71.965,12.5695],[71.869,12.5745],[71.7995,12.552],[71.7525,12.52],[71.7025,12.4575],[71.6765,12.3525]]],[[[71.8165,11.153],[71.826,11.089],[71.882,10.997],[71.979,10.939],[71.96,10.8635],[71.9675,10.787],[71.9905,10.7325],[72.032,10.682],[72.0975,10.64],[72.1585,10.6235],[72.2585,10.6325],[72.3315,10.671],[72.402,10.591],[72.411,10.491],[72.4395,10.434],[72.5075,10.3695],[72.6145,10.336],[72.733,10.3595],[72.7965,10.4065],[72.833,10.4575],[72.855,10.522],[72.852,10.613],[72.8285,10.6725],[72.7625,10.744],[72.7545,10.84],[72.724,10.902],[72.7705,10.907],[72.8485,10.938],[72.8985,10.981],[72.988,11.1425],[73.001,11.196],[72.998,11.266],[73.074,11.277],[73.1595,11.3255],[73.2125,11.397],[73.232,11.465],[73.2255,11.549],[73.207,11.5955],[73.148,11.666],[73.0635,11.7075],[73.007,11.7155],[72.9385,11.706],[72.9295,11.7495],[72.872,11.8435],[72.794,11.8935],[72.686,11.9075],[72.615,11.8885],[72.539,11.8335],[72.486,11.732],[72.481,11.6835],[72.4975,11.6015],[72.527,11.55],[72.585,11.4965],[72.6565,11.466],[72.748,11.463],[72.749,11.445],[72.6555,11.414],[72.5945,11.362],[72.521,11.2315],[72.4965,11.156],[72.4615,11.091],[72.3985,11.1385],[72.351,11.157],[72.2745,11.164],[72.265,11.2195],[72.2155,11.305],[72.2205,11.335],[72.309,11.379],[72.361,11.438],[72.392,11.533],[72.385,11.6105],[72.3295,11.7075],[72.253,11.7595],[72.192,11.7755],[72.1215,11.7735],[72.0305,11.7355],[71.9695,11.6725],[71.9355,11.5755],[71.9415,11.4975],[71.983,11.4145],[71.967,11.3655],[71.9075,11.3335],[71.863,11.29],[71.8245,11.213],[71.8165,11.153]]],[[[72.056,10.0635],[72.062,10.0135],[72.096,9.9375],[72.155,9.879],[72.2405,9.843],[72.2975,9.839],[72.3835,9.8605],[72.434,9.8925],[72.4935,9.9705],[72.513,10.0385],[72.507,10.1225],[72.464,10.2055],[72.408,10.255],[72.32,10.2875],[72.243,10.2865],[72.152,10.248],[72.1065,10.2055],[72.074,10.152],[72.056,10.0635]]],[[[72.809,8.278],[72.8305,8.192],[72.871,8.133],[72.956,8.081],[73.0035,8.069],[73.1095,8.076],[73.172,8.109],[73.2485,8.199],[73.281,8.329],[73.252,8.428],[73.19,8.492],[73.114,8.522],[73.015,8.515],[72.924,8.482],[72.869,8.442],[72.8185,8.352],[72.809,8.278]]],[[[73.404,10.1165],[73.426,10.0205],[73.4695,9.9595],[73.5115,9.926],[73.593,9.8955],[73.6605,9.8935],[73.746,9.921],[73.796,9.959],[73.8415,10.0235],[73.858,10.073],[73.8605,10.1465],[73.8225,10.2445],[73.756,10.308],[73.6925,10.3355],[73.579,10.337],[73.505,10.3045],[73.439,10.238],[73.409,10.1655],[73.404,10.1165]]],[[[73.4505,10.816],[73.463,10.7435],[73.505,10.6715],[73.589,10.6105],[73.683,10.592],[73.737,10.599],[73.813,10.634],[73.847,10.663],[73.8925,10.7325],[73.908,10.7975],[73.8935,10.899],[73.828,10.9885],[73.745,11.033],[73.6375,11.0385],[73.5735,11.0165],[73.5045,10.962],[73.477,10.9215],[73.4505,10.816]]],[[[93.035,13.882],[92.9025,13.85],[92.7655,13.755],[92.704,13.68],[92.6185,13.4995],[92.4925,13.1535],[92.447,12.892],[92.445,12.849],[92.4615,12.574],[92.352,12.3535],[92.0125,11.673],[91.992,11.581],[92.0065,10.9725],[92.0205,10.9035],[92.1895,10.477],[92.2145,10.4245],[92.2705,10.369],[92.3435,10.3395],[92.3895,10.336],[92.457,10.3095],[92.5705,10.3155],[92.644,10.3455],[92.7,10.4005],[92.7565,10.5025],[92.798,10.635],[92.803,10.704],[92.7885,10.819],[92.8365,10.8765],[92.867,10.9485],[92.8695,11.001],[92.9035,11.0385],[92.934,11.1105],[92.934,11.1885],[92.9085,11.252],[92.922,11.2955],[92.922,11.3735],[92.905,11.4195],[92.9555,11.58],[93.005,11.596],[93.084,11.5805],[93.1625,11.596],[93.229,11.6395],[93.2735,11.7045],[93.289,11.7815],[93.275,11.879],[93.242,11.9875],[93.2925,12.0385],[93.323,12.111],[93.323,12.189],[93.3085,12.231],[93.2955,12.336],[93.2455,12.4305],[93.174,12.4935],[93.1805,12.5415],[93.1635,12.621],[93.181,12.6695],[93.181,12.7475],[93.1565,12.8275],[93.1975,12.919],[93.236,13.042],[93.241,13.124],[93.2635,13.181],[93.292,13.2985],[93.3105,13.4325],[93.295,13.509],[93.2625,13.559],[93.2675,13.692],[93.239,13.7725],[93.1345,13.8195],[93.035,13.882]]],[[[92.5325,9.2105],[92.5525,9.136],[92.8165,8.758],[92.895,8.195],[93.4755,6.9225],[93.631,6.658],[93.6925,6.5935],[93.776,6.561],[94.1165,6.2345],[94.1845,6.2365],[94.2575,6.2665],[94.3775,6.382],[94.405,6.4365],[94.4195,6.519],[94.452,6.594],[94.4585,6.683],[94.4435,6.7595],[94.402,6.828],[94.3885,6.92],[94.323,7.0805],[94.276,7.1285],[94.2245,7.2185],[94.1325,7.289],[94.0385,7.3385],[93.986,7.3515],[93.916,7.41],[93.999,7.441],[94.0545,7.496],[94.0845,7.568],[94.11,7.7285],[94.0945,7.828],[94.065,7.8985],[94.107,7.929],[94.1505,7.994],[94.166,8.07],[94.1445,8.229],[94.114,8.3255],[94.0705,8.39],[93.992,8.4455],[93.915,8.461],[93.756,8.7415],[93.619,8.778],[93.336,8.7795],[93.3385,8.8855],[93.295,9.0075],[92.96,9.403],[92.903,9.452],[92.83,9.4815],[92.7515,9.4815],[92.679,9.452],[92.597,9.3895],[92.5535,9.325],[92.5325,9.2105]]],[[[93.647,12.2765],[93.6635,12.195],[93.7105,12.126],[93.7815,12.08],[93.8645,12.064],[93.907,12.068],[93.9855,12.0995],[94.0455,12.1585],[94.078,12.235],[94.078,12.318],[94.0455,12.395],[93.9855,12.4535],[93.907,12.485],[93.822,12.485],[93.7435,12.4535],[93.6835,12.395],[93.651,12.318],[93.647,12.2765]]],[[[94.045,13.4385],[94.0465,13.401],[94.0775,13.337],[94.1385,13.2705],[94.202,13.2395],[94.326,13.244],[94.388,13.274],[94.4345,13.3165],[94.4785,13.411],[94.4705,13.525],[94.4375,13.5835],[94.333,13.6515],[94.2805,13.661],[94.2035,13.6485],[94.101,13.5785],[94.064,13.513],[94.045,13.4385]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/41/Flag_of_India.svg","name:en":"India","wikidata":"Q668","ISO3166-1:alpha2":"IN","ISO3166-1:alpha3":"IND","ISO3166-1:numeric":"356"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[51.586,24.664],[51.391,24.6235],[51.376,24.5785],[51.302,24.5045],[51.266,24.5055],[51.0985,24.471],[50.9945,24.504],[50.9285,24.547],[50.8115,24.7445],[50.794,24.8775],[50.706,24.923],[50.7135,25.0425],[50.666,25.1375],[50.647,25.256],[50.647,25.3205],[50.615,25.4785],[50.573,25.5415],[50.5675,25.576],[50.529,25.594],[50.4165,25.6985],[50.366,25.819],[50.304,25.879],[50.27,26.0795],[50.311,26.171],[50.3165,26.252],[50.3415,26.3735],[50.3765,26.4075],[50.3875,26.53],[50.4885,26.5845],[50.4375,27.011],[50.395,27.11],[50.104,27.459],[50.0715,27.502],[50.013,27.545],[50.0445,27.615],[50.106,27.587],[50.2215,27.581],[50.2995,27.6095],[50.362,27.6635],[50.393,27.7195],[50.4035,27.7815],[50.367,27.887],[49.9835,27.882],[49.8985,27.915],[49.8225,27.924],[49.746,27.9095],[49.6485,27.8455],[49.607,27.7745],[49.522,27.847],[49.2815,28.1265],[49.159,28.3035],[49.1,28.36],[48.6965,28.622],[48.6695,28.6725],[48.5895,28.639],[48.4305,28.5345],[47.7045,28.5245],[47.709,28.543],[47.6055,28.655],[47.59,28.716],[47.598,28.7565],[47.5845,28.8355],[47.465,29.0],[46.841,29.068],[46.5525,29.1005],[46.4245,29.0585],[45.725,29.1195],[45.3745,29.142],[44.8335,29.187],[44.727,29.1915],[44.5135,29.3545],[44.0405,29.705],[43.7065,29.9505],[43.2445,30.2865],[42.6585,30.7065],[42.0855,31.1115],[41.4405,31.373],[40.796,31.736],[40.4135,31.948],[39.973,32.0245],[39.201,32.1545],[39.0065,32.0005],[38.4785,31.872],[38.04,31.7635],[37.4035,31.6015],[37.006,31.5005],[37.283,31.228],[37.5835,30.928],[37.933,30.5765],[37.997,30.5005],[37.6655,30.3325],[37.521,30.0425],[37.5055,30.001],[36.865,29.8855],[36.785,29.868],[36.736,29.789],[36.681,29.7495],[36.626,29.639],[36.5485,29.5605],[36.5275,29.5145],[36.4095,29.4055],[36.371,29.3975],[36.2125,29.286],[36.152,29.232],[36.073,29.1835],[35.823,29.2195],[35.737,29.238],[34.9495,29.359],[34.8845,29.375],[34.8305,29.2695],[34.816,29.193],[34.7625,29.053],[34.7615,28.9525],[34.7335,28.905],[34.737,28.8415],[34.7115,28.728],[34.688,28.6725],[34.677,28.579],[34.6225,28.432],[34.5825,28.369],[34.545,28.277],[34.536,28.193],[34.49,28.0645],[34.466,28.025],[34.457,27.9005],[34.477,27.7895],[34.519,27.7135],[34.68,27.7],[34.9725,27.636],[35.0545,27.5545],[35.257,27.398],[35.3325,27.32],[35.4275,27.151],[35.507,27.0525],[35.566,26.8925],[35.5895,26.848],[35.8025,26.5485],[35.9015,26.4285],[36.0655,26.263],[36.1565,26.0965],[36.2775,25.9645],[36.309,25.8205],[36.2685,25.699],[36.259,25.633],[36.274,25.568],[36.314,25.5035],[36.502,25.272],[36.6545,25.124],[36.784,24.7945],[36.912,24.422],[36.9525,24.3235],[37.011,24.2445],[37.07,24.21],[37.291,24.155],[37.513,24.016],[37.71,23.731],[37.847,23.5425],[37.9045,23.486],[38.0875,23.3635],[38.389,22.9785],[38.394,22.75],[38.4315,22.6405],[38.636,22.361],[38.5525,22.1145],[38.543,22.0665],[38.5305,21.868],[38.5505,21.7705],[38.632,21.609],[38.8245,21.0375],[38.8555,20.9805],[38.9815,20.817],[39.078,20.651],[39.276,20.2135],[39.33,20.1315],[39.724,19.6405],[39.823,19.405],[39.889,19.1655],[39.9345,18.9605],[39.963,18.8935],[40.0145,18.841],[40.3195,18.6235],[40.4605,18.428],[40.513,18.1765],[40.595,17.9735],[40.629,17.9085],[40.8405,17.5675],[41.198,16.8665],[41.225,16.805],[41.315,16.6565],[41.4125,16.5445],[41.4935,16.432],[41.545,16.382],[41.68,16.29],[41.7555,16.29],[41.7835,16.29],[42.15,16.404],[42.772,16.404],[42.8305,16.3795],[42.95,16.3995],[42.945,16.49],[42.992,16.5215],[43.1205,16.5285],[43.1465,16.6365],[43.1285,16.6715],[43.2345,16.643],[43.2305,16.7305],[43.252,16.7795],[43.2215,16.838],[43.18,16.849],[43.138,16.9175],[43.178,16.9635],[43.191,17.016],[43.24,17.024],[43.227,17.0755],[43.158,17.114],[43.171,17.1725],[43.2165,17.2105],[43.2015,17.259],[43.326,17.3285],[43.228,17.3855],[43.241,17.4805],[43.355,17.5565],[43.4195,17.566],[43.4845,17.545],[43.5665,17.4835],[43.6835,17.3665],[43.789,17.375],[43.832,17.339],[43.9665,17.3305],[44.0115,17.4025],[44.0665,17.406],[44.1005,17.366],[44.138,17.409],[44.366,17.4335],[44.4665,17.4335],[44.5665,17.4055],[44.65,17.4335],[45.2165,17.4335],[45.4,17.3335],[46.1,17.25],[46.3665,17.2335],[46.75,17.2835],[47.0,16.95],[47.1835,16.95],[47.4665,17.1165],[47.6,17.45],[47.849,17.7565],[48.1835,18.1665],[48.588,18.3615],[49.1165,18.6165],[49.713,18.6785],[50.1295,18.7215],[50.7835,18.789],[51.4245,18.9],[52.0,19.0],[52.423,19.1415],[52.917,19.3065],[53.667,19.5565],[54.209,19.737],[54.644,19.8815],[55.0,20.0],[55.1495,20.453],[55.3355,21.007],[55.4795,21.438],[55.6665,22.0],[55.4815,22.287],[55.2115,22.7055],[55.1375,22.6315],[54.38,22.727],[53.8075,22.797],[53.3315,22.8535],[52.581,22.939],[52.1635,23.4425],[51.92,23.7375],[51.5905,24.127],[51.59,24.266],[51.5295,24.3365],[51.456,24.364],[51.416,24.393],[51.4665,24.4625],[51.5475,24.531],[51.5845,24.599],[51.586,24.664]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/0d/Flag_of_Saudi_Arabia.svg","name:en":"Saudi Arabia","wikidata":"Q851","ISO3166-1:alpha2":"SA","ISO3166-1:alpha3":"SAU","ISO3166-1:numeric":"682"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[44.7845,37.144],[44.7775,37.0965],[44.817,37.04],[44.8545,37.047],[44.904,37.004],[44.8825,36.954],[44.9125,36.9165],[44.8945,36.8535],[44.8385,36.816],[44.845,36.7785],[44.9425,36.7845],[44.9725,36.7495],[45.0305,36.7405],[45.0615,36.695],[45.071,36.63],[45.0265,36.6005],[45.0815,36.4255],[45.1505,36.4045],[45.2375,36.433],[45.2765,36.3765],[45.261,36.3015],[45.3025,36.275],[45.3365,36.204],[45.327,36.1395],[45.3815,36.084],[45.343,36.0095],[45.402,35.971],[45.4535,35.9945],[45.5555,35.9995],[45.6655,35.927],[45.7095,35.8825],[45.763,35.8],[45.8315,35.8095],[45.896,35.8375],[45.9555,35.823],[46.0585,35.856],[46.1375,35.8435],[46.1665,35.8005],[46.2125,35.795],[46.2895,35.827],[46.34,35.82],[46.347,35.787],[46.2335,35.715],[46.165,35.689],[46.101,35.6875],[46.0355,35.7055],[46.014,35.6845],[46.0135,35.574],[45.9855,35.496],[46.0385,35.4055],[46.1455,35.313],[46.1585,35.2845],[46.1125,35.235],[46.194,35.211],[46.157,35.164],[46.1915,35.111],[46.0675,35.043],[45.944,35.091],[45.8805,35.038],[45.8925,34.95],[45.865,34.8965],[45.7885,34.9115],[45.795,34.856],[45.7225,34.838],[45.658,34.7185],[45.702,34.6945],[45.7395,34.5865],[45.714,34.541],[45.577,34.5585],[45.515,34.555],[45.5255,34.493],[45.44,34.459],[45.4675,34.379],[45.562,34.3315],[45.583,34.248],[45.5555,34.198],[45.5815,34.146],[45.515,34.1125],[45.467,34.019],[45.4205,33.9875],[45.451,33.945],[45.501,33.951],[45.648,33.7635],[45.6745,33.699],[45.7715,33.637],[45.753,33.593],[45.858,33.632],[45.961,33.5615],[45.863,33.493],[45.954,33.4905],[46.008,33.5045],[46.078,33.3575],[46.134,33.292],[46.19,33.264],[46.1985,33.1915],[46.1235,33.116],[46.0845,33.0915],[46.148,33.0505],[46.094,32.985],[46.1735,32.9535],[46.244,32.97],[46.3125,32.969],[46.4155,32.9415],[46.5185,32.898],[46.656,32.8075],[46.7205,32.786],[46.887,32.632],[46.956,32.5975],[47.111,32.4895],[47.1685,32.4575],[47.247,32.4635],[47.282,32.4885],[47.378,32.474],[47.4655,32.3915],[47.4625,32.321],[47.5655,32.193],[47.529,32.142],[47.5995,32.1165],[47.646,32.06],[47.6975,32.022],[47.7315,31.9395],[47.8095,31.8815],[47.8065,31.842],[47.866,31.7835],[47.6855,31.395],[47.6875,31.003],[47.8,31.0005],[47.8705,31.01],[48.0355,30.998],[48.0435,30.724],[48.04,30.5445],[48.0285,30.4775],[48.136,30.444],[48.176,30.4155],[48.1955,30.336],[48.278,30.3325],[48.405,30.2165],[48.415,30.166],[48.386,30.1335],[48.4485,30.0595],[48.4515,30.0075],[48.508,29.9675],[48.611,29.9365],[48.68,29.888],[48.802,29.8245],[48.859,29.8165],[48.8545,29.7475],[49.4645,29.7895],[49.8425,29.39],[50.1315,29.084],[50.384,28.785],[50.702,28.4075],[50.9715,28.086],[51.2725,27.7255],[51.33,27.677],[51.8705,27.355],[52.4825,26.9895],[53.0915,26.6245],[53.128,26.606],[53.8205,26.3355],[53.964,26.2945],[54.2235,26.0575],[54.2695,25.9815],[54.2775,25.8605],[54.3345,25.762],[54.4275,25.7085],[54.552,25.692],[54.6505,25.715],[54.867,25.707],[54.9295,25.67],[55.001,25.6545],[55.1285,25.67],[55.228,25.733],[55.266,25.7945],[55.2765,25.887],[55.423,26.07],[55.509,26.14],[55.8935,26.412],[55.96,26.43],[56.1325,26.5035],[56.1735,26.547],[56.2415,26.5905],[56.298,26.6035],[56.546,26.7025],[56.587,26.742],[56.6705,26.903],[56.7195,26.8575],[56.7725,26.772],[56.8085,26.741],[56.845,26.647],[56.859,26.5685],[56.8295,26.519],[56.816,26.432],[56.853,26.291],[56.8845,26.2135],[56.9515,26.105],[56.9535,26.016],[56.978,25.9355],[57.036,25.8665],[57.071,25.8425],[57.096,25.713],[57.1465,25.6475],[57.186,25.619],[57.2965,25.5835],[57.678,25.449],[58.053,25.3575],[58.632,25.269],[59.057,25.2035],[59.092,25.201],[59.5675,25.1955],[60.1705,25.124],[60.3605,25.095],[60.4195,25.0795],[60.5765,25.073],[60.956,24.972],[61.3545,24.8665],[61.5495,24.8465],[61.5755,25.0455],[61.6295,25.2095],[61.6505,25.306],[61.679,25.6585],[61.725,25.726],[61.84,25.745],[61.849,25.8225],[61.825,25.9605],[61.845,26.019],[61.8415,26.065],[61.86,26.176],[61.9175,26.254],[61.997,26.2805],[62.07,26.327],[62.1,26.2845],[62.215,26.268],[62.253,26.3595],[62.2595,26.4085],[62.314,26.473],[62.3035,26.5085],[62.37,26.5395],[62.42,26.533],[62.44,26.565],[62.604,26.5765],[62.6485,26.6085],[62.6965,26.609],[62.755,26.646],[63.0165,26.646],[63.049,26.6275],[63.1005,26.6505],[63.195,26.6465],[63.202,26.7555],[63.187,26.8365],[63.2415,26.8415],[63.2535,26.9035],[63.251,27.092],[63.309,27.1295],[63.277,27.218],[63.2255,27.2255],[63.1985,27.2595],[63.122,27.237],[63.0405,27.2375],[62.947,27.202],[62.8775,27.226],[62.8205,27.2185],[62.809,27.264],[62.8265,27.31],[62.7965,27.3335],[62.8485,27.463],[62.829,27.7645],[62.761,28.026],[62.7945,28.2275],[62.793,28.279],[62.597,28.2485],[62.463,28.378],[62.3885,28.4325],[62.282,28.4505],[62.1685,28.489],[62.044,28.51],[62.008,28.5335],[61.91,28.5645],[61.809,28.649],[61.751,28.718],[61.663,28.784],[61.602,28.873],[61.5335,29.01],[61.4715,29.091],[61.428,29.128],[61.427,29.199],[61.353,29.276],[61.373,29.3395],[61.1625,29.5335],[60.873,29.8585],[61.343,30.359],[61.5115,30.5385],[61.805,30.8395],[61.782,30.911],[61.814,30.9555],[61.8305,31.092],[61.777,31.214],[61.7785,31.3025],[61.7065,31.376],[60.856,31.4865],[60.8135,31.7085],[60.818,31.89],[60.8325,31.98],[60.819,32.0115],[60.883,32.1975],[60.859,32.2665],[60.815,32.4815],[60.7095,32.696],[60.6295,33.021],[60.5835,33.13],[60.634,33.228],[60.8245,33.4],[60.8665,33.4215],[60.851,33.482],[60.903,33.54],[60.7035,33.5455],[60.5815,33.597],[60.5515,33.64],[60.547,33.7315],[60.582,33.8055],[60.5175,34.062],[60.5375,34.1505],[60.6205,34.244],[60.669,34.272],[60.6865,34.3105],[60.9185,34.305],[60.8495,34.3685],[60.8075,34.462],[60.7425,34.527],[60.8485,34.542],[60.8975,34.5675],[60.922,34.623],[60.9845,34.62],[61.003,34.7085],[61.068,34.8125],[61.0575,34.9075],[61.0975,34.952],[61.1085,35.03],[61.14,35.102],[61.093,35.183],[61.092,35.2635],[61.1905,35.293],[61.1875,35.3995],[61.2265,35.4215],[61.2335,35.4625],[61.2825,35.538],[61.274,35.605],[61.226,35.6505],[61.262,35.8135],[61.241,35.8855],[61.1835,35.943],[61.164,36.033],[61.2285,36.1125],[61.2265,36.1665],[61.1615,36.297],[61.1425,36.393],[61.1665,36.4135],[61.157,36.4865],[61.1855,36.5495],[61.146,36.6465],[60.675,36.622],[60.6085,36.628],[60.3455,36.6295],[60.267,36.757],[60.215,36.8205],[60.1695,36.848],[60.0945,36.9365],[60.085,36.978],[60.043,37.021],[59.9815,37.047],[59.931,37.0425],[59.772,37.1255],[59.6535,37.142],[59.6265,37.1185],[59.558,37.1315],[59.538,37.1855],[59.435,37.304],[59.397,37.3175],[59.378,37.4075],[59.392,37.479],[59.3535,37.5285],[59.229,37.512],[59.0605,37.63],[58.926,37.67],[58.8765,37.669],[58.836,37.6995],[58.8045,37.667],[58.713,37.6485],[58.6655,37.655],[58.55,37.706],[58.498,37.648],[58.3885,37.627],[58.3595,37.661],[58.227,37.684],[58.229,37.7295],[58.2035,37.7755],[58.155,37.7935],[58.028,37.806],[57.8915,37.871],[57.8255,37.863],[57.796,37.8995],[57.7205,37.922],[57.6285,37.922],[57.5795,37.938],[57.512,37.9195],[57.458,37.938],[57.3485,37.999],[57.373,38.0755],[57.2465,38.2665],[57.161,38.272],[57.1345,38.236],[57.051,38.1935],[56.992,38.2145],[56.91,38.2145],[56.7925,38.2515],[56.7565,38.285],[56.664,38.2685],[56.614,38.2405],[56.5465,38.266],[56.4245,38.2545],[56.333,38.1975],[56.3195,38.1745],[56.352,38.117],[56.303,38.083],[56.216,38.072],[56.173,38.0945],[56.0215,38.0775],[55.842,38.102],[55.7485,38.1255],[55.443,38.086],[55.3845,38.042],[55.2735,37.9905],[55.127,37.9455],[55.0395,37.8635],[54.942,37.79],[54.843,37.745],[54.7885,37.647],[54.819,37.6005],[54.7985,37.522],[54.7315,37.488],[54.6735,37.437],[54.5825,37.4585],[54.4875,37.418],[54.3975,37.3605],[54.285,37.352],[54.2445,37.32],[53.8965,37.3475],[53.861,37.322],[53.8775,37.247],[53.8625,37.204],[53.897,37.0185],[53.8525,36.9845],[53.2905,36.931],[52.9815,36.875],[52.7355,36.823],[52.452,36.7775],[52.168,36.7125],[52.0385,36.675],[51.9165,36.6625],[51.6235,36.7195],[51.488,36.775],[51.217,36.8155],[50.9555,36.8935],[50.81,36.9575],[50.439,37.1715],[50.2925,37.436],[50.2325,37.4655],[50.0335,37.501],[49.957,37.552],[49.8575,37.551],[49.787,37.527],[49.4285,37.574],[49.1955,37.675],[49.1205,37.7505],[49.0665,37.9665],[49.2125,38.4085],[48.7915,38.4515],[48.7385,38.411],[48.6595,38.3935],[48.608,38.4155],[48.5915,38.453],[48.472,38.5535],[48.425,38.6135],[48.321,38.602],[48.295,38.6475],[48.2525,38.662],[48.249,38.726],[48.192,38.756],[48.1075,38.77],[48.0205,38.838],[48.028,38.8995],[48.088,38.947],[48.1455,38.946],[48.271,38.9675],[48.339,39.034],[48.303,39.109],[48.2305,39.134],[48.2135,39.1665],[48.141,39.208],[48.13,39.271],[48.211,39.329],[48.248,39.3305],[48.361,39.394],[48.332,39.4285],[48.032,39.6925],[47.9855,39.709],[47.9145,39.6615],[47.8125,39.659],[47.753,39.606],[47.4205,39.465],[47.296,39.367],[47.2155,39.319],[47.133,39.292],[47.058,39.238],[47.054,39.194],[46.9635,39.1405],[46.9255,39.1645],[46.8665,39.1405],[46.7905,39.087],[46.762,39.037],[46.6955,39.018],[46.6735,38.978],[46.6035,38.91],[46.534,38.867],[46.458,38.897],[46.425,38.8855],[46.363,38.9165],[46.2825,38.9005],[46.187,38.843],[46.1405,38.8445],[46.112,38.865],[45.979,38.879],[45.918,38.8735],[45.737,38.9275],[45.69,38.9515],[45.6185,38.9425],[45.455,38.9905],[45.4525,39.055],[45.3525,39.133],[45.3135,39.2],[45.2475,39.1855],[45.185,39.2205],[45.0865,39.351],[45.0175,39.406],[44.964,39.424],[44.952,39.492],[44.91,39.525],[44.9035,39.577],[44.8095,39.6275],[44.7135,39.7145],[44.669,39.7145],[44.6145,39.7825],[44.467,39.684],[44.48,39.6105],[44.416,39.5565],[44.4395,39.501],[44.432,39.443],[44.295,39.3755],[44.233,39.4155],[44.1415,39.3975],[44.051,39.403],[44.0375,39.3615],[44.0755,39.332],[44.094,39.2155],[44.1665,39.1775],[44.2135,39.1305],[44.191,39.0765],[44.2115,39.0205],[44.181,39.0105],[44.1895,38.934],[44.2115,38.89],[44.2965,38.841],[44.315,38.809],[44.261,38.7055],[44.2815,38.6415],[44.3215,38.6245],[44.3095,38.531],[44.3255,38.502],[44.3055,38.441],[44.3165,38.3745],[44.3765,38.3595],[44.4395,38.3835],[44.4975,38.3335],[44.478,38.3025],[44.402,38.251],[44.3925,38.1465],[44.351,38.135],[44.3015,38.0325],[44.2405,37.9555],[44.2225,37.888],[44.268,37.867],[44.317,37.8765],[44.403,37.852],[44.392,37.828],[44.445,37.771],[44.5305,37.783],[44.588,37.7635],[44.6245,37.698],[44.568,37.645],[44.6145,37.6005],[44.5875,37.4395],[44.619,37.437],[44.6575,37.386],[44.711,37.38],[44.743,37.3345],[44.798,37.311],[44.815,37.2795],[44.7575,37.2285],[44.7845,37.144]]],[[[50.367,27.887],[50.3955,27.95],[50.3965,28.028],[50.368,28.0965],[50.309,28.1545],[50.225,28.1895],[50.0975,28.1845],[50.03,28.1515],[49.9785,28.1],[49.95,28.036],[49.95,27.951],[49.9835,27.882],[50.367,27.887]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/ca/Flag_of_Iran.svg","name:en":"Iran","wikidata":"Q794","ISO3166-1:alpha2":"IR","ISO3166-1:alpha3":"IRN","ISO3166-1:numeric":"364"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[76.776,35.658],[76.691,35.7485],[76.6155,35.7615],[76.561,35.8225],[76.599,35.9],[76.556,35.927],[76.5175,35.8865],[76.4685,35.891],[76.427,35.8525],[76.3665,35.8635],[76.3565,35.8315],[76.2245,35.8425],[76.145,35.8375],[76.1595,35.917],[76.107,35.977],[76.101,36.016],[76.0045,36.017],[75.957,36.046],[75.9465,36.119],[75.9695,36.1635],[76.014,36.1725],[76.0065,36.234],[76.0575,36.246],[75.995,36.3075],[75.985,36.3415],[76.0355,36.409],[75.9875,36.5025],[75.926,36.573],[75.9405,36.593],[75.804,36.71],[75.7195,36.752],[75.6375,36.77],[75.534,36.7715],[75.4695,36.716],[75.4195,36.7735],[75.432,36.83],[75.406,36.9365],[75.2855,36.9745],[75.2335,36.959],[75.1255,37.0125],[74.919,36.979],[74.906,36.9295],[74.8405,37.02],[74.739,37.0215],[74.702,37.0825],[74.5645,37.031],[74.519,37.0175],[74.5435,36.967],[74.4195,37.0075],[74.4135,36.9755],[74.35,36.9625],[74.3095,36.919],[74.237,36.895],[74.1805,36.9165],[74.121,36.838],[74.048,36.8265],[73.9575,36.8425],[73.9035,36.876],[73.8905,36.9125],[73.836,36.9255],[73.8,36.8905],[73.6915,36.916],[73.548,36.891],[73.4005,36.899],[73.1775,36.879],[73.083,36.887],[73.0295,36.8615],[72.943,36.868],[72.93,36.843],[72.818,36.8415],[72.768,36.854],[72.7175,36.837],[72.6525,36.852],[72.5615,36.829],[72.5025,36.784],[72.3355,36.7665],[72.2985,36.74],[72.2535,36.7525],[72.1845,36.7115],[72.2095,36.6635],[72.0965,36.647],[72.088,36.5965],[72.0305,36.592],[72.0035,36.5575],[71.936,36.5465],[71.9165,36.5085],[71.8095,36.508],[71.8205,36.4345],[71.8065,36.3995],[71.657,36.4835],[71.616,36.403],[71.558,36.3725],[71.583,36.345],[71.4505,36.272],[71.436,36.2325],[71.3605,36.204],[71.214,36.0825],[71.197,36.041],[71.3225,35.959],[71.368,35.968],[71.396,35.8915],[71.431,35.888],[71.4775,35.8215],[71.494,35.7495],[71.553,35.7225],[71.5365,35.6695],[71.4995,35.6295],[71.521,35.6065],[71.6205,35.571],[71.594,35.5],[71.6555,35.437],[71.5445,35.3125],[71.564,35.2785],[71.6335,35.2255],[71.6815,35.2095],[71.625,35.139],[71.532,35.091],[71.5525,35.0225],[71.507,35.006],[71.475,34.9495],[71.351,34.9145],[71.296,34.8775],[71.2775,34.7995],[71.187,34.7495],[71.0895,34.6785],[71.1145,34.628],[71.025,34.5595],[71.011,34.534],[71.024,34.4505],[71.0595,34.4245],[71.1075,34.4335],[71.1155,34.377],[71.173,34.365],[71.13,34.2825],[71.13,34.1645],[71.071,34.1095],[71.0825,34.0635],[71.0305,34.054],[70.8835,33.974],[70.822,33.9785],[70.777,33.962],[70.643,33.9525],[70.584,33.9625],[70.547,33.943],[70.4595,33.945],[70.4145,33.9675],[70.325,33.966],[70.2905,33.9815],[70.194,33.983],[70.149,34.0145],[70.0875,34.0085],[70.0485,34.035],[69.9045,34.0395],[69.856,33.949],[69.9155,33.887],[69.9715,33.7585],[70.1535,33.695],[70.1435,33.658],[70.1985,33.6195],[70.1715,33.539],[70.1995,33.4875],[70.251,33.44],[70.297,33.43],[70.3285,33.343],[70.166,33.2215],[70.096,33.205],[70.0735,33.22],[70.0205,33.1385],[69.941,33.131],[69.879,33.0945],[69.7985,33.131],[69.672,33.101],[69.573,33.0985],[69.4995,33.0205],[69.4955,32.933],[69.5065,32.896],[69.441,32.804],[69.3875,32.768],[69.438,32.731],[69.454,32.6585],[69.371,32.5625],[69.278,32.529],[69.2395,32.4645],[69.278,32.3615],[69.27,32.162],[69.292,32.095],[69.3025,31.987],[69.33,31.9295],[69.193,31.847],[69.116,31.7005],[69.0405,31.6615],[69.02,31.6295],[68.96,31.649],[68.908,31.5965],[68.7895,31.6245],[68.7875,31.6545],[68.728,31.6955],[68.7085,31.771],[68.643,31.778],[68.5755,31.834],[68.475,31.7735],[68.591,31.753],[68.5655,31.7145],[68.523,31.7355],[68.4615,31.735],[68.425,31.756],[68.2795,31.757],[68.2655,31.8035],[68.1795,31.817],[68.1465,31.8045],[68.0705,31.696],[67.9745,31.6405],[67.8575,31.624],[67.7165,31.514],[67.6465,31.5285],[67.571,31.5245],[67.651,31.3925],[67.75,31.4165],[67.796,31.383],[67.7875,31.3325],[67.722,31.327],[67.678,31.2935],[67.4855,31.2325],[67.4,31.211],[67.279,31.1995],[67.1975,31.217],[67.1695,31.2455],[67.07,31.214],[67.024,31.2565],[67.033,31.3105],[66.956,31.308],[66.834,31.265],[66.813,31.223],[66.7155,31.186],[66.688,31.0825],[66.5785,30.9765],[66.392,30.9405],[66.288,30.577],[66.2865,30.5255],[66.3565,30.4765],[66.3625,30.4185],[66.3415,30.3845],[66.3265,30.2475],[66.289,30.153],[66.232,30.063],[66.373,29.9715],[66.332,29.92],[66.25,29.8495],[65.8095,29.7295],[65.6965,29.705],[65.493,29.6445],[65.065,29.5295],[64.5715,29.5865],[64.3445,29.525],[64.2635,29.522],[64.249,29.499],[64.1795,29.4835],[64.142,29.4365],[64.166,29.408],[64.128,29.3785],[64.0545,29.4075],[63.5765,29.487],[63.233,29.4575],[62.471,29.3895],[61.8975,29.56],[61.564,29.658],[60.873,29.8585],[61.1625,29.5335],[61.373,29.3395],[61.353,29.276],[61.427,29.199],[61.428,29.128],[61.4715,29.091],[61.5335,29.01],[61.602,28.873],[61.663,28.784],[61.751,28.718],[61.809,28.649],[61.91,28.5645],[62.008,28.5335],[62.044,28.51],[62.1685,28.489],[62.282,28.4505],[62.3885,28.4325],[62.463,28.378],[62.597,28.2485],[62.793,28.279],[62.7945,28.2275],[62.761,28.026],[62.829,27.7645],[62.8485,27.463],[62.7965,27.3335],[62.8265,27.31],[62.809,27.264],[62.8205,27.2185],[62.8775,27.226],[62.947,27.202],[63.0405,27.2375],[63.122,27.237],[63.1985,27.2595],[63.2255,27.2255],[63.277,27.218],[63.309,27.1295],[63.251,27.092],[63.2535,26.9035],[63.2415,26.8415],[63.187,26.8365],[63.202,26.7555],[63.195,26.6465],[63.1005,26.6505],[63.049,26.6275],[63.0165,26.646],[62.755,26.646],[62.6965,26.609],[62.6485,26.6085],[62.604,26.5765],[62.44,26.565],[62.42,26.533],[62.37,26.5395],[62.3035,26.5085],[62.314,26.473],[62.2595,26.4085],[62.253,26.3595],[62.215,26.268],[62.1,26.2845],[62.07,26.327],[61.997,26.2805],[61.9175,26.254],[61.86,26.176],[61.8415,26.065],[61.845,26.019],[61.825,25.9605],[61.849,25.8225],[61.84,25.745],[61.725,25.726],[61.679,25.6585],[61.6505,25.306],[61.6295,25.2095],[61.5755,25.0455],[61.5495,24.8465],[61.732,24.8415],[61.879,24.876],[61.951,24.918],[61.985,24.9805],[62.2825,24.974],[62.4215,24.98],[62.4885,25.021],[62.5625,25.1195],[62.927,25.0515],[62.9875,25.044],[63.083,25.0725],[63.1445,25.103],[63.4585,25.06],[63.6595,25.025],[63.882,24.9805],[63.9825,25.02],[64.0505,25.067],[64.0825,25.1085],[64.3155,25.039],[64.5305,25.033],[64.61,25.019],[64.775,25.0795],[64.887,25.168],[65.121,25.138],[65.2615,25.154],[65.341,25.2075],[65.3475,25.2355],[65.52,25.218],[65.6025,25.1915],[65.664,25.1845],[65.843,25.245],[65.875,25.273],[66.063,25.2775],[66.2585,25.3205],[66.396,25.2645],[66.521,25.1705],[66.498,25.039],[66.4555,24.976],[66.4155,24.8695],[66.454,24.753],[66.5855,24.6895],[66.7025,24.6895],[66.795,24.713],[66.948,24.601],[67.019,24.513],[67.1025,24.2],[67.1645,24.025],[67.2375,23.858],[67.3755,23.7135],[67.5205,23.6545],[67.742,23.6015],[68.115,23.5395],[68.1115,23.6015],[68.1355,23.6485],[68.186,23.6885],[68.207,23.8445],[68.2905,23.9445],[68.32,23.9135],[68.3795,23.971],[68.753,23.9715],[68.7695,24.2655],[68.7645,24.296],[68.831,24.3115],[68.8565,24.214],[68.88,24.216],[68.907,24.28],[68.9455,24.3025],[68.985,24.2275],[69.013,24.224],[69.095,24.2745],[69.194,24.2365],[69.313,24.2815],[69.367,24.27],[69.4445,24.2805],[69.5035,24.2685],[69.5945,24.2925],[69.7315,24.171],[70.025,24.171],[70.0665,24.199],[70.11,24.295],[70.254,24.3255],[70.327,24.352],[70.573,24.4225],[70.6025,24.408],[70.5625,24.351],[70.585,24.278],[70.5715,24.252],[70.6445,24.225],[70.714,24.2155],[70.8055,24.221],[70.8515,24.245],[70.8785,24.302],[70.986,24.3655],[71.0495,24.356],[71.103,24.4355],[70.9985,24.4445],[71.005,24.523],[70.9865,24.5955],[71.009,24.6355],[71.0745,24.662],[71.0655,24.7175],[71.0265,24.809],[70.9375,24.9385],[70.8885,25.148],[70.7515,25.2775],[70.737,25.3325],[70.665,25.397],[70.6785,25.5255],[70.667,25.5315],[70.674,25.676],[70.645,25.713],[70.6085,25.715],[70.53,25.6835],[70.387,25.6735],[70.2685,25.7135],[70.2225,25.793],[70.1745,25.8285],[70.1,25.938],[70.0835,26.0835],[70.141,26.156],[70.175,26.2515],[70.1635,26.295],[70.1855,26.374],[70.1745,26.5515],[70.1175,26.587],[70.0565,26.6005],[69.886,26.5785],[69.792,26.598],[69.7255,26.652],[69.5105,26.7435],[69.4845,26.805],[69.5135,27.01],[69.587,27.1835],[69.703,27.2845],[69.863,27.402],[69.934,27.4975],[70.026,27.563],[70.1325,27.806],[70.227,27.9015],[70.296,27.936],[70.372,28.012],[70.5055,28.037],[70.5895,28.0105],[70.6775,27.922],[70.6845,27.828],[70.7595,27.721],[70.906,27.7095],[71.2055,27.8355],[71.383,27.8725],[71.6665,27.878],[71.8985,27.961],[71.9275,28.1215],[72.0045,28.2185],[72.1325,28.313],[72.206,28.394],[72.2995,28.6695],[72.404,28.783],[72.4795,28.812],[72.733,28.948],[72.946,29.028],[73.0045,29.153],[73.0855,29.238],[73.2825,29.572],[73.397,29.946],[73.597,30.019],[73.8065,30.068],[73.83,30.0935],[73.9725,30.1985],[73.9595,30.27],[73.9025,30.349],[73.946,30.468],[73.993,30.514],[74.0725,30.523],[74.1285,30.6325],[74.149,30.6315],[74.2745,30.7355],[74.3205,30.8465],[74.38,30.862],[74.366,30.893],[74.48,30.974],[74.5455,30.992],[74.548,31.032],[74.671,31.0535],[74.7025,31.0915],[74.689,31.128],[74.5515,31.0865],[74.5105,31.132],[74.537,31.33],[74.5965,31.4165],[74.6435,31.416],[74.635,31.4845],[74.5875,31.504],[74.616,31.5575],[74.5555,31.608],[74.535,31.6775],[74.4865,31.715],[74.5595,31.758],[74.5705,31.837],[74.6155,31.89],[74.677,31.926],[74.819,31.9585],[74.8285,31.998],[74.9265,32.0665],[75.0125,32.0355],[75.123,32.0815],[75.1795,32.0765],[75.2205,32.1075],[75.261,32.1015],[75.314,32.172],[75.3315,32.2195],[75.373,32.2285],[75.3715,32.2795],[75.2895,32.3695],[75.238,32.387],[75.192,32.426],[75.137,32.41],[75.109,32.46],[75.0265,32.4975],[75.0155,32.4645],[74.943,32.452],[74.859,32.4935],[74.8125,32.48],[74.7295,32.481],[74.6855,32.4995],[74.69,32.5345],[74.6515,32.563],[74.657,32.6305],[74.695,32.6605],[74.6535,32.697],[74.7045,32.817],[74.6585,32.83],[74.6305,32.7675],[74.5185,32.7485],[74.4485,32.7935],[74.4195,32.84],[74.42,32.8855],[74.3385,32.9555],[74.318,33.032],[74.2015,33.0665],[74.154,33.1365],[74.0705,33.194],[74.017,33.205],[74.018,33.2705],[74.1265,33.3045],[74.1665,33.3375],[74.1885,33.4085],[74.1925,33.4785],[74.1405,33.5575],[74.081,33.585],[74.0315,33.5785],[73.981,33.6415],[73.9815,33.707],[74.01,33.7765],[74.06,33.824],[74.1895,33.839],[74.2815,33.901],[74.277,33.9695],[74.233,34.0235],[74.1975,34.017],[74.1325,34.047],[74.016,34.0395],[73.965,34.0135],[73.896,34.06],[73.927,34.1275],[74.0035,34.1905],[73.9905,34.2705],[73.9455,34.276],[73.939,34.3365],[73.859,34.324],[73.774,34.3325],[73.7505,34.369],[73.803,34.42],[73.88,34.4535],[73.905,34.528],[73.9535,34.5605],[73.932,34.6415],[73.969,34.6855],[74.142,34.6605],[74.158,34.6885],[74.2415,34.727],[74.3095,34.7825],[74.4485,34.7825],[74.58,34.7615],[74.651,34.706],[74.7305,34.681],[74.936,34.673],[75.026,34.6295],[75.163,34.6565],[75.267,34.6365],[75.2475,34.6035],[75.301,34.5865],[75.365,34.538],[75.463,34.5345],[75.6705,34.54],[75.785,34.5135],[75.9455,34.6255],[76.063,34.688],[76.116,34.6395],[76.1635,34.6325],[76.2505,34.6765],[76.2825,34.7235],[76.328,34.7195],[76.4195,34.7375],[76.4865,34.796],[76.541,34.762],[76.642,34.734],[76.697,34.7505],[76.7015,34.796],[76.737,34.8065],[76.7455,34.8885],[76.792,34.954],[76.8615,34.9485],[76.898,34.926],[76.961,35.0175],[77.047,35.0515],[77.1105,35.049],[77.0825,35.099],[77.0855,35.169],[77.0175,35.183],[76.975,35.2515],[77.0065,35.2945],[76.948,35.393],[76.863,35.3895],[76.8385,35.443],[76.759,35.5185],[76.7495,35.555],[76.7935,35.588],[76.755,35.6295],[76.776,35.658]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/32/Flag_of_Pakistan.svg","name:en":"Pakistan","wikidata":"Q843","ISO3166-1:alpha2":"PK","ISO3166-1:alpha3":"PAK","ISO3166-1:numeric":"586"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[88.135,27.8815],[88.091,27.8715],[88.027,27.9055],[87.983,27.888],[87.9305,27.918],[87.866,27.911],[87.834,27.952],[87.7855,27.9005],[87.725,27.8055],[87.6645,27.8375],[87.606,27.8185],[87.5785,27.862],[87.4895,27.846],[87.4475,27.8225],[87.4255,27.8595],[87.3165,27.8275],[87.2645,27.851],[87.227,27.821],[87.157,27.8245],[87.111,27.8455],[87.073,27.9205],[87.038,27.9505],[86.9325,27.9615],[86.9245,27.988],[86.7495,28.046],[86.7485,28.0985],[86.6655,28.1025],[86.6075,28.075],[86.575,28.1135],[86.5355,28.051],[86.514,27.957],[86.468,27.946],[86.442,27.906],[86.372,27.942],[86.3195,27.948],[86.2885,27.978],[86.2265,27.9815],[86.2045,28.0785],[86.2185,28.1135],[86.16,28.1385],[86.118,28.091],[86.084,28.088],[86.0805,28.022],[86.1245,27.9275],[86.065,27.9],[86.0,27.9115],[85.9515,27.945],[85.9775,27.988],[85.9,28.0545],[85.897,28.111],[85.8495,28.1715],[85.7505,28.2365],[85.7315,28.337],[85.6835,28.3825],[85.6625,28.303],[85.6085,28.2565],[85.5915,28.308],[85.46,28.3365],[85.4135,28.325],[85.377,28.2775],[85.3375,28.3035],[85.255,28.293],[85.204,28.3405],[85.183,28.323],[85.1085,28.3465],[85.1275,28.3925],[85.118,28.4855],[85.147,28.4875],[85.1905,28.5695],[85.157,28.644],[85.1165,28.6855],[85.058,28.6825],[84.9485,28.5805],[84.9205,28.595],[84.8565,28.571],[84.78,28.6105],[84.696,28.6365],[84.6255,28.7365],[84.558,28.746],[84.493,28.7365],[84.4375,28.77],[84.435,28.821],[84.392,28.86],[84.3285,28.8615],[84.226,28.893],[84.2255,28.9435],[84.249,29.0365],[84.187,29.081],[84.168,29.2005],[84.0915,29.294],[83.903,29.327],[83.814,29.3025],[83.7685,29.241],[83.711,29.244],[83.632,29.159],[83.5705,29.203],[83.518,29.2185],[83.5145,29.2555],[83.4435,29.2995],[83.4135,29.422],[83.3715,29.4285],[83.345,29.495],[83.282,29.499],[83.2175,29.605],[83.15,29.6245],[83.0695,29.61],[83.038,29.649],[82.9565,29.662],[82.928,29.7],[82.869,29.687],[82.8185,29.6965],[82.765,29.731],[82.738,29.814],[82.697,29.8565],[82.603,29.889],[82.5335,29.971],[82.497,29.9475],[82.4215,30.0055],[82.313,30.0385],[82.2845,30.0585],[82.1665,30.076],[82.1855,30.111],[82.185,30.19],[82.141,30.197],[82.117,30.258],[82.127,30.304],[82.1065,30.349],[81.988,30.322],[81.9375,30.3475],[81.75,30.3885],[81.634,30.445],[81.6065,30.4115],[81.5645,30.4295],[81.5395,30.373],[81.429,30.3835],[81.396,30.3235],[81.4225,30.3055],[81.39,30.2345],[81.3955,30.207],[81.2825,30.123],[81.2715,30.0445],[81.1655,30.0105],[81.092,30.0535],[81.109,30.0855],[81.0345,30.197],[80.8715,30.1605],[80.878,30.1285],[80.8055,30.09],[80.7385,29.999],[80.6745,29.957],[80.6015,29.958],[80.574,29.9235],[80.5535,29.853],[80.493,29.795],[80.4175,29.796],[80.366,29.726],[80.385,29.6735],[80.4165,29.652],[80.408,29.597],[80.3485,29.5555],[80.342,29.5105],[80.298,29.49],[80.3025,29.4545],[80.246,29.447],[80.2795,29.3475],[80.318,29.3045],[80.29,29.2315],[80.262,29.206],[80.2715,29.1465],[80.2355,29.1175],[80.1865,29.137],[80.1455,29.1045],[80.127,29.006],[80.059,28.916],[80.0645,28.8375],[80.1185,28.828],[80.216,28.7555],[80.2565,28.754],[80.275,28.711],[80.377,28.629],[80.4605,28.622],[80.5225,28.5525],[80.5035,28.665],[80.5395,28.6905],[80.614,28.639],[80.6675,28.642],[80.7145,28.5685],[80.768,28.5655],[80.9055,28.466],[81.0335,28.428],[81.0815,28.3845],[81.211,28.361],[81.2325,28.289],[81.321,28.1975],[81.313,28.1565],[81.368,28.141],[81.3745,28.177],[81.447,28.161],[81.484,28.1185],[81.4785,28.0825],[81.644,27.9935],[81.6985,27.988],[81.805,27.904],[81.9,27.8535],[81.9685,27.929],[82.0625,27.9215],[82.121,27.866],[82.209,27.843],[82.3035,27.773],[82.368,27.7425],[82.402,27.7035],[82.473,27.6765],[82.605,27.706],[82.7075,27.715],[82.757,27.5835],[82.7365,27.5025],[82.9295,27.501],[82.954,27.468],[83.0345,27.449],[83.188,27.4545],[83.272,27.3835],[83.2965,27.3335],[83.3375,27.3325],[83.388,27.3755],[83.4075,27.415],[83.389,27.48],[83.6145,27.469],[83.8295,27.3705],[83.865,27.371],[83.874,27.4345],[84.052,27.4435],[84.1055,27.521],[84.176,27.4745],[84.254,27.453],[84.294,27.385],[84.6225,27.336],[84.682,27.2365],[84.6705,27.091],[84.6435,27.046],[84.7575,27.003],[84.8195,27.0215],[84.855,26.986],[84.9625,26.9605],[85.0575,26.849],[85.099,26.871],[85.193,26.8665],[85.177,26.8145],[85.197,26.771],[85.334,26.742],[85.4075,26.7915],[85.4515,26.7815],[85.543,26.8385],[85.642,26.853],[85.7205,26.8205],[85.735,26.7795],[85.723,26.687],[85.732,26.654],[85.851,26.6085],[85.861,26.5705],[85.974,26.657],[86.028,26.6665],[86.141,26.617],[86.306,26.62],[86.542,26.5385],[86.57,26.4965],[86.694,26.451],[86.737,26.423],[86.7655,26.4595],[86.8335,26.439],[86.894,26.462],[86.932,26.516],[87.0725,26.543],[87.0915,26.4505],[87.1615,26.404],[87.247,26.4145],[87.266,26.374],[87.3135,26.3675],[87.3885,26.419],[87.4665,26.4405],[87.516,26.431],[87.5875,26.393],[87.6515,26.3935],[87.678,26.416],[87.7695,26.4215],[87.793,26.469],[87.8485,26.437],[87.9,26.4775],[87.916,26.434],[87.992,26.3695],[88.0775,26.419],[88.1035,26.4665],[88.1055,26.561],[88.1635,26.646],[88.1895,26.7465],[88.172,26.869],[88.136,26.899],[88.118,26.9875],[88.083,27.029],[88.0375,27.037],[87.991,27.131],[88.007,27.1435],[88.0315,27.2865],[88.0665,27.3365],[88.0415,27.3705],[88.0785,27.432],[88.044,27.4785],[88.085,27.5905],[88.144,27.665],[88.1585,27.741],[88.197,27.791],[88.201,27.8375],[88.135,27.8815]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9b/Flag_of_Nepal.svg","name:en":"Nepal","wikidata":"Q837","ISO3166-1:alpha2":"NP","ISO3166-1:alpha3":"NPL","ISO3166-1:numeric":"524"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[70.894,40.2315],[70.8855,40.188],[70.7995,40.1475],[70.7685,40.1165],[70.6575,40.11],[70.6095,40.043],[70.5675,40.0305],[70.498,40.054],[70.4245,40.0575],[70.358,40.081],[70.292,40.1295],[70.241,40.124],[70.1755,40.143],[70.021,40.2305],[69.9955,40.2345],[69.784,40.1795],[69.6755,40.1225],[69.582,40.1045],[69.537,40.117],[69.507,40.034],[69.5355,39.9525],[69.4575,39.935],[69.432,39.9885],[69.3945,40.0025],[69.297,39.9205],[69.327,39.877],[69.265,39.806],[69.3265,39.7205],[69.3375,39.5425],[69.408,39.5495],[69.448,39.5285],[69.574,39.553],[69.6295,39.593],[69.678,39.5805],[69.7375,39.595],[69.8285,39.56],[69.867,39.5295],[69.9015,39.576],[69.978,39.568],[69.996,39.537],[70.127,39.5865],[70.168,39.554],[70.2065,39.5785],[70.239,39.538],[70.309,39.53],[70.3295,39.562],[70.3895,39.582],[70.4645,39.583],[70.525,39.622],[70.606,39.586],[70.65,39.582],[70.6925,39.52],[70.7435,39.497],[70.768,39.3995],[70.9125,39.3835],[70.941,39.4335],[71.0165,39.3955],[71.072,39.4255],[71.0895,39.499],[71.1935,39.5115],[71.2585,39.549],[71.3075,39.5235],[71.3355,39.5685],[71.413,39.571],[71.5145,39.6115],[71.565,39.576],[71.544,39.505],[71.5655,39.457],[71.633,39.4455],[71.761,39.4565],[71.804,39.403],[71.7525,39.324],[71.802,39.2735],[71.919,39.2805],[71.958,39.3315],[72.0355,39.3665],[72.089,39.278],[72.1535,39.2735],[72.202,39.2415],[72.2195,39.1825],[72.271,39.1895],[72.3,39.2925],[72.3425,39.332],[72.4625,39.35],[72.493,39.38],[72.589,39.3595],[72.621,39.399],[72.694,39.396],[72.7825,39.362],[72.959,39.3465],[73.1065,39.3765],[73.1605,39.3525],[73.2525,39.381],[73.353,39.3935],[73.3935,39.4525],[73.505,39.4735],[73.6005,39.4595],[73.638,39.474],[73.7255,39.461],[73.8745,39.483],[73.8785,39.5425],[73.949,39.6215],[73.904,39.7445],[73.832,39.7815],[73.848,39.8345],[73.903,39.8615],[73.907,39.9205],[73.977,40.005],[73.983,40.0485],[74.042,40.0995],[74.066,40.0785],[74.2,40.1235],[74.304,40.115],[74.3445,40.0935],[74.5255,40.209],[74.5905,40.282],[74.6605,40.273],[74.701,40.325],[74.79,40.3535],[74.862,40.324],[74.9055,40.3535],[74.796,40.435],[74.838,40.522],[74.921,40.493],[74.987,40.452],[75.018,40.4665],[75.09,40.435],[75.124,40.458],[75.2385,40.461],[75.3725,40.5485],[75.4085,40.5525],[75.462,40.603],[75.539,40.6475],[75.5955,40.6475],[75.63,40.623],[75.6235,40.5455],[75.647,40.505],[75.7235,40.472],[75.68,40.4215],[75.6635,40.355],[75.718,40.287],[75.8115,40.3245],[75.93,40.302],[75.962,40.3745],[76.1315,40.397],[76.1855,40.38],[76.2515,40.418],[76.3125,40.406],[76.3395,40.3495],[76.44,40.389],[76.5385,40.474],[76.552,40.5455],[76.6115,40.6105],[76.654,40.622],[76.64,40.762],[76.7025,40.7875],[76.7625,40.953],[76.8195,40.977],[76.878,41.0275],[76.94,41.0305],[76.9635,41.0585],[77.0855,41.063],[77.1175,41.027],[77.242,41.0265],[77.2625,41.0045],[77.3705,41.0405],[77.4675,40.9985],[77.5835,40.994],[77.6465,41.0145],[77.687,41.0035],[77.765,41.015],[77.796,41.0485],[77.8045,41.1225],[77.912,41.186],[78.0215,41.193],[78.1215,41.2275],[78.146,41.3675],[78.1895,41.394],[78.382,41.3915],[78.532,41.442],[78.5575,41.4765],[78.6445,41.469],[78.7245,41.555],[78.815,41.5585],[78.941,41.6445],[79.083,41.689],[79.124,41.7225],[79.2095,41.725],[79.323,41.811],[79.347,41.7935],[79.4095,41.841],[79.4975,41.8365],[79.6075,41.857],[79.638,41.8935],[79.765,41.893],[79.802,41.9195],[79.8545,42.022],[79.912,42.042],[80.0265,42.049],[80.138,42.0315],[80.225,42.0595],[80.1655,42.101],[80.1745,42.211],[80.0815,42.3395],[80.0305,42.343],[79.982,42.3775],[79.968,42.432],[79.787,42.4465],[79.6735,42.48],[79.641,42.4545],[79.505,42.46],[79.3465,42.6025],[79.271,42.6215],[79.182,42.6975],[79.17,42.7435],[79.1995,42.804],[79.0565,42.7755],[78.9305,42.7745],[78.8655,42.8005],[78.642,42.8425],[78.492,42.9005],[78.3505,42.855],[78.198,42.882],[78.1715,42.8605],[78.035,42.865],[77.9675,42.851],[77.7795,42.915],[77.697,42.904],[77.5805,42.9155],[77.55,42.9395],[77.4225,42.9285],[77.3535,42.899],[77.302,42.9165],[77.2335,42.912],[77.155,42.9725],[77.0845,42.981],[77.034,42.9475],[77.0045,42.983],[76.9165,42.966],[76.8515,42.9785],[76.709,42.904],[76.5225,42.922],[76.486,42.8885],[76.344,42.861],[76.309,42.901],[76.1955,42.931],[76.0285,42.911],[75.937,42.9555],[75.8235,42.9385],[75.7865,42.899],[75.7615,42.8335],[75.717,42.7975],[75.5705,42.8305],[75.419,42.8395],[75.3365,42.8555],[75.2315,42.8535],[75.037,42.9205],[74.8535,43.0],[74.7515,42.99],[74.6155,43.085],[74.5775,43.133],[74.432,43.1655],[74.3845,43.1975],[74.3085,43.2165],[74.294,43.242],[74.1925,43.2555],[74.222,43.205],[74.0765,43.187],[74.042,43.172],[73.969,43.2225],[73.9575,43.1805],[73.8995,43.119],[73.838,43.128],[73.766,43.1065],[73.612,43.041],[73.5595,43.029],[73.5575,42.9825],[73.516,42.935],[73.5215,42.8625],[73.501,42.7655],[73.4655,42.7315],[73.433,42.549],[73.4485,42.5085],[73.5155,42.435],[73.487,42.4175],[73.357,42.4365],[73.3145,42.458],[73.3095,42.518],[73.12,42.552],[72.911,42.535],[72.7975,42.5805],[72.7445,42.639],[72.588,42.684],[72.499,42.685],[72.282,42.7595],[72.166,42.7545],[72.1205,42.7365],[72.057,42.769],[71.8635,42.833],[71.6755,42.79],[71.637,42.767],[71.5705,42.775],[71.534,42.8015],[71.464,42.7855],[71.396,42.7975],[71.268,42.778],[71.274,42.743],[71.182,42.6635],[71.1795,42.6105],[71.0015,42.5855],[71.0755,42.4725],[70.9815,42.498],[70.9555,42.402],[70.898,42.3665],[70.8655,42.32],[70.891,42.263],[70.9435,42.2635],[70.9885,42.2525],[71.025,42.2925],[71.1335,42.282],[71.269,42.1965],[71.218,42.137],[71.174,42.144],[71.029,42.0675],[70.9925,42.0305],[70.865,42.054],[70.838,41.9995],[70.854,41.9415],[70.665,41.907],[70.5965,41.818],[70.5275,41.7985],[70.4965,41.7195],[70.3965,41.684],[70.367,41.6475],[70.263,41.6075],[70.213,41.611],[70.172,41.5175],[70.2405,41.4915],[70.303,41.5205],[70.4075,41.4705],[70.488,41.398],[70.666,41.47],[70.721,41.442],[70.7785,41.3885],[70.776,41.2165],[70.841,41.251],[70.9625,41.166],[71.039,41.1905],[71.127,41.1435],[71.2315,41.1925],[71.2725,41.1735],[71.2795,41.102],[71.3465,41.127],[71.3955,41.1075],[71.4515,41.157],[71.4425,41.248],[71.4705,41.297],[71.569,41.293],[71.6365,41.3425],[71.681,41.422],[71.6695,41.4975],[71.711,41.4875],[71.7595,41.4355],[71.831,41.3875],[71.925,41.294],[71.862,41.201],[71.8865,41.168],[72.074,41.1215],[72.137,41.1625],[72.2085,41.0595],[72.1715,40.995],[72.2465,41.004],[72.3305,41.037],[72.444,41.032],[72.4895,40.976],[72.5515,40.962],[72.593,40.905],[72.5915,40.868],[72.7125,40.8485],[72.832,40.8565],[72.939,40.8005],[73.014,40.845],[73.0895,40.8495],[73.1375,40.8275],[73.1395,40.7855],[72.9905,40.7645],[72.9465,40.732],[72.8015,40.6775],[72.757,40.622],[72.6925,40.597],[72.6695,40.5235],[72.613,40.5175],[72.5055,40.5605],[72.476,40.551],[72.4095,40.619],[72.3855,40.604],[72.42,40.549],[72.441,40.4735],[72.4105,40.401],[72.321,40.446],[72.278,40.434],[72.2535,40.479],[72.159,40.483],[72.087,40.451],[72.089,40.405],[71.9665,40.3195],[71.9785,40.2565],[71.8845,40.2625],[71.8285,40.241],[71.72,40.1535],[71.6895,40.1875],[71.6985,40.2445],[71.62,40.267],[71.6165,40.2065],[71.513,40.231],[71.5115,40.268],[71.428,40.284],[71.369,40.319],[71.308,40.3085],[71.274,40.3435],[71.1245,40.3355],[71.0325,40.306],[70.9815,40.3215],[70.897,40.312],[70.894,40.2315]],[[71.036,40.1805],[71.076,40.1505],[71.091,40.1045],[71.0875,40.07],[71.115,40.0205],[71.21,39.9545],[71.155,39.933],[71.0875,39.9885],[71.1145,40.014],[71.103,40.026],[71.085,40.0755],[71.0535,40.0925],[71.036,40.1805]],[[71.7145,39.966],[71.785,39.999],[71.8305,39.955],[71.7145,39.966]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/c7/Flag_of_Kyrgyzstan.svg","name:en":"Kyrgyzstan","wikidata":"Q813","ISO3166-1:alpha2":"KG","ISO3166-1:alpha3":"KGZ","ISO3166-1:numeric":"417"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[6.3675,49.4695],[6.356,49.5295],[6.3745,49.5915],[6.4215,49.622],[6.431,49.67],[6.506,49.7165],[6.5165,49.805],[6.397,49.8225],[6.364,49.8505],[6.2615,49.881],[6.1985,49.9485],[6.112,50.0595],[6.1375,50.13],[6.1195,50.1635],[6.025,50.183],[5.9645,50.1715],[5.9615,50.1315],[5.901,50.116],[5.819,50.013],[5.832,49.9765],[5.775,49.961],[5.736,49.897],[5.755,49.7915],[5.792,49.787],[5.887,49.7095],[5.9095,49.6645],[5.8185,49.5465],[5.8665,49.5],[5.94,49.501],[6.042,49.448],[6.196,49.5055],[6.257,49.51],[6.3675,49.4695]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/da/Flag_of_Luxembourg.svg","name:en":"Luxembourg","wikidata":"Q32","ISO3166-1:alpha2":"LU","ISO3166-1:alpha3":"LUX","ISO3166-1:numeric":"442"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[13.467,45.5895],[13.601,45.468],[13.6755,45.4425],[13.7655,45.467],[13.8145,45.434],[13.887,45.426],[13.9145,45.4535],[14.0705,45.4855],[14.143,45.475],[14.2455,45.5035],[14.328,45.472],[14.4375,45.511],[14.5005,45.5495],[14.507,45.5945],[14.5955,45.628],[14.698,45.568],[14.7205,45.534],[14.8035,45.4955],[14.8165,45.4605],[14.9795,45.4995],[15.0535,45.4945],[15.1665,45.422],[15.222,45.4255],[15.277,45.466],[15.329,45.4525],[15.3855,45.4865],[15.301,45.5375],[15.3065,45.6325],[15.39,45.6375],[15.3545,45.7145],[15.311,45.684],[15.2595,45.726],[15.3,45.7545],[15.5385,45.8475],[15.629,45.833],[15.683,45.8635],[15.709,45.931],[15.715,46.058],[15.6325,46.0835],[15.6075,46.167],[15.6745,46.227],[15.7855,46.2165],[15.7915,46.2585],[15.8635,46.2675],[16.0015,46.3075],[16.0775,46.348],[16.0505,46.382],[16.148,46.405],[16.189,46.378],[16.3015,46.3785],[16.2415,46.4985],[16.3655,46.5465],[16.4715,46.5165],[16.5385,46.476],[16.597,46.476],[16.5235,46.5055],[16.5085,46.5655],[16.392,46.6335],[16.4285,46.694],[16.3185,46.754],[16.313,46.7975],[16.3475,46.8405],[16.291,46.873],[16.114,46.869],[15.986,46.8275],[15.985,46.753],[16.0425,46.686],[15.95,46.688],[15.8625,46.722],[15.7215,46.696],[15.65,46.706],[15.5465,46.667],[15.5435,46.632],[15.464,46.6145],[15.414,46.6555],[15.236,46.6395],[15.1105,46.6595],[15.016,46.641],[14.9795,46.6015],[14.8865,46.613],[14.844,46.577],[14.8185,46.5095],[14.759,46.5045],[14.675,46.4505],[14.54,46.4115],[14.447,46.4215],[14.4295,46.447],[14.308,46.4305],[14.1915,46.443],[14.1215,46.4765],[14.0195,46.4815],[13.912,46.521],[13.7935,46.5055],[13.714,46.523],[13.6935,46.444],[13.582,46.4305],[13.5655,46.398],[13.437,46.3545],[13.4495,46.335],[13.3925,46.2825],[13.444,46.2255],[13.6335,46.192],[13.6445,46.1375],[13.516,46.0625],[13.502,45.9805],[13.568,45.9685],[13.643,45.9825],[13.638,45.9365],[13.5745,45.8435],[13.596,45.808],[13.6695,45.7995],[13.784,45.7485],[13.8575,45.666],[13.9185,45.6335],[13.8515,45.585],[13.7185,45.5945],[13.639,45.639],[13.467,45.5895]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/f0/Flag_of_Slovenia.svg","name:en":"Slovenia","wikidata":"Q215","ISO3166-1:alpha2":"SI","ISO3166-1:alpha3":"SVN","ISO3166-1:numeric":"705"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[23.618,51.508],[23.5655,51.534],[23.5405,51.601],[23.553,51.715],[23.531,51.7435],[23.6315,51.78],[23.612,51.9175],[23.6885,51.994],[23.64,52.0855],[23.5565,52.1115],[23.49,52.1685],[23.3955,52.201],[23.2035,52.2265],[23.2155,52.3295],[23.3565,52.469],[23.4665,52.5495],[23.6415,52.6075],[23.773,52.623],[23.9385,52.713],[23.9395,52.813],[23.9165,52.939],[23.9255,53.0245],[23.8735,53.087],[23.915,53.162],[23.819,53.244],[23.7075,53.4365],[23.549,53.768],[23.515,53.9565],[23.482,54.0],[23.5285,54.066],[23.486,54.153],[23.4245,54.1775],[23.3375,54.2515],[23.234,54.261],[23.2025,54.2885],[23.092,54.2985],[22.984,54.3895],[22.8365,54.4065],[22.792,54.3635],[22.6415,54.354],[22.153,54.3365],[21.4955,54.324],[21.2745,54.3285],[21.007,54.3535],[20.8185,54.36],[20.4385,54.388],[20.3325,54.401],[19.647,54.4535],[19.404,54.604],[19.0815,54.7605],[18.958,54.8335],[18.504,55.0085],[18.306,55.036],[18.0685,55.0345],[17.837,55.022],[17.5475,54.9725],[17.281,54.9455],[17.099,54.9125],[16.8705,54.8415],[16.7575,54.784],[16.525,54.7535],[16.391,54.726],[16.2965,54.691],[16.204,54.6395],[16.048,54.511],[15.7605,54.4345],[15.5535,54.3905],[15.203,54.3425],[14.7855,54.2445],[14.61,54.212],[14.279,54.1255],[14.2375,54.126],[14.199,54.2505],[14.1565,54.3015],[14.106,54.318],[14.1125,54.4405],[14.0785,54.441],[14.0695,54.2775],[14.168,54.239],[14.242,53.9875],[14.2125,53.8675],[14.2835,53.7725],[14.267,53.6985],[14.284,53.6345],[14.317,53.618],[14.3025,53.5535],[14.3715,53.4565],[14.3735,53.409],[14.4495,53.2595],[14.3775,53.202],[14.3875,53.1425],[14.338,53.0465],[14.2355,52.993],[14.1435,52.9615],[14.158,52.8765],[14.1415,52.824],[14.21,52.818],[14.3505,52.7515],[14.468,52.6595],[14.596,52.6105],[14.638,52.5745],[14.604,52.529],[14.635,52.4975],[14.534,52.396],[14.594,52.274],[14.6895,52.257],[14.716,52.233],[14.683,52.1125],[14.746,52.0815],[14.721,51.9525],[14.693,51.901],[14.5905,51.838],[14.644,51.7965],[14.6565,51.7405],[14.7475,51.6755],[14.766,51.6105],[14.712,51.5615],[14.737,51.5255],[14.9465,51.472],[14.9775,51.3415],[15.033,51.2945],[15.038,51.244],[14.993,51.1625],[14.9795,51.0775],[14.8965,50.9405],[14.8235,50.8705],[15.002,50.869],[14.9895,50.9215],[15.0175,50.967],[15.0165,51.022],[15.105,50.9915],[15.2295,50.9965],[15.292,50.9535],[15.277,50.891],[15.353,50.8505],[15.392,50.776],[15.439,50.809],[15.5245,50.777],[15.579,50.779],[15.7055,50.7375],[15.816,50.7555],[15.8635,50.68],[15.9885,50.685],[16.029,50.604],[16.1035,50.6635],[16.188,50.6275],[16.235,50.6715],[16.343,50.6615],[16.445,50.5795],[16.3605,50.501],[16.199,50.442],[16.2675,50.3795],[16.361,50.3795],[16.4895,50.264],[16.5485,50.23],[16.5605,50.1645],[16.641,50.112],[16.706,50.0965],[16.7835,50.1455],[16.81,50.1895],[16.898,50.222],[16.999,50.216],[17.02,50.2785],[16.9405,50.32],[16.908,50.391],[16.8605,50.411],[16.908,50.4495],[16.9835,50.42],[17.1105,50.405],[17.29,50.3175],[17.3425,50.281],[17.6105,50.266],[17.689,50.302],[17.7585,50.2065],[17.5925,50.16],[17.6765,50.103],[17.75,50.0775],[17.7775,50.02],[17.8685,49.9725],[17.954,50.005],[18.103,50.0225],[18.117,49.994],[18.2065,49.998],[18.278,49.9635],[18.431,49.938],[18.604,49.857],[18.5695,49.8345],[18.636,49.715],[18.719,49.684],[18.8045,49.679],[18.851,49.517],[18.9715,49.5045],[18.961,49.4545],[19.027,49.394],[19.1775,49.414],[19.219,49.4485],[19.2335,49.511],[19.2815,49.5355],[19.36,49.5355],[19.41,49.592],[19.469,49.5965],[19.5295,49.573],[19.5305,49.536],[19.582,49.458],[19.6345,49.4125],[19.7295,49.3915],[19.7905,49.4105],[19.805,49.323],[19.763,49.2075],[19.8445,49.195],[19.9195,49.236],[20.0085,49.22],[20.0755,49.179],[20.1025,49.253],[20.1465,49.318],[20.242,49.3505],[20.3195,49.347],[20.3295,49.391],[20.408,49.393],[20.464,49.416],[20.574,49.3765],[20.6115,49.4135],[20.723,49.4195],[20.826,49.3345],[20.8655,49.3475],[20.9255,49.296],[20.994,49.3125],[21.044,49.3655],[21.104,49.3765],[21.0565,49.4215],[21.124,49.4365],[21.192,49.401],[21.2775,49.461],[21.434,49.4125],[21.631,49.4475],[21.7635,49.3835],[21.961,49.349],[22.034,49.2785],[22.0305,49.225],[22.236,49.1545],[22.3205,49.1355],[22.3695,49.1455],[22.414,49.102],[22.5655,49.088],[22.6395,49.0595],[22.7655,49.0535],[22.8915,49.008],[22.8645,49.0665],[22.789,49.158],[22.7075,49.175],[22.7475,49.2165],[22.747,49.36],[22.6965,49.495],[22.641,49.53],[22.848,49.71],[22.9705,49.8385],[23.0335,49.8815],[23.2795,50.0865],[23.47,50.218],[23.581,50.266],[23.639,50.3205],[23.6865,50.3315],[23.703,50.3755],[23.8035,50.405],[23.9975,50.412],[24.07,50.5035],[24.0985,50.5995],[24.0715,50.7205],[24.0185,50.7255],[24.0095,50.772],[23.9575,50.795],[23.99,50.8375],[24.0945,50.836],[24.099,50.877],[23.9985,50.9275],[23.8765,51.079],[23.8215,51.1645],[23.7265,51.238],[23.695,51.287],[23.636,51.319],[23.6975,51.403],[23.6715,51.475],[23.618,51.508]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/12/Flag_of_Poland.svg","name:en":"Poland","wikidata":"Q36","ISO3166-1:alpha2":"PL","ISO3166-1:alpha3":"POL","ISO3166-1:numeric":"616"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-180.0,62.5545],[-179.955,62.617],[-179.934,62.697],[-179.944,62.763],[-180.0,62.876],[-180.0,62.5545]]],[[[-168.9245,65.986],[-168.977,66.015],[-169.1855,66.014],[-169.1605,66.1055],[-169.2075,66.195],[-169.317,66.2695],[-169.53,66.336],[-169.7395,66.3605],[-169.8305,66.413],[-169.996,66.466],[-170.208,66.502],[-170.291,66.552],[-170.5815,66.667],[-170.8275,66.7455],[-170.8495,66.811],[-170.91,66.8665],[-171.128,66.9455],[-171.1965,67.027],[-171.2955,67.0765],[-171.494,67.129],[-171.788,67.169],[-172.005,67.174],[-172.108,67.1635],[-172.4425,67.2025],[-172.656,67.2435],[-172.9245,67.2405],[-173.3565,67.2805],[-174.1665,67.5795],[-174.2275,67.6075],[-174.94,67.817],[-175.4245,67.9945],[-175.5745,68.028],[-176.4905,68.2655],[-177.2225,68.45],[-177.6285,68.594],[-178.09,68.73],[-178.4005,68.874],[-178.644,68.9485],[-178.9375,69.009],[-179.0035,69.0465],[-179.201,69.1035],[-179.3395,69.124],[-179.623,69.1265],[-180.0,69.2895],[-180.0,68.9755],[-180.0,68.97],[-180.0,68.959],[-180.0,68.93],[-180.0,68.9255],[-180.0,68.5505],[-180.0,68.513],[-180.0,68.3565],[-180.0,67.9265],[-180.0,67.552],[-180.0,67.168],[-180.0,66.9295],[-180.0,66.914],[-180.0,66.894],[-180.0,66.6405],[-180.0,65.866],[-180.0,65.8635],[-180.0,65.8035],[-180.0,65.479],[-180.0,65.454],[-180.0,65.4455],[-180.0,65.432],[-180.0,65.408],[-180.0,65.386],[-180.0,65.3825],[-180.0,65.3605],[-180.0,65.33],[-180.0,65.3245],[-180.0,65.3115],[-180.0,65.0385],[-180.0,64.7465],[-179.7515,64.8655],[-179.3925,64.976],[-179.2545,65.0435],[-179.119,65.1455],[-179.07,65.2125],[-178.728,65.2625],[-178.4635,65.2455],[-177.9815,65.2435],[-177.5195,65.2445],[-177.2845,65.2645],[-177.1555,65.2855],[-176.957,65.3385],[-176.746,65.3525],[-176.555,65.3115],[-176.394,65.255],[-176.3365,65.189],[-176.358,64.9725],[-176.286,64.8915],[-176.156,64.8215],[-175.6825,64.607],[-175.5205,64.578],[-175.134,64.563],[-174.831,64.5225],[-174.556,64.4485],[-174.46,64.39],[-174.3595,64.2955],[-174.259,64.2535],[-173.816,64.1395],[-173.5275,64.103],[-173.341,64.0635],[-173.202,64.0465],[-173.0325,64.0445],[-172.706,64.0885],[-172.382,64.1915],[-172.135,64.2075],[-172.009,64.228],[-171.845,64.294],[-171.789,64.3455],[-171.777,64.4425],[-171.8325,64.559],[-171.698,64.632],[-171.6225,64.6905],[-171.5965,64.7455],[-171.627,64.83],[-171.641,65.0115],[-171.6155,65.119],[-171.6895,65.232],[-171.5575,65.3065],[-171.495,65.3125],[-171.119,65.2675],[-170.941,65.2705],[-170.8165,65.2905],[-170.648,65.35],[-170.2235,65.471],[-170.125,65.5245],[-170.038,65.601],[-170.01,65.7375],[-169.8775,65.787],[-169.384,65.5875],[-169.016,65.481],[-168.9245,65.986]]],[[[-180.0,70.7165],[-179.726,70.669],[-179.532,70.6615],[-179.036,70.6945],[-178.555,70.763],[-178.3425,70.7715],[-177.6325,70.845],[-177.3355,70.908],[-177.1365,70.9645],[-176.9055,71.08],[-176.8245,71.1885],[-176.8175,71.238],[-176.893,71.327],[-177.0005,71.3825],[-177.2605,71.4525],[-177.4565,71.5595],[-177.7225,71.648],[-178.0285,71.714],[-178.5845,71.775],[-179.058,71.803],[-179.612,71.791],[-180.0,71.749],[-180.0,71.534],[-180.0,71.0255],[-180.0,70.7165]]],[[[-176.3625,71.4065],[-176.3,71.3265],[-176.0885,71.2305],[-175.807,71.168],[-175.577,71.157],[-175.3095,71.181],[-175.0685,71.248],[-174.9765,71.3055],[-174.9395,71.3935],[-174.996,71.4715],[-175.141,71.539],[-175.5645,71.6155],[-175.799,71.6265],[-176.028,71.606],[-176.2155,71.557],[-176.333,71.487],[-176.3625,71.4065]]],[[[22.792,54.3635],[22.7365,54.443],[22.7035,54.453],[22.6805,54.533],[22.6865,54.591],[22.743,54.627],[22.7415,54.7285],[22.8735,54.789],[22.855,54.888],[22.726,54.9635],[22.6035,55.0135],[22.589,55.07],[22.466,55.0445],[22.287,55.0645],[22.1575,55.0555],[22.101,55.024],[21.9665,55.074],[21.758,55.124],[21.649,55.181],[21.5725,55.198],[21.5075,55.1855],[21.4495,55.2215],[21.3845,55.2935],[21.271,55.245],[21.0985,55.2565],[20.9545,55.281],[20.6555,55.384],[20.401,55.1805],[20.202,55.16],[19.951,55.16],[19.824,55.14],[19.7045,55.0845],[19.606,54.9795],[19.584,54.909],[19.6175,54.827],[19.5775,54.737],[19.404,54.604],[19.647,54.4535],[20.3325,54.401],[20.4385,54.388],[20.8185,54.36],[21.007,54.3535],[21.2745,54.3285],[21.4955,54.324],[22.153,54.3365],[22.6415,54.354],[22.792,54.3635]]],[[[37.4375,46.716],[37.457,46.6235],[37.512,46.5665],[37.572,46.443],[37.696,46.3035],[37.8835,46.2055],[37.776,46.1545],[37.738,46.115],[37.6675,46.0005],[37.632,45.886],[37.435,45.8065],[37.3595,45.727],[37.3405,45.5395],[37.292,45.515],[37.153,45.5655],[37.042,45.579],[36.954,45.6205],[36.8875,45.633],[36.6685,45.6265],[36.3385,45.6715],[36.1355,45.6475],[36.0725,45.6255],[35.982,45.6165],[35.871,45.6455],[35.7355,45.633],[35.6275,45.5745],[35.5765,45.4905],[35.4595,45.5605],[35.429,45.6175],[35.3375,45.683],[35.3165,45.7235],[35.2335,45.7915],[34.975,45.762],[34.799,45.8105],[34.802,45.9005],[34.7545,45.9085],[34.67,45.9675],[34.561,45.9945],[34.4985,45.9425],[34.443,45.962],[34.405,46.0095],[34.3295,46.0605],[34.248,46.053],[34.1885,46.066],[34.1175,46.1075],[34.0525,46.109],[33.8115,46.204],[33.736,46.186],[33.615,46.226],[33.6355,46.1465],[33.572,46.1025],[33.591,46.061],[33.5405,46.012],[32.7725,45.8265],[32.589,45.7125],[32.478,45.6605],[32.3505,45.6165],[32.2975,45.575],[32.231,45.4915],[32.2025,45.383],[32.229,45.289],[32.314,45.1955],[32.38,45.1645],[32.5535,45.122],[32.6315,45.112],[32.7485,45.1255],[32.8315,45.151],[32.89,45.089],[33.028,45.0075],[33.193,44.9505],[33.2945,44.94],[33.244,44.8215],[33.2465,44.7635],[33.1405,44.696],[33.0915,44.5895],[33.127,44.48],[33.2955,44.335],[33.4205,44.2945],[33.478,44.258],[33.618,44.2095],[33.716,44.188],[33.8565,44.1945],[33.9515,44.1845],[34.0925,44.2135],[34.2375,44.232],[34.3045,44.263],[34.555,44.4055],[34.666,44.547],[34.736,44.585],[34.8085,44.604],[34.929,44.611],[35.06,44.584],[35.1585,44.5925],[35.3015,44.6495],[35.3975,44.7375],[35.535,44.7755],[35.632,44.849],[35.6875,44.82],[35.7805,44.7955],[35.8595,44.793],[36.033,44.811],[36.103,44.8335],[36.216,44.8195],[36.509,44.8755],[36.6095,44.9405],[36.705,44.922],[36.791,44.923],[36.9545,44.8815],[37.035,44.845],[37.1145,44.748],[37.1485,44.6635],[37.1905,44.624],[37.319,44.5525],[37.542,44.4835],[37.7535,44.471],[37.7985,44.4335],[37.9095,44.391],[38.0555,44.269],[38.1945,44.229],[38.263,44.1985],[38.4605,44.1685],[38.6025,44.1295],[38.705,44.0425],[38.7975,44.002],[38.8525,43.9525],[38.9205,43.917],[39.204,43.7205],[39.25,43.665],[39.334,43.608],[39.388,43.547],[39.471,43.4945],[39.542,43.42],[39.6415,43.369],[39.681,43.312],[39.8,43.2395],[39.8845,43.2245],[40.0085,43.3855],[40.0905,43.5555],[40.2615,43.5855],[40.2995,43.57],[40.478,43.549],[40.5665,43.519],[40.662,43.563],[40.8935,43.457],[40.95,43.4195],[41.0045,43.432],[41.0395,43.3995],[41.221,43.3805],[41.288,43.337],[41.363,43.3685],[41.413,43.3245],[41.5435,43.2705],[41.6215,43.222],[41.6845,43.217],[41.7455,43.237],[41.804,43.202],[41.867,43.244],[42.038,43.188],[42.1995,43.228],[42.253,43.2125],[42.3365,43.2195],[42.358,43.247],[42.442,43.251],[42.4475,43.22],[42.5435,43.1765],[42.617,43.1635],[42.6665,43.136],[42.698,43.172],[42.7765,43.189],[42.853,43.179],[42.99,43.119],[43.051,43.019],[43.173,42.963],[43.185,42.9385],[43.561,42.8675],[43.609,42.8135],[43.6775,42.802],[43.779,42.758],[43.804,42.715],[43.759,42.655],[43.715,42.6365],[43.7705,42.589],[43.8365,42.5985],[43.9625,42.5475],[44.0105,42.5915],[44.1155,42.6175],[44.162,42.6065],[44.225,42.6305],[44.2495,42.681],[44.3195,42.723],[44.394,42.7065],[44.5,42.734],[44.68,42.756],[44.753,42.714],[44.7665,42.643],[44.804,42.6145],[44.8875,42.747],[44.98,42.745],[45.053,42.6925],[45.086,42.7115],[45.1585,42.7075],[45.252,42.62],[45.2835,42.606],[45.3545,42.522],[45.4185,42.5515],[45.4935,42.535],[45.5715,42.548],[45.614,42.5055],[45.6875,42.5025],[45.7215,42.4755],[45.7755,42.4885],[45.7745,42.4285],[45.7345,42.3785],[45.7535,42.3095],[45.652,42.292],[45.609,42.234],[45.6475,42.1865],[45.748,42.146],[45.786,42.102],[45.8555,42.1135],[45.9215,42.081],[45.9295,42.032],[45.9875,42.0455],[46.0385,42.02],[46.1615,41.9905],[46.237,42.016],[46.246,41.979],[46.3205,41.9295],[46.3995,41.94],[46.422,41.908],[46.4635,41.8655],[46.5085,41.8895],[46.5515,41.867],[46.5565,41.8205],[46.6215,41.824],[46.757,41.8625],[46.7655,41.801],[46.8665,41.7205],[47.0125,41.6275],[46.9915,41.595],[47.0515,41.5545],[47.11,41.575],[47.1715,41.527],[47.222,41.419],[47.252,41.3985],[47.3005,41.308],[47.377,41.2725],[47.4985,41.2685],[47.5065,41.226],[47.564,41.198],[47.6185,41.234],[47.701,41.226],[47.7265,41.1935],[47.7835,41.185],[47.8205,41.222],[47.8845,41.2185],[47.9115,41.255],[47.8905,41.2875],[47.9915,41.3555],[48.003,41.4165],[48.065,41.4925],[48.203,41.5125],[48.2845,41.561],[48.3775,41.591],[48.491,41.7275],[48.5555,41.7825],[48.5925,41.843],[48.814,41.9505],[48.745,41.9915],[48.685,42.0515],[48.5575,42.141],[48.531,42.196],[48.439,42.2915],[48.322,42.4435],[48.2215,42.522],[48.1495,42.6395],[47.984,42.832],[47.9655,42.9145],[47.904,42.9995],[47.813,43.0605],[47.7775,43.1375],[47.8215,43.2155],[47.8315,43.3195],[47.7935,43.481],[47.822,43.529],[47.845,43.636],[47.933,43.7535],[48.0925,43.868],[48.1355,43.9365],[48.1435,43.993],[48.091,44.1035],[48.0175,44.1555],[47.9145,44.186],[47.6985,44.1995],[47.6635,44.2105],[47.7925,44.3105],[47.84,44.3945],[47.839,44.471],[47.7815,44.594],[47.6905,44.658],[47.6195,44.683],[47.504,44.695],[47.4055,44.681],[47.3105,44.6405],[47.165,44.6055],[47.1535,44.6435],[47.259,44.692],[47.3345,44.759],[47.4175,44.885],[47.5,44.9915],[47.558,45.1295],[47.6155,45.2065],[47.827,45.2625],[47.9665,45.274],[48.0335,45.292],[48.1145,45.337],[48.243,45.4505],[48.334,45.4615],[48.4935,45.422],[48.677,45.4025],[48.8485,45.4345],[48.9585,45.4985],[49.0155,45.577],[49.0325,45.641],[49.071,45.689],[49.1895,45.7575],[49.417,45.846],[49.5175,45.919],[49.614,45.975],[49.886,46.046],[49.7785,46.1185],[49.7015,46.1865],[49.6,46.1765],[49.5065,46.1935],[49.2625,46.294],[49.162,46.384],[49.045,46.3965],[48.986,46.433],[48.912,46.4505],[48.8785,46.4815],[48.8195,46.4855],[48.788,46.541],[48.7025,46.563],[48.545,46.5635],[48.5735,46.6065],[48.5605,46.642],[48.478,46.6705],[48.5485,46.711],[48.7135,46.721],[48.7505,46.6855],[48.92,46.6935],[48.996,46.743],[48.9155,46.8805],[48.71,47.096],[48.5195,47.412],[48.4515,47.4115],[48.319,47.5515],[48.2095,47.6915],[48.1115,47.745],[48.028,47.763],[47.9625,47.7515],[47.6525,47.758],[47.4155,47.8385],[47.412,47.7635],[47.385,47.6815],[47.1945,47.761],[47.122,47.8315],[47.181,47.854],[47.101,47.928],[47.05,47.998],[47.2005,48.055],[47.211,48.082],[47.091,48.103],[47.125,48.158],[47.1035,48.212],[47.123,48.2685],[46.8895,48.3275],[46.7475,48.3535],[46.493,48.4325],[46.779,48.9515],[46.8925,48.982],[46.972,49.0275],[47.0285,49.089],[47.0515,49.1655],[46.996,49.2325],[46.9145,49.283],[46.782,49.34],[46.8295,49.5655],[46.858,49.6435],[46.87,49.743],[46.9025,49.864],[46.9575,49.8715],[47.1825,49.935],[47.3535,50.0945],[47.3175,50.152],[47.2575,50.1915],[47.3355,50.238],[47.3005,50.303],[47.4065,50.3365],[47.4725,50.42],[47.5415,50.4605],[47.6125,50.464],[47.6635,50.4085],[47.7315,50.386],[47.7625,50.341],[47.8285,50.3275],[47.8855,50.2685],[47.939,50.2425],[48.009,50.142],[48.095,50.1],[48.1315,49.998],[48.269,49.8595],[48.4505,49.835],[48.7455,49.9215],[48.9035,50.0185],[48.848,50.0915],[48.7635,50.098],[48.809,50.1705],[48.7325,50.257],[48.659,50.528],[48.652,50.601],[48.5705,50.6325],[48.606,50.662],[48.689,50.6125],[48.8145,50.5955],[49.0095,50.682],[49.126,50.7845],[49.2625,50.823],[49.42,50.849],[49.4435,50.8775],[49.408,50.961],[49.3385,50.987],[49.3965,51.049],[49.393,51.09],[49.5545,51.11],[49.776,51.107],[49.911,51.201],[50.04,51.2515],[50.243,51.28],[50.373,51.3325],[50.338,51.382],[50.497,51.4275],[50.547,51.465],[50.5375,51.589],[50.5865,51.5905],[50.636,51.629],[50.7315,51.6285],[50.7675,51.575],[50.812,51.585],[50.8125,51.649],[50.768,51.7145],[50.768,51.773],[50.8715,51.7535],[50.8935,51.6815],[51.0845,51.6665],[51.204,51.6675],[51.272,51.685],[51.3035,51.641],[51.38,51.641],[51.3805,51.5635],[51.2855,51.532],[51.2865,51.488],[51.4315,51.475],[51.566,51.506],[51.64,51.5385],[51.656,51.4485],[51.8135,51.497],[51.7705,51.583],[51.894,51.6835],[51.9995,51.6835],[52.09,51.6585],[52.2385,51.724],[52.3355,51.7435],[52.416,51.64],[52.4505,51.6235],[52.5655,51.4635],[52.6475,51.4885],[52.747,51.4865],[52.7905,51.5135],[52.9045,51.4775],[53.0565,51.4895],[53.144,51.485],[53.255,51.512],[53.3925,51.491],[53.4815,51.444],[53.575,51.4245],[53.5955,51.306],[53.66,51.26],[53.6615,51.231],[53.7475,51.204],[53.9325,51.1935],[54.042,51.136],[54.137,51.108],[54.1995,50.964],[54.2885,50.949],[54.288,50.9025],[54.4415,50.8795],[54.518,50.8545],[54.5185,50.812],[54.4735,50.7785],[54.4135,50.6205],[54.466,50.5665],[54.545,50.5275],[54.614,50.5385],[54.73,50.6175],[54.718,50.69],[54.6785,50.718],[54.6975,50.8925],[54.658,50.915],[54.566,50.9155],[54.5685,51.0185],[54.7185,51.0285],[54.7915,50.9855],[54.898,50.958],[54.894,50.92],[55.01,50.9055],[55.071,50.924],[55.1295,50.8795],[55.056,50.8195],[55.1465,50.797],[55.3835,50.6535],[55.403,50.6815],[55.5025,50.67],[55.534,50.6135],[55.6115,50.5985],[55.6615,50.56],[55.7465,50.5795],[55.83,50.623],[55.916,50.6415],[56.0545,50.695],[56.137,50.7535],[56.133,50.8305],[56.1815,50.938],[56.298,50.902],[56.3615,50.9015],[56.3925,50.9455],[56.4605,50.965],[56.448,51.057],[56.51,51.0805],[56.634,50.985],[56.751,50.9815],[56.6995,51.075],[56.78,51.094],[56.8875,51.0605],[56.943,51.0875],[56.9845,51.0625],[57.1465,51.0875],[57.185,51.115],[57.246,51.026],[57.2825,51.0325],[57.3245,50.943],[57.415,50.8965],[57.507,50.876],[57.559,50.936],[57.736,50.9275],[57.7515,50.9395],[57.754,51.056],[57.772,51.1385],[57.867,51.0995],[57.9515,51.0865],[58.0735,51.123],[58.1025,51.07],[58.177,51.066],[58.206,51.1295],[58.3405,51.1455],[58.384,51.075],[58.5205,51.085],[58.5765,51.056],[58.6425,50.9875],[58.5785,50.94],[58.5935,50.8695],[58.688,50.8855],[58.6965,50.848],[58.6565,50.8085],[58.7745,50.8145],[58.8745,50.7],[59.114,50.683],[59.418,50.6365],[59.4795,50.6415],[59.569,50.5735],[59.463,50.5845],[59.4575,50.5435],[59.5165,50.5285],[59.776,50.541],[59.813,50.5355],[59.91,50.6365],[59.9975,50.675],[59.9725,50.7685],[60.015,50.822],[60.188,50.8385],[60.183,50.7785],[60.325,50.6705],[60.5575,50.661],[60.741,50.6655],[60.809,50.6565],[61.449,50.806],[61.486,50.9585],[61.568,51.238],[61.69,51.256],[61.5495,51.3235],[61.505,51.407],[61.391,51.42],[61.3535,51.439],[61.2565,51.441],[61.203,51.461],[60.9995,51.4675],[60.911,51.5505],[60.9355,51.6155],[60.538,51.618],[60.4255,51.647],[60.3545,51.6905],[60.4315,51.7195],[60.5175,51.7975],[60.428,51.7985],[60.162,51.892],[60.144,51.8705],[60.0325,51.9135],[60.002,51.9935],[60.1975,51.991],[60.3395,52.055],[60.511,52.1565],[60.7165,52.156],[60.772,52.208],[60.9455,52.2675],[61.0105,52.326],[61.067,52.347],[60.992,52.423],[60.9825,52.508],[60.842,52.5225],[60.843,52.641],[60.7615,52.6265],[60.7145,52.663],[60.712,52.7645],[60.8345,52.774],[60.987,52.8865],[61.076,52.928],[61.0495,52.981],[61.1215,52.9875],[61.251,53.036],[61.307,52.996],[61.3905,52.9925],[61.469,53.0365],[61.557,53.012],[61.632,52.954],[61.702,52.998],[61.834,52.993],[61.961,52.95],[62.0295,52.951],[62.1305,52.99],[62.1475,53.068],[62.1195,53.112],[62.0275,53.142],[61.916,53.142],[61.784,53.1845],[61.7325,53.239],[61.674,53.2655],[61.6305,53.223],[61.527,53.2155],[61.4,53.274],[61.226,53.2835],[61.177,53.312],[61.1555,53.4055],[61.2165,53.432],[61.229,53.484],[61.2995,53.5125],[61.4285,53.4555],[61.488,53.476],[61.565,53.5385],[61.553,53.593],[61.391,53.602],[61.358,53.5615],[61.2155,53.5635],[61.1265,53.59],[61.122,53.615],[60.9005,53.6285],[60.896,53.668],[60.9955,53.673],[61.0585,53.7215],[61.1145,53.721],[61.227,53.7955],[61.237,53.8415],[61.179,53.8525],[61.137,53.9045],[60.9935,53.907],[61.0295,53.955],[61.1,53.975],[61.1805,53.972],[61.205,53.919],[61.28,53.9285],[61.25,54.0235],[61.294,54.074],[61.48,54.083],[61.4805,54.03],[61.569,54.008],[61.7005,54.019],[61.782,53.9845],[61.8185,54.019],[61.893,54.009],[61.857,53.9625],[62.044,53.9485],[62.006,54.0375],[62.0835,54.049],[62.1755,54.0285],[62.339,54.0325],[62.3965,54.004],[62.4465,53.927],[62.5545,53.9335],[62.5975,53.995],[62.569,54.0465],[62.5965,54.072],[62.806,54.112],[62.936,54.1165],[63.0795,54.104],[63.1515,54.123],[63.151,54.1825],[63.337,54.201],[63.357,54.1885],[63.5185,54.207],[63.728,54.261],[63.8035,54.271],[63.8975,54.2165],[63.9615,54.2005],[64.0215,54.2305],[63.984,54.2715],[64.0985,54.311],[64.1845,54.309],[64.359,54.3365],[64.4195,54.3265],[64.4815,54.3665],[64.6,54.375],[64.7385,54.354],[64.975,54.424],[65.121,54.3305],[65.239,54.376],[65.2015,54.466],[65.2125,54.532],[65.306,54.5685],[65.495,54.5965],[65.4565,54.6245],[65.633,54.641],[65.7475,54.6075],[65.831,54.653],[65.8455,54.697],[65.982,54.717],[65.964,54.638],[65.9985,54.625],[66.3815,54.7035],[66.654,54.744],[66.738,54.7435],[66.782,54.7685],[66.994,54.7895],[67.282,54.8255],[67.3325,54.8735],[67.3985,54.8555],[67.5165,54.862],[67.563,54.8445],[67.7735,54.886],[67.8195,54.9715],[67.9105,54.9835],[68.0325,54.9505],[68.2345,54.969],[68.2375,55.054],[68.2715,55.085],[68.1895,55.1515],[68.282,55.205],[68.4445,55.1965],[68.6355,55.204],[68.635,55.2655],[68.697,55.289],[68.7085,55.348],[68.7485,55.379],[68.929,55.3185],[68.916,55.3655],[68.9325,55.442],[69.048,55.427],[69.1605,55.3905],[69.1995,55.33],[69.4165,55.3815],[69.442,55.342],[69.707,55.3515],[69.863,55.3],[69.9505,55.21],[70.057,55.209],[70.1135,55.172],[70.2275,55.148],[70.292,55.1925],[70.402,55.2155],[70.41,55.2535],[70.478,55.2725],[70.6205,55.2535],[70.695,55.2895],[70.789,55.2895],[70.9215,55.1305],[70.993,55.0735],[71.0085,54.9705],[70.9565,54.8885],[71.0195,54.852],[71.0305,54.7785],[71.0965,54.713],[71.2105,54.7],[71.293,54.668],[71.2915,54.606],[71.2145,54.61],[71.1675,54.5605],[71.1705,54.461],[71.2295,54.354],[71.1985,54.3115],[71.1125,54.335],[70.9985,54.336],[70.9965,54.2755],[71.073,54.275],[71.0715,54.2055],[71.138,54.162],[71.1225,54.1295],[71.179,54.095],[71.2745,54.147],[71.296,54.185],[71.491,54.1585],[71.488,54.101],[71.61,54.117],[71.7205,54.1065],[71.764,54.1475],[71.7265,54.1875],[71.751,54.254],[71.886,54.2315],[71.949,54.2435],[72.0735,54.1995],[72.101,54.1475],[72.1845,54.1205],[72.2185,54.182],[72.0855,54.219],[72.136,54.305],[72.0515,54.338],[72.0325,54.3665],[72.189,54.355],[72.2785,54.317],[72.2995,54.187],[72.4175,54.151],[72.44,54.12],[72.3965,54.0515],[72.4175,53.9985],[72.3695,53.9445],[72.4865,53.901],[72.543,53.976],[72.7145,53.951],[72.7195,53.9995],[72.68,54.045],[72.571,54.0515],[72.56,54.1165],[72.6085,54.137],[72.8255,54.1215],[72.8315,54.098],[72.994,54.0985],[72.9785,54.0495],[73.0595,54.0405],[73.067,53.9855],[73.1935,53.9705],[73.276,53.9425],[73.5045,53.939],[73.519,54.004],[73.609,54.0085],[73.657,54.0465],[73.7675,54.054],[73.691,53.856],[73.4525,53.876],[73.449,53.8075],[73.3555,53.766],[73.323,53.6755],[73.277,53.6395],[73.2385,53.5675],[73.3975,53.522],[73.3625,53.4675],[73.4385,53.4355],[73.645,53.5525],[73.6665,53.613],[73.7475,53.607],[73.821,53.5785],[73.901,53.651],[74.072,53.6295],[74.0515,53.566],[74.1465,53.555],[74.1615,53.6015],[74.2875,53.5605],[74.2915,53.4915],[74.3935,53.4595],[74.4865,53.5725],[74.421,53.594],[74.457,53.691],[74.635,53.668],[74.6675,53.756],[74.757,53.7445],[74.7885,53.828],[74.982,53.8225],[75.0465,53.7925],[75.377,53.9595],[75.441,53.9725],[75.4345,54.0095],[75.375,54.07],[75.529,54.115],[75.598,54.099],[76.203,54.26],[76.1865,54.3015],[76.2575,54.3595],[76.352,54.334],[76.476,54.318],[76.675,54.345],[76.73,54.418],[76.7955,54.419],[76.929,54.458],[76.9355,54.4155],[76.86,54.361],[76.8785,54.302],[76.8285,54.274],[76.828,54.225],[76.7565,54.162],[76.645,54.1245],[76.5825,54.149],[76.4405,54.1675],[76.435,54.1225],[76.4985,54.0715],[76.538,54.0],[76.829,53.8495],[77.339,53.595],[77.9065,53.2915],[78.0255,53.161],[78.267,52.924],[78.403,52.7815],[78.7175,52.429],[78.975,52.1505],[79.1875,51.9235],[79.4115,51.624],[79.7205,51.217],[80.076,50.738],[80.083,50.828],[80.185,50.8275],[80.193,50.9005],[80.2455,50.9185],[80.376,50.927],[80.421,50.962],[80.482,50.9685],[80.482,51.1095],[80.4365,51.119],[80.447,51.2085],[80.6345,51.207],[80.635,51.263],[80.6775,51.3165],[80.9405,51.2595],[80.92,51.219],[81.177,51.1615],[81.142,51.079],[81.103,51.0605],[81.06,50.948],[81.191,50.951],[81.289,50.974],[81.4125,50.9755],[81.4355,50.863],[81.486,50.824],[81.4495,50.756],[81.5825,50.7425],[81.797,50.772],[81.8855,50.8045],[81.997,50.788],[82.0785,50.751],[82.2225,50.737],[82.2705,50.77],[82.351,50.7755],[82.5675,50.747],[82.7015,50.812],[82.739,50.8505],[82.733,50.9275],[82.911,50.9075],[82.9795,50.884],[83.006,50.925],[83.1125,50.966],[83.121,51.011],[83.202,50.9935],[83.407,51.013],[83.4475,50.977],[83.5935,50.9495],[83.6485,50.955],[83.7115,50.8935],[83.8335,50.88],[83.9105,50.8165],[83.9645,50.801],[83.951,50.7465],[84.023,50.698],[84.0825,50.6335],[84.1455,50.603],[84.176,50.5515],[84.2485,50.5155],[84.204,50.469],[84.2685,50.3565],[84.2515,50.29],[84.326,50.2285],[84.41,50.209],[84.447,50.2465],[84.5305,50.206],[84.628,50.2105],[84.692,50.1885],[84.7575,50.137],[84.8565,50.092],[84.946,50.0965],[85.024,50.06],[85.038,50.009],[84.9835,49.984],[84.995,49.9055],[85.0595,49.885],[85.1505,49.7675],[85.1985,49.738],[85.2105,49.6275],[85.2575,49.5885],[85.3215,49.591],[85.3885,49.635],[85.49,49.598],[85.5835,49.6135],[85.6785,49.551],[85.757,49.577],[85.841,49.5475],[85.8835,49.567],[85.969,49.487],[86.037,49.522],[86.113,49.5245],[86.202,49.466],[86.267,49.5465],[86.2715,49.5825],[86.3715,49.5935],[86.4885,49.658],[86.5265,49.702],[86.5825,49.724],[86.6105,49.772],[86.5905,49.801],[86.6975,49.8085],[86.7715,49.764],[86.779,49.696],[86.7095,49.6875],[86.6025,49.6055],[86.618,49.5705],[86.7395,49.571],[86.827,49.5455],[86.8555,49.499],[86.831,49.47],[86.8685,49.435],[86.93,49.42],[86.9265,49.349],[87.006,49.299],[87.0255,49.2575],[87.1985,49.2525],[87.2695,49.2325],[87.3025,49.1695],[87.286,49.116],[87.4265,49.0695],[87.564,49.135],[87.695,49.1755],[87.8145,49.17],[87.9885,49.183],[88.018,49.2265],[88.169,49.2925],[88.1605,49.363],[88.1195,49.3915],[88.185,49.4185],[88.1655,49.4455],[88.222,49.4795],[88.2965,49.471],[88.331,49.4935],[88.411,49.4935],[88.495,49.472],[88.591,49.501],[88.733,49.4515],[88.88,49.478],[88.9325,49.517],[88.9845,49.4635],[89.201,49.523],[89.2325,49.5535],[89.1915,49.586],[89.189,49.6325],[89.241,49.645],[89.36,49.5845],[89.459,49.665],[89.661,49.7],[89.719,49.7285],[89.719,49.772],[89.629,49.8085],[89.6115,49.8635],[89.6295,49.919],[89.7335,49.948],[89.883,49.953],[90.0175,49.9905],[90.0025,50.054],[90.165,50.108],[90.285,50.111],[90.389,50.1925],[90.453,50.197],[90.504,50.235],[90.5805,50.244],[90.6735,50.2145],[90.731,50.2435],[90.7065,50.313],[90.8195,50.3545],[90.911,50.353],[90.903,50.4085],[90.9695,50.4295],[91.093,50.436],[91.16,50.42],[91.2935,50.4695],[91.4005,50.4765],[91.459,50.5085],[91.455,50.5485],[91.5345,50.5815],[91.65,50.586],[91.661,50.64],[91.7235,50.6975],[91.855,50.734],[92.0725,50.6965],[92.172,50.7065],[92.316,50.754],[92.313,50.8765],[92.373,50.88],[92.432,50.803],[92.477,50.7865],[92.571,50.798],[92.6185,50.768],[92.628,50.7035],[92.754,50.7275],[92.7875,50.8055],[92.854,50.81],[93.032,50.768],[93.023,50.716],[92.975,50.6695],[93.05,50.601],[93.249,50.594],[93.3975,50.6345],[93.5445,50.602],[93.636,50.607],[93.7035,50.586],[93.856,50.601],[93.941,50.59],[94.031,50.5965],[94.2405,50.588],[94.2835,50.572],[94.344,50.4915],[94.389,50.215],[94.4215,50.1915],[94.522,50.1725],[94.5435,50.1175],[94.615,50.0355],[94.7605,50.055],[94.999,50.0445],[95.0165,49.9805],[95.0815,49.963],[95.426,49.9575],[95.531,49.8975],[95.5725,49.9445],[95.666,49.9645],[95.7955,49.964],[95.7655,50.017],[95.844,50.0435],[95.9155,50.0215],[95.9675,49.971],[96.0175,50.0035],[96.2605,49.9765],[96.3485,49.9055],[96.417,49.877],[96.5145,49.943],[96.549,49.9435],[96.6005,49.8775],[96.71,49.9285],[96.741,49.9075],[96.999,49.8885],[97.01,49.8335],[97.117,49.82],[97.123,49.795],[97.231,49.743],[97.318,49.752],[97.3575,49.7815],[97.4215,49.7805],[97.5105,49.8145],[97.5805,49.8585],[97.555,49.9225],[97.7805,49.9935],[97.8295,49.923],[97.898,49.984],[97.982,50.019],[98.07,50.036],[98.0635,50.07],[98.1205,50.1],[98.11,50.1315],[98.1825,50.158],[98.1695,50.202],[98.2285,50.236],[98.253,50.2945],[98.308,50.3235],[98.2725,50.41],[98.3275,50.474],[98.274,50.538],[98.1465,50.575],[98.008,50.669],[97.9785,50.784],[98.0085,50.8365],[97.998,50.876],[97.858,50.9595],[97.828,51.019],[97.866,51.046],[97.899,51.1495],[97.9395,51.202],[97.962,51.276],[97.9535,51.334],[98.017,51.3895],[98.05,51.45],[98.126,51.4715],[98.224,51.4565],[98.2565,51.5115],[98.234,51.5475],[98.327,51.692],[98.3785,51.74],[98.4525,51.7365],[98.5215,51.7785],[98.6125,51.8065],[98.7645,51.87],[98.78,51.942],[98.809,51.958],[98.8065,52.0255],[98.8415,52.059],[98.8615,52.136],[98.969,52.1425],[98.9975,52.0865],[99.0715,52.0695],[99.1325,52.024],[99.1735,52.0355],[99.276,52.0185],[99.3055,51.9575],[99.4985,51.9515],[99.52,51.9685],[99.6255,51.8925],[99.801,51.9155],[99.8195,51.848],[99.9095,51.7455],[99.978,51.7535],[100.033,51.7335],[100.1035,51.7545],[100.201,51.743],[100.3535,51.7415],[100.4105,51.73],[100.529,51.75],[100.688,51.7115],[100.739,51.678],[100.93,51.607],[100.99,51.613],[101.1435,51.52],[101.243,51.5475],[101.37,51.456],[101.439,51.4555],[101.5,51.5035],[101.6225,51.469],[101.6205,51.4435],[101.749,51.4555],[101.8935,51.401],[101.928,51.4165],[102.1245,51.3615],[102.1685,51.3185],[102.1195,51.2795],[102.138,51.1765],[102.1235,51.139],[102.151,51.0575],[102.2035,51.0395],[102.241,50.9175],[102.211,50.873],[102.2095,50.817],[102.295,50.7795],[102.3405,50.7325],[102.3025,50.682],[102.3955,50.6445],[102.446,50.6455],[102.479,50.5975],[102.5255,50.5945],[102.547,50.527],[102.6105,50.5065],[102.6475,50.402],[102.727,50.408],[102.7585,50.379],[102.942,50.3055],[103.1765,50.3325],[103.238,50.322],[103.2765,50.285],[103.2565,50.193],[103.294,50.186],[103.425,50.2115],[103.514,50.199],[103.6085,50.144],[103.8005,50.1515],[103.8465,50.1975],[103.9455,50.179],[103.9985,50.1505],[104.108,50.1405],[104.2785,50.201],[104.3035,50.2445],[104.3655,50.265],[104.3965,50.3125],[104.557,50.307],[104.65,50.324],[104.699,50.367],[104.8115,50.341],[104.8765,50.375],[104.89,50.408],[105.008,50.387],[105.12,50.39],[105.198,50.4115],[105.2985,50.472],[105.3475,50.476],[105.4265,50.444],[105.525,50.458],[105.609,50.429],[105.705,50.4265],[105.844,50.4405],[105.899,50.4125],[105.989,50.416],[106.0745,50.3895],[106.084,50.3335],[106.183,50.3395],[106.261,50.298],[106.3955,50.32],[106.4475,50.3145],[106.51,50.3415],[106.5915,50.3385],[106.8155,50.298],[106.9795,50.209],[107.0,50.161],[107.072,50.0685],[107.211,50.0],[107.349,49.9995],[107.383,49.9775],[107.5985,49.97],[107.729,49.9825],[107.794,49.933],[107.969,49.9415],[107.919,49.8755],[107.9675,49.735],[107.9345,49.7115],[107.9685,49.655],[108.0125,49.667],[108.0515,49.6175],[108.161,49.562],[108.304,49.532],[108.3565,49.428],[108.426,49.4135],[108.431,49.372],[108.5175,49.3225],[108.608,49.3275],[108.6525,49.3475],[108.718,49.335],[108.9555,49.345],[109.058,49.323],[109.171,49.353],[109.326,49.329],[109.4125,49.3],[109.487,49.243],[109.559,49.221],[109.684,49.226],[109.8535,49.2015],[109.9025,49.2055],[110.226,49.158],[110.328,49.199],[110.3795,49.247],[110.476,49.2015],[110.6835,49.171],[110.8195,49.182],[111.0785,49.262],[111.277,49.3105],[111.375,49.3575],[111.515,49.323],[111.6685,49.38],[111.788,49.3845],[111.909,49.3765],[112.0075,49.3945],[112.1945,49.4465],[112.2785,49.4845],[112.4865,49.524],[112.689,49.504],[112.8065,49.515],[112.907,49.5685],[113.044,49.608],[113.2185,49.837],[113.474,49.9355],[113.489,49.9735],[113.652,49.9995],[113.7425,50.075],[113.8785,50.105],[114.1785,50.243],[114.339,50.2825],[114.4675,50.2335],[114.617,50.2455],[114.831,50.2235],[115.0075,50.164],[115.0675,50.094],[115.224,49.9885],[115.361,49.94],[115.5065,49.907],[115.6825,49.886],[115.7445,49.8875],[115.983,49.9705],[116.0725,50.0135],[116.233,50.036],[116.3435,49.996],[116.527,49.947],[116.6215,49.931],[116.7135,49.8455],[117.0615,49.6855],[117.2735,49.631],[117.4715,49.6265],[117.634,49.5645],[117.793,49.52],[117.881,49.5155],[117.891,49.5935],[117.974,49.62],[118.074,49.614],[118.1125,49.658],[118.2045,49.69],[118.2395,49.7375],[118.372,49.786],[118.555,49.922],[118.648,49.9475],[118.7345,49.945],[118.9375,49.9915],[118.9865,49.9765],[119.084,49.9845],[119.274,50.105],[119.3295,50.172],[119.31,50.2165],[119.351,50.3575],[119.247,50.3415],[119.145,50.388],[119.2425,50.4465],[119.274,50.6035],[119.3475,50.628],[119.3735,50.68],[119.442,50.694],[119.499,50.766],[119.5205,50.862],[119.5105,50.8975],[119.5835,50.975],[119.663,51.012],[119.754,51.0885],[119.7815,51.172],[119.7525,51.2125],[119.812,51.2315],[119.803,51.278],[119.8685,51.2935],[119.8755,51.333],[119.933,51.354],[119.9955,51.458],[119.978,51.502],[120.045,51.5525],[120.0505,51.6305],[120.1665,51.678],[120.3045,51.781],[120.356,51.7875],[120.3915,51.8305],[120.544,51.883],[120.5425,51.9075],[120.6475,51.9225],[120.712,52.007],[120.679,52.036],[120.755,52.103],[120.7795,52.1635],[120.739,52.2045],[120.7515,52.2555],[120.6215,52.3245],[120.618,52.361],[120.6835,52.429],[120.6865,52.5175],[120.6185,52.5705],[120.4775,52.629],[120.391,52.615],[120.282,52.622],[120.1845,52.577],[120.0785,52.583],[120.027,52.6355],[120.062,52.707],[120.0265,52.7765],[120.281,52.861],[120.3615,52.943],[120.5555,53.0805],[120.636,53.104],[120.6835,53.171],[120.816,53.241],[120.8155,53.2685],[120.941,53.2955],[121.1275,53.275],[121.276,53.289],[121.327,53.323],[121.41,53.317],[121.572,53.3475],[121.6945,53.3905],[121.8175,53.4155],[121.9485,53.429],[122.079,53.4205],[122.168,53.471],[122.2435,53.4635],[122.3495,53.5005],[122.4295,53.443],[122.596,53.464],[122.8495,53.4565],[123.06,53.5075],[123.1375,53.498],[123.223,53.5495],[123.3045,53.5595],[123.3755,53.5365],[123.4785,53.528],[123.622,53.5455],[123.6855,53.4985],[123.8795,53.4805],[124.0615,53.399],[124.11,53.3465],[124.2325,53.378],[124.3205,53.329],[124.37,53.2525],[124.4965,53.2035],[124.637,53.207],[124.717,53.187],[124.7115,53.1515],[124.824,53.143],[124.9755,53.196],[125.158,53.204],[125.3025,53.146],[125.498,53.0885],[125.5315,53.0545],[125.605,53.0815],[125.6725,53.0075],[125.734,52.9915],[125.7275,52.944],[125.6665,52.9225],[125.6555,52.869],[125.8295,52.8955],[125.909,52.8185],[125.9395,52.763],[126.0085,52.7925],[126.096,52.7755],[126.0375,52.7345],[126.053,52.676],[125.9835,52.673],[125.973,52.6085],[126.012,52.5785],[126.068,52.603],[126.2015,52.531],[126.181,52.4775],[126.2625,52.4735],[126.347,52.383],[126.311,52.329],[126.346,52.2625],[126.3005,52.206],[126.49,52.1595],[126.5565,52.12],[126.5125,52.053],[126.4385,52.0255],[126.465,51.9365],[126.538,51.885],[126.6175,51.7745],[126.671,51.727],[126.7155,51.727],[126.7215,51.6245],[126.7085,51.5685],[126.833,51.5345],[126.776,51.444],[126.801,51.4205],[126.896,51.408],[126.924,51.363],[126.8135,51.3295],[126.8435,51.253],[126.9155,51.2615],[126.8675,51.3095],[126.9455,51.3335],[126.973,51.298],[126.894,51.2035],[126.9175,51.057],[126.986,51.021],[127.0465,50.9605],[127.135,50.9125],[127.233,50.774],[127.2915,50.7545],[127.2875,50.664],[127.367,50.574],[127.311,50.524],[127.292,50.457],[127.353,50.4435],[127.3615,50.396],[127.3255,50.335],[127.3805,50.285],[127.6015,50.2375],[127.6035,50.181],[127.572,50.1285],[127.5015,50.0595],[127.499,49.972],[127.5415,49.917],[127.5255,49.819],[127.5565,49.7905],[127.6485,49.7765],[127.673,49.748],[127.687,49.667],[127.7815,49.622],[127.7985,49.5935],[127.885,49.5695],[127.959,49.5965],[128.0345,49.5555],[128.2015,49.538],[128.2345,49.5615],[128.336,49.542],[128.367,49.5835],[128.553,49.602],[128.6585,49.57],[128.802,49.5505],[128.747,49.513],[128.757,49.476],[128.8605,49.4895],[128.9835,49.457],[129.0735,49.3535],[129.126,49.3505],[129.1745,49.3885],[129.261,49.392],[129.309,49.357],[129.378,49.3755],[129.369,49.418],[129.4305,49.4415],[129.5365,49.398],[129.548,49.309],[129.6,49.276],[129.7105,49.291],[129.7535,49.252],[129.7525,49.204],[129.8425,49.177],[129.8585,49.1085],[129.9275,49.0735],[129.928,49.0325],[129.998,49.02],[130.0505,48.972],[130.1905,48.9],[130.2245,48.865],[130.294,48.869],[130.421,48.904],[130.5375,48.8535],[130.64,48.883],[130.682,48.8655],[130.607,48.775],[130.522,48.626],[130.6065,48.5735],[130.6085,48.502],[130.66,48.4905],[130.758,48.4975],[130.7305,48.444],[130.7665,48.3585],[130.8355,48.3015],[130.765,48.2475],[130.752,48.19],[130.6535,48.1075],[130.6905,48.04],[130.864,47.936],[130.9515,47.815],[130.9575,47.7205],[130.9935,47.696],[131.0895,47.683],[131.175,47.6955],[131.2545,47.735],[131.366,47.7265],[131.425,47.7435],[131.5475,47.7265],[131.5665,47.665],[131.622,47.657],[131.678,47.7025],[131.7305,47.7045],[131.812,47.667],[131.902,47.691],[131.9425,47.6615],[131.989,47.701],[132.253,47.708],[132.309,47.757],[132.3845,47.7505],[132.485,47.716],[132.5485,47.7145],[132.6035,47.742],[132.5985,47.8105],[132.6805,47.872],[132.652,47.9355],[132.719,47.962],[132.7805,47.925],[132.863,47.9915],[133.008,48.0405],[133.0495,48.105],[133.182,48.1085],[133.266,48.093],[133.3915,48.1235],[133.4645,48.109],[133.5565,48.1305],[133.58,48.1885],[133.7115,48.1875],[133.7465,48.257],[133.9495,48.3045],[134.0075,48.309],[134.0555,48.346],[134.14,48.338],[134.1885,48.3835],[134.337,48.379],[134.4085,48.388],[134.4705,48.422],[134.5805,48.407],[134.688,48.408],[134.768,48.3575],[134.717,48.28],[134.676,48.2575],[134.6675,48.152],[134.6275,48.097],[134.5445,48.0245],[134.544,47.985],[134.593,47.9475],[134.607,47.9015],[134.6705,47.8775],[134.6635,47.825],[134.775,47.74],[134.7435,47.6835],[134.6755,47.625],[134.6805,47.598],[134.5725,47.5185],[134.5705,47.4895],[134.486,47.443],[134.311,47.4335],[134.2555,47.3665],[134.1695,47.3185],[134.15,47.253],[134.22,47.187],[134.218,47.1075],[134.14,47.0925],[134.0965,47.009],[134.0555,46.975],[134.068,46.933],[134.0355,46.8855],[134.016,46.811],[134.0265,46.7545],[134.0135,46.666],[133.913,46.596],[133.883,46.521],[133.8455,46.481],[133.9275,46.4195],[133.9375,46.3795],[133.8705,46.3615],[133.9105,46.2635],[133.823,46.2235],[133.682,46.1375],[133.7355,46.054],[133.6755,45.9885],[133.67,45.9435],[133.61,45.9415],[133.5765,45.8665],[133.505,45.8885],[133.4615,45.8355],[133.476,45.7805],[133.435,45.703],[133.44,45.6485],[133.386,45.578],[133.213,45.5135],[133.141,45.434],[133.135,45.365],[133.1115,45.3505],[133.1045,45.2645],[133.1305,45.128],[133.0615,45.0945],[133.0375,45.0565],[132.9385,45.0285],[132.8645,45.0575],[132.004,45.252],[131.9235,45.2875],[131.91,45.337],[131.828,45.31],[131.781,45.244],[131.6745,45.2135],[131.643,45.157],[131.6875,45.13],[131.6245,45.0725],[131.5355,45.017],[131.427,44.965],[131.35,44.9875],[131.271,44.9215],[131.1985,44.916],[131.152,44.9445],[131.082,44.922],[131.0945,44.8945],[130.977,44.863],[131.0085,44.8105],[131.1045,44.7075],[131.303,44.044],[131.2555,44.0305],[131.2345,43.965],[131.261,43.9365],[131.2095,43.833],[131.233,43.6655],[131.203,43.582],[131.207,43.5265],[131.2695,43.493],[131.311,43.395],[131.273,43.3755],[131.2485,43.2675],[131.1985,43.234],[131.21,43.1485],[131.1145,43.067],[131.0955,43.021],[131.14,42.943],[131.1085,42.9135],[131.0105,42.9105],[131.0355,42.8605],[130.9415,42.8745],[130.882,42.8505],[130.828,42.8805],[130.776,42.8395],[130.659,42.845],[130.5565,42.813],[130.526,42.785],[130.4595,42.77],[130.4055,42.729],[130.4575,42.686],[130.5215,42.7015],[130.588,42.665],[130.627,42.5975],[130.5535,42.5185],[130.592,42.4845],[130.5925,42.446],[130.637,42.4185],[130.6695,42.378],[130.6545,42.325],[130.702,42.2925],[130.9245,42.1705],[130.9505,42.216],[131.071,42.2915],[131.341,42.376],[131.59,42.4635],[131.6685,42.5105],[131.741,42.596],[131.835,42.6645],[132.156,42.5815],[132.285,42.533],[132.403,42.5335],[132.5455,42.5835],[132.6965,42.568],[132.9315,42.489],[133.0545,42.4725],[133.244,42.4975],[133.447,42.571],[133.5425,42.5955],[133.7615,42.609],[133.8315,42.623],[134.025,42.6815],[134.1395,42.7375],[134.354,42.883],[134.5665,42.979],[134.8135,43.099],[134.916,43.136],[135.027,43.222],[135.1545,43.2925],[135.288,43.3345],[135.381,43.405],[135.4455,43.508],[135.6575,43.648],[135.7495,43.759],[135.78,43.8165],[135.874,43.9385],[135.92,44.0505],[136.032,44.1615],[136.065,44.2085],[136.1415,44.262],[136.309,44.333],[136.434,44.4355],[136.5415,44.579],[136.63,44.6195],[136.702,44.6845],[136.743,44.76],[136.896,44.9075],[136.99,44.9725],[137.123,45.112],[137.1865,45.158],[137.308,45.215],[137.3765,45.2645],[137.518,45.396],[137.5895,45.481],[137.6935,45.5345],[137.841,45.632],[137.9425,45.72],[138.0365,45.854],[138.1625,45.957],[138.346,46.1315],[138.387,46.1945],[138.403,46.299],[138.533,46.388],[138.5965,46.4435],[138.6455,46.566],[138.654,46.6645],[138.7415,46.7645],[138.829,46.9465],[138.9105,46.996],[139.0015,47.0845],[139.188,47.169],[139.258,47.234],[139.327,47.3355],[139.348,47.407],[139.4095,47.5135],[139.4745,47.5865],[139.5185,47.6755],[139.5835,47.745],[139.7525,47.8315],[139.8885,47.9475],[139.9565,48.025],[140.052,48.0885],[140.2715,48.2085],[140.438,48.3535],[140.474,48.435],[140.5085,48.721],[140.6235,48.821],[140.6885,48.938],[140.6885,49.016],[140.6605,49.1095],[140.729,49.273],[140.7355,49.328],[140.7945,49.413],[140.844,49.5145],[140.8535,49.577],[140.835,49.7575],[140.912,49.947],[140.9835,50.0305],[140.997,50.1075],[140.983,50.1545],[140.823,50.4125],[140.797,50.467],[140.805,50.7425],[140.9375,50.876],[140.9905,50.9975],[140.9995,51.058],[140.987,51.147],[141.0405,51.2045],[141.1455,51.283],[141.2065,51.3965],[141.212,51.4485],[141.2865,51.5045],[141.4145,51.5615],[141.5685,51.5285],[141.7235,51.4115],[141.837,51.2665],[141.931,51.078],[141.8385,50.9885],[141.741,50.8725],[141.718,50.795],[141.7435,50.651],[141.73,50.525],[141.763,50.423],[141.794,50.3775],[141.8565,50.1305],[141.829,50.042],[141.8215,49.9625],[141.844,49.8045],[141.8315,49.536],[141.774,49.4],[141.7645,49.28],[141.7335,49.1915],[141.7125,49.057],[141.559,48.8365],[141.548,48.74],[141.5775,48.632],[141.6135,48.5665],[141.7075,48.4425],[141.8395,48.2905],[141.867,48.163],[141.878,48.0525],[141.81,47.934],[141.787,47.8595],[141.731,47.7775],[141.675,47.6695],[141.6595,47.5385],[141.672,47.284],[141.691,47.227],[141.758,47.131],[141.717,46.9975],[141.649,46.885],[141.53,46.654],[141.521,46.528],[141.542,46.4325],[141.601,46.2765],[141.6325,46.0995],[141.638,46.0165],[141.677,45.94],[141.763,45.853],[141.7165,45.7425],[141.9005,45.7185],[142.292,45.656],[142.3495,45.8225],[142.4505,45.9615],[142.5205,46.1265],[142.5405,46.2425],[142.588,46.336],[142.7685,46.399],[142.934,46.4075],[143.0645,46.324],[143.118,46.2245],[143.11,46.089],[143.1385,45.9615],[143.1655,45.921],[143.239,45.863],[143.3365,45.8285],[143.445,45.8215],[143.525,45.8355],[143.616,45.8775],[143.666,45.923],[143.7435,46.047],[143.7725,46.1435],[143.8905,46.3095],[143.9055,46.3755],[143.8815,46.461],[143.831,46.531],[143.7995,46.7355],[143.7535,46.89],[143.717,46.939],[143.601,47.016],[143.335,47.1085],[143.335,47.1645],[143.296,47.3175],[143.185,47.4645],[143.15,47.495],[142.929,47.619],[142.873,47.689],[142.8235,47.796],[142.826,47.929],[142.869,48.0915],[143.0065,48.399],[143.032,48.4805],[143.135,48.667],[143.246,48.8025],[143.2745,48.8525],[143.286,48.967],[143.3105,49.067],[143.4445,49.1075],[143.598,49.116],[143.8945,49.077],[143.9535,49.0385],[144.116,48.8985],[144.253,48.8215],[144.339,48.7355],[144.373,48.6115],[144.3365,48.5545],[144.3265,48.4855],[144.343,48.435],[144.3945,48.3745],[144.504,48.319],[144.5935,48.3025],[144.6765,48.304],[144.8305,48.3535],[144.8865,48.3995],[144.935,48.4865],[145.0005,48.5345],[145.0465,48.6125],[145.043,48.6885],[145.0035,48.81],[144.988,48.901],[144.959,48.9545],[144.896,49.012],[144.729,49.1115],[144.659,49.165],[144.587,49.2915],[144.552,49.399],[144.5465,49.507],[144.5255,49.576],[144.4335,49.6875],[144.43,49.7785],[144.315,49.975],[144.293,50.08],[144.1305,50.301],[144.064,50.4415],[144.0175,50.5865],[144.014,50.6635],[143.986,50.759],[143.984,50.823],[143.955,50.898],[143.8455,51.246],[143.794,51.3655],[143.755,51.522],[143.649,51.764],[143.545,51.9255],[143.479,52.0685],[143.4675,52.2055],[143.593,52.389],[143.645,52.5895],[143.6635,52.8595],[143.591,53.1975],[143.532,53.362],[143.4625,53.492],[143.2595,53.8175],[143.24,53.8565],[143.3085,53.991],[143.336,54.074],[143.318,54.1615],[143.2815,54.2245],[143.148,54.3515],[143.001,54.54],[142.9025,54.592],[142.825,54.6135],[142.6985,54.626],[142.5675,54.612],[142.4765,54.5825],[142.1,54.487],[141.995,54.436],[141.928,54.3595],[141.918,54.282],[141.9665,54.198],[142.0295,54.153],[142.176,54.003],[142.296,53.916],[142.307,53.8435],[142.257,53.812],[142.0375,53.71],[141.759,53.6255],[141.6235,53.5995],[141.389,53.594],[141.2535,53.641],[141.006,53.704],[140.912,53.7355],[140.763,53.85],[140.6165,54.061],[140.453,54.187],[140.1875,54.308],[140.1115,54.447],[139.9995,54.5195],[139.8795,54.5495],[139.7785,54.558],[139.6775,54.5485],[139.5315,54.502],[139.3455,54.393],[139.2485,54.3825],[139.0765,54.4195],[138.8905,54.4855],[138.786,54.502],[138.5895,54.6915],[138.7625,55.013],[138.776,55.101],[138.7345,55.1805],[138.622,55.253],[138.491,55.2865],[138.335,55.2945],[137.832,55.3605],[137.7255,55.389],[137.5485,55.3905],[137.3395,55.337],[137.255,55.283],[137.1875,55.1975],[136.905,55.126],[136.723,55.104],[136.646,55.054],[136.411,55.016],[136.05,55.0045],[136.1915,55.076],[136.307,55.116],[136.4155,55.1705],[136.537,55.2715],[136.743,55.418],[136.9615,55.4815],[137.2835,55.637],[137.424,55.739],[137.548,55.7665],[137.655,55.811],[137.711,55.856],[137.9805,55.997],[138.133,56.12],[138.1765,56.171],[138.247,56.2105],[138.4,56.248],[138.545,56.3285],[138.613,56.4375],[138.628,56.5605],[138.8035,56.628],[139.152,56.8835],[139.303,57.005],[139.5065,57.1055],[139.647,57.145],[139.8045,57.228],[140.0615,57.3485],[140.1715,57.447],[140.202,57.501],[140.463,57.566],[140.5475,57.5945],[140.793,57.7275],[140.8535,57.793],[140.8745,57.8755],[140.9595,57.9955],[141.028,58.127],[141.0615,58.164],[141.193,58.2445],[141.545,58.3475],[141.787,58.4485],[141.985,58.564],[142.1805,58.7245],[142.2835,58.8355],[142.3885,58.912],[142.639,59.023],[142.9735,59.085],[143.1385,59.129],[143.521,59.121],[143.5965,59.1285],[143.891,59.1985],[144.048,59.2005],[144.382,59.1705],[145.0205,59.169],[145.263,59.185],[145.5785,59.089],[145.707,59.003],[145.836,58.959],[145.9345,58.9445],[146.127,58.946],[146.2725,58.977],[146.465,59.0015],[146.5995,59.05],[146.9125,59.1465],[147.054,59.128],[147.359,59.056],[147.47,59.0395],[147.619,59.04],[147.8405,59.0625],[148.3665,59.054],[148.4415,59.047],[148.8475,58.9255],[148.9265,58.915],[149.6765,58.862],[150.542,58.798],[150.6725,58.806],[150.9835,58.766],[151.0645,58.7005],[151.1905,58.654],[151.341,58.6375],[151.597,58.647],[151.69,58.642],[152.1935,58.6985],[152.267,58.7165],[152.5,58.742],[152.5835,58.721],[152.731,58.706],[152.8975,58.705],[153.0515,58.7215],[153.172,58.7615],[153.4245,58.886],[153.82,58.879],[154.0345,58.8475],[154.1725,58.859],[154.499,58.9175],[154.688,58.937],[154.81,58.9275],[154.9485,58.941],[155.109,58.9735],[155.5735,58.9975],[155.6955,59.015],[155.8225,59.063],[155.899,59.1285],[155.9815,59.2905],[155.971,59.383],[155.8945,59.4575],[155.736,59.5165],[155.392,59.556],[155.2895,59.62],[155.118,59.6805],[154.977,59.6985],[154.8805,59.9035],[154.903,59.9735],[154.983,60.051],[155.104,60.122],[155.1765,60.1855],[155.41,60.2625],[155.47,60.294],[155.6305,60.338],[155.776,60.396],[155.9625,60.4915],[156.1775,60.5535],[156.267,60.6115],[156.3085,60.6685],[156.328,60.765],[156.3655,60.8305],[156.4365,60.8925],[156.597,60.9615],[156.854,61.0215],[156.989,61.0835],[157.0615,61.158],[157.0635,61.2915],[157.177,61.391],[157.236,61.4175],[157.518,61.4965],[157.918,61.536],[158.1525,61.5345],[158.6415,61.604],[158.8265,61.6145],[159.15,61.5725],[159.2585,61.5145],[159.4245,61.3915],[159.362,61.341],[159.3315,61.2665],[159.406,61.0055],[159.3795,60.914],[159.4255,60.8385],[159.559,60.763],[159.733,60.6085],[159.747,60.534],[159.8285,60.4525],[159.945,60.402],[160.0915,60.3775],[160.235,60.3775],[160.397,60.4055],[160.497,60.4385],[161.1535,60.149],[160.88,59.9435],[160.776,59.891],[160.4935,59.7665],[160.3325,59.7375],[160.19,59.6805],[160.0995,59.5815],[159.8975,59.458],[159.743,59.352],[159.5735,59.263],[159.414,59.1255],[159.278,58.9145],[159.218,58.846],[158.898,58.6655],[158.771,58.5535],[158.3925,58.4],[158.1775,58.2885],[158.067,58.2195],[157.6345,58.2145],[157.4405,58.1715],[157.3295,58.1055],[156.8505,58.036],[156.623,57.9585],[156.525,57.8965],[156.4135,57.776],[156.405,57.698],[156.4885,57.596],[156.6175,57.5145],[156.627,57.4915],[156.3505,57.4235],[156.2105,57.363],[156.148,57.2925],[156.1365,57.234],[156.1635,57.115],[156.112,57.049],[155.914,56.9775],[155.8105,56.9195],[155.665,56.7725],[155.6065,56.679],[155.532,56.4895],[155.2965,55.9795],[155.299,55.8205],[155.2815,55.667],[155.222,55.4015],[155.215,55.2325],[155.257,55.057],[155.289,54.8155],[155.339,54.609],[155.393,54.415],[155.487,54.15],[155.566,53.9485],[155.654,53.629],[155.672,53.5275],[155.7465,53.237],[155.7995,52.9],[155.8145,52.8365],[155.924,52.606],[156.0535,52.365],[156.106,52.245],[156.148,52.0905],[156.1745,51.839],[156.175,51.4625],[156.2215,51.2835],[156.2455,51.223],[156.3435,51.104],[156.272,51.0325],[156.11,50.9695],[155.741,51.096],[155.608,51.1185],[155.414,51.111],[155.252,51.056],[155.185,50.995],[155.144,50.9095],[155.1545,50.8235],[155.2065,50.7385],[155.294,50.6725],[155.391,50.556],[155.1005,50.4835],[154.7635,50.3615],[154.679,50.2955],[154.6485,50.2425],[154.657,50.138],[154.492,50.0145],[154.4165,50.0165],[154.2815,49.992],[154.211,49.9625],[154.113,49.879],[154.081,49.799],[154.0825,49.7165],[154.127,49.644],[154.1965,49.593],[154.316,49.4185],[154.218,49.294],[153.9425,49.1725],[153.875,49.1675],[153.489,49.193],[153.3545,49.175],[153.2555,49.13],[153.184,49.0535],[153.165,48.9945],[153.1815,48.91],[153.244,48.8395],[153.3175,48.7995],[153.275,48.5005],[153.125,48.4855],[153.0305,48.444],[152.9515,48.361],[152.869,48.1455],[152.863,48.0885],[152.7905,47.9315],[152.7175,47.86],[152.634,47.704],[152.59,47.67],[152.385,47.5735],[152.238,47.5215],[151.945,47.269],[151.8365,47.15],[151.754,47.1035],[151.538,47.01],[151.4355,46.915],[151.4155,46.819],[151.435,46.7645],[151.511,46.6655],[151.5715,46.6235],[151.6725,46.5845],[151.748,46.5715],[151.872,46.575],[151.962,46.601],[152.127,46.7055],[152.2125,46.746],[152.355,46.85],[152.5375,47.025],[152.793,47.2165],[153.017,47.352],[153.1405,47.474],[153.277,47.5925],[153.3255,47.652],[153.3525,47.719],[153.5395,47.935],[153.5915,48.0315],[153.597,48.0935],[153.569,48.2845],[153.704,48.3505],[153.785,48.3315],[153.928,48.3355],[154.0065,48.3595],[154.1135,48.431],[154.2495,48.586],[154.438,48.7165],[154.483,48.767],[154.6885,48.8995],[154.799,48.946],[155.009,49.1355],[155.0845,49.1895],[155.145,49.2925],[155.189,49.484],[155.2225,49.564],[155.221,49.6595],[155.403,49.7945],[155.4875,49.806],[155.6035,49.8505],[155.7565,49.972],[155.9635,50.023],[156.138,50.1275],[156.234,50.24],[156.382,50.3605],[156.624,50.4885],[156.6955,50.5485],[156.776,50.6495],[156.9475,50.755],[157.2015,50.9315],[157.3885,51.033],[157.5475,51.1085],[157.755,51.2665],[157.9225,51.3555],[157.9965,51.4095],[158.151,51.4965],[158.265,51.6145],[158.3525,51.6785],[158.425,51.7585],[158.5245,51.835],[158.5805,51.8975],[158.6235,51.9875],[158.6935,52.068],[158.8205,52.18],[158.8815,52.2785],[158.898,52.3965],[158.8585,52.5315],[158.9185,52.6385],[158.94,52.7085],[159.0995,52.8585],[159.2845,52.9435],[159.7225,52.9695],[159.8525,52.919],[160.0575,52.8975],[160.1955,52.9225],[160.3325,53.0085],[160.3875,53.1095],[160.3895,53.1715],[160.361,53.2945],[160.299,53.389],[160.2915,53.572],[160.2735,53.685],[160.1945,53.829],[160.294,53.989],[160.4105,54.0875],[160.572,54.172],[160.6575,54.2395],[160.7565,54.292],[160.899,54.349],[161.049,54.3295],[161.1475,54.294],[161.2515,54.28],[161.544,54.268],[161.65,54.273],[161.8805,54.3235],[161.9765,54.372],[162.1135,54.471],[162.407,54.627],[162.4825,54.7305],[162.503,54.836],[162.4865,54.9095],[162.277,55.1175],[162.143,55.2305],[162.093,55.387],[162.0915,55.4565],[162.1335,55.5905],[162.249,55.7125],[162.296,55.8],[162.394,55.926],[162.439,55.959],[162.5335,55.9415],[162.745,55.846],[162.9985,55.806],[163.2075,55.8265],[163.322,55.8755],[163.4965,55.9885],[163.64,56.0585],[163.6955,56.1115],[163.7195,56.1995],[163.7055,56.3665],[163.6375,56.497],[163.649,56.673],[163.634,56.747],[163.555,56.8445],[163.216,57.0565],[163.143,57.213],[163.223,57.291],[163.3165,57.323],[163.4065,57.3745],[163.5365,57.4805],[163.6695,57.651],[163.694,57.708],[163.872,58.1885],[163.9745,58.464],[164.28,58.593],[164.603,58.6645],[164.802,58.6885],[164.9195,58.734],[165.0125,58.796],[165.0765,58.8725],[165.1165,59.005],[165.104,59.1015],[164.9975,59.2575],[165.8945,59.6325],[166.052,59.603],[166.1365,59.6],[166.404,59.6195],[166.5705,59.669],[166.6735,59.731],[166.7765,59.82],[166.8695,59.865],[167.0575,59.9785],[167.1575,60.0695],[167.2825,60.133],[167.5585,60.1985],[167.658,60.2305],[167.932,60.2835],[168.3265,60.3855],[168.6225,60.3465],[168.779,60.344],[168.9625,60.362],[169.1165,60.3515],[169.2455,60.311],[169.3825,60.231],[169.629,59.9595],[169.8705,59.8185],[170.089,59.7495],[170.1665,59.7345],[170.342,59.7285],[170.4675,59.745],[170.6225,59.7835],[170.7475,59.8505],[170.8095,59.916],[170.8625,60.077],[171.032,60.2045],[171.1225,60.3015],[171.2085,60.335],[171.3775,60.3755],[171.6165,60.447],[172.058,60.634],[172.1715,60.6435],[172.379,60.6995],[172.5185,60.8055],[172.743,60.885],[172.9515,61.026],[173.179,61.1055],[173.452,61.2455],[173.5575,61.288],[173.7465,61.3835],[174.0565,61.475],[174.302,61.566],[174.435,61.605],[174.6455,61.6205],[174.922,61.6785],[175.139,61.7745],[175.4135,61.832],[175.513,61.866],[175.652,61.9365],[175.8145,61.99],[176.184,62.0715],[176.4705,62.114],[176.6295,62.169],[176.759,62.2395],[177.0835,62.325],[177.1885,62.342],[177.5525,62.36],[177.827,62.3455],[178.1525,62.2765],[178.6815,62.182],[178.9255,62.0915],[179.087,62.0745],[179.3325,62.1035],[179.4305,62.135],[179.5315,62.1935],[179.7075,62.352],[179.938,62.5015],[180.0,62.5545],[180.0,62.876],[179.944,62.9385],[179.8865,63.15],[179.8085,63.235],[179.643,63.336],[179.383,63.438],[179.2685,63.565],[179.23,63.765],[179.1305,64.0135],[179.091,64.0845],[178.985,64.1735],[178.846,64.323],[178.936,64.429],[179.066,64.4685],[179.3005,64.561],[179.439,64.59],[179.6565,64.6055],[179.806,64.641],[180.0,64.7465],[180.0,65.0385],[180.0,65.3115],[180.0,65.3245],[180.0,65.33],[180.0,65.3605],[180.0,65.3825],[180.0,65.386],[180.0,65.4455],[180.0,65.454],[180.0,65.479],[180.0,65.8035],[180.0,65.8635],[180.0,65.866],[180.0,66.6405],[180.0,66.894],[180.0,66.914],[180.0,66.9295],[180.0,67.168],[180.0,67.552],[180.0,67.927],[180.0,68.3565],[180.0,68.513],[180.0,68.5505],[180.0,68.91],[180.0,68.9255],[180.0,68.93],[180.0,68.959],[180.0,68.97],[180.0,68.9755],[180.0,68.977],[180.0,69.2895],[179.7395,69.392],[179.219,69.537],[179.037,69.58],[178.735,69.632],[178.417,69.658],[178.221,69.655],[177.7995,69.759],[177.571,69.7915],[177.3055,69.8025],[177.15,69.823],[176.793,69.898],[176.564,70.0055],[176.341,70.059],[176.1935,70.074],[175.717,70.0775],[175.1115,70.04],[174.636,70.044],[174.4755,70.073],[174.214,70.1015],[173.5685,70.1305],[172.8885,70.1785],[172.753,70.183],[172.467,70.1545],[172.061,70.1795],[171.591,70.244],[171.3305,70.2565],[171.1005,70.2835],[170.9,70.2865],[170.662,70.3205],[170.4675,70.3225],[170.2085,70.299],[170.022,70.255],[169.9285,70.2145],[169.843,70.126],[169.535,70.1045],[169.4115,70.1245],[168.9515,70.1665],[168.8185,70.2015],[168.5695,70.23],[168.291,70.224],[167.932,70.1825],[167.6925,70.1245],[167.4555,70.0285],[167.3185,69.944],[167.2335,69.8695],[166.839,69.7075],[166.674,69.7125],[166.469,69.697],[166.322,69.704],[166.1735,69.7345],[165.827,69.7705],[165.528,69.7695],[165.2945,69.7885],[165.099,69.784],[164.89,69.761],[164.715,69.794],[164.55,69.885],[164.3975,69.9245],[164.1815,69.948],[163.854,69.946],[163.5665,69.8855],[163.2535,69.904],[163.0175,69.8885],[162.8185,69.854],[162.6985,69.867],[162.3005,69.8765],[161.7935,69.878],[161.1905,69.889],[160.6545,69.9225],[160.5375,70.099],[160.6645,70.195],[160.676,70.296],[160.6125,70.4095],[160.4285,70.603],[160.8045,70.5985],[161.0715,70.6305],[161.1985,70.5345],[161.366,70.487],[161.507,70.4675],[161.7605,70.461],[161.924,70.4745],[162.0845,70.441],[162.3685,70.4205],[162.653,70.437],[162.8755,70.4785],[163.0625,70.567],[163.094,70.681],[163.0075,70.7515],[162.8815,70.7975],[162.7115,70.83],[162.515,70.8475],[162.2745,70.8505],[162.126,70.9795],[161.988,71.0445],[161.7615,71.108],[161.509,71.1295],[161.2915,71.122],[161.0625,71.0865],[160.966,71.0575],[160.716,71.1],[160.5015,71.113],[160.156,71.0895],[159.906,71.0095],[159.823,70.894],[159.308,71.028],[158.916,71.104],[158.6745,71.1425],[157.972,71.218],[157.259,71.2665],[157.062,71.275],[156.407,71.267],[156.157,71.276],[155.754,71.2665],[155.3985,71.2325],[154.9705,71.205],[154.3325,71.1505],[153.6115,71.0635],[153.3835,71.0555],[152.9845,71.0185],[152.812,71.0175],[152.2775,71.364],[151.675,71.6805],[151.3995,71.7475],[150.832,71.816],[150.726,71.95],[150.598,72.0555],[150.484,72.122],[150.1945,72.2335],[149.995,72.2935],[149.7365,72.352],[149.4985,72.392],[149.044,72.4445],[148.803,72.484],[148.4435,72.518],[147.9465,72.5165],[147.615,72.5265],[147.199,72.5115],[146.5195,72.6315],[145.721,72.716],[145.131,72.769],[144.3815,72.8405],[144.3205,73.2205],[144.308,73.4295],[144.246,73.516],[144.0335,73.641],[143.77,73.748],[143.35,73.868],[143.0955,73.959],[142.8345,74.0115],[142.6505,74.032],[141.8375,74.195],[141.802,74.26],[142.956,74.622],[144.1215,74.7045],[144.285,74.722],[144.51,74.7715],[145.3855,75.0425],[145.4905,75.111],[145.837,75.01],[146.281,74.9435],[146.5795,74.866],[146.774,74.8285],[147.189,74.784],[147.638,74.639],[147.966,74.588],[148.606,74.5395],[148.9375,74.529],[149.2945,74.531],[149.731,74.551],[150.0605,74.5825],[150.3625,74.6285],[150.9455,74.6795],[151.215,74.732],[151.3815,74.811],[151.465,74.944],[151.6765,75.045],[151.7415,75.142],[151.682,75.207],[151.5685,75.2575],[151.2415,75.323],[150.328,75.3985],[150.0465,75.41],[149.6035,75.4545],[148.587,75.594],[148.187,75.599],[147.1235,75.718],[146.9205,75.7595],[146.5845,75.787],[146.112,75.767],[145.8235,75.712],[145.4155,75.789],[145.242,75.839],[144.8035,75.895],[144.6525,75.9355],[144.3045,75.996],[143.948,76.0355],[143.4475,76.05],[143.1045,76.026],[142.9415,76.087],[142.736,76.1385],[142.461,76.231],[142.262,76.2745],[141.814,76.3465],[140.7585,76.4775],[140.3035,76.496],[140.1175,76.4875],[138.947,76.3995],[138.587,76.3915],[138.1005,76.3345],[137.6985,76.2655],[137.5015,76.2085],[137.119,76.142],[136.853,76.0675],[136.6355,75.945],[136.522,75.9295],[136.3555,76.003],[135.98,76.062],[135.6725,76.071],[135.4705,76.061],[135.209,76.027],[135.029,75.978],[134.876,75.8775],[134.863,75.793],[134.7975,75.6855],[134.8395,75.5915],[134.7005,75.4455],[134.7435,75.3415],[134.912,75.2485],[135.0925,75.2055],[135.355,75.1745],[135.8485,75.1665],[136.2155,75.196],[136.5475,75.0195],[136.7705,74.926],[137.2,74.8285],[137.314,74.7485],[137.5595,74.641],[137.8785,74.573],[138.351,74.534],[138.6615,74.4675],[139.4485,74.136],[139.445,74.0755],[139.5105,73.9805],[139.1575,73.5005],[139.078,73.404],[139.115,73.3405],[139.219,73.2675],[139.481,73.179],[139.923,72.9005],[139.508,72.748],[139.21,72.668],[138.739,72.4745],[138.5985,72.393],[138.2915,72.1225],[138.0455,72.059],[137.843,71.9685],[137.2645,71.812],[136.2335,71.8515],[135.697,71.843],[135.1955,71.8],[134.8605,71.753],[134.56,71.6875],[134.232,71.5755],[133.9205,71.628],[133.7785,71.6685],[133.706,71.7155],[133.8925,71.7985],[133.9565,71.857],[133.9595,71.919],[133.8615,72.0],[133.7035,72.0735],[133.5375,72.1255],[133.232,72.165],[133.032,72.1685],[132.573,72.138],[132.2375,72.0745],[131.973,71.9515],[131.6905,71.7385],[131.5765,71.612],[131.458,71.407],[131.378,71.3],[130.814,71.192],[130.7475,71.202],[130.668,71.485],[130.665,71.5885],[130.53,71.7045],[130.2445,71.791],[130.287,72.2275],[130.331,72.372],[130.2455,73.004],[130.1655,73.09],[130.078,73.1295],[129.205,73.424],[128.648,73.6085],[128.2575,73.689],[127.814,73.7245],[126.3125,73.863],[125.464,74.037],[125.278,74.08],[124.96,74.127],[124.581,74.135],[124.331,74.1185],[123.3685,74.188],[123.0215,74.1825],[122.7835,74.152],[122.551,74.0835],[122.427,73.9875],[122.3935,73.8245],[122.5705,73.716],[122.4605,73.5325],[122.494,73.412],[122.573,73.312],[122.4125,73.2915],[121.893,73.26],[121.701,73.238],[121.4115,73.1605],[121.1165,73.138],[121.0415,73.2105],[120.941,73.263],[120.68,73.3265],[120.2935,73.3735],[120.048,73.3835],[119.438,73.649],[119.1575,73.7115],[118.715,73.76],[118.1175,73.7785],[117.793,73.7715],[117.5575,73.778],[116.7865,73.863],[116.3645,73.866],[115.7555,73.9065],[115.3355,73.9075],[114.987,73.881],[114.542,73.789],[114.318,73.798],[114.025,73.787],[113.8755,73.916],[113.7425,73.992],[113.584,74.039],[113.7755,74.0845],[113.968,74.1945],[114.113,74.2555],[114.211,74.376],[114.1505,74.4895],[113.7095,74.737],[113.5665,74.894],[114.219,75.1235],[114.385,75.2125],[114.4635,75.2845],[114.5535,75.4395],[114.4915,75.5515],[114.5745,75.6475],[114.706,75.751],[114.7395,75.8425],[114.7115,75.9465],[114.636,76.001],[114.3655,76.139],[114.296,76.4235],[114.027,76.5445],[113.6485,76.627],[113.4155,76.6555],[113.1145,76.7595],[112.8735,76.8035],[111.9425,76.883],[111.616,76.945],[111.3635,76.968],[110.938,76.986],[109.695,76.9565],[108.9925,77.0955],[108.6185,77.384],[108.481,77.448],[108.4355,77.9435],[108.6315,78.0145],[108.729,78.084],[108.74,78.169],[108.577,78.2625],[108.4645,78.294],[107.235,78.535],[106.4355,78.648],[106.3685,78.7845],[106.1415,78.9065],[105.297,79.1535],[104.6685,79.312],[104.0105,79.438],[103.7465,79.505],[103.4965,79.547],[103.048,79.5965],[101.2895,79.8065],[100.862,80.002],[100.2505,80.167],[99.869,80.219],[99.0645,80.27],[98.707,80.3035],[99.345,80.607],[99.405,80.6925],[99.305,80.79],[99.099,80.862],[97.8885,81.098],[97.3375,81.282],[97.0615,81.351],[96.5015,81.4375],[95.8245,81.4735],[95.4445,81.4715],[94.874,81.4465],[94.3235,81.3965],[92.6205,81.288],[92.2175,81.3555],[91.475,81.417],[90.92,81.4255],[90.198,81.399],[89.3475,81.331],[89.0115,81.2625],[88.8835,81.197],[88.8935,81.093],[89.036,81.0195],[89.213,80.9725],[89.6225,80.91],[90.1045,80.8665],[90.5555,80.842],[91.029,80.8355],[91.5405,80.8495],[90.438,80.494],[90.31,80.4165],[90.3045,80.302],[89.8795,80.1245],[89.8265,80.059],[90.0405,79.7855],[89.518,79.6245],[89.456,79.5745],[89.499,79.4975],[89.6375,79.4435],[89.9935,79.3785],[90.559,79.319],[91.4215,79.0115],[91.7445,78.9495],[92.371,78.88],[92.759,78.862],[94.66,78.841],[95.402,78.8],[96.5715,78.7105],[96.8665,78.6495],[96.9745,78.306],[97.1015,78.219],[97.242,78.1805],[98.394,77.937],[96.83,77.558],[95.989,77.349],[95.543,77.258],[95.224,77.229],[94.9795,77.19],[94.605,77.1025],[93.821,76.8895],[93.2465,76.712],[93.193,76.6815],[92.4275,76.47],[91.674,76.259],[91.3215,76.248],[91.0285,76.2245],[89.869,76.041],[88.955,75.8945],[88.7185,75.903],[87.889,75.901],[87.655,75.8835],[87.4535,75.8495],[87.2185,75.7545],[85.612,75.4295],[85.448,75.38],[84.6205,75.01],[83.6315,74.785],[83.5295,74.741],[83.462,74.669],[83.491,74.5615],[82.3295,74.331],[82.055,74.287],[81.8825,74.236],[81.7535,74.1735],[81.069,73.992],[80.204,73.7595],[79.0645,73.7045],[78.0625,73.6555],[77.0605,73.607],[76.6175,73.679],[76.287,73.714],[75.7705,73.7205],[75.3005,73.6865],[75.0505,73.6335],[74.764,73.5145],[74.682,73.435],[74.3855,73.309],[74.0805,73.2915],[73.8955,73.2625],[72.2105,73.338],[71.8685,73.5125],[71.675,73.574],[71.47,73.6175],[71.0715,73.6675],[70.753,73.676],[70.082,73.6275],[69.6185,73.5475],[69.377,73.464],[68.7285,72.9925],[68.6125,72.862],[68.447,72.794],[68.321,72.683],[68.2925,72.5835],[68.189,72.447],[68.135,72.2925],[68.02,72.082],[67.895,71.892],[67.7145,71.7595],[67.476,71.6525],[67.2235,71.59],[67.0355,71.5205],[66.815,71.47],[66.51,71.4185],[66.3735,71.3575],[66.229,71.212],[66.155,71.1695],[65.9645,70.9965],[65.853,70.851],[65.8155,70.705],[65.8335,70.612],[65.895,70.5155],[66.095,70.37],[66.321,70.2855],[66.3865,70.11],[65.7425,69.8645],[64.965,69.564],[64.702,69.642],[64.4045,69.7065],[63.939,69.784],[63.289,69.8735],[62.8565,69.9125],[62.18,69.933],[62.0135,69.946],[61.617,70.0055],[61.382,70.052],[60.6695,70.123],[60.4565,70.235],[60.2435,70.282],[60.078,70.333],[59.8395,70.4695],[59.6805,70.522],[59.624,70.559],[59.4265,70.625],[58.851,70.7305],[57.907,70.923],[57.498,71.0075],[57.113,71.149],[56.6875,71.3375],[56.648,71.3885],[56.3405,71.6385],[56.188,71.829],[56.1785,71.891],[56.1075,71.9675],[56.109,72.0265],[56.21,72.126],[56.214,72.2345],[56.257,72.3825],[56.8345,72.759],[57.074,72.953],[57.3325,73.133],[57.6575,73.258],[58.2015,73.5005],[58.5305,73.68],[58.89,73.8895],[59.309,74.0835],[59.9675,74.227],[60.184,74.3045],[60.497,74.4905],[60.893,74.622],[61.2085,74.744],[61.6225,74.919],[62.105,75.087],[62.6435,75.2375],[62.975,75.3055],[63.3265,75.3625],[64.045,75.422],[64.3095,75.459],[64.632,75.535],[64.968,75.5605],[65.2495,75.6005],[65.559,75.6235],[66.0285,75.7225],[66.282,75.75],[66.4935,75.7895],[66.8075,75.8095],[67.0495,75.8515],[67.563,75.9115],[67.9385,75.982],[68.3625,76.0495],[68.738,76.0775],[69.0465,76.155],[69.705,76.4415],[69.7895,76.4955],[69.9395,76.6625],[69.944,76.7385],[69.799,76.8635],[69.613,76.956],[69.2425,77.092],[68.869,77.1525],[68.1225,77.2255],[67.7965,77.243],[67.491,77.234],[67.1795,77.2035],[66.5045,77.096],[65.456,76.8885],[65.203,76.8155],[65.076,76.755],[64.8595,76.7015],[64.5725,76.6635],[63.921,76.6105],[63.626,76.573],[63.3045,76.507],[62.699,76.464],[61.768,76.4965],[60.828,76.4775],[60.626,76.4595],[59.7405,76.336],[58.815,76.255],[58.4405,76.189],[58.26,76.122],[58.0525,75.9845],[57.908,75.923],[56.5215,75.533],[56.252,75.479],[56.0445,75.4105],[55.5225,75.3445],[55.167,75.2445],[55.0445,75.168],[54.978,75.076],[54.983,75.024],[55.066,74.941],[55.043,74.817],[54.6725,74.4805],[54.2945,74.236],[53.7835,74.0505],[53.1455,73.918],[52.9795,73.801],[52.963,73.7365],[53.0385,73.647],[53.2955,73.5595],[52.67,73.273],[51.993,72.9575],[51.4005,72.4965],[50.993,72.172],[50.7885,71.9205],[50.796,71.6345],[51.661,71.128],[52.5625,70.796],[53.2955,70.522],[54.7145,70.3545],[55.289,70.286],[56.6385,70.244],[57.2085,70.22],[57.897,70.071],[58.147,69.926],[58.3595,69.8355],[58.6685,69.7155],[59.153,69.5665],[59.358,69.5235],[59.626,69.4855],[59.7135,69.413],[60.081,69.1915],[60.108,69.081],[60.206,69.0035],[60.311,68.9585],[60.23,68.899],[60.075,68.9605],[60.0745,69.0435],[59.9715,69.1435],[59.866,69.197],[59.8115,69.2955],[59.678,69.3785],[59.4915,69.439],[59.2375,69.49],[59.0965,69.5445],[58.965,69.6175],[58.7715,69.664],[58.6585,69.6755],[58.396,69.678],[58.095,69.626],[57.9655,69.562],[57.9085,69.495],[57.909,69.4265],[58.016,69.3395],[58.1335,69.2995],[58.3575,69.1915],[58.5185,69.138],[58.129,69.0595],[57.6295,68.9675],[57.218,68.9295],[56.6275,69.0115],[55.9245,69.0555],[55.771,69.0955],[55.5045,69.131],[54.722,69.1835],[54.4485,69.1895],[53.959,69.173],[53.706,69.15],[53.311,69.0965],[53.059,69.0475],[52.53,68.9185],[52.1645,68.819],[51.907,68.741],[51.589,68.686],[51.2215,68.6895],[51.058,68.683],[50.755,68.6375],[50.542,68.574],[50.256,68.435],[49.94,68.3215],[49.5265,68.1855],[49.2315,68.102],[49.0205,68.0515],[48.9175,68.083],[48.7235,68.111],[48.5255,68.1115],[47.1115,68.033],[47.074,68.062],[47.0695,68.1645],[46.87,68.4105],[46.7075,68.498],[46.1955,68.623],[45.7375,68.703],[45.374,68.7355],[44.766,68.752],[44.188,68.735],[44.0205,68.787],[43.62,68.857],[43.4925,68.8675],[43.243,68.8655],[43.07,68.8475],[42.2115,68.726],[41.3125,68.5975],[40.5795,68.4925],[39.7595,68.3745],[39.1775,68.4725],[38.902,68.547],[38.777,68.5645],[38.1955,68.826],[37.7455,68.965],[37.6465,68.9865],[36.9705,69.1575],[36.589,69.266],[36.0895,69.378],[35.964,69.3965],[35.377,69.448],[34.653,69.5165],[34.4465,69.559],[34.2745,69.5805],[33.619,69.827],[33.461,69.8945],[33.2485,69.9425],[32.372,70.115],[32.0535,70.15],[31.727,70.1385],[31.441,70.0985],[31.1045,69.9795],[30.8175,69.795],[30.9455,69.6775],[30.939,69.5605],[30.818,69.529],[30.516,69.5405],[30.4175,69.59],[30.224,69.653],[30.138,69.6435],[30.188,69.566],[30.1195,69.5135],[30.115,69.4685],[29.9705,69.408],[29.8685,69.424],[29.7245,69.3895],[29.573,69.3185],[29.3905,69.322],[29.286,69.294],[29.313,69.2295],[29.242,69.113],[29.0565,69.015],[28.9295,69.052],[28.4955,68.93],[28.468,68.8855],[28.661,68.8865],[28.8015,68.8695],[28.707,68.7325],[28.434,68.5395],[28.646,68.1965],[29.327,68.0745],[29.6595,67.803],[30.0155,67.673],[29.9305,67.523],[29.717,67.394],[29.527,67.311],[29.5155,67.281],[29.0735,66.996],[29.033,66.9255],[29.061,66.8525],[29.1185,66.8015],[29.3505,66.644],[29.5245,66.4905],[29.7095,66.268],[29.924,66.126],[29.9975,65.979],[30.068,65.895],[30.1385,65.6685],[30.017,65.6965],[29.7225,65.637],[29.864,65.5605],[29.733,65.4725],[29.7465,65.3475],[29.602,65.26],[29.635,65.2315],[29.764,65.229],[29.8935,65.193],[29.8195,65.1445],[29.897,65.105],[29.7325,65.0915],[29.627,65.0605],[29.5995,64.995],[29.645,64.8665],[29.7395,64.79],[30.043,64.793],[30.0415,64.741],[30.136,64.649],[29.9895,64.5875],[29.987,64.534],[30.0585,64.451],[30.045,64.402],[30.11,64.365],[30.21,64.3505],[30.4825,64.2625],[30.4665,64.2045],[30.5535,64.132],[30.528,64.049],[30.447,63.983],[30.321,63.9095],[30.2605,63.822],[29.972,63.757],[30.244,63.6075],[30.3845,63.5455],[30.484,63.4665],[30.7875,63.4055],[30.85,63.3685],[30.9345,63.3555],[30.979,63.308],[31.1485,63.2615],[31.24,63.218],[31.2655,63.115],[31.463,63.0245],[31.5865,62.9085],[31.439,62.7855],[31.3455,62.6405],[31.222,62.4985],[31.1385,62.442],[30.7205,62.209],[30.6565,62.2085],[30.602,62.1415],[30.423,62.0225],[30.305,61.964],[30.1555,61.858],[30.0705,61.8175],[30.0385,61.765],[29.8185,61.6555],[29.7405,61.5735],[29.503,61.4615],[29.3345,61.355],[29.2335,61.2685],[28.9855,61.1735],[28.957,61.1515],[28.819,61.1215],[28.714,61.0445],[28.658,60.951],[28.5245,60.957],[28.1355,60.741],[27.8735,60.6045],[27.7735,60.5335],[27.747,60.451],[27.686,60.4335],[27.725,60.3915],[27.455,60.2235],[27.294,60.2005],[26.8725,60.1155],[26.44,59.9385],[26.915,59.6315],[27.857,59.582],[28.0425,59.4715],[28.191,59.4005],[28.21,59.3705],[28.1295,59.291],[27.954,59.2705],[27.9015,59.2385],[27.865,59.161],[27.8085,59.1295],[27.792,59.07],[27.745,59.027],[27.731,58.973],[27.357,58.7875],[27.553,58.366],[27.487,58.3035],[27.4915,58.2245],[27.602,58.1175],[27.6215,58.005],[27.6565,57.9555],[27.813,57.86],[27.741,57.8275],[27.6155,57.839],[27.5415,57.823],[27.5055,57.7665],[27.5215,57.716],[27.4475,57.717],[27.3765,57.668],[27.405,57.6125],[27.3305,57.5705],[27.3515,57.518],[27.5005,57.54],[27.547,57.5195],[27.5525,57.469],[27.5175,57.427],[27.6715,57.395],[27.8675,57.297],[27.817,57.1425],[27.757,57.131],[27.748,57.053],[27.7695,57.005],[27.7375,56.92],[27.686,56.9115],[27.6595,56.8345],[27.8475,56.88],[27.8985,56.838],[27.9765,56.812],[27.901,56.76],[27.981,56.707],[28.0115,56.6365],[28.062,56.586],[28.125,56.5825],[28.0975,56.511],[28.1945,56.4425],[28.1655,56.3745],[28.24,56.2715],[28.1515,56.17],[28.32,56.0595],[28.458,56.1025],[28.5485,56.116],[28.62,56.0995],[28.723,55.9785],[28.829,55.9635],[28.858,55.9885],[29.088,56.034],[29.156,56.0265],[29.214,55.989],[29.3055,55.9915],[29.426,55.9505],[29.3605,55.7985],[29.4,55.7535],[29.5155,55.7015],[29.623,55.78],[29.755,55.8005],[29.8065,55.7835],[29.895,55.8625],[29.976,55.8715],[30.107,55.8315],[30.239,55.872],[30.2865,55.8315],[30.3695,55.8085],[30.4815,55.8125],[30.5335,55.7505],[30.595,55.747],[30.648,55.71],[30.6705,55.6395],[30.734,55.6545],[30.757,55.5945],[30.8095,55.5905],[30.872,55.63],[30.9325,55.617],[30.959,55.501],[30.901,55.4735],[30.9345,55.4],[30.83,55.3345],[30.9235,55.2005],[30.996,55.1445],[30.9905,55.077],[31.028,55.0625],[30.9085,54.949],[30.8345,54.9485],[30.835,54.9075],[30.7515,54.8095],[30.9535,54.743],[31.0255,54.706],[31.012,54.6745],[31.0955,54.6615],[31.178,54.67],[31.2105,54.632],[31.093,54.5295],[31.1085,54.492],[31.236,54.464],[31.3225,54.3405],[31.3135,54.2485],[31.383,54.2325],[31.4925,54.1615],[31.6765,54.1175],[31.7745,54.113],[31.898,54.083],[31.854,54.0045],[31.892,53.9665],[31.769,53.8355],[31.867,53.7825],[32.1,53.8145],[32.208,53.7995],[32.22,53.7705],[32.3205,53.758],[32.358,53.7205],[32.4605,53.7375],[32.499,53.681],[32.426,53.6075],[32.478,53.549],[32.757,53.458],[32.723,53.374],[32.7335,53.3325],[32.6265,53.3305],[32.5735,53.298],[32.5225,53.3065],[32.4925,53.2535],[32.4145,53.186],[32.339,53.172],[32.302,53.1275],[32.2545,53.1315],[32.095,53.076],[32.018,53.091],[31.9345,53.083],[31.887,53.1145],[31.831,53.1105],[31.7865,53.1795],[31.6455,53.2195],[31.5435,53.191],[31.5005,53.2045],[31.4185,53.1875],[31.335,53.091],[31.3305,53.042],[31.3725,52.9335],[31.441,52.881],[31.5895,52.7915],[31.6005,52.746],[31.567,52.708],[31.504,52.6985],[31.5695,52.6345],[31.564,52.5945],[31.652,52.545],[31.6025,52.4235],[31.6325,52.398],[31.6145,52.3275],[31.6965,52.258],[31.711,52.215],[31.781,52.1855],[31.7815,52.112],[31.8565,52.111],[31.954,52.0815],[31.9175,52.053],[32.1255,52.046],[32.29,52.103],[32.3445,52.1825],[32.3245,52.2235],[32.3955,52.2465],[32.3515,52.3165],[32.55,52.327],[32.685,52.2665],[32.763,52.2565],[32.8335,52.279],[32.996,52.2725],[33.073,52.325],[33.208,52.376],[33.289,52.3575],[33.519,52.355],[33.5045,52.306],[33.56,52.3025],[33.6065,52.3345],[33.7855,52.3665],[33.8365,52.3615],[33.875,52.3065],[34.0545,52.1715],[34.1165,52.141],[34.0625,52.073],[34.094,52.011],[34.1895,51.969],[34.2035,51.941],[34.4155,51.826],[34.4325,51.7295],[34.1155,51.6845],[34.308,51.5155],[34.2225,51.4285],[34.2855,51.375],[34.337,51.3655],[34.2375,51.2925],[34.2445,51.2635],[34.3315,51.24],[34.384,51.274],[34.4865,51.2445],[34.6625,51.2475],[34.669,51.1975],[34.818,51.169],[34.951,51.2265],[35.1505,51.2235],[35.1235,51.165],[35.168,51.1265],[35.166,51.0775],[35.2135,51.0465],[35.305,51.076],[35.406,51.048],[35.33,50.996],[35.333,50.9345],[35.388,50.9235],[35.419,50.844],[35.4105,50.808],[35.4885,50.777],[35.4595,50.689],[35.392,50.642],[35.4255,50.603],[35.436,50.53],[35.4755,50.489],[35.5865,50.448],[35.584,50.3955],[35.6285,50.3545],[35.738,50.3545],[35.8315,50.434],[35.932,50.431],[36.068,50.451],[36.1605,50.4315],[36.284,50.3355],[36.297,50.292],[36.3665,50.288],[36.4735,50.313],[36.575,50.275],[36.5605,50.251],[36.6485,50.2175],[36.693,50.269],[36.9375,50.3505],[37.1055,50.352],[37.1815,50.363],[37.2925,50.4015],[37.333,50.437],[37.465,50.431],[37.485,50.357],[37.6265,50.2935],[37.615,50.217],[37.639,50.1795],[37.755,50.0785],[37.797,50.084],[37.9265,50.034],[37.962,49.983],[38.056,49.923],[38.171,49.942],[38.222,49.979],[38.186,50.023],[38.178,50.08],[38.3295,50.0855],[38.3505,50.007],[38.4885,49.963],[38.5825,49.9775],[38.724,49.927],[38.745,49.8975],[38.848,49.8645],[38.901,49.8695],[38.9095,49.8195],[38.9515,49.797],[39.067,49.8155],[39.18,49.889],[39.2275,49.8075],[39.285,49.7555],[39.379,49.7385],[39.4785,49.7565],[39.5915,49.7185],[39.6605,49.615],[39.7505,49.5975],[39.806,49.558],[39.891,49.5585],[39.952,49.597],[40.1355,49.617],[40.1695,49.569],[40.039,49.5205],[40.0295,49.4535],[40.1145,49.3855],[40.196,49.3445],[40.186,49.281],[40.0775,49.187],[40.031,49.18],[39.9385,49.083],[39.805,49.06],[39.7665,49.04],[39.693,49.0505],[39.6635,49.001],[39.7495,48.978],[39.7765,48.9205],[39.8525,48.8905],[40.0585,48.904],[40.08,48.87],[39.9755,48.793],[39.807,48.8385],[39.779,48.7855],[39.7255,48.7525],[39.7185,48.6875],[39.668,48.621],[39.688,48.587],[39.7875,48.5935],[39.8555,48.561],[39.853,48.4665],[39.898,48.4475],[39.946,48.352],[39.8455,48.333],[39.841,48.31],[39.9365,48.291],[39.9905,48.317],[40.021,48.254],[39.942,48.2285],[39.937,48.181],[39.8765,48.119],[39.8835,48.0415],[39.7765,48.04],[39.816,48.0],[39.7935,47.9195],[39.7385,47.828],[39.5655,47.8365],[39.521,47.8255],[39.478,47.8605],[39.412,47.831],[39.3875,47.871],[39.2415,47.867],[39.1495,47.8425],[39.083,47.8695],[38.884,47.875],[38.8375,47.8645],[38.789,47.816],[38.7725,47.6855],[38.669,47.699],[38.6165,47.6445],[38.4565,47.644],[38.457,47.617],[38.3505,47.6165],[38.2845,47.5445],[38.3025,47.393],[38.2575,47.373],[38.221,47.3055],[38.336,47.3065],[38.3245,47.257],[38.2605,47.2385],[38.236,47.1985],[38.23,47.1195],[38.338,46.981],[38.141,46.861],[37.62,46.83],[37.4375,46.716]]],[[[35.4205,80.1595],[35.4845,80.0925],[35.7815,80.0105],[36.2645,79.9505],[36.7085,79.933],[37.0955,79.942],[37.4975,79.977],[37.86,80.0555],[37.9645,80.117],[37.9135,80.2135],[37.6615,80.29],[37.275,80.3435],[36.891,80.3645],[36.3365,80.362],[35.871,80.3235],[35.558,80.258],[35.4205,80.1595]]],[[[43.6835,80.5925],[43.8105,80.5065],[44.035,80.4535],[44.7615,80.358],[45.55,80.2675],[45.8625,80.11],[46.1245,80.0395],[46.404,80.0015],[46.9855,79.8935],[47.3905,79.8555],[47.793,79.847],[48.259,79.863],[48.786,79.802],[49.3665,79.791],[49.6775,79.759],[50.0935,79.736],[50.9605,79.715],[51.4325,79.7145],[51.8835,79.7365],[52.253,79.7805],[52.5735,79.861],[52.9815,79.8195],[53.2935,79.809],[53.888,79.828],[54.231,79.872],[54.4365,79.925],[54.5395,79.9975],[54.7365,80.011],[54.87,79.9705],[55.35,79.9065],[55.806,79.826],[56.1505,79.8045],[56.4975,79.802],[57.015,79.8315],[57.22,79.86],[57.5015,79.79],[57.535,79.7235],[57.83,79.6315],[58.2335,79.5845],[58.7545,79.5725],[59.058,79.5855],[59.357,79.616],[59.698,79.692],[60.0955,79.693],[60.6575,79.737],[61.029,79.829],[61.1035,79.902],[61.0175,80.0005],[61.248,80.0485],[61.41,80.1395],[62.149,80.2105],[62.5605,80.29],[62.673,80.4],[62.9895,80.441],[63.308,80.442],[64.8945,80.5295],[65.2785,80.5685],[65.8965,80.6555],[66.356,80.771],[66.555,80.851],[66.6445,81.015],[66.5255,81.1525],[66.384,81.215],[65.9405,81.3085],[65.572,81.351],[65.0695,81.383],[64.362,81.392],[63.9725,81.376],[63.518,81.334],[63.065,81.265],[62.793,81.1905],[62.4695,81.252],[61.8925,81.302],[61.872,81.3255],[62.499,81.3325],[63.073,81.381],[63.5635,81.3785],[64.263,81.4165],[64.725,81.476],[64.9685,81.535],[65.132,81.622],[65.112,81.682],[64.8545,81.78],[64.594,81.8265],[64.0285,81.885],[63.4465,81.907],[62.565,81.903],[61.9485,81.8845],[61.4615,81.8485],[60.995,81.787],[60.712,81.7895],[60.703,81.8595],[60.4945,81.9495],[59.9405,82.029],[59.132,82.0585],[58.438,82.0495],[57.3565,81.999],[56.754,81.925],[56.545,81.864],[56.549,81.735],[56.14,81.714],[55.766,81.671],[55.444,81.577],[55.085,81.5935],[54.6435,81.592],[53.997,81.5455],[53.505,81.521],[53.0415,81.4545],[52.8745,81.394],[52.891,81.295],[53.127,81.2145],[52.9595,81.1595],[52.917,81.077],[53.134,80.9725],[52.9405,80.9265],[52.772,80.8395],[52.427,80.8925],[52.146,80.955],[52.0775,81.0125],[52.297,81.1185],[52.266,81.1815],[51.999,81.2765],[51.6115,81.333],[51.2195,81.365],[50.387,81.3795],[49.899,81.357],[49.5215,81.31],[49.2085,81.235],[49.082,81.143],[49.1105,81.0785],[48.6785,81.0065],[48.246,81.014],[47.9525,81.041],[47.341,81.0555],[46.579,81.0225],[46.2095,80.9785],[45.934,80.899],[45.5035,80.8415],[44.5815,80.801],[44.276,80.775],[43.9115,80.7165],[43.725,80.651],[43.6835,80.5925]]],[[[47.655,68.923],[47.6725,68.8025],[47.7105,68.734],[47.874,68.6235],[48.105,68.554],[48.2485,68.5285],[48.5955,68.4965],[49.1755,68.4565],[49.6325,68.4725],[49.915,68.5195],[50.079,68.5775],[50.59,68.851],[50.802,68.9975],[50.8715,69.124],[50.824,69.22],[50.737,69.293],[50.6105,69.3655],[50.4355,69.432],[50.123,69.5125],[49.683,69.649],[49.3805,69.694],[49.16,69.7015],[48.843,69.6905],[48.707,69.675],[48.394,69.618],[48.092,69.507],[47.845,69.3685],[47.7575,69.2695],[47.6785,69.119],[47.655,68.923]]],[[[74.987,79.659],[75.0345,79.593],[75.276,79.4965],[75.624,79.4115],[76.2755,79.311],[76.7475,79.284],[77.4715,79.279],[77.7485,79.285],[78.158,79.318],[78.3975,79.359],[78.5955,79.424],[78.671,79.496],[78.591,79.5785],[78.479,79.618],[78.13,79.683],[77.214,79.8035],[76.5545,79.864],[75.9045,79.8705],[75.587,79.8475],[75.187,79.7765],[75.042,79.7205],[74.987,79.659]]],[[[77.577,80.793],[77.6235,80.7225],[77.8325,80.65],[78.192,80.592],[78.4505,80.5685],[79.078,80.545],[79.827,80.55],[80.537,80.59],[80.866,80.635],[81.1545,80.694],[81.3655,80.774],[81.4265,80.843],[81.2295,80.9535],[80.921,81.0115],[80.1395,81.0815],[79.8385,81.0975],[79.3495,81.1005],[78.5375,81.0525],[78.189,81.0135],[77.759,80.9205],[77.577,80.793]]],[[[78.461,74.588],[78.51,74.504],[78.73,74.4095],[79.0335,74.3505],[79.5055,74.314],[79.808,74.3255],[80.054,74.364],[80.258,74.442],[80.363,74.5415],[80.361,74.616],[80.2155,74.7025],[79.8095,74.7985],[79.578,74.831],[79.2075,74.839],[78.8125,74.795],[78.6285,74.7415],[78.5255,74.687],[78.461,74.588]]],[[[80.811,75.312],[80.851,75.2185],[80.9995,75.126],[81.181,75.056],[81.529,74.943],[81.78,74.89],[82.0325,74.8695],[82.425,74.8825],[82.7595,74.9435],[82.8875,75.0],[82.939,75.0645],[82.9655,75.186],[83.138,75.2985],[83.131,75.3685],[83.0315,75.4505],[83.0685,75.5205],[83.01,75.586],[82.866,75.6435],[82.713,75.6765],[82.965,75.7185],[83.3035,75.7195],[83.6275,75.742],[83.856,75.7835],[84.072,75.8865],[84.0865,75.9645],[84.041,76.0155],[83.897,76.0775],[83.5365,76.138],[82.9315,76.1745],[82.584,76.1865],[81.999,76.1505],[81.776,76.1565],[81.451,76.1395],[81.2115,76.1005],[80.9555,76.02],[80.852,75.957],[80.8745,75.8555],[81.0035,75.795],[81.2065,75.7485],[81.669,75.6745],[81.4055,75.6315],[81.1515,75.5615],[80.9405,75.4795],[80.833,75.3975],[80.811,75.312]]],[[[81.3055,77.5345],[81.3755,77.435],[81.554,77.36],[81.751,77.321],[82.248,77.279],[82.7945,77.266],[83.13,77.2895],[83.3975,77.3405],[83.556,77.4095],[83.5455,77.5225],[83.2895,77.6165],[83.066,77.67],[82.7765,77.7055],[82.435,77.7245],[81.974,77.7205],[81.5455,77.6615],[81.3965,77.609],[81.3055,77.5345]]],[[[87.806,77.078],[87.8565,76.9975],[88.1385,76.8735],[88.412,76.8175],[88.6565,76.7895],[88.939,76.775],[89.405,76.79],[89.6215,76.773],[89.9115,76.77],[90.2505,76.795],[90.5505,76.8555],[90.6995,76.9315],[91.003,77.0125],[91.0915,77.0845],[91.3715,77.121],[91.529,77.161],[91.6745,77.2465],[91.6415,77.372],[91.735,77.4035],[92.2035,77.4035],[92.5305,77.436],[92.919,77.533],[93.013,77.593],[93.01,77.6625],[92.8775,77.7335],[92.515,77.8145],[92.158,77.852],[91.721,77.8545],[91.2705,77.8095],[91.0345,77.7475],[90.9195,77.658],[90.969,77.566],[90.8755,77.5185],[90.5805,77.52],[90.307,77.5035],[90.0695,77.471],[89.692,77.4995],[89.3745,77.5005],[89.1045,77.487],[88.6615,77.4225],[88.452,77.3545],[88.356,77.297],[87.989,77.2165],[87.831,77.129],[87.806,77.078]]],[[[92.6775,78.183],[92.785,78.076],[93.0615,77.999],[93.393,77.9565],[93.678,77.942],[94.1545,77.957],[94.4805,78.001],[94.6195,78.0355],[94.78,78.121],[94.772,78.2345],[94.6665,78.3135],[94.489,78.3635],[94.259,78.3985],[93.892,78.4215],[93.509,78.4145],[93.0925,78.3665],[92.8245,78.2965],[92.6775,78.183]]],[[[115.212,74.2995],[115.278,74.2135],[115.5195,74.125],[115.787,74.087],[116.139,74.079],[116.39,74.1015],[116.6395,74.147],[116.8385,74.2145],[116.895,74.254],[116.9275,74.339],[116.8215,74.441],[116.6535,74.5025],[116.287,74.5595],[116.0385,74.567],[115.749,74.5495],[115.5135,74.5045],[115.2705,74.393],[115.212,74.2995]]],[[[134.7045,74.2395],[134.7225,74.138],[134.8625,74.0355],[135.4505,73.8095],[135.762,73.717],[136.029,73.684],[136.328,73.6835],[136.5195,73.702],[136.7115,73.74],[136.919,73.8145],[137.013,73.8885],[136.962,74.041],[136.618,74.203],[136.1565,74.3535],[135.9085,74.4035],[135.4575,74.441],[135.098,74.4185],[134.8695,74.3685],[134.733,74.2985],[134.7045,74.2395]]],[[[138.897,54.639],[138.9075,54.558],[138.9745,54.486],[139.0855,54.4365],[139.222,54.417],[139.3605,54.432],[139.474,54.4765],[139.5475,54.5435],[139.569,54.622],[139.535,54.699],[139.451,54.7615],[139.357,54.794],[139.25,54.808],[139.141,54.801],[139.0415,54.7745],[138.9445,54.7155],[138.897,54.639]]],[[[140.922,46.2525],[140.947,46.15],[141.0155,46.083],[141.075,46.052],[141.189,46.0235],[141.276,46.024],[141.362,46.044],[141.463,46.088],[141.514,46.1305],[141.549,46.187],[141.5565,46.299],[141.538,46.344],[141.479,46.4065],[141.3685,46.4705],[141.223,46.493],[141.1195,46.4765],[141.054,46.452],[140.9725,46.395],[140.9395,46.348],[140.922,46.2525]]],[[[143.0465,56.413],[143.0665,56.3415],[143.1335,56.279],[143.2955,56.223],[143.3915,56.216],[143.5385,56.2355],[143.6555,56.288],[143.721,56.3635],[143.721,56.447],[143.656,56.522],[143.5385,56.5745],[143.3915,56.5935],[143.263,56.5805],[143.1525,56.542],[143.077,56.483],[143.0465,56.413]]],[[[145.6375,44.3015],[145.514,44.132],[145.32,43.9405],[145.2765,43.8395],[145.279,43.7355],[145.4475,43.6235],[145.7595,43.502],[145.8425,43.381],[146.0085,43.2255],[146.0595,43.1775],[146.1175,43.1775],[146.2925,43.2345],[146.5555,43.3965],[146.777,43.5215],[146.9745,43.5925],[147.1035,43.67],[147.162,43.73],[147.1955,43.8215],[147.1935,43.8645],[147.146,43.9565],[147.178,44.303],[147.375,44.4065],[147.4925,44.486],[147.56,44.574],[147.6445,44.615],[147.7885,44.7035],[147.9045,44.759],[148.057,44.793],[148.182,44.8615],[148.2605,44.93],[148.409,45.0115],[148.6195,45.075],[148.9715,45.158],[149.073,45.22],[149.146,45.3265],[149.408,45.3735],[149.519,45.371],[149.631,45.385],[149.812,45.4515],[149.8615,45.478],[150.018,45.594],[150.201,45.669],[150.324,45.7445],[150.418,45.816],[150.5355,45.9435],[150.6765,46.0295],[150.8225,46.102],[151.0715,46.3215],[151.151,46.409],[151.1985,46.4825],[151.199,46.584],[151.1675,46.6375],[150.9765,46.8535],[150.8485,46.921],[150.711,46.939],[150.621,46.927],[150.5275,46.8885],[150.4655,46.8395],[150.432,46.788],[150.421,46.6955],[150.457,46.623],[150.4765,46.522],[150.365,46.4275],[150.196,46.4055],[150.0645,46.357],[149.7555,46.1855],[149.6445,46.081],[149.508,46.0175],[149.4245,45.961],[149.331,45.8675],[149.201,45.7575],[148.9635,45.7295],[148.896,45.746],[148.731,45.756],[148.582,45.732],[148.464,45.6875],[148.348,45.611],[148.048,45.6185],[147.899,45.6375],[147.798,45.618],[147.6845,45.5585],[147.6195,45.4945],[147.52,45.3425],[147.375,45.2945],[147.302,45.2575],[147.241,45.1975],[147.191,45.075],[147.1395,45.0495],[146.984,45.003],[146.8675,44.9275],[146.725,44.7515],[146.5195,44.666],[146.338,44.6765],[146.2195,44.7135],[146.1245,44.715],[146.0245,44.6945],[145.9475,44.66],[145.839,44.574],[145.728,44.4385],[145.6375,44.3015]]],[[[147.618,76.6425],[147.7465,76.534],[148.001,76.472],[148.296,76.442],[148.5955,76.4365],[148.897,76.4445],[149.308,76.4325],[149.657,76.4615],[149.841,76.497],[150.0475,76.5665],[150.111,76.6145],[150.273,76.668],[150.351,76.722],[150.3535,76.79],[150.241,76.86],[150.007,76.918],[149.5675,76.955],[149.246,76.95],[148.4875,76.9075],[148.2555,76.873],[147.925,76.803],[147.687,76.7185],[147.618,76.6425]]],[[[151.6385,75.7],[151.705,75.6325],[151.9085,75.5615],[152.2785,75.514],[152.558,75.511],[152.9725,75.5555],[153.1345,75.599],[153.26,75.6715],[153.2675,75.749],[153.081,75.8485],[152.8685,75.8915],[153.11,75.9055],[153.476,75.9705],[153.6225,76.038],[153.6785,76.1565],[153.6595,76.229],[153.5325,76.3005],[153.3535,76.3455],[153.132,76.3745],[152.71,76.3845],[152.4005,76.372],[152.129,76.3405],[151.974,76.306],[151.803,76.2385],[151.7085,76.1515],[151.739,76.092],[151.913,76.0105],[152.3115,75.9155],[152.0695,75.894],[151.858,75.8525],[151.7325,75.807],[151.6385,75.7]]],[[[155.5795,77.0745],[155.7115,76.971],[155.9625,76.9105],[156.339,76.8755],[156.6225,76.875],[157.0635,76.9025],[157.3115,76.948],[157.518,77.0445],[157.53,77.0945],[157.441,77.1875],[157.274,77.244],[157.033,77.2855],[156.647,77.31],[156.4105,77.307],[156.096,77.2815],[155.889,77.247],[155.6575,77.1705],[155.5795,77.0745]]],[[[157.155,76.7845],[157.202,76.733],[157.352,76.67],[157.5445,76.6255],[157.992,76.5835],[158.3625,76.5915],[158.5465,76.61],[158.814,76.6635],[159.002,76.7595],[158.9965,76.836],[158.9115,76.889],[158.653,76.956],[158.375,76.986],[157.9275,76.996],[157.6615,76.9795],[157.437,76.946],[157.2595,76.8945],[157.155,76.7845]]],[[[165.404,55.291],[165.4535,55.1585],[165.5555,55.064],[165.8075,54.933],[165.8865,54.849],[166.1135,54.6915],[166.458,54.52],[166.594,54.484],[166.6965,54.48],[166.8555,54.5105],[166.957,54.5675],[167.0235,54.6845],[167.015,54.79],[166.988,54.898],[166.893,55.015],[166.688,55.1515],[166.6475,55.3265],[166.5985,55.4055],[166.4455,55.497],[166.3265,55.5245],[166.029,55.5625],[165.8975,55.5615],[165.7635,55.5285],[165.549,55.449],[165.45,55.3855],[165.404,55.291]]],[[[167.0735,54.891],[167.0865,54.8295],[167.1585,54.714],[167.288,54.6255],[167.5235,54.501],[167.8345,54.3615],[167.9745,54.308],[168.1105,54.2965],[168.223,54.311],[168.31,54.3395],[168.3945,54.3945],[168.4455,54.4885],[168.4255,54.571],[168.384,54.621],[168.288,54.6885],[168.184,54.793],[168.0665,54.8455],[167.96,54.9125],[167.737,55.0095],[167.6015,55.0575],[167.4735,55.0825],[167.3635,55.082],[167.2365,55.0545],[167.1375,55.001],[167.0915,54.949],[167.0735,54.891]]],[[[178.011,71.065],[178.03,70.976],[178.1605,70.846],[178.207,70.7275],[178.311,70.6635],[178.551,70.602],[178.7485,70.5865],[179.0395,70.602],[179.3035,70.6575],[179.4765,70.652],[179.721,70.6675],[180.0,70.7165],[180.0,70.976],[180.0,71.0255],[180.0,71.749],[179.649,71.7025],[179.007,71.5395],[178.7235,71.417],[178.4735,71.3635],[178.301,71.2675],[178.125,71.1895],[178.023,71.1095],[178.011,71.065]]]]},"properties":{"flag":"https://upload.wikimedia.org/wikipedia/commons/f/f3/Flag_of_Russia.svg","name:en":"Russia","wikidata":"Q159","ISO3166-1:alpha2":"RU","ISO3166-1:alpha3":"RUS","ISO3166-1:numeric":"643"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[28.214,45.467],[28.1605,45.511],[28.165,45.546],[28.0925,45.598],[28.1735,45.6475],[28.151,45.745],[28.109,45.8305],[28.133,45.8765],[28.086,46.009],[28.09,46.072],[28.13,46.1255],[28.1415,46.1855],[28.112,46.2325],[28.1365,46.28],[28.2065,46.317],[28.1975,46.37],[28.258,46.425],[28.2235,46.4955],[28.2225,46.543],[28.2515,46.621],[28.235,46.6745],[28.1865,46.725],[28.1555,46.7915],[28.1075,46.842],[28.1125,46.921],[28.0805,46.991],[27.9175,47.067],[27.801,47.138],[27.7865,47.2175],[27.7055,47.2895],[27.634,47.3025],[27.569,47.373],[27.5695,47.4655],[27.476,47.485],[27.405,47.583],[27.3335,47.6275],[27.2675,47.712],[27.2855,47.7445],[27.2165,47.8165],[27.194,47.9065],[27.152,47.921],[27.1615,47.996],[27.1235,47.993],[27.027,48.0875],[27.0205,48.1385],[26.933,48.171],[26.8085,48.2545],[26.667,48.2465],[26.63,48.2595],[26.529,48.21],[26.46,48.2145],[26.335,48.1835],[26.2725,48.082],[26.214,48.0525],[26.1845,47.9945],[25.952,47.971],[25.861,47.9705],[25.775,47.9395],[25.6255,47.949],[25.5925,47.9385],[25.311,47.9145],[25.237,47.8955],[25.2215,47.859],[25.113,47.756],[25.0405,47.7305],[24.883,47.7245],[24.836,47.7795],[24.8275,47.8205],[24.753,47.83],[24.6725,47.8635],[24.674,47.8965],[24.58,47.967],[24.502,47.9525],[24.436,47.9705],[24.345,47.9145],[24.217,47.903],[24.01,47.9665],[23.882,47.9435],[23.8195,47.983],[23.751,47.9985],[23.6655,47.9835],[23.6375,48.0025],[23.539,48.0115],[23.495,47.968],[23.295,48.0445],[23.2695,48.086],[23.1465,48.0995],[23.1055,48.066],[23.091,48.006],[22.8975,47.954],[22.8475,47.908],[22.7685,47.878],[22.68,47.788],[22.549,47.772],[22.481,47.811],[22.426,47.75],[22.2645,47.731],[22.188,47.609],[22.045,47.54],[22.0075,47.4755],[22.0355,47.4275],[22.012,47.376],[21.9385,47.373],[21.852,47.239],[21.858,47.187],[21.8175,47.173],[21.773,47.109],[21.726,47.0985],[21.6825,47.0455],[21.6795,46.998],[21.595,46.8605],[21.519,46.836],[21.484,46.765],[21.5295,46.721],[21.4165,46.6425],[21.33,46.6315],[21.321,46.583],[21.2605,46.502],[21.318,46.4505],[21.2755,46.4065],[21.2065,46.403],[21.1995,46.348],[21.168,46.298],[21.1155,46.3015],[21.066,46.243],[21.0245,46.2665],[20.922,46.262],[20.8735,46.288],[20.749,46.251],[20.715,46.167],[20.632,46.128],[20.503,46.1895],[20.459,46.143],[20.3555,46.1695],[20.2645,46.1265],[20.273,46.0985],[20.346,46.0475],[20.3485,45.9995],[20.4055,45.965],[20.4835,45.9535],[20.516,45.892],[20.6605,45.829],[20.7005,45.7505],[20.8025,45.738],[20.805,45.657],[20.766,45.6125],[20.8325,45.536],[20.769,45.5],[20.879,45.4545],[20.9605,45.367],[21.0165,45.3245],[21.0635,45.332],[21.0965,45.296],[21.18,45.3125],[21.203,45.2655],[21.483,45.192],[21.5275,45.138],[21.4785,45.1215],[21.4475,45.0575],[21.36,45.0205],[21.4065,44.9785],[21.5465,44.9305],[21.56,44.889],[21.4855,44.868],[21.3715,44.8665],[21.3585,44.8215],[21.425,44.7735],[21.537,44.7725],[21.608,44.7335],[21.642,44.66],[21.842,44.6555],[21.9955,44.632],[22.037,44.542],[22.1295,44.474],[22.184,44.482],[22.2735,44.623],[22.333,44.676],[22.371,44.6725],[22.4295,44.71],[22.4845,44.707],[22.5695,44.637],[22.6695,44.619],[22.7545,44.565],[22.699,44.5165],[22.619,44.552],[22.5645,44.5355],[22.5505,44.4825],[22.475,44.4805],[22.5235,44.3405],[22.558,44.309],[22.6835,44.2715],[22.6745,44.216],[22.7545,44.194],[22.7915,44.164],[22.922,44.1],[23.001,44.095],[23.0485,44.0625],[23.0035,44.0105],[22.8795,43.981],[22.841,43.882],[22.881,43.832],[23.0465,43.7965],[23.1405,43.8055],[23.268,43.846],[23.433,43.8495],[23.5115,43.838],[23.6255,43.7915],[23.705,43.806],[23.8725,43.753],[23.967,43.7445],[24.0865,43.702],[24.1745,43.682],[24.3495,43.698],[24.407,43.7365],[24.501,43.7625],[24.623,43.742],[24.746,43.6845],[24.8015,43.709],[25.007,43.7245],[25.115,43.6845],[25.1895,43.697],[25.252,43.683],[25.3435,43.6305],[25.391,43.6185],[25.5085,43.647],[25.5655,43.646],[25.6805,43.691],[25.7855,43.7135],[25.8525,43.759],[25.9525,43.8595],[26.06,43.91],[26.106,43.968],[26.198,43.9855],[26.3075,44.027],[26.4345,44.0355],[26.5535,44.058],[26.601,44.0525],[26.774,44.0805],[26.9015,44.1325],[27.042,44.1445],[27.135,44.1405],[27.229,44.1155],[27.2915,44.075],[27.356,44.0585],[27.3995,44.012],[27.469,44.0225],[27.612,44.012],[27.6735,44.03],[27.71,43.9595],[27.843,43.966],[27.917,44.0085],[27.944,43.9845],[27.9945,43.843],[28.236,43.7585],[28.3485,43.752],[28.4465,43.7335],[28.579,43.7385],[28.8555,43.7385],[28.941,43.936],[28.9725,44.075],[29.1315,44.4375],[29.224,44.5415],[29.5735,44.5805],[29.6715,44.605],[29.7285,44.6355],[29.851,44.7265],[29.882,44.7695],[30.0455,45.0865],[29.9955,45.1145],[29.952,45.1695],[29.6905,45.1915],[29.651,45.3395],[29.589,45.39],[29.4295,45.4425],[29.294,45.428],[29.238,45.4325],[29.179,45.4],[29.044,45.3605],[28.9145,45.2875],[28.8165,45.3365],[28.7925,45.2435],[28.714,45.2235],[28.569,45.248],[28.349,45.3205],[28.2855,45.3995],[28.2865,45.4335],[28.214,45.467]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/7/73/Flag_of_Romania.svg","name:en":"Romania","wikidata":"Q218","ISO3166-1:alpha2":"RO","ISO3166-1:alpha3":"ROU","ISO3166-1:numeric":"642"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[26.63,48.2595],[26.667,48.2465],[26.8085,48.2545],[26.933,48.171],[27.0205,48.1385],[27.027,48.0875],[27.1235,47.993],[27.1615,47.996],[27.152,47.921],[27.194,47.9065],[27.2165,47.8165],[27.2855,47.7445],[27.2675,47.712],[27.3335,47.6275],[27.405,47.583],[27.476,47.485],[27.5695,47.4655],[27.569,47.373],[27.634,47.3025],[27.7055,47.2895],[27.7865,47.2175],[27.801,47.138],[27.9175,47.067],[28.0805,46.991],[28.1125,46.921],[28.1075,46.842],[28.1555,46.7915],[28.1865,46.725],[28.235,46.6745],[28.2515,46.621],[28.2225,46.543],[28.2235,46.4955],[28.258,46.425],[28.1975,46.37],[28.2065,46.317],[28.1365,46.28],[28.112,46.2325],[28.1415,46.1855],[28.13,46.1255],[28.09,46.072],[28.086,46.009],[28.133,45.8765],[28.109,45.8305],[28.151,45.745],[28.1735,45.6475],[28.0925,45.598],[28.165,45.546],[28.1605,45.511],[28.214,45.467],[28.305,45.547],[28.421,45.513],[28.515,45.5],[28.491,45.571],[28.544,45.58],[28.516,45.6655],[28.4805,45.678],[28.5195,45.736],[28.5895,45.729],[28.6245,45.766],[28.7095,45.78],[28.697,45.818],[28.786,45.8325],[28.755,45.9275],[28.7765,45.9705],[28.979,46.0035],[29.0055,46.0495],[28.9505,46.0935],[29.067,46.1955],[28.9525,46.2595],[28.9865,46.343],[28.931,46.4575],[29.0255,46.4625],[29.0385,46.506],[29.164,46.5155],[29.162,46.5445],[29.236,46.5585],[29.2295,46.4585],[29.2465,46.416],[29.2965,46.417],[29.308,46.465],[29.387,46.4465],[29.4485,46.4985],[29.502,46.4615],[29.507,46.423],[29.566,46.4165],[29.5805,46.361],[29.6775,46.361],[29.686,46.426],[29.7765,46.4545],[29.805,46.3855],[29.8865,46.3715],[29.9385,46.4005],[30.0915,46.383],[30.11,46.4315],[30.0235,46.442],[29.9925,46.501],[29.9265,46.502],[29.9685,46.595],[29.946,46.6485],[29.971,46.685],[29.9755,46.7555],[29.906,46.8205],[29.884,46.886],[29.7495,46.861],[29.731,46.9195],[29.648,46.9195],[29.596,46.9635],[29.612,47.1],[29.58,47.136],[29.552,47.2515],[29.5985,47.2575],[29.574,47.3705],[29.4875,47.356],[29.4855,47.306],[29.3985,47.3005],[29.3835,47.345],[29.3375,47.3705],[29.3175,47.449],[29.2425,47.462],[29.182,47.449],[29.117,47.5545],[29.2175,47.6125],[29.231,47.684],[29.2045,47.719],[29.2485,47.7515],[29.2195,47.7985],[29.1755,47.994],[29.093,47.983],[29.0865,47.9465],[29.026,47.9455],[28.9615,47.979],[28.926,47.96],[28.8395,48.035],[28.8555,48.108],[28.8335,48.129],[28.6775,48.143],[28.5445,48.169],[28.4635,48.074],[28.383,48.175],[28.361,48.2415],[28.303,48.2415],[28.2315,48.21],[28.1825,48.2555],[28.0825,48.2375],[28.0935,48.2935],[28.042,48.326],[27.964,48.325],[27.882,48.373],[27.869,48.407],[27.7475,48.458],[27.6435,48.442],[27.581,48.491],[27.465,48.4475],[27.447,48.409],[27.3825,48.411],[27.3195,48.4435],[27.2865,48.3715],[27.1925,48.395],[27.124,48.379],[27.087,48.413],[26.9955,48.3595],[26.8945,48.3835],[26.8515,48.413],[26.775,48.418],[26.765,48.3535],[26.824,48.3445],[26.7945,48.291],[26.696,48.327],[26.6485,48.305],[26.63,48.2595]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/27/Flag_of_Moldova.svg","name:en":"Moldova","wikidata":"Q217","ISO3166-1:alpha2":"MD","ISO3166-1:alpha3":"MDA","ISO3166-1:numeric":"498"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[23.515,53.9565],[23.6305,53.928],[23.7545,53.9275],[23.908,53.967],[23.983,53.924],[24.103,53.9405],[24.2015,53.97],[24.352,53.897],[24.448,53.904],[24.5075,53.9605],[24.626,54.0105],[24.7265,53.967],[24.839,54.021],[24.779,54.1],[24.866,54.147],[24.953,54.17],[25.016,54.1375],[25.0945,54.1505],[25.2025,54.221],[25.215,54.256],[25.3535,54.264],[25.513,54.3085],[25.5845,54.2345],[25.5155,54.1755],[25.65,54.1285],[25.7105,54.169],[25.781,54.1595],[25.7855,54.2335],[25.677,54.324],[25.5525,54.315],[25.562,54.366],[25.629,54.417],[25.626,54.4565],[25.6825,54.5365],[25.7625,54.577],[25.734,54.677],[25.7495,54.7645],[25.734,54.8025],[25.853,54.8965],[25.858,54.9275],[25.9555,54.951],[26.081,54.9545],[26.121,54.9895],[26.186,54.9915],[26.271,55.0775],[26.2295,55.1075],[26.3575,55.1505],[26.461,55.1285],[26.6765,55.159],[26.675,55.1975],[26.7315,55.245],[26.8355,55.2855],[26.792,55.321],[26.6685,55.3385],[26.6025,55.321],[26.4415,55.3475],[26.554,55.389],[26.557,55.4635],[26.524,55.51],[26.628,55.5725],[26.6305,55.6805],[26.531,55.677],[26.443,55.709],[26.3755,55.7095],[26.35,55.7425],[26.2685,55.7675],[26.2035,55.859],[26.1205,55.8795],[26.0455,55.945],[25.974,55.9815],[25.8605,55.9995],[25.82,56.055],[25.6885,56.0865],[25.6505,56.135],[25.48,56.143],[25.404,56.158],[25.2795,56.1585],[25.092,56.186],[25.056,56.266],[24.973,56.3105],[24.969,56.366],[24.9025,56.418],[24.699,56.3975],[24.587,56.3315],[24.5645,56.289],[24.454,56.258],[24.342,56.295],[24.1215,56.249],[24.019,56.33],[23.795,56.339],[23.7805,56.3675],[23.63,56.36],[23.545,56.332],[23.439,56.3515],[23.388,56.379],[23.177,56.3685],[23.184,56.3375],[23.0935,56.305],[23.027,56.331],[23.0025,56.4065],[22.8405,56.3655],[22.6165,56.3825],[22.423,56.41],[22.3455,56.394],[22.241,56.4],[22.1255,56.4325],[21.9945,56.4135],[21.9195,56.3685],[21.8355,56.3715],[21.722,56.3135],[21.618,56.3245],[21.5025,56.2955],[21.4525,56.2485],[21.3225,56.215],[21.2005,56.0765],[20.7095,56.0455],[20.6895,55.9155],[20.722,55.725],[20.754,55.6355],[20.7485,55.565],[20.7055,55.4555],[20.6555,55.384],[20.9545,55.281],[21.0985,55.2565],[21.271,55.245],[21.3845,55.2935],[21.4495,55.2215],[21.5075,55.1855],[21.5725,55.198],[21.649,55.181],[21.758,55.124],[21.9665,55.074],[22.101,55.024],[22.1575,55.0555],[22.287,55.0645],[22.466,55.0445],[22.589,55.07],[22.6035,55.0135],[22.726,54.9635],[22.855,54.888],[22.8735,54.789],[22.7415,54.7285],[22.743,54.627],[22.6865,54.591],[22.6805,54.533],[22.7035,54.453],[22.7365,54.443],[22.792,54.3635],[22.8365,54.4065],[22.984,54.3895],[23.092,54.2985],[23.2025,54.2885],[23.234,54.261],[23.3375,54.2515],[23.4245,54.1775],[23.486,54.153],[23.5285,54.066],[23.482,54.0],[23.515,53.9565]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/11/Flag_of_Lithuania.svg","name:en":"Lithuania","wikidata":"Q37","ISO3166-1:alpha2":"LT","ISO3166-1:alpha3":"LTU","ISO3166-1:numeric":"440"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[99.4585,6.3065],[99.5175,6.1995],[99.5365,6.0965],[99.58,6.0315],[99.645,5.9885],[99.796,5.9555],[99.856,5.9675],[99.893,5.9125],[99.958,5.869],[100.035,5.854],[100.101,5.867],[100.0795,5.77],[100.099,5.659],[100.0335,5.6155],[99.99,5.551],[99.975,5.4745],[99.99,5.354],[99.976,5.283],[99.9915,5.2065],[100.035,5.1415],[100.1,5.0985],[100.1595,5.086],[100.175,5.0095],[100.2395,4.865],[100.342,4.725],[100.3805,4.6995],[100.392,4.6405],[100.3815,4.5605],[100.3895,4.497],[100.373,4.3865],[100.35,4.3425],[100.328,4.2285],[100.349,4.1255],[100.327,3.998],[100.342,3.9215],[100.3855,3.8565],[100.451,3.813],[100.5335,3.799],[100.5565,3.765],[100.6265,3.7145],[100.671,3.64],[100.7525,3.5935],[100.7925,3.534],[100.9015,3.463],[100.912,3.41],[100.998,3.295],[101.0035,3.2665],[101.0805,3.177],[101.0185,3.081],[101.001,2.946],[101.0395,2.8305],[101.2015,2.6915],[101.775,2.2565],[102.2235,1.92],[102.5835,1.6865],[103.065,1.325],[103.433,1.2365],[103.5665,1.1955],[103.5765,1.2545],[103.603,1.264],[103.618,1.3215],[103.674,1.428],[103.714,1.4575],[103.7605,1.4485],[103.8125,1.4785],[103.898,1.428],[104.003,1.4205],[104.041,1.444],[104.0765,1.431],[104.0795,1.3575],[104.125,1.276],[104.189,1.2725],[104.3155,1.2835],[104.376,1.252],[104.416,1.256],[104.4725,1.2955],[104.5215,1.357],[104.523,1.3935],[104.389,1.317],[104.349,1.333],[104.3785,1.4105],[104.4635,1.4995],[104.508,1.5015],[104.4245,1.747],[104.2715,2.0995],[104.322,2.1625],[104.351,2.251],[104.3885,2.278],[104.491,2.232],[104.5525,2.227],[104.644,2.2635],[104.721,2.3475],[104.744,2.397],[104.7505,2.4685],[104.7285,2.519],[104.663,2.607],[104.6285,2.638],[104.5185,2.679],[104.477,2.735],[104.4005,2.7885],[104.4015,2.861],[104.38,2.9265],[104.311,3.04],[104.2515,3.0815],[104.107,3.1125],[104.049,3.104],[103.9775,3.0725],[103.9245,3.015],[103.8955,2.902],[103.808,2.886],[103.7325,2.8515],[103.647,2.9325],[103.635,2.9795],[103.644,3.205],[103.6295,3.343],[103.676,3.46],[103.6705,3.5825],[103.5525,3.7345],[103.5735,3.819],[103.627,3.906],[103.6385,3.9585],[103.6135,4.081],[103.6855,4.2705],[103.6875,4.37],[103.6665,4.429],[103.6775,4.5405],[103.6575,4.5915],[103.705,4.594],[103.8345,4.6565],[103.8935,4.787],[103.8785,4.8765],[103.8165,4.9685],[103.729,5.009],[103.6295,5.007],[103.565,4.978],[103.47,5.141],[103.469,5.261],[103.4345,5.336],[103.399,5.385],[103.3235,5.4255],[103.287,5.4735],[103.325,5.5005],[103.365,5.611],[103.336,5.7265],[103.1965,5.922],[103.1105,5.9875],[103.0045,6.018],[102.9435,6.009],[102.9015,6.065],[102.856,6.0985],[102.7535,6.151],[102.6755,6.1645],[102.582,6.152],[102.538,6.2345],[102.477,6.317],[102.444,6.343],[102.1665,6.4585],[102.0805,6.2255],[102.0875,6.141],[102.057,6.0855],[102.0035,6.0505],[101.9425,5.981],[101.9305,5.9095],[101.944,5.8725],[101.88,5.832],[101.7935,5.7505],[101.7535,5.797],[101.691,5.756],[101.658,5.817],[101.6625,5.8685],[101.5815,5.9345],[101.5405,5.919],[101.4845,5.87],[101.397,5.8725],[101.343,5.8095],[101.276,5.8115],[101.2495,5.7625],[101.26,5.7115],[101.215,5.6615],[101.136,5.613],[101.111,5.681],[101.06,5.7445],[101.034,5.738],[100.985,5.81],[101.037,5.918],[101.087,5.911],[101.107,5.9905],[101.1005,6.0495],[101.119,6.1145],[101.0585,6.1415],[101.0755,6.171],[101.1265,6.1925],[101.0945,6.2605],[101.015,6.247],[100.984,6.279],[100.904,6.234],[100.835,6.2965],[100.8125,6.442],[100.7395,6.492],[100.6625,6.451],[100.618,6.46],[100.564,6.495],[100.5255,6.4875],[100.496,6.5215],[100.3665,6.5395],[100.316,6.604],[100.326,6.6595],[100.29,6.689],[100.1715,6.694],[100.1705,6.6075],[100.154,6.5575],[100.159,6.4805],[100.1335,6.429],[100.076,6.406],[100.014,6.442],[99.917,6.5235],[99.812,6.5125],[99.689,6.4715],[99.5565,6.5035],[99.5115,6.4815],[99.4585,6.3065]]],[[[99.8995,3.9765],[99.915,3.9],[99.9585,3.835],[100.0235,3.7915],[100.1005,3.7765],[100.177,3.7915],[100.242,3.835],[100.2855,3.9],[100.301,3.9765],[100.2855,4.0535],[100.242,4.1185],[100.177,4.1615],[100.1005,4.177],[100.0235,4.1615],[99.9585,4.1185],[99.915,4.0535],[99.8995,3.9765]]],[[[116.8375,7.6665],[116.871,7.65],[117.0465,7.4805],[116.7925,7.4165],[116.559,7.1585],[116.3645,6.804],[116.1195,6.4805],[115.897,6.2115],[115.8535,5.9175],[115.6445,5.835],[115.555,5.76],[115.435,5.5785],[115.216,5.46],[115.115,5.387],[115.0605,5.264],[115.1585,5.025],[115.1635,4.988],[115.1425,4.9155],[115.1505,4.872],[115.2375,4.796],[115.248,4.7015],[115.289,4.604],[115.268,4.5275],[115.2725,4.4475],[115.3495,4.352],[115.3225,4.2965],[115.296,4.338],[115.246,4.341],[115.1555,4.383],[115.1125,4.3725],[115.099,4.4685],[115.0225,4.75],[115.027,4.807],[115.0495,4.8595],[115.052,4.8795],[115.025,4.8965],[114.9875,4.871],[114.9715,4.808],[114.8955,4.8155],[114.8585,4.7975],[114.775,4.696],[114.8025,4.6755],[114.8185,4.4765],[114.8295,4.4295],[114.8775,4.4265],[114.88,4.3705],[114.8575,4.2695],[114.794,4.1635],[114.8075,4.1495],[114.7185,4.0435],[114.649,4.006],[114.553,4.084],[114.5455,4.125],[114.496,4.1465],[114.454,4.242],[114.382,4.265],[114.3165,4.2635],[114.333,4.349],[114.307,4.366],[114.307,4.4185],[114.26,4.507],[114.162,4.5735],[114.077,4.5835],[114.084,4.645],[113.833,4.659],[113.5655,4.547],[112.7205,3.461],[111.1365,3.112],[110.7625,1.9435],[109.718,2.055],[109.645,2.0815],[109.6205,1.983],[109.56,1.971],[109.54,1.9265],[109.5515,1.859],[109.576,1.844],[109.5865,1.792],[109.623,1.8035],[109.6855,1.782],[109.6675,1.733],[109.662,1.6175],[109.7805,1.509],[109.8015,1.4695],[109.838,1.4755],[109.8375,1.422],[109.9305,1.425],[109.9635,1.403],[109.9795,1.299],[110.064,1.263],[110.097,1.199],[110.165,1.196],[110.2125,1.151],[110.2105,1.1185],[110.2795,1.0525],[110.2985,0.9955],[110.3965,0.9975],[110.4055,0.953],[110.4905,0.8765],[110.5955,0.8575],[110.6975,0.884],[110.762,0.9235],[110.8855,0.978],[110.907,1.029],[110.998,1.0295],[111.0695,1.0495],[111.1385,1.0505],[111.2315,1.086],[111.385,1.015],[111.445,1.014],[111.4885,1.0355],[111.551,0.9565],[111.596,1.009],[111.6675,1.043],[111.7175,1.007],[111.772,1.016],[111.818,0.9865],[111.8595,1.004],[111.887,1.0785],[111.9355,1.122],[112.057,1.1355],[112.143,1.135],[112.181,1.306],[112.2025,1.314],[112.2325,1.379],[112.212,1.4495],[112.2875,1.4735],[112.445,1.5395],[112.501,1.5835],[112.544,1.574],[112.6575,1.5715],[112.677,1.5545],[112.7745,1.564],[112.812,1.5405],[112.8845,1.5865],[112.9335,1.5675],[112.9895,1.579],[113.064,1.5525],[113.0315,1.4915],[112.986,1.4525],[113.015,1.405],[113.097,1.443],[113.1335,1.4015],[113.183,1.377],[113.241,1.3925],[113.356,1.357],[113.37,1.3235],[113.4275,1.286],[113.5375,1.3225],[113.5745,1.3065],[113.5965,1.264],[113.6645,1.2245],[113.7035,1.2655],[113.8035,1.3005],[113.8295,1.3345],[113.8145,1.3665],[113.8675,1.3875],[113.9745,1.45],[114.1425,1.466],[114.213,1.4105],[114.2495,1.451],[114.416,1.511],[114.5265,1.442],[114.586,1.4465],[114.611,1.501],[114.615,1.575],[114.649,1.5895],[114.711,1.6715],[114.718,1.728],[114.6945,1.8105],[114.7435,1.8695],[114.786,1.8485],[114.815,1.889],[114.8785,1.9145],[114.8485,1.972],[114.8805,2.0175],[114.8565,2.0455],[114.8065,2.0245],[114.792,2.06],[114.8105,2.1005],[114.78,2.1445],[114.7995,2.2495],[114.864,2.272],[114.906,2.257],[114.9485,2.3115],[114.9505,2.3515],[115.0215,2.368],[115.047,2.408],[115.095,2.411],[115.1395,2.4775],[115.1935,2.4715],[115.2375,2.506],[115.172,2.6055],[115.128,2.5825],[115.088,2.603],[115.1165,2.647],[115.093,2.694],[115.141,2.7445],[115.1425,2.8025],[115.114,2.8335],[115.151,2.872],[115.15,2.909],[115.2095,2.9555],[115.249,2.9665],[115.2855,3.0495],[115.335,2.9735],[115.3975,2.979],[115.429,3.017],[115.4835,3.0195],[115.5195,3.0585],[115.514,3.093],[115.564,3.171],[115.525,3.188],[115.516,3.261],[115.538,3.362],[115.574,3.422],[115.6345,3.4555],[115.6145,3.5445],[115.5765,3.6095],[115.5795,3.7475],[115.6185,3.8425],[115.582,3.888],[115.581,3.9415],[115.616,3.938],[115.65,3.9885],[115.6775,4.0905],[115.6755,4.127],[115.7075,4.1995],[115.731,4.1945],[115.766,4.2505],[115.8295,4.241],[115.864,4.3225],[115.878,4.391],[115.929,4.355],[116.006,4.348],[116.039,4.295],[116.079,4.2765],[116.1195,4.3385],[116.162,4.342],[116.1805,4.3825],[116.2595,4.364],[116.3485,4.3915],[116.4325,4.3255],[116.441,4.2885],[116.5025,4.3245],[116.5355,4.323],[116.536,4.3755],[116.612,4.3765],[116.6195,4.336],[116.782,4.3575],[116.84,4.327],[116.899,4.367],[116.9735,4.345],[117.044,4.3465],[117.1055,4.3335],[117.1515,4.354],[117.1965,4.336],[117.2425,4.374],[117.289,4.316],[117.342,4.291],[117.426,4.233],[117.4415,4.1935],[117.5295,4.1615],[117.5625,4.179],[117.642,4.1655],[117.899,4.166],[117.9585,4.1905],[118.265,4.097],[118.9615,4.093],[118.8375,4.4525],[119.0,4.443],[119.0,4.7],[119.3335,5.025],[119.5835,5.2665],[118.833,6.0],[118.3335,6.0],[117.9665,6.2835],[117.967,6.867],[117.425,7.4125],[117.0,7.6665],[116.8375,7.6665]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/66/Flag_of_Malaysia.svg","name:en":"Malaysia","wikidata":"Q833","ISO3166-1:alpha2":"MY","ISO3166-1:alpha3":"MYS","ISO3166-1:numeric":"458"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[100.0845,20.3525],[100.1235,20.4055],[100.1185,20.4335],[100.1755,20.6355],[100.2235,20.714],[100.2965,20.78],[100.3615,20.825],[100.4235,20.8325],[100.494,20.815],[100.608,20.841],[100.637,20.898],[100.544,20.8705],[100.5095,20.888],[100.546,21.0245],[100.596,21.029],[100.6405,21.0665],[100.642,21.0955],[100.696,21.1735],[100.7005,21.222],[100.732,21.316],[100.8105,21.2935],[100.8475,21.3045],[100.8825,21.3465],[100.949,21.3795],[100.996,21.3855],[101.059,21.455],[101.0845,21.459],[101.1635,21.5275],[101.1475,21.562],[101.1695,21.5955],[101.1525,21.6705],[101.115,21.6935],[101.11,21.751],[101.0875,21.776],[101.014,21.71],[100.8865,21.688],[100.801,21.604],[100.7225,21.5125],[100.6855,21.505],[100.572,21.451],[100.538,21.471],[100.4795,21.459],[100.431,21.5415],[100.3455,21.5285],[100.2915,21.4795],[100.247,21.4665],[100.205,21.513],[100.1685,21.486],[100.126,21.5115],[100.1115,21.603],[100.169,21.6665],[100.1185,21.706],[100.0725,21.694],[99.991,21.7065],[99.9435,21.825],[99.997,21.977],[99.9625,22.0525],[99.904,22.0695],[99.862,22.0595],[99.8545,22.026],[99.756,22.0735],[99.67,22.077],[99.642,22.106],[99.5155,22.104],[99.4735,22.136],[99.4085,22.0995],[99.2725,22.101],[99.1675,22.1495],[99.174,22.189],[99.2355,22.2505],[99.233,22.297],[99.278,22.362],[99.296,22.4145],[99.381,22.5045],[99.358,22.537],[99.385,22.5755],[99.3605,22.664],[99.3145,22.7395],[99.3855,22.765],[99.3995,22.8285],[99.4515,22.861],[99.441,22.9425],[99.496,22.912],[99.5605,22.909],[99.56,22.9515],[99.5225,22.9905],[99.522,23.077],[99.384,23.102],[99.3445,23.1375],[99.249,23.08],[99.146,23.109],[99.103,23.0915],[99.0475,23.123],[99.058,23.165],[99.0025,23.163],[98.9225,23.1885],[98.8855,23.183],[98.931,23.269],[98.9385,23.314],[98.9195,23.355],[98.921,23.4205],[98.8755,23.4865],[98.829,23.4785],[98.8035,23.542],[98.891,23.6175],[98.8515,23.6345],[98.83,23.7285],[98.789,23.784],[98.698,23.787],[98.704,23.8445],[98.6785,23.913],[98.6785,23.9575],[98.754,23.983],[98.866,24.069],[98.897,24.1075],[98.887,24.143],[98.758,24.1275],[98.7165,24.1305],[98.679,24.102],[98.6175,24.091],[98.543,24.1315],[98.4175,24.122],[98.3595,24.099],[98.2225,24.117],[98.1975,24.102],[98.109,24.095],[98.0395,24.0735],[97.985,24.035],[97.901,24.0175],[97.84,23.9635],[97.7685,23.936],[97.7035,23.867],[97.631,23.8815],[97.528,23.9295],[97.5725,23.986],[97.6285,24.008],[97.632,24.038],[97.7285,24.1185],[97.7525,24.172],[97.7295,24.23],[97.768,24.263],[97.74,24.291],[97.6665,24.3],[97.661,24.339],[97.7135,24.3775],[97.6755,24.409],[97.6645,24.453],[97.532,24.4375],[97.556,24.4965],[97.571,24.6035],[97.568,24.7235],[97.547,24.742],[97.6515,24.7955],[97.707,24.8385],[97.772,24.831],[97.797,24.8515],[97.73,24.915],[97.72,25.0215],[97.779,25.126],[97.8395,25.2725],[97.8755,25.2615],[97.904,25.2185],[97.939,25.217],[98.0065,25.2805],[98.0705,25.315],[98.1365,25.386],[98.157,25.459],[98.155,25.5275],[98.205,25.62],[98.2645,25.601],[98.3025,25.552],[98.4095,25.611],[98.4175,25.673],[98.4605,25.6915],[98.475,25.783],[98.5315,25.8465],[98.6325,25.8],[98.708,25.86],[98.6815,25.9415],[98.619,25.975],[98.6035,26.0535],[98.573,26.122],[98.6305,26.151],[98.667,26.122],[98.7095,26.121],[98.736,26.19],[98.7115,26.2365],[98.672,26.2455],[98.682,26.31],[98.734,26.3545],[98.757,26.501],[98.754,26.5655],[98.782,26.606],[98.743,26.713],[98.7625,26.802],[98.731,26.8545],[98.758,26.8855],[98.7335,27.006],[98.7665,27.052],[98.712,27.078],[98.7135,27.143],[98.6915,27.2],[98.7295,27.25],[98.741,27.332],[98.7075,27.3645],[98.6845,27.4885],[98.7045,27.522],[98.6745,27.586],[98.647,27.5685],[98.5865,27.593],[98.5645,27.6405],[98.475,27.6375],[98.43,27.6585],[98.4305,27.5535],[98.3765,27.511],[98.317,27.523],[98.311,27.5865],[98.284,27.6565],[98.2345,27.6925],[98.227,27.7965],[98.1705,27.854],[98.206,27.892],[98.184,27.9435],[98.132,27.986],[98.1605,28.0895],[98.1385,28.1465],[98.097,28.167],[98.0765,28.2065],[98.0115,28.208],[98.0205,28.258],[97.909,28.3685],[97.8705,28.3675],[97.842,28.3285],[97.797,28.3295],[97.7785,28.3705],[97.7355,28.3985],[97.7375,28.466],[97.6635,28.5385],[97.612,28.5185],[97.566,28.5465],[97.502,28.495],[97.5235,28.447],[97.478,28.3795],[97.504,28.315],[97.425,28.298],[97.3955,28.2415],[97.346,28.2145],[97.361,28.1655],[97.3445,28.117],[97.3585,28.063],[97.3945,28.0185],[97.3675,27.977],[97.379,27.892],[97.36,27.873],[97.293,27.9135],[97.255,27.894],[97.1125,27.7695],[97.026,27.7355],[96.995,27.671],[96.9,27.6085],[96.9335,27.508],[96.9145,27.461],[97.002,27.3455],[97.088,27.245],[97.1015,27.2145],[97.1765,27.14],[97.1455,27.0925],[97.076,27.0955],[97.0105,27.145],[96.89,27.1765],[96.858,27.215],[96.855,27.267],[96.8295,27.312],[96.7765,27.356],[96.7155,27.376],[96.6765,27.3355],[96.606,27.363],[96.582,27.314],[96.5265,27.289],[96.4335,27.305],[96.4095,27.292],[96.314,27.2935],[96.091,27.2235],[96.022,27.18],[96.0075,27.14],[95.946,27.052],[95.831,27.008],[95.804,27.0155],[95.7555,26.951],[95.7555,26.91],[95.7135,26.883],[95.658,26.8915],[95.6095,26.814],[95.546,26.8295],[95.5035,26.8065],[95.485,26.7485],[95.4395,26.7025],[95.315,26.6645],[95.208,26.6475],[95.149,26.6155],[95.154,26.583],[95.1085,26.543],[95.114,26.518],[95.073,26.4725],[95.1325,26.3775],[95.1225,26.3065],[95.12,26.0995],[95.185,26.075],[95.1565,26.0195],[95.081,25.947],[95.029,25.935],[95.02,25.872],[95.0515,25.798],[95.038,25.74],[94.9405,25.672],[94.918,25.6145],[94.845,25.5605],[94.808,25.4955],[94.6865,25.466],[94.5855,25.268],[94.5775,25.216],[94.6035,25.1845],[94.7255,25.134],[94.745,25.063],[94.737,25.001],[94.697,24.961],[94.7135,24.93],[94.6845,24.882],[94.633,24.835],[94.6295,24.754],[94.607,24.711],[94.5465,24.707],[94.541,24.6425],[94.5095,24.5925],[94.4555,24.5695],[94.4085,24.44],[94.2605,24.164],[94.2555,24.081],[94.238,24.033],[94.169,23.9275],[94.156,23.847],[94.117,23.838],[94.095,23.8855],[94.0465,23.8925],[94.022,23.926],[93.9735,23.9235],[93.894,23.9515],[93.815,23.924],[93.7565,24.006],[93.7225,23.999],[93.6265,24.0115],[93.5945,23.962],[93.564,23.9785],[93.51,23.9465],[93.4655,23.972],[93.3985,24.0855],[93.344,24.092],[93.3255,24.0465],[93.352,23.947],[93.3925,23.924],[93.385,23.8765],[93.3945,23.754],[93.436,23.6875],[93.4175,23.6365],[93.4185,23.5415],[93.3975,23.5105],[93.388,23.4205],[93.4025,23.3895],[93.3555,23.3535],[93.3875,23.216],[93.3645,23.121],[93.32,23.029],[93.2945,23.008],[93.235,23.011],[93.2105,23.0475],[93.14,23.054],[93.123,23.0075],[93.146,22.9275],[93.0955,22.807],[93.1065,22.746],[93.092,22.7095],[93.108,22.6355],[93.141,22.594],[93.113,22.5595],[93.1315,22.468],[93.1855,22.428],[93.1855,22.339],[93.202,22.2645],[93.142,22.2445],[93.1575,22.187],[93.0715,22.2115],[93.0385,22.1955],[93.042,22.1365],[92.9895,22.061],[92.9225,21.994],[92.8655,22.0255],[92.8545,22.0595],[92.806,22.104],[92.7185,22.1595],[92.678,22.0995],[92.6795,22.027],[92.601,21.982],[92.6215,21.8755],[92.5995,21.7945],[92.5985,21.66],[92.618,21.4695],[92.643,21.408],[92.674,21.2835],[92.5945,21.2495],[92.564,21.372],[92.5175,21.3885],[92.475,21.3545],[92.4275,21.381],[92.425,21.433],[92.381,21.4795],[92.3425,21.4665],[92.3245,21.4195],[92.27,21.4305],[92.2585,21.363],[92.1975,21.328],[92.218,21.2355],[92.176,21.16],[92.2585,21.0775],[92.2535,21.021],[92.272,20.947],[92.34,20.819],[92.3715,20.7025],[92.343,20.649],[92.363,20.5895],[92.4285,20.565],[92.4245,20.4815],[92.3985,20.385],[92.424,20.365],[92.361,20.308],[92.3295,20.236],[92.3295,20.158],[92.361,20.086],[92.402,20.045],[92.861,19.6805],[93.0755,19.3055],[93.236,18.806],[93.283,18.7285],[93.7605,18.238],[94.1125,17.441],[94.188,16.674],[94.151,16.645],[94.0935,16.559],[94.0925,16.4885],[94.065,16.3335],[94.029,16.1985],[94.0105,16.058],[94.037,15.966],[94.0935,15.874],[94.159,15.841],[94.264,15.8375],[94.286,15.7565],[94.323,15.69],[94.4,15.6825],[94.4865,15.719],[94.528,15.7655],[94.7675,15.626],[94.915,15.565],[95.0475,15.5705],[95.195,15.5905],[95.287,15.567],[95.445,15.569],[95.5785,15.6335],[95.679,15.7125],[95.8275,15.8865],[95.886,16.0295],[95.998,16.1025],[96.0915,16.1335],[96.2125,16.2195],[96.386,16.3025],[96.49,16.3625],[96.6685,16.421],[96.792,16.5215],[96.8575,16.6485],[96.8595,16.6725],[96.921,16.7445],[96.9135,16.8465],[96.9665,16.912],[97.036,16.898],[97.0705,16.727],[97.1215,16.6125],[97.184,16.552],[97.1975,16.471],[97.2545,16.411],[97.2975,16.3985],[97.3095,16.2885],[97.3005,16.269],[97.3645,16.1555],[97.4155,16.086],[97.4015,16.017],[97.4075,15.965],[97.437,15.9015],[97.478,15.8525],[97.536,15.807],[97.531,15.7465],[97.5595,15.602],[97.562,15.467],[97.5725,15.393],[97.5445,15.3285],[97.555,15.23],[97.5855,15.156],[97.6235,15.098],[97.6275,15.03],[97.616,14.9035],[97.569,14.2635],[97.5755,14.148],[97.5535,13.5255],[97.5445,13.271],[97.524,12.699],[97.536,12.6245],[97.579,12.507],[97.4505,12.144],[97.2725,11.905],[97.238,11.8285],[97.2385,11.7445],[97.3105,11.425],[97.4905,10.6255],[97.477,10.4895],[97.485,10.411],[97.6755,9.8075],[97.7105,9.6395],[97.7245,9.6005],[97.8535,9.5815],[98.042,9.4835],[98.106,9.44],[98.1185,9.4415],[98.2175,9.5655],[98.275,9.7505],[98.3215,9.832],[98.3345,9.891],[98.3665,9.943],[98.471,9.9565],[98.519,9.926],[98.567,9.9435],[98.5795,9.9865],[98.6705,10.1705],[98.7075,10.231],[98.743,10.3245],[98.7555,10.393],[98.795,10.445],[98.817,10.4985],[98.81,10.5815],[98.774,10.6165],[98.7795,10.678],[98.8615,10.7785],[98.913,10.81],[98.959,10.812],[99.0115,10.8565],[98.9975,10.911],[99.024,10.9705],[99.077,10.954],[99.104,11.013],[99.1585,11.034],[99.19,11.084],[99.229,11.113],[99.2635,11.215],[99.3245,11.282],[99.3125,11.3165],[99.367,11.3725],[99.402,11.3885],[99.3935,11.461],[99.4405,11.4795],[99.4745,11.533],[99.4675,11.615],[99.5165,11.637],[99.5655,11.6265],[99.5835,11.6795],[99.638,11.7325],[99.659,11.829],[99.625,11.8315],[99.58,11.9065],[99.592,11.9925],[99.538,12.014],[99.534,12.0655],[99.5705,12.145],[99.515,12.1475],[99.4715,12.2345],[99.434,12.343],[99.442,12.4005],[99.401,12.46],[99.4355,12.566],[99.4125,12.6155],[99.348,12.6395],[99.2945,12.678],[99.2895,12.715],[99.2325,12.74],[99.218,12.8285],[99.1885,12.847],[99.1725,12.943],[99.18,12.9935],[99.0995,13.0725],[99.1275,13.103],[99.139,13.2055],[99.2105,13.2075],[99.187,13.291],[99.207,13.3805],[99.1725,13.563],[99.167,13.726],[99.1215,13.7735],[99.077,13.895],[99.021,13.9455],[98.9985,14.0195],[98.972,14.033],[98.968,14.0825],[98.8785,14.1235],[98.835,14.172],[98.756,14.2145],[98.631,14.316],[98.597,14.3275],[98.5495,14.4345],[98.524,14.4555],[98.487,14.536],[98.436,14.6085],[98.3235,14.7105],[98.2945,14.77],[98.246,14.831],[98.257,14.8635],[98.2335,14.9665],[98.2085,14.9805],[98.2315,15.0445],[98.1835,15.0965],[98.2125,15.178],[98.198,15.2345],[98.252,15.225],[98.306,15.3135],[98.394,15.2625],[98.4175,15.2665],[98.3945,15.3425],[98.471,15.371],[98.4895,15.3935],[98.5375,15.371],[98.5805,15.3755],[98.5855,15.471],[98.553,15.6015],[98.5485,15.685],[98.577,15.8],[98.609,15.8735],[98.584,15.9185],[98.6085,15.9725],[98.5605,16.034],[98.599,16.0735],[98.625,16.0425],[98.7,16.136],[98.8055,16.1045],[98.8515,16.1365],[98.852,16.214],[98.9035,16.2545],[98.9315,16.329],[98.9135,16.393],[98.8825,16.4225],[98.8285,16.4135],[98.817,16.385],[98.7355,16.338],[98.676,16.2805],[98.6575,16.3785],[98.637,16.4255],[98.658,16.455],[98.579,16.557],[98.574,16.6205],[98.5115,16.649],[98.5115,16.701],[98.464,16.7325],[98.4855,16.7895],[98.536,16.8295],[98.5345,16.873],[98.49,16.9685],[98.4375,17.037],[98.3935,17.059],[98.347,17.048],[98.2795,17.1155],[98.2875,17.1565],[98.248,17.2085],[98.1755,17.2585],[98.113,17.319],[98.1105,17.3855],[98.083,17.3905],[98.0575,17.438],[97.9925,17.51],[97.923,17.5395],[97.9065,17.5835],[97.794,17.6795],[97.718,17.8195],[97.672,17.8825],[97.6875,17.925],[97.7315,17.9525],[97.7365,17.9865],[97.677,18.115],[97.676,18.1615],[97.6135,18.225],[97.6395,18.2875],[97.62,18.318],[97.551,18.334],[97.5365,18.286],[97.502,18.2675],[97.444,18.3405],[97.452,18.39],[97.4265,18.408],[97.387,18.5055],[97.346,18.546],[97.393,18.561],[97.426,18.5465],[97.444,18.495],[97.4905,18.51],[97.535,18.491],[97.5495,18.531],[97.605,18.537],[97.6505,18.577],[97.768,18.578],[97.774,18.689],[97.739,18.8285],[97.737,18.887],[97.697,18.9045],[97.6905,18.9485],[97.7385,18.9785],[97.736,19.0405],[97.77,19.0735],[97.8355,19.093],[97.8415,19.225],[97.822,19.329],[97.792,19.395],[97.876,19.5065],[97.8555,19.531],[97.8635,19.577],[97.975,19.602],[97.983,19.6405],[98.026,19.6375],[98.0245,19.722],[98.036,19.801],[98.0835,19.81],[98.1355,19.788],[98.238,19.708],[98.2485,19.6765],[98.3205,19.697],[98.3715,19.69],[98.474,19.695],[98.519,19.715],[98.608,19.709],[98.6725,19.752],[98.7775,19.752],[98.83,19.796],[98.9315,19.774],[98.9845,19.739],[99.034,19.8555],[99.0235,19.9195],[99.045,19.9485],[99.044,20.0355],[99.077,20.101],[99.1085,20.098],[99.159,20.133],[99.242,20.114],[99.3445,20.105],[99.4,20.086],[99.499,20.118],[99.5375,20.147],[99.5625,20.207],[99.523,20.233],[99.507,20.326],[99.4555,20.363],[99.472,20.394],[99.5195,20.3615],[99.6115,20.3325],[99.647,20.3415],[99.6815,20.316],[99.73,20.35],[99.81,20.3365],[99.862,20.4435],[99.9655,20.4625],[99.9905,20.4235],[100.047,20.3915],[100.0845,20.3525]]],[[[93.239,13.7725],[93.2945,13.7845],[93.369,13.8375],[93.504,13.888],[93.5595,13.977],[93.5825,14.101],[93.5645,14.2455],[93.5415,14.313],[93.504,14.3455],[93.4205,14.3805],[93.3305,14.388],[93.2565,14.367],[93.2085,14.3295],[93.165,14.226],[93.098,14.175],[93.0455,14.1185],[93.0245,14.0735],[93.0115,13.948],[93.035,13.882],[93.1345,13.8195],[93.239,13.7725]]],[[[93.341,14.811],[93.364,14.697],[93.3945,14.644],[93.43,14.6165],[93.515,14.587],[93.6115,14.5945],[93.6635,14.612],[93.7545,14.6735],[93.806,14.7565],[93.849,14.853],[93.86,14.92],[93.84,15.021],[93.8015,15.077],[93.7255,15.1135],[93.654,15.1295],[93.589,15.1285],[93.5355,15.107],[93.4785,15.0615],[93.452,14.9945],[93.384,14.9345],[93.357,14.885],[93.341,14.811]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/8c/Flag_of_Myanmar.svg","name:en":"Myanmar","wikidata":"Q836","ISO3166-1:alpha2":"MM","ISO3166-1:alpha3":"MMR","ISO3166-1:numeric":"104"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[131.0685,3.007],[131.1135,2.949],[131.1695,2.974],[131.1825,3.027],[131.163,3.057],[131.108,3.064],[131.0685,3.007]]],[[[131.6735,2.822],[131.6805,2.788],[131.723,2.752],[131.788,2.755],[131.854,2.815],[131.8945,2.935],[131.865,3.032],[131.8,3.061],[131.7585,3.028],[131.7405,2.981],[131.695,2.931],[131.6735,2.822]]],[[[131.8965,4.668],[131.9035,4.64],[131.9745,4.611],[132.0155,4.641],[132.0145,4.702],[131.9905,4.727],[131.938,4.729],[131.8965,4.668]]],[[[132.168,5.33],[132.182,5.29],[132.2275,5.268],[132.258,5.279],[132.2805,5.358],[132.2555,5.401],[132.217,5.407],[132.183,5.384],[132.168,5.33]]],[[[132.258,4.314],[132.2875,4.263],[132.358,4.285],[132.3625,4.336],[132.3235,4.373],[132.276,4.359],[132.258,4.314]]],[[[134.0715,6.89],[134.1135,6.84],[134.189,6.872],[134.2015,6.929],[134.253,6.932],[134.332,6.999],[134.3485,7.037],[134.4095,7.084],[134.4345,7.126],[134.4445,7.201],[134.486,7.216],[134.502,7.252],[134.613,7.308],[134.6365,7.333],[134.6415,7.407],[134.679,7.461],[134.697,7.635],[134.694,7.713],[134.6615,7.789],[134.6215,7.809],[134.569,7.772],[134.5585,7.668],[134.5055,7.637],[134.4635,7.572],[134.4135,7.458],[134.4215,7.418],[134.385,7.391],[134.361,7.323],[134.2805,7.34],[134.235,7.31],[134.251,7.24],[134.1985,7.23],[134.178,7.193],[134.1765,7.128],[134.2035,7.059],[134.175,7.026],[134.1695,6.982],[134.1145,6.971],[134.076,6.936],[134.0715,6.89]]],[[[134.5915,8.172],[134.623,8.124],[134.6625,8.124],[134.6935,8.166],[134.6625,8.218],[134.6225,8.218],[134.5915,8.172]]],[[[134.643,8.04],[134.6835,7.991],[134.7315,8.001],[134.756,8.031],[134.7705,8.095],[134.7295,8.142],[134.676,8.126],[134.643,8.04]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/48/Flag_of_Palau.svg","name:en":"Palau","wikidata":"Q695","ISO3166-1:alpha2":"PW","ISO3166-1:alpha3":"PLW","ISO3166-1:numeric":"585"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[160.595,9.848],[160.611,9.766],[160.6505,9.706],[160.698,9.669],[160.8055,9.627],[160.861,9.592],[160.9825,9.566],[161.0535,9.577],[161.139,9.633],[161.19,9.738],[161.1895,9.816],[161.1425,9.915],[161.0935,9.962],[160.9875,10.033],[160.8785,10.064],[160.797,10.064],[160.743,10.045],[160.65,9.982],[160.614,9.93],[160.595,9.848]]],[[[161.884,11.455],[161.8955,11.391],[161.9215,11.341],[162.0355,11.212],[162.1215,11.165],[162.2,11.145],[162.315,11.136],[162.4045,11.153],[162.503,11.227],[162.55,11.298],[162.587,11.397],[162.595,11.463],[162.5875,11.535],[162.5025,11.719],[162.467,11.763],[162.335,11.848],[162.2895,11.864],[162.1915,11.876],[162.1165,11.861],[162.019,11.801],[161.968,11.747],[161.942,11.683],[161.942,11.597],[161.8985,11.531],[161.884,11.455]]],[[[165.015,11.577],[165.024,11.517],[165.063,11.446],[165.17,11.359],[165.298,11.3],[165.369,11.296],[165.493,11.325],[165.5655,11.314],[165.656,11.336],[165.7265,11.393],[165.7575,11.444],[165.7745,11.534],[165.7505,11.684],[165.6965,11.771],[165.623,11.819],[165.469,11.892],[165.258,11.903],[165.156,11.862],[165.113,11.831],[165.0715,11.776],[165.015,11.577]]],[[[165.3195,9.217],[165.3385,9.133],[165.3855,9.062],[165.3885,9.012],[165.441,8.909],[165.525,8.853],[165.5805,8.796],[165.7,8.735],[165.7835,8.727],[165.879,8.762],[165.9395,8.825],[165.9615,8.873],[165.9695,8.945],[165.936,9.043],[165.8775,9.136],[165.8295,9.235],[165.7965,9.28],[165.6545,9.374],[165.5885,9.41],[165.528,9.42],[165.456,9.409],[165.4035,9.382],[165.3525,9.329],[165.326,9.269],[165.3195,9.217]]],[[[165.7175,10.182],[165.752,10.042],[165.8065,9.94],[165.8605,9.883],[165.9215,9.842],[165.9835,9.82],[166.094,9.827],[166.176,9.88],[166.223,9.962],[166.2305,10.06],[166.217,10.116],[166.216,10.212],[166.1845,10.287],[166.141,10.333],[166.048,10.373],[165.9005,10.38],[165.817,10.353],[165.751,10.291],[165.7175,10.182]]],[[[166.0135,8.958],[166.0155,8.904],[166.039,8.826],[166.109,8.751],[166.2025,8.719],[166.28,8.72],[166.359,8.74],[166.433,8.797],[166.471,8.871],[166.4775,8.931],[166.456,9.013],[166.39,9.099],[166.297,9.15],[166.1815,9.157],[166.109,9.127],[166.06,9.085],[166.029,9.034],[166.0135,8.958]]],[[[166.084,11.144],[166.0965,11.074],[166.119,11.03],[166.1835,10.97],[166.2975,10.928],[166.377,10.917],[166.514,10.916],[166.6245,10.946],[166.676,10.983],[166.823,10.95],[166.9535,10.964],[167.0085,10.99],[167.0595,11.038],[167.0995,11.131],[167.1035,11.185],[167.189,11.266],[167.2385,11.214],[167.293,11.185],[167.384,11.111],[167.4435,11.096],[167.539,11.107],[167.6065,11.144],[167.646,11.185],[167.71,11.303],[167.725,11.359],[167.71,11.461],[167.678,11.512],[167.6105,11.567],[167.529,11.601],[167.412,11.607],[167.2785,11.572],[167.2415,11.551],[167.192,11.619],[167.093,11.669],[166.969,11.658],[166.9035,11.683],[166.84,11.686],[166.7445,11.665],[166.691,11.672],[166.6135,11.661],[166.52,11.596],[166.4705,11.492],[166.4655,11.449],[166.4265,11.371],[166.4045,11.362],[166.2955,11.379],[166.2225,11.368],[166.148,11.323],[166.1135,11.28],[166.0885,11.216],[166.084,11.144]]],[[[166.614,9.328],[166.6375,9.237],[166.707,9.16],[166.857,9.09],[166.9755,9.072],[167.0035,9.024],[167.0495,8.982],[167.185,8.914],[167.2585,8.895],[167.368,8.906],[167.3775,8.807],[167.4025,8.747],[167.454,8.674],[167.5825,8.561],[167.704,8.517],[167.803,8.529],[167.8775,8.575],[167.9155,8.621],[167.9445,8.707],[167.943,8.78],[167.976,8.875],[167.965,8.973],[167.944,9.014],[167.945,9.076],[167.917,9.172],[167.888,9.223],[167.838,9.268],[167.741,9.3],[167.728,9.358],[167.6635,9.492],[167.625,9.542],[167.537,9.592],[167.4305,9.599],[167.354,9.569],[167.274,9.507],[167.1375,9.544],[166.91,9.52],[166.8425,9.531],[166.759,9.523],[166.6645,9.463],[166.6285,9.404],[166.614,9.328]]],[[[167.17,8.316],[167.182,8.2355],[167.226,8.1765],[167.2985,8.1185],[167.387,8.1065],[167.446,8.1115],[167.5535,8.1845],[167.5835,8.2675],[167.582,8.347],[167.5615,8.414],[167.52,8.469],[167.464,8.501],[167.363,8.518],[167.3015,8.503],[167.2445,8.472],[167.185,8.405],[167.17,8.316]]],[[[167.77,8.199],[167.779,8.137],[167.8465,8.019],[167.9075,7.959],[167.9555,7.937],[168.0225,7.878],[168.009,7.794],[168.0205,7.72],[168.0585,7.648],[168.108,7.599],[168.201,7.557],[168.2685,7.554],[168.361,7.584],[168.444,7.657],[168.5055,7.789],[168.5065,7.859],[168.49,7.913],[168.424,8.035],[168.383,8.082],[168.3875,8.184],[168.3575,8.263],[168.275,8.34],[168.2135,8.361],[168.1245,8.359],[168.084,8.378],[167.9695,8.4],[167.8725,8.374],[167.822,8.334],[167.785,8.275],[167.77,8.199]]],[[[167.887,5.639],[167.911,5.525],[167.952,5.459],[168.026,5.408],[168.0915,5.392],[168.1645,5.396],[168.227,5.422],[168.274,5.462],[168.3095,5.52],[168.331,5.59],[168.334,5.662],[168.303,5.744],[168.253,5.796],[168.2115,5.819],[168.1125,5.839],[168.0535,5.837],[167.976,5.806],[167.9145,5.741],[167.887,5.639]]],[[[168.344,7.442],[168.369,7.32],[168.4145,7.245],[168.4875,7.183],[168.624,7.107],[168.7255,7.081],[168.859,7.076],[168.9235,7.099],[168.969,7.134],[169.061,7.272],[169.077,7.323],[169.118,7.385],[169.168,7.538],[169.1605,7.662],[169.182,7.752],[169.1655,7.834],[169.138,7.88],[169.0455,7.945],[168.972,7.956],[168.8825,7.934],[168.8195,7.884],[168.786,7.827],[168.7725,7.726],[168.655,7.685],[168.5535,7.682],[168.494,7.658],[168.413,7.6],[168.358,7.518],[168.344,7.442]]],[[[168.4445,4.638],[168.463,4.554],[168.551,4.435],[168.6105,4.395],[168.664,4.378],[168.7305,4.375],[168.844,4.415],[168.9275,4.486],[168.9525,4.527],[168.972,4.603],[168.9595,4.721],[168.9165,4.801],[168.868,4.845],[168.7795,4.876],[168.667,4.88],[168.553,4.837],[168.4805,4.756],[168.4555,4.704],[168.4445,4.638]]],[[[168.731,14.568],[168.7645,14.457],[168.8545,14.383],[168.96,14.367],[169.0225,14.383],[169.1295,14.45],[169.182,14.504],[169.2165,14.579],[169.2235,14.667],[169.195,14.763],[169.1135,14.845],[169.029,14.872],[168.924,14.856],[168.8435,14.796],[168.804,14.719],[168.7595,14.667],[168.731,14.568]]],[[[168.786,10.052],[168.8095,9.955],[168.8105,9.869],[168.852,9.785],[168.916,9.733],[168.9755,9.663],[169.041,9.623],[169.1005,9.605],[169.2085,9.606],[169.2545,9.621],[169.3405,9.623],[169.4185,9.652],[169.471,9.695],[169.5115,9.77],[169.5135,9.877],[169.625,9.902],[169.686,9.953],[169.7235,10.028],[169.73,10.086],[169.8405,10.038],[169.9765,10.015],[170.018,10.018],[170.101,10.052],[170.164,10.121],[170.188,10.189],[170.19,10.265],[170.168,10.473],[170.1305,10.562],[170.0615,10.636],[169.968,10.669],[169.899,10.665],[169.8225,10.63],[169.7605,10.556],[169.738,10.454],[169.669,10.365],[169.6565,10.269],[169.642,10.246],[169.586,10.273],[169.502,10.281],[169.395,10.238],[169.3415,10.173],[169.3195,10.098],[169.2755,10.118],[169.189,10.199],[169.144,10.218],[169.0115,10.251],[168.955,10.249],[168.8645,10.209],[168.8165,10.156],[168.786,10.052]]],[[[168.9125,5.64],[168.922,5.58],[168.974,5.496],[169.048,5.451],[169.1235,5.44],[169.1865,5.451],[169.2715,5.505],[169.323,5.591],[169.3295,5.675],[169.2805,5.781],[169.197,5.837],[169.131,5.849],[169.031,5.825],[168.97,5.781],[168.9265,5.714],[168.9125,5.64]]],[[[169.205,6.266],[169.2265,6.17],[169.2565,6.124],[169.2215,5.948],[169.236,5.878],[169.2715,5.82],[169.3415,5.768],[169.3905,5.698],[169.4595,5.639],[169.559,5.592],[169.6275,5.588],[169.7085,5.614],[169.752,5.648],[169.8035,5.733],[169.819,5.803],[169.8605,5.837],[169.9035,5.903],[169.9205,5.959],[169.9225,6.051],[169.871,6.153],[169.7715,6.233],[169.7255,6.286],[169.665,6.382],[169.5785,6.467],[169.5275,6.492],[169.4255,6.506],[169.3095,6.465],[169.253,6.418],[169.223,6.368],[169.205,6.266]]],[[[169.346,11.197],[169.3595,11.127],[169.416,11.047],[169.4485,10.972],[169.5185,10.91],[169.5745,10.887],[169.637,10.88],[169.7215,10.899],[169.8155,10.972],[169.848,11.017],[169.964,11.052],[170.023,11.105],[170.059,11.18],[170.063,11.252],[170.0205,11.353],[169.931,11.457],[169.888,11.489],[169.808,11.514],[169.7315,11.508],[169.647,11.462],[169.599,11.397],[169.5295,11.398],[169.455,11.376],[169.3775,11.305],[169.346,11.197]]],[[[169.623,9.529],[169.6395,9.449],[169.71,9.363],[169.7215,9.277],[169.701,9.187],[169.73,9.085],[169.7745,9.034],[169.8375,8.988],[169.8635,8.919],[169.8935,8.88],[169.952,8.838],[170.008,8.818],[170.096,8.812],[170.15,8.825],[170.207,8.858],[170.286,8.962],[170.3055,9.032],[170.297,9.146],[170.2755,9.193],[170.3575,9.248],[170.401,9.308],[170.445,9.427],[170.436,9.525],[170.3945,9.596],[170.2855,9.706],[170.187,9.752],[170.0905,9.747],[170.0355,9.722],[169.8,9.729],[169.7215,9.7],[169.643,9.615],[169.623,9.529]]],[[[169.9,12.195],[169.9115,12.125],[169.9695,12.038],[170.055,11.992],[170.1465,11.988],[170.235,12.026],[170.292,12.092],[170.331,12.17],[170.349,12.258],[170.3375,12.318],[170.2955,12.387],[170.198,12.445],[170.121,12.451],[170.059,12.435],[169.985,12.384],[169.915,12.267],[169.9,12.195]]],[[[170.6375,8.904],[170.642,8.86],[170.6915,8.686],[170.7505,8.595],[170.819,8.546],[170.867,8.474],[170.8375,8.383],[170.8405,8.327],[170.8135,8.226],[170.822,8.17],[170.8565,8.104],[170.892,8.069],[171.0855,7.955],[171.137,7.937],[171.2235,7.938],[171.321,7.991],[171.3665,8.06],[171.381,8.126],[171.3605,8.25],[171.3685,8.33],[171.3575,8.377],[171.382,8.42],[171.397,8.514],[171.387,8.564],[171.43,8.643],[171.4385,8.731],[171.4055,8.82],[171.324,8.908],[171.26,8.954],[171.1905,9.022],[171.136,9.053],[170.993,9.095],[170.886,9.106],[170.758,9.086],[170.706,9.053],[170.6525,8.978],[170.6375,8.904]]],[[[170.6595,10.276],[170.6885,10.168],[170.7345,10.115],[170.778,10.088],[170.875,10.068],[170.939,10.079],[171.0245,10.134],[171.0635,10.196],[171.0805,10.268],[171.079,10.326],[171.051,10.402],[170.9765,10.473],[170.9115,10.496],[170.852,10.498],[170.7885,10.481],[170.7145,10.426],[170.675,10.362],[170.6595,10.276]]],[[[170.8255,7.146],[170.839,7.074],[170.9115,6.978],[171.015,6.917],[171.1615,6.864],[171.2535,6.854],[171.4265,6.89],[171.522,6.814],[171.622,6.793],[171.6835,6.766],[171.7585,6.757],[171.809,6.764],[171.8825,6.801],[171.9465,6.888],[172.016,6.916],[172.0735,6.967],[172.125,7.051],[172.1375,7.127],[172.1275,7.183],[172.0935,7.246],[172.034,7.298],[171.9435,7.33],[171.858,7.322],[171.8095,7.42],[171.756,7.462],[171.6935,7.484],[171.609,7.486],[171.558,7.47],[171.4995,7.429],[171.4665,7.385],[171.4395,7.31],[171.3375,7.344],[171.224,7.36],[171.165,7.401],[171.0865,7.421],[170.983,7.406],[170.9195,7.365],[170.8695,7.299],[170.835,7.208],[170.8255,7.146]]],[[[171.515,6.203],[171.5275,6.121],[171.5275,6.039],[171.543,5.993],[171.5835,5.936],[171.6415,5.896],[171.7285,5.856],[171.7895,5.84],[171.872,5.846],[171.955,5.832],[172.024,5.738],[172.1,5.689],[172.166,5.677],[172.259,5.697],[172.321,5.743],[172.371,5.847],[172.3585,5.967],[172.3145,6.041],[172.293,6.215],[172.248,6.326],[172.1905,6.385],[172.1355,6.411],[172.041,6.42],[171.9855,6.447],[171.895,6.458],[171.6515,6.404],[171.566,6.345],[171.5215,6.261],[171.515,6.203]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/2e/Flag_of_the_Marshall_Islands.svg","name:en":"Marshall Islands","wikidata":"Q709","ISO3166-1:alpha2":"MH","ISO3166-1:alpha3":"MHL","ISO3166-1:numeric":"584"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-62.6405,-22.236],[-62.63,-22.303],[-62.571,-22.327],[-62.51,-22.3805],[-62.4655,-22.383],[-62.4505,-22.4195],[-62.336,-22.4815],[-62.2875,-22.4775],[-62.2815,-22.5245],[-62.228,-22.5445],[-62.2545,-22.6115],[-62.2025,-22.6705],[-62.1985,-22.706],[-62.158,-22.76],[-62.099,-22.806],[-62.036,-22.8785],[-61.997,-22.9485],[-61.9975,-23.0075],[-61.85,-23.1045],[-61.7905,-23.1645],[-61.753,-23.173],[-61.736,-23.2345],[-61.627,-23.2775],[-61.5235,-23.3675],[-61.501,-23.4105],[-61.445,-23.42],[-61.417,-23.4485],[-61.3255,-23.4665],[-61.2195,-23.5575],[-61.1735,-23.5605],[-61.096,-23.613],[-61.0805,-23.691],[-61.0125,-23.7615],[-60.99,-23.818],[-60.9215,-23.823],[-60.8595,-23.8695],[-60.732,-23.872],[-60.7095,-23.892],[-60.595,-23.9175],[-60.572,-23.96],[-60.4875,-23.951],[-60.436,-23.9665],[-60.309,-24.038],[-60.197,-24.045],[-60.039,-24.0115],[-59.7555,-24.1705],[-59.4745,-24.3315],[-59.4215,-24.409],[-59.373,-24.423],[-59.354,-24.478],[-59.239,-24.5465],[-59.186,-24.5635],[-59.13,-24.617],[-59.0565,-24.6315],[-59.0235,-24.66],[-58.9705,-24.663],[-58.8785,-24.7335],[-58.804,-24.7735],[-58.726,-24.7745],[-58.6725,-24.832],[-58.573,-24.821],[-58.4405,-24.8795],[-58.393,-24.9515],[-58.341,-24.9965],[-58.236,-24.927],[-58.194,-24.968],[-58.153,-24.973],[-58.1345,-25.01],[-58.077,-25.038],[-58.0105,-25.038],[-57.9885,-25.0815],[-57.8825,-25.076],[-57.8215,-25.142],[-57.7765,-25.1555],[-57.752,-25.2275],[-57.695,-25.2885],[-57.6985,-25.3165],[-57.6365,-25.3855],[-57.601,-25.398],[-57.555,-25.4485],[-57.5795,-25.569],[-57.6085,-25.6065],[-57.677,-25.6055],[-57.6705,-25.6505],[-57.7405,-25.6505],[-57.7675,-25.6995],[-57.733,-25.725],[-57.774,-25.758],[-57.8275,-25.759],[-57.7965,-25.825],[-57.8585,-25.858],[-57.842,-25.921],[-57.8935,-25.964],[-57.8555,-26.009],[-57.926,-26.037],[-57.9495,-26.0675],[-58.0415,-26.1125],[-58.0845,-26.112],[-58.1195,-26.1525],[-58.1065,-26.2375],[-58.158,-26.2605],[-58.1655,-26.3575],[-58.2105,-26.3775],[-58.2235,-26.4635],[-58.2085,-26.505],[-58.2225,-26.5425],[-58.193,-26.5945],[-58.197,-26.6535],[-58.2635,-26.6515],[-58.246,-26.7425],[-58.282,-26.7915],[-58.337,-26.817],[-58.325,-26.8695],[-58.4935,-26.94],[-58.4685,-26.9865],[-58.5195,-27.004],[-58.555,-27.058],[-58.555,-27.109],[-58.6315,-27.115],[-58.6625,-27.1625],[-58.6565,-27.192],[-58.5925,-27.23],[-58.599,-27.3],[-58.489,-27.2735],[-58.4135,-27.2865],[-58.3035,-27.274],[-58.26,-27.257],[-58.198,-27.2735],[-58.0595,-27.2625],[-57.9145,-27.2655],[-57.8775,-27.2785],[-57.8145,-27.334],[-57.702,-27.3245],[-57.667,-27.356],[-57.4875,-27.444],[-57.4125,-27.425],[-57.3115,-27.418],[-57.232,-27.4665],[-57.1425,-27.4835],[-57.0425,-27.481],[-56.9655,-27.502],[-56.942,-27.5585],[-56.8495,-27.6065],[-56.796,-27.587],[-56.747,-27.605],[-56.689,-27.579],[-56.6765,-27.5505],[-56.721,-27.468],[-56.6495,-27.4605],[-56.6065,-27.4315],[-56.542,-27.4385],[-56.463,-27.5695],[-56.401,-27.599],[-56.3565,-27.567],[-56.339,-27.5245],[-56.2935,-27.494],[-56.2945,-27.42],[-56.243,-27.4045],[-56.176,-27.3435],[-56.0875,-27.3085],[-56.037,-27.3125],[-55.9845,-27.353],[-55.8965,-27.3425],[-55.8395,-27.407],[-55.787,-27.4405],[-55.737,-27.445],[-55.675,-27.373],[-55.599,-27.3375],[-55.6005,-27.279],[-55.581,-27.235],[-55.6155,-27.21],[-55.5745,-27.169],[-55.549,-27.098],[-55.481,-27.1115],[-55.423,-26.9955],[-55.3705,-26.9645],[-55.306,-26.9625],[-55.238,-26.9425],[-55.195,-26.9685],[-55.135,-26.9485],[-55.1435,-26.8685],[-55.0525,-26.7975],[-54.9635,-26.7875],[-54.9485,-26.702],[-54.9165,-26.6685],[-54.86,-26.656],[-54.8125,-26.668],[-54.7845,-26.605],[-54.807,-26.554],[-54.7815,-26.51],[-54.7155,-26.4595],[-54.698,-26.382],[-54.649,-26.312],[-54.6795,-26.2645],[-54.6185,-26.209],[-54.6695,-26.164],[-54.647,-26.075],[-54.677,-26.017],[-54.655,-25.979],[-54.6085,-25.955],[-54.6225,-25.9145],[-54.5915,-25.818],[-54.6225,-25.7835],[-54.658,-25.6875],[-54.6495,-25.6635],[-54.581,-25.658],[-54.5935,-25.593],[-54.602,-25.4855],[-54.6185,-25.4515],[-54.5835,-25.3955],[-54.499,-25.313],[-54.4275,-25.1505],[-54.4555,-25.0975],[-54.4355,-24.9475],[-54.3955,-24.803],[-54.3245,-24.6605],[-54.3175,-24.5815],[-54.336,-24.515],[-54.3215,-24.4545],[-54.2605,-24.3705],[-54.277,-24.2965],[-54.3155,-24.258],[-54.3455,-24.147],[-54.282,-24.0735],[-54.325,-24.021],[-54.415,-23.958],[-54.44,-23.9045],[-54.515,-23.885],[-54.589,-23.839],[-54.6685,-23.8175],[-54.7055,-23.8645],[-54.7935,-23.868],[-54.8595,-23.905],[-54.927,-23.9245],[-54.9275,-23.9615],[-54.999,-23.9575],[-55.0625,-23.993],[-55.1295,-23.984],[-55.229,-24.014],[-55.3175,-23.963],[-55.336,-23.993],[-55.4195,-23.9575],[-55.4465,-23.917],[-55.43,-23.79],[-55.464,-23.712],[-55.475,-23.6505],[-55.5305,-23.628],[-55.527,-23.5675],[-55.5465,-23.5225],[-55.5445,-23.4485],[-55.5045,-23.379],[-55.556,-23.3165],[-55.542,-23.227],[-55.5235,-23.1985],[-55.542,-23.156],[-55.596,-23.1195],[-55.634,-22.992],[-55.6655,-22.852],[-55.651,-22.7925],[-55.62,-22.765],[-55.6135,-22.694],[-55.6255,-22.628],[-55.7235,-22.552],[-55.753,-22.4755],[-55.735,-22.459],[-55.749,-22.3835],[-55.7895,-22.3845],[-55.853,-22.2805],[-55.9695,-22.292],[-56.1235,-22.2715],[-56.2135,-22.2755],[-56.243,-22.2355],[-56.316,-22.218],[-56.3575,-22.176],[-56.368,-22.137],[-56.419,-22.0795],[-56.4715,-22.08],[-56.517,-22.108],[-56.5565,-22.195],[-56.61,-22.223],[-56.638,-22.258],[-56.7055,-22.2365],[-56.7445,-22.241],[-56.8445,-22.3005],[-56.8835,-22.2475],[-56.946,-22.256],[-57.0605,-22.2305],[-57.1785,-22.233],[-57.237,-22.251],[-57.304,-22.224],[-57.362,-22.234],[-57.389,-22.205],[-57.4835,-22.1925],[-57.5205,-22.1695],[-57.5805,-22.1755],[-57.5865,-22.145],[-57.637,-22.106],[-57.6895,-22.0885],[-57.733,-22.0995],[-57.8005,-22.1505],[-57.93,-22.119],[-58.009,-22.0395],[-57.974,-22.0155],[-57.9165,-21.8765],[-57.93,-21.823],[-57.9085,-21.773],[-57.946,-21.741],[-57.896,-21.7045],[-57.941,-21.6355],[-57.9205,-21.581],[-57.9685,-21.529],[-57.9275,-21.4705],[-57.9095,-21.4065],[-57.8525,-21.32],[-57.92,-21.2765],[-57.8515,-21.2245],[-57.8645,-21.14],[-57.8465,-21.098],[-57.867,-21.04],[-57.8165,-20.9795],[-57.8815,-20.914],[-57.927,-20.893],[-57.856,-20.848],[-57.935,-20.7455],[-57.87,-20.7255],[-57.9155,-20.6685],[-57.9515,-20.702],[-57.988,-20.6845],[-57.9705,-20.6425],[-58.0135,-20.6055],[-57.995,-20.5615],[-58.016,-20.527],[-57.9965,-20.448],[-58.022,-20.4005],[-58.075,-20.3865],[-58.1025,-20.3225],[-58.0915,-20.26],[-58.1435,-20.272],[-58.166,-20.231],[-58.128,-20.183],[-58.1695,-20.167],[-58.138,-20.124],[-58.1655,-20.0645],[-58.197,-19.925],[-58.202,-19.8625],[-58.164,-19.827],[-58.236,-19.775],[-58.6965,-19.5055],[-59.069,-19.2875],[-59.5,-19.291],[-59.978,-19.2945],[-60.6045,-19.4565],[-60.9985,-19.519],[-61.735,-19.6345],[-61.9225,-20.089],[-62.2665,-20.563],[-62.258,-20.9895],[-62.261,-21.0585],[-62.458,-21.6725],[-62.6405,-22.236]],[[-57.593,-27.392],[-57.4885,-27.406],[-57.4925,-27.4385],[-57.593,-27.392]],[[-57.032,-27.481],[-56.9225,-27.4225],[-56.885,-27.4245],[-56.77,-27.502],[-56.726,-27.5125],[-56.749,-27.5615],[-56.833,-27.596],[-56.8735,-27.5815],[-56.911,-27.5315],[-56.967,-27.495],[-57.032,-27.481]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/27/Flag_of_Paraguay.svg","name:en":"Paraguay","wikidata":"Q733","ISO3166-1:alpha2":"PY","ISO3166-1:alpha3":"PRY","ISO3166-1:numeric":"600"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-81.3445,-3.392],[-81.5445,-3.392],[-84.4395,-3.392],[-84.527,-3.7375],[-84.578,-4.017],[-84.615,-4.31],[-84.634,-4.5795],[-84.6355,-4.7015],[-84.628,-4.9155],[-84.607,-5.129],[-84.572,-5.3405],[-84.4945,-5.7045],[-84.467,-6.031],[-84.4615,-6.1715],[-84.4425,-6.386],[-84.4195,-6.546],[-84.377,-6.757],[-84.3205,-6.965],[-84.2585,-7.1515],[-84.1775,-7.354],[-84.0835,-7.551],[-83.9585,-7.7775],[-83.897,-7.983],[-83.823,-8.1855],[-83.7005,-8.453],[-83.5995,-8.639],[-83.486,-8.8185],[-83.362,-8.9905],[-83.2265,-9.154],[-83.081,-9.309],[-82.9255,-9.454],[-82.831,-9.534],[-82.6615,-9.6645],[-82.4835,-9.7835],[-82.298,-9.8915],[-82.1055,-9.987],[-82.0045,-10.0315],[-81.9635,-10.077],[-81.8655,-10.2575],[-81.7255,-10.4755],[-81.642,-10.6405],[-81.466,-10.944],[-81.4295,-11.027],[-81.3815,-11.1815],[-81.3085,-11.378],[-81.229,-11.5565],[-81.2125,-11.807],[-81.1835,-12.018],[-81.059,-12.636],[-81.0105,-12.8405],[-80.9485,-13.0415],[-80.874,-13.2385],[-80.787,-13.4305],[-80.661,-13.662],[-80.5765,-13.7965],[-80.4535,-13.969],[-80.3195,-14.1335],[-80.136,-14.329],[-79.978,-14.474],[-79.805,-14.6135],[-79.757,-14.796],[-79.6725,-15.0455],[-79.568,-15.288],[-79.3795,-15.6445],[-79.312,-15.777],[-79.2075,-15.9565],[-79.122,-16.087],[-78.998,-16.2545],[-78.856,-16.4275],[-78.7395,-16.5995],[-78.5725,-16.811],[-78.426,-16.9705],[-78.2285,-17.1565],[-77.9785,-17.361],[-77.8465,-17.524],[-77.739,-17.6425],[-77.5865,-17.7925],[-77.424,-17.9335],[-77.2415,-18.0755],[-77.0565,-18.202],[-76.795,-18.353],[-76.698,-18.414],[-76.5055,-18.522],[-76.3725,-18.587],[-76.194,-18.698],[-75.938,-18.833],[-75.6495,-19.0235],[-75.509,-19.11],[-75.315,-19.2145],[-75.063,-19.3285],[-74.819,-19.417],[-74.6085,-19.507],[-74.4665,-19.5585],[-74.264,-19.6565],[-74.203,-19.701],[-74.023,-19.9155],[-73.831,-20.109],[-73.7305,-20.1985],[-73.727,-20.164],[-73.7535,-19.9735],[-73.6035,-19.8785],[-73.153,-19.561],[-72.9275,-19.4025],[-72.8635,-19.351],[-72.34,-18.89],[-72.0335,-18.6295],[-71.7825,-18.35],[-71.4005,-18.35],[-70.91,-18.35],[-70.591,-18.35],[-70.3765,-18.35],[-70.302,-18.309],[-70.1495,-18.3195],[-70.0505,-18.269],[-69.966,-18.262],[-69.8605,-18.17],[-69.816,-18.1165],[-69.7545,-17.9895],[-69.75,-17.9475],[-69.799,-17.8655],[-69.801,-17.762],[-69.826,-17.706],[-69.7965,-17.646],[-69.6665,-17.6605],[-69.5525,-17.5755],[-69.4685,-17.4985],[-69.4685,-17.374],[-69.616,-17.2615],[-69.557,-17.1595],[-69.512,-17.146],[-69.449,-17.098],[-69.4065,-17.1005],[-69.3735,-17.073],[-69.3945,-17.024],[-69.3435,-16.987],[-69.3045,-16.916],[-69.219,-16.836],[-69.17,-16.7275],[-69.0455,-16.6885],[-69.017,-16.638],[-69.04,-16.5735],[-68.9885,-16.4255],[-68.8005,-16.349],[-68.7955,-16.3315],[-68.893,-16.2595],[-68.9615,-16.1945],[-69.013,-16.22],[-69.0555,-16.1975],[-69.1025,-16.225],[-69.1965,-16.168],[-69.402,-15.606],[-69.3295,-15.537],[-69.29,-15.437],[-69.2535,-15.469],[-69.2485,-15.371],[-69.2155,-15.317],[-69.1315,-15.246],[-69.133,-15.221],[-69.236,-15.1205],[-69.285,-15.095],[-69.299,-15.0495],[-69.3615,-14.949],[-69.344,-14.8825],[-69.354,-14.8015],[-69.301,-14.7655],[-69.2255,-14.7405],[-69.258,-14.683],[-69.2295,-14.6565],[-69.22,-14.5815],[-69.15,-14.5805],[-69.1405,-14.5135],[-69.084,-14.452],[-69.031,-14.426],[-68.9855,-14.3745],[-69.015,-14.3145],[-68.9625,-14.22],[-68.828,-14.22],[-68.856,-14.1625],[-68.8955,-14.0415],[-68.942,-14.0215],[-68.9785,-13.976],[-68.982,-13.894],[-68.951,-13.8785],[-68.9175,-13.8135],[-68.9805,-13.7835],[-68.977,-13.758],[-69.066,-13.6885],[-69.061,-13.657],[-68.993,-13.65],[-68.917,-13.4865],[-68.8455,-13.246],[-68.8745,-13.1155],[-68.85,-13.037],[-68.8705,-13.019],[-68.8715,-12.8855],[-68.836,-12.859],[-68.8345,-12.813],[-68.788,-12.757],[-68.743,-12.726],[-68.713,-12.6815],[-68.7415,-12.6355],[-68.713,-12.603],[-68.652,-12.498],[-68.9705,-11.913],[-69.255,-11.459],[-69.379,-11.264],[-69.572,-10.9455],[-69.7395,-10.964],[-69.7885,-10.9295],[-69.901,-10.92],[-70.067,-10.9945],[-70.092,-10.9855],[-70.171,-11.043],[-70.256,-11.0505],[-70.3085,-11.071],[-70.3765,-11.06],[-70.4375,-11.0265],[-70.5305,-10.9345],[-70.614,-10.9965],[-70.6135,-10.608],[-70.613,-10.162],[-70.6125,-9.8055],[-70.5365,-9.766],[-70.528,-9.726],[-70.551,-9.67],[-70.598,-9.6075],[-70.5915,-9.5485],[-70.5415,-9.538],[-70.4945,-9.4405],[-70.5055,-9.422],[-70.5845,-9.443],[-70.6735,-9.5295],[-70.75,-9.5695],[-70.799,-9.642],[-70.868,-9.665],[-70.9245,-9.7415],[-70.974,-9.7605],[-70.9985,-9.818],[-71.051,-9.816],[-71.1575,-9.8725],[-71.192,-9.9405],[-71.2975,-9.9925],[-71.3425,-9.967],[-71.378,-10.0005],[-71.8225,-10.0005],[-72.181,-10.0005],[-72.1615,-9.9805],[-72.174,-9.93],[-72.1505,-9.9055],[-72.162,-9.831],[-72.1515,-9.7975],[-72.215,-9.779],[-72.259,-9.712],[-72.246,-9.6575],[-72.2885,-9.603],[-72.2815,-9.5425],[-72.318,-9.544],[-72.341,-9.5065],[-72.407,-9.4775],[-72.5305,-9.4825],[-72.6425,-9.4435],[-72.6975,-9.436],[-72.717,-9.4125],[-73.2005,-9.4115],[-73.189,-9.363],[-73.156,-9.3565],[-73.064,-9.2275],[-73.034,-9.234],[-73.0195,-9.1855],[-72.9635,-9.144],[-72.94,-9.093],[-72.948,-9.029],[-73.0015,-8.917],[-73.037,-8.916],[-73.112,-8.8195],[-73.1145,-8.7855],[-73.167,-8.6985],[-73.251,-8.6905],[-73.3195,-8.6105],[-73.344,-8.6025],[-73.331,-8.476],[-73.373,-8.472],[-73.408,-8.4305],[-73.4415,-8.4255],[-73.543,-8.3475],[-73.526,-8.2745],[-73.563,-8.2455],[-73.5955,-8.166],[-73.585,-8.127],[-73.6405,-8.0065],[-73.669,-8.0125],[-73.706,-7.962],[-73.7455,-7.9495],[-73.767,-7.9105],[-73.7355,-7.879],[-73.678,-7.858],[-73.6765,-7.8],[-73.714,-7.743],[-73.8035,-7.714],[-73.8375,-7.6705],[-73.869,-7.674],[-73.9,-7.639],[-73.8895,-7.603],[-73.9585,-7.5645],[-73.9175,-7.5005],[-73.9235,-7.362],[-73.8615,-7.388],[-73.8185,-7.338],[-73.7225,-7.341],[-73.695,-7.299],[-73.7165,-7.2275],[-73.7985,-7.113],[-73.762,-7.0625],[-73.7615,-6.94],[-73.724,-6.8875],[-73.7105,-6.84],[-73.6035,-6.732],[-73.5615,-6.7215],[-73.521,-6.676],[-73.392,-6.6415],[-73.3525,-6.5935],[-73.2315,-6.5855],[-73.1995,-6.5695],[-73.171,-6.518],[-73.1115,-6.447],[-73.1565,-6.327],[-73.1605,-6.2765],[-73.1865,-6.2625],[-73.221,-6.177],[-73.25,-6.133],[-73.2375,-6.043],[-73.1935,-6.0055],[-73.1855,-5.95],[-73.152,-5.868],[-73.0575,-5.7965],[-72.959,-5.6565],[-72.9735,-5.6135],[-72.9495,-5.5475],[-72.958,-5.4645],[-72.9245,-5.408],[-72.8955,-5.325],[-72.867,-5.29],[-72.864,-5.2345],[-72.887,-5.1615],[-72.822,-5.1405],[-72.7085,-5.049],[-72.6595,-5.063],[-72.607,-5.028],[-72.5995,-4.9875],[-72.5205,-4.933],[-72.4855,-4.935],[-72.429,-4.9085],[-72.388,-4.8655],[-72.3825,-4.8315],[-72.3265,-4.8015],[-72.31,-4.7745],[-72.2295,-4.7755],[-72.208,-4.7465],[-72.102,-4.706],[-72.059,-4.6495],[-71.9865,-4.6135],[-71.887,-4.53],[-71.784,-4.4835],[-71.708,-4.511],[-71.6445,-4.5015],[-71.6195,-4.528],[-71.566,-4.5045],[-71.537,-4.4635],[-71.422,-4.4685],[-71.3795,-4.425],[-71.34,-4.443],[-71.264,-4.4305],[-71.2615,-4.3995],[-71.145,-4.3815],[-71.107,-4.401],[-71.085,-4.373],[-71.038,-4.402],[-71.017,-4.383],[-70.9335,-4.3795],[-70.878,-4.2935],[-70.8365,-4.2555],[-70.8025,-4.1845],[-70.7475,-4.161],[-70.7265,-4.185],[-70.672,-4.1955],[-70.6355,-4.172],[-70.5845,-4.1855],[-70.523,-4.1375],[-70.467,-4.1765],[-70.43,-4.131],[-70.3295,-4.1445],[-70.2875,-4.1655],[-70.284,-4.272],[-70.256,-4.31],[-70.211,-4.3175],[-70.202,-4.3555],[-70.126,-4.2865],[-70.04,-4.348],[-69.952,-4.311],[-69.948,-4.2315],[-69.9695,-4.1955],[-70.0405,-4.125],[-70.062,-4.0825],[-70.1265,-4.035],[-70.161,-3.9875],[-70.1805,-3.9305],[-70.2475,-3.8965],[-70.284,-3.824],[-70.3475,-3.8005],[-70.415,-3.828],[-70.4535,-3.863],[-70.5235,-3.88],[-70.5605,-3.827],[-70.6505,-3.8305],[-70.713,-3.7955],[-70.3355,-3.1975],[-70.0805,-2.795],[-70.061,-2.7595],[-70.0675,-2.6755],[-70.1145,-2.697],[-70.1605,-2.691],[-70.1565,-2.647],[-70.219,-2.6455],[-70.229,-2.5815],[-70.2675,-2.5455],[-70.3335,-2.578],[-70.354,-2.49],[-70.4115,-2.526],[-70.4445,-2.512],[-70.472,-2.454],[-70.601,-2.4845],[-70.6425,-2.4585],[-70.626,-2.4075],[-70.674,-2.4105],[-70.6615,-2.363],[-70.7615,-2.3205],[-70.768,-2.298],[-70.843,-2.2855],[-70.8635,-2.226],[-70.898,-2.224],[-70.9415,-2.2555],[-70.978,-2.2125],[-71.046,-2.265],[-71.1435,-2.297],[-71.1715,-2.3745],[-71.1935,-2.3825],[-71.231,-2.336],[-71.266,-2.377],[-71.3535,-2.3795],[-71.392,-2.355],[-71.4675,-2.272],[-71.599,-2.239],[-71.6375,-2.202],[-71.713,-2.23],[-71.718,-2.1665],[-71.829,-2.1875],[-71.872,-2.2965],[-71.927,-2.3085],[-71.9695,-2.3675],[-72.0055,-2.3705],[-72.06,-2.343],[-72.129,-2.4095],[-72.227,-2.447],[-72.2595,-2.432],[-72.2985,-2.4745],[-72.3685,-2.491],[-72.38,-2.453],[-72.5765,-2.3935],[-72.6065,-2.3625],[-72.6865,-2.4205],[-72.735,-2.424],[-72.777,-2.3855],[-72.8575,-2.4395],[-72.9315,-2.418],[-73.003,-2.3605],[-73.0435,-2.3575],[-73.096,-2.324],[-73.155,-2.2585],[-73.173,-2.195],[-73.1255,-2.173],[-73.1165,-2.1305],[-73.0705,-2.1055],[-73.1135,-2.072],[-73.092,-2.0415],[-73.1295,-1.9945],[-73.1115,-1.95],[-73.11,-1.877],[-73.1505,-1.863],[-73.1465,-1.8055],[-73.1945,-1.7885],[-73.212,-1.752],[-73.252,-1.7805],[-73.3,-1.7775],[-73.3345,-1.802],[-73.3775,-1.776],[-73.4325,-1.7875],[-73.466,-1.735],[-73.5385,-1.7005],[-73.5165,-1.64],[-73.463,-1.589],[-73.4905,-1.571],[-73.491,-1.4835],[-73.531,-1.4375],[-73.5815,-1.346],[-73.611,-1.3185],[-73.6195,-1.264],[-73.674,-1.2405],[-73.853,-1.2335],[-73.8955,-1.1695],[-73.904,-1.1245],[-73.958,-1.131],[-74.006,-1.099],[-74.027,-1.0615],[-74.126,-1.0325],[-74.1725,-1.0055],[-74.2255,-1.0085],[-74.2725,-0.979],[-74.262,-0.941],[-74.2795,-0.899],[-74.2655,-0.8415],[-74.318,-0.778],[-74.37,-0.737],[-74.338,-0.6775],[-74.374,-0.6535],[-74.3865,-0.555],[-74.4245,-0.55],[-74.4195,-0.504],[-74.487,-0.4885],[-74.537,-0.4585],[-74.544,-0.419],[-74.6115,-0.351],[-74.676,-0.3655],[-74.732,-0.334],[-74.729,-0.2985],[-74.7615,-0.2235],[-74.7935,-0.189],[-74.845,-0.231],[-74.8835,-0.2435],[-74.931,-0.2215],[-74.9725,-0.155],[-75.012,-0.1485],[-75.0775,-0.082],[-75.1315,-0.0705],[-75.162,-0.0445],[-75.2095,-0.046],[-75.258,-0.116],[-75.3045,-0.154],[-75.4035,-0.17],[-75.504,-0.127],[-75.567,-0.1305],[-75.6105,-0.1135],[-75.6105,-0.1925],[-75.531,-0.181],[-75.482,-0.237],[-75.4735,-0.297],[-75.3855,-0.437],[-75.3275,-0.4595],[-75.313,-0.4945],[-75.2415,-0.5245],[-75.2235,-0.629],[-75.2575,-0.6435],[-75.2515,-0.6915],[-75.2775,-0.73],[-75.243,-0.7975],[-75.225,-0.8625],[-75.2315,-0.939],[-75.195,-0.9705],[-75.26,-0.989],[-75.3135,-0.9845],[-75.386,-0.9375],[-75.5555,-1.547],[-75.5865,-1.5535],[-76.0445,-2.125],[-76.6325,-2.591],[-77.1745,-2.7715],[-77.7105,-2.951],[-77.844,-3.0005],[-77.944,-3.0655],[-77.971,-3.118],[-78.0325,-3.189],[-78.0785,-3.2265],[-78.107,-3.2765],[-78.17,-3.35],[-78.1975,-3.365],[-78.155,-3.4265],[-78.148,-3.479],[-78.229,-3.5055],[-78.248,-3.398],[-78.324,-3.391],[-78.359,-3.4695],[-78.365,-3.5295],[-78.3875,-3.555],[-78.401,-3.6515],[-78.4225,-3.691],[-78.4025,-3.7355],[-78.414,-3.7925],[-78.4765,-3.8585],[-78.4885,-3.9335],[-78.5245,-3.9375],[-78.566,-3.9935],[-78.5625,-4.05],[-78.541,-4.074],[-78.5815,-4.1355],[-78.5785,-4.198],[-78.5985,-4.208],[-78.618,-4.294],[-78.6525,-4.3325],[-78.634,-4.415],[-78.6375,-4.501],[-78.661,-4.53],[-78.661,-4.586],[-78.706,-4.624],[-78.805,-4.638],[-78.8425,-4.6545],[-78.889,-4.715],[-78.891,-4.8085],[-78.917,-4.892],[-78.9725,-4.894],[-79.0125,-5.012],[-79.076,-4.97],[-79.102,-4.9785],[-79.1805,-4.9605],[-79.2655,-4.967],[-79.3065,-4.901],[-79.352,-4.8805],[-79.361,-4.844],[-79.399,-4.829],[-79.4315,-4.737],[-79.458,-4.702],[-79.463,-4.6545],[-79.488,-4.6275],[-79.477,-4.5685],[-79.505,-4.5175],[-79.5445,-4.525],[-79.6175,-4.4455],[-79.6555,-4.434],[-79.745,-4.483],[-79.8135,-4.492],[-79.8715,-4.413],[-79.92,-4.386],[-79.9525,-4.398],[-80.0335,-4.3495],[-80.0615,-4.311],[-80.1065,-4.2915],[-80.1555,-4.304],[-80.2825,-4.4065],[-80.3295,-4.4655],[-80.3885,-4.486],[-80.4405,-4.4555],[-80.4535,-4.3825],[-80.412,-4.316],[-80.3675,-4.28],[-80.3315,-4.2255],[-80.372,-4.198],[-80.41,-4.218],[-80.45,-4.2095],[-80.449,-4.125],[-80.4845,-4.09],[-80.469,-4.038],[-80.398,-3.981],[-80.3385,-3.993],[-80.299,-4.0175],[-80.1865,-3.929],[-80.14,-3.913],[-80.1585,-3.8715],[-80.159,-3.809],[-80.182,-3.7855],[-80.1995,-3.689],[-80.1855,-3.648],[-80.212,-3.592],[-80.2065,-3.5345],[-80.243,-3.4665],[-80.2495,-3.4125],[-80.3065,-3.3925],[-80.671,-3.392],[-81.3445,-3.392]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/cf/Flag_of_Peru.svg","name:en":"Peru","wikidata":"Q419","ISO3166-1:alpha2":"PE","ISO3166-1:alpha3":"PER","ISO3166-1:numeric":"604"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-87.663,13.1275],[-87.72,13.109],[-87.811,13.055],[-87.9015,12.976],[-87.834,12.8865],[-87.7415,12.7815],[-87.588,12.676],[-87.4175,12.499],[-87.291,12.4025],[-87.237,12.335],[-86.8955,12.137],[-86.7995,11.924],[-86.742,11.852],[-86.73,11.8095],[-86.6405,11.7175],[-86.627,11.684],[-86.454,11.5415],[-86.436,11.512],[-86.2605,11.3955],[-85.898,11.076],[-85.706,11.069],[-85.693,11.079],[-85.61,11.2195],[-85.5605,11.21],[-85.5235,11.168],[-85.4235,11.129],[-85.357,11.126],[-85.23,11.064],[-84.91,10.9435],[-84.6805,11.0845],[-84.606,11.0385],[-84.485,11.0],[-84.4205,10.9555],[-84.3585,10.996],[-84.319,10.916],[-84.226,10.8745],[-84.222,10.8005],[-84.14,10.7875],[-84.0705,10.76],[-84.006,10.7665],[-83.9685,10.731],[-83.9135,10.711],[-83.8625,10.7175],[-83.7945,10.7675],[-83.671,10.797],[-83.667,10.8815],[-83.7035,10.9425],[-83.658,11.0295],[-83.695,11.068],[-83.77,11.283],[-83.77,11.3625],[-83.7185,11.3915],[-83.6975,11.461],[-83.624,11.5055],[-83.5675,11.564],[-83.5455,11.6145],[-83.6165,11.955],[-83.563,12.019],[-83.5565,12.2835],[-83.465,12.293],[-83.373,12.3455],[-83.3915,12.452],[-83.439,12.6245],[-83.411,12.912],[-83.4745,13.295],[-83.4515,13.4715],[-83.4305,13.5345],[-83.412,13.7475],[-83.3605,13.855],[-83.2955,13.97],[-83.1865,14.113],[-83.0975,14.3125],[-83.1085,14.3885],[-83.194,14.6645],[-83.2135,14.743],[-83.21,14.815],[-83.188,14.8745],[-83.0425,14.9535],[-83.046,15.033],[-83.1415,14.998],[-83.2355,14.9825],[-83.385,15.0165],[-83.459,14.981],[-83.5015,15.011],[-83.541,14.975],[-83.529,14.951],[-83.5775,14.912],[-83.7,14.858],[-83.8895,14.765],[-83.9285,14.7785],[-83.9715,14.7475],[-84.0395,14.7655],[-84.0955,14.7315],[-84.1885,14.716],[-84.2355,14.7605],[-84.2735,14.7235],[-84.2585,14.675],[-84.297,14.663],[-84.3755,14.6995],[-84.434,14.632],[-84.496,14.6195],[-84.5435,14.6545],[-84.6295,14.6745],[-84.7035,14.6665],[-84.745,14.7155],[-84.752,14.7735],[-84.7995,14.822],[-84.9005,14.8145],[-84.9425,14.754],[-84.987,14.74],[-85.0275,14.696],[-85.0215,14.6075],[-85.0425,14.575],[-85.096,14.5525],[-85.147,14.5765],[-85.1385,14.519],[-85.183,14.4695],[-85.181,14.4285],[-85.2055,14.3865],[-85.1985,14.3475],[-85.159,14.288],[-85.1985,14.2565],[-85.3415,14.247],[-85.404,14.123],[-85.4985,14.0855],[-85.536,14.046],[-85.592,14.0425],[-85.626,14.0085],[-85.6645,14.011],[-85.7535,13.968],[-85.7665,13.8495],[-85.8265,13.859],[-85.8455,13.9175],[-85.9125,13.926],[-86.042,13.996],[-86.0085,14.0555],[-86.076,14.07],[-86.1525,14.0355],[-86.1405,14.006],[-86.227,13.9065],[-86.2785,13.8755],[-86.3325,13.769],[-86.417,13.759],[-86.5225,13.781],[-86.723,13.787],[-86.7655,13.7665],[-86.7605,13.7255],[-86.786,13.662],[-86.749,13.6395],[-86.7695,13.582],[-86.7495,13.5655],[-86.741,13.4865],[-86.722,13.4325],[-86.744,13.4065],[-86.7105,13.359],[-86.706,13.303],[-86.7545,13.2675],[-86.829,13.3135],[-86.9085,13.269],[-86.931,13.19],[-86.9255,13.083],[-86.955,13.039],[-87.0275,13.003],[-87.3085,12.9875],[-87.3945,13.004],[-87.4795,13.078],[-87.543,13.1675],[-87.663,13.1275]]],[[[-83.1815,12.156],[-83.159,12.084],[-83.083,12.048],[-83.006,12.0495],[-82.932,12.1265],[-82.92,12.1815],[-82.887,12.2065],[-82.8615,12.2815],[-82.8935,12.3655],[-82.938,12.4035],[-83.046,12.3935],[-83.088,12.36],[-83.099,12.2845],[-83.13,12.269],[-83.1745,12.202],[-83.1815,12.156]]],[[[-82.928,14.3855],[-82.927,14.3355],[-82.896,14.277],[-82.8545,14.252],[-82.726,14.2455],[-82.67,14.2755],[-82.632,14.331],[-82.628,14.4315],[-82.6515,14.482],[-82.702,14.5195],[-82.796,14.525],[-82.883,14.473],[-82.928,14.3855]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/19/Flag_of_Nicaragua.svg","name:en":"Nicaragua","wikidata":"Q811","ISO3166-1:alpha2":"NI","ISO3166-1:alpha3":"NIC","ISO3166-1:numeric":"558"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-78.578,18.269],[-78.577,18.241],[-78.3985,16.768],[-78.3765,16.698],[-78.33,16.6405],[-78.265,16.603],[-78.1905,16.59],[-78.1165,16.6035],[-77.456,16.849],[-75.953,17.188],[-75.872,17.218],[-75.8305,17.247],[-75.7735,17.3225],[-75.754,17.409],[-75.7695,17.487],[-75.986,17.9935],[-76.1585,18.26],[-76.203,18.3095],[-76.27,18.3495],[-76.8085,18.5935],[-76.866,18.6105],[-77.282,18.671],[-77.7945,18.7235],[-77.9325,18.7155],[-78.2555,18.652],[-78.3565,18.605],[-78.486,18.5095],[-78.549,18.4055],[-78.578,18.269]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/0a/Flag_of_Jamaica.svg","name:en":"Jamaica","wikidata":"Q766","ISO3166-1:alpha2":"JM","ISO3166-1:alpha3":"JAM","ISO3166-1:numeric":"388"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-11.377,12.4125],[-11.4365,12.3825],[-11.4305,12.283],[-11.4955,12.2135],[-11.493,12.179],[-11.4545,12.134],[-11.367,12.1075],[-11.3585,12.0665],[-11.311,12.024],[-11.225,11.998],[-11.1755,12.024],[-11.0735,12.137],[-11.0475,12.2215],[-10.9855,12.2155],[-10.9225,12.2255],[-10.841,12.1305],[-10.792,12.1155],[-10.8015,12.0415],[-10.765,11.9715],[-10.7735,11.9475],[-10.7075,11.909],[-10.634,11.906],[-10.609,11.9745],[-10.5675,11.9895],[-10.5795,12.025],[-10.5265,12.0375],[-10.513,12.126],[-10.453,12.12],[-10.41,12.145],[-10.396,12.1825],[-10.3585,12.178],[-10.342,12.223],[-10.1925,12.2055],[-10.149,12.1765],[-10.091,12.1695],[-9.968,12.103],[-9.914,12.104],[-9.872,12.058],[-9.8295,12.057],[-9.7445,12.0305],[-9.6885,12.0345],[-9.683,12.1185],[-9.6465,12.1685],[-9.572,12.1975],[-9.5325,12.199],[-9.4845,12.257],[-9.4225,12.2645],[-9.3735,12.2505],[-9.3185,12.281],[-9.302,12.367],[-9.3795,12.4305],[-9.3555,12.5015],[-9.284,12.4855],[-9.25,12.506],[-9.135,12.48],[-9.0835,12.441],[-9.0145,12.4205],[-9.007,12.396],[-8.9335,12.325],[-8.9885,12.239],[-8.971,12.1925],[-8.918,12.1975],[-8.8835,12.1515],[-8.9115,12.0945],[-8.9065,12.0575],[-8.8625,12.0305],[-8.8285,12.0395],[-8.772,11.977],[-8.7985,11.8285],[-8.82,11.781],[-8.849,11.6545],[-8.751,11.6245],[-8.7015,11.6455],[-8.6415,11.548],[-8.655,11.523],[-8.601,11.4755],[-8.52,11.484],[-8.498,11.4165],[-8.372,11.3885],[-8.404,11.332],[-8.3535,11.3155],[-8.391,11.276],[-8.4655,11.29],[-8.4735,11.2315],[-8.5505,11.2115],[-8.559,11.138],[-8.6045,11.1305],[-8.601,11.0955],[-8.6345,11.039],[-8.675,11.0035],[-8.665,10.953],[-8.5795,10.9605],[-8.5115,10.999],[-8.481,11.0715],[-8.3425,11.0625],[-8.2785,10.994],[-8.26,10.8915],[-8.306,10.8565],[-8.3035,10.818],[-8.3295,10.7715],[-8.2895,10.758],[-8.2885,10.6985],[-8.32,10.674],[-8.325,10.5905],[-8.2875,10.5955],[-8.246,10.5135],[-8.2305,10.4195],[-8.1825,10.415],[-8.1005,10.4495],[-8.105,10.3935],[-8.071,10.341],[-7.985,10.3435],[-7.945,10.2525],[-7.9795,10.1705],[-7.932,10.1545],[-7.8925,10.2],[-7.8545,10.2005],[-7.8005,10.2445],[-7.754,10.3415],[-7.7215,10.3485],[-7.718,10.3955],[-7.626,10.462],[-7.55,10.4125],[-7.514,10.4605],[-7.4495,10.4445],[-7.4525,10.4015],[-7.421,10.342],[-7.3585,10.3345],[-7.363,10.2745],[-7.3415,10.236],[-7.2705,10.2595],[-7.1415,10.2495],[-7.0755,10.1965],[-7.049,10.148],[-6.995,10.1725],[-6.977,10.2165],[-7.013,10.2425],[-6.945,10.3505],[-6.8675,10.344],[-6.789,10.371],[-6.6785,10.3385],[-6.648,10.371],[-6.626,10.439],[-6.6625,10.457],[-6.682,10.528],[-6.661,10.5885],[-6.669,10.6255],[-6.6335,10.6735],[-6.59,10.623],[-6.505,10.5795],[-6.4215,10.574],[-6.3975,10.5985],[-6.415,10.698],[-6.395,10.709],[-6.3165,10.6855],[-6.246,10.74],[-6.2105,10.569],[-6.242,10.5445],[-6.193,10.4975],[-6.181,10.4115],[-6.1635,10.3665],[-6.2305,10.305],[-6.218,10.264],[-6.178,10.227],[-6.108,10.205],[-5.9845,10.1985],[-5.9495,10.274],[-5.9015,10.263],[-5.874,10.3145],[-5.874,10.3555],[-5.8075,10.419],[-5.7655,10.439],[-5.704,10.431],[-5.6495,10.468],[-5.621,10.452],[-5.5625,10.464],[-5.513,10.431],[-5.508,10.461],[-5.4575,10.556],[-5.463,10.728],[-5.431,10.778],[-5.4025,10.8545],[-5.4455,10.8945],[-5.452,10.976],[-5.4895,11.0815],[-5.392,11.1025],[-5.343,11.1295],[-5.3265,11.201],[-5.256,11.244],[-5.255,11.359],[-5.2425,11.3965],[-5.1985,11.429],[-5.21,11.4575],[-5.2,11.528],[-5.24,11.6045],[-5.294,11.617],[-5.268,11.6765],[-5.2595,11.736],[-5.285,11.7765],[-5.3555,11.825],[-5.319,11.8415],[-5.245,11.84],[-5.1725,11.927],[-5.127,11.957],[-4.9275,12.005],[-4.843,12.0145],[-4.7405,11.999],[-4.7005,12.066],[-4.63,12.0595],[-4.6285,12.1135],[-4.6075,12.139],[-4.544,12.1415],[-4.569,12.2085],[-4.4715,12.286],[-4.472,12.332],[-4.3965,12.3105],[-4.439,12.4045],[-4.419,12.487],[-4.3645,12.533],[-4.4025,12.5605],[-4.4115,12.61],[-4.4805,12.6585],[-4.453,12.7165],[-4.3995,12.7185],[-4.347,12.744],[-4.3245,12.7115],[-4.2675,12.7045],[-4.233,12.734],[-4.209,12.8165],[-4.226,12.866],[-4.2155,12.92],[-4.2255,12.974],[-4.2645,12.99],[-4.275,13.0395],[-4.346,13.114],[-4.34,13.143],[-4.259,13.2335],[-4.2075,13.2695],[-4.1405,13.2935],[-4.1075,13.3345],[-4.1005,13.387],[-4.053,13.407],[-3.9595,13.473],[-3.9135,13.3825],[-3.8195,13.3605],[-3.798,13.372],[-3.7225,13.2925],[-3.6725,13.275],[-3.5875,13.201],[-3.5235,13.166],[-3.4635,13.156],[-3.4225,13.1785],[-3.4375,13.2765],[-3.3385,13.288],[-3.234,13.289],[-3.255,13.3655],[-3.278,13.5575],[-3.2505,13.5855],[-3.247,13.682],[-3.108,13.689],[-3.0295,13.6145],[-3.0075,13.6545],[-2.9525,13.6245],[-2.874,13.654],[-2.9065,13.7335],[-2.9065,13.821],[-2.8805,13.867],[-2.836,13.993],[-2.839,14.0545],[-2.806,14.077],[-2.6765,14.135],[-2.589,14.216],[-2.4735,14.2995],[-2.2975,14.249],[-2.178,14.192],[-2.1035,14.147],[-1.998,14.1915],[-1.9805,14.4755],[-1.907,14.4895],[-1.7775,14.4825],[-1.678,14.5015],[-1.3185,14.73],[-1.093,14.785],[-1.069,14.785],[-0.724,15.084],[-0.4315,15.0835],[-0.39,15.004],[-0.2455,15.079],[0.0615,14.9745],[0.1295,14.978],[0.232,15.0],[0.3945,14.964],[0.5145,14.9975],[0.5725,14.989],[0.6875,14.9445],[0.7335,14.96],[0.9065,14.972],[1.0,15.0],[1.3115,15.278],[1.8495,15.3065],[2.166,15.3225],[2.6365,15.347],[3.02,15.338],[3.0315,15.4285],[3.493,15.358],[3.5365,15.4035],[3.537,15.485],[3.5915,15.517],[3.645,15.586],[3.7225,15.659],[3.798,15.6635],[3.856,15.6865],[3.901,15.747],[3.928,15.8645],[3.9775,15.935],[3.9935,16.0295],[3.986,16.081],[4.063,16.2225],[4.097,16.323],[4.1185,16.35],[4.2,16.395],[4.1975,16.815],[4.2065,16.837],[4.2145,17.0],[4.2665,17.0015],[4.266,17.388],[4.2675,17.92],[4.2665,18.2855],[4.267,18.7635],[4.2665,19.144],[3.8105,19.0585],[3.3575,18.968],[3.2945,19.003],[3.276,19.0335],[3.1635,19.1145],[3.1245,19.1255],[3.1225,19.185],[3.2005,19.277],[3.1785,19.359],[3.208,19.431],[3.263,19.439],[3.248,19.498],[3.265,19.5305],[3.2325,19.6055],[3.2505,19.6495],[3.23,19.711],[3.2595,19.8175],[3.2375,19.842],[3.145,19.8585],[3.0765,19.9055],[2.977,19.953],[2.857,19.973],[2.8235,19.9645],[2.723,20.006],[2.701,20.087],[2.666,20.052],[2.562,20.033],[2.525,20.089],[2.4745,20.098],[2.3975,20.061],[2.4015,20.1175],[2.3565,20.1905],[2.318,20.218],[2.3125,20.2695],[2.2735,20.299],[2.194,20.3155],[2.192,20.28],[2.1335,20.2445],[2.084,20.244],[2.037,20.2695],[2.0025,20.2425],[1.947,20.26],[1.8975,20.243],[1.884,20.2945],[1.798,20.298],[1.775,20.337],[1.668,20.4065],[1.675,20.4795],[1.6425,20.56],[1.591,20.6005],[1.5035,20.6225],[1.353,20.677],[1.3165,20.74],[1.1785,20.7265],[1.164,20.7905],[1.1915,20.924],[1.192,21.0035],[1.1665,21.1165],[0.9095,21.2825],[0.505,21.5445],[-0.061,21.911],[-0.52,22.208],[-0.923,22.469],[-1.304,22.7155],[-1.668,22.951],[-2.054,23.201],[-2.5945,23.5505],[-2.987,23.805],[-3.602,24.203],[-4.0945,24.5215],[-4.4805,24.7715],[-4.8335,25.0],[-5.553,25.001],[-6.0,25.0005],[-6.572,25.0],[-6.4995,24.356],[-6.5485,24.354],[-6.4845,24.222],[-6.4565,23.972],[-6.4055,23.568],[-6.3585,23.201],[-6.3345,22.9635],[-6.2805,22.5],[-6.2175,21.9615],[-6.178,21.618],[-6.1045,20.969],[-6.0595,20.569],[-6.0005,20.041],[-5.943,19.511],[-5.9075,19.187],[-5.8265,18.4875],[-5.7715,18.0],[-5.705,17.3975],[-5.6615,17.0005],[-5.609,16.5],[-5.3335,16.3335],[-5.3885,16.057],[-5.5,15.5],[-6.189,15.5],[-6.731,15.5],[-7.429,15.5],[-8.0,15.5],[-8.509,15.5005],[-9.0,15.5005],[-9.3315,15.5015],[-9.3315,15.5655],[-9.3095,15.6935],[-9.331,15.703],[-9.447,15.6055],[-9.401,15.439],[-9.685,15.427],[-9.722,15.4075],[-9.781,15.414],[-9.799,15.389],[-9.9225,15.4],[-10.065,15.3615],[-10.1375,15.3765],[-10.1675,15.402],[-10.3205,15.443],[-10.3325,15.4345],[-10.519,15.451],[-10.639,15.42],[-10.705,15.4435],[-10.7285,15.4275],[-10.7155,15.375],[-10.732,15.3435],[-10.8,15.307],[-10.829,15.2705],[-10.833,15.2155],[-10.867,15.1985],[-10.882,15.12],[-10.954,15.16],[-10.993,15.232],[-11.2045,15.399],[-11.2515,15.4195],[-11.3395,15.526],[-11.411,15.637],[-11.4925,15.6415],[-11.517,15.5935],[-11.5605,15.5835],[-11.581,15.55],[-11.64,15.521],[-11.71,15.533],[-11.7045,15.492],[-11.7435,15.461],[-11.767,15.336],[-11.806,15.278],[-11.7995,15.2325],[-11.836,15.1845],[-11.812,15.1315],[-11.8445,15.096],[-11.789,15.03],[-11.8395,14.858],[-11.9355,14.8125],[-11.9375,14.7805],[-12.025,14.7635],[-12.0555,14.721],[-12.119,14.7545],[-12.2405,14.7645],[-12.2145,14.7055],[-12.146,14.6525],[-12.189,14.5545],[-12.2165,14.55],[-12.22,14.49],[-12.19,14.443],[-12.2005,14.4065],[-12.1025,14.375],[-12.092,14.3045],[-12.024,14.2835],[-11.989,14.195],[-11.9825,14.09],[-12.0145,14.0285],[-12.009,13.986],[-11.933,13.9245],[-11.949,13.8115],[-12.026,13.743],[-12.072,13.721],[-12.04,13.6665],[-12.0315,13.6165],[-11.9535,13.522],[-11.868,13.4585],[-11.8875,13.394],[-11.8285,13.309],[-11.7665,13.342],[-11.742,13.39],[-11.6275,13.3945],[-11.596,13.365],[-11.591,13.314],[-11.525,13.2595],[-11.5415,13.2325],[-11.5185,13.157],[-11.4355,13.0625],[-11.396,13.0055],[-11.355,12.976],[-11.346,12.9435],[-11.3975,12.93],[-11.4105,12.8485],[-11.3805,12.8035],[-11.383,12.743],[-11.4235,12.729],[-11.4235,12.664],[-11.4035,12.5875],[-11.4105,12.537],[-11.3585,12.508],[-11.352,12.4675],[-11.377,12.4125]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/92/Flag_of_Mali.svg","name:en":"Mali","wikidata":"Q912","ISO3166-1:alpha2":"ML","ISO3166-1:alpha3":"MLI","ISO3166-1:numeric":"466"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-4.8685,54.434],[-4.8965,54.391],[-4.9885,54.336],[-5.0365,54.286],[-5.0815,54.189],[-5.147,54.127],[-5.1655,54.018],[-5.116,53.942],[-5.0115,53.878],[-4.829,53.845],[-4.6195,53.854],[-4.4865,53.871],[-4.4175,53.895],[-4.132,54.06],[-4.0675,54.125],[-3.9795,54.24],[-3.9655,54.302],[-4.0175,54.404],[-4.0345,54.479],[-4.1535,54.5505],[-4.4005,54.5465],[-4.6725,54.4995],[-4.8685,54.434]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/bc/Flag_of_the_Isle_of_Man.svg","name:en":"Isle of Man","wikidata":"Q9676","ISO3166-1:alpha2":"IM","ISO3166-1:alpha3":"IMN","ISO3166-1:numeric":"833"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[33.2165,-13.9995],[33.3,-14.0315],[33.322,-14.0845],[33.2975,-14.146],[33.3415,-14.2165],[33.3815,-14.2305],[33.445,-14.328],[33.4495,-14.365],[33.512,-14.4235],[33.545,-14.4345],[33.566,-14.4815],[33.6075,-14.4915],[33.634,-14.587],[33.6795,-14.616],[33.708,-14.578],[33.7165,-14.5015],[33.7405,-14.501],[33.799,-14.5515],[33.9155,-14.4775],[34.087,-14.4895],[34.085,-14.4585],[34.239,-14.425],[34.301,-14.3985],[34.391,-14.395],[34.4755,-14.5325],[34.5155,-14.5545],[34.551,-14.649],[34.5205,-14.687],[34.5835,-14.809],[34.58,-14.908],[34.618,-15.015],[34.573,-15.0675],[34.578,-15.2005],[34.6035,-15.238],[34.5985,-15.287],[34.519,-15.3535],[34.521,-15.3845],[34.4255,-15.476],[34.455,-15.611],[34.437,-15.6595],[34.388,-15.6925],[34.3645,-15.7425],[34.2995,-15.761],[34.2505,-15.8425],[34.259,-15.906],[34.355,-15.9695],[34.389,-16.027],[34.4295,-16.0445],[34.3975,-16.1855],[34.4195,-16.25],[34.489,-16.2955],[34.52,-16.2805],[34.5755,-16.3265],[34.594,-16.4175],[34.6525,-16.453],[34.6895,-16.505],[34.7215,-16.497],[34.775,-16.544],[34.7875,-16.5855],[34.8435,-16.6085],[34.8585,-16.676],[34.9095,-16.6935],[34.919,-16.746],[34.9845,-16.749],[34.9905,-16.7895],[35.0635,-16.8355],[35.113,-16.818],[35.1575,-16.84],[35.1675,-16.9215],[35.1355,-16.9715],[35.063,-16.994],[35.0565,-17.0495],[35.0885,-17.0785],[35.0975,-17.1295],[35.2955,-17.128],[35.2965,-16.9645],[35.2635,-16.939],[35.3145,-16.831],[35.2755,-16.706],[35.167,-16.6195],[35.146,-16.557],[35.213,-16.5],[35.262,-16.475],[35.263,-16.399],[35.303,-16.3455],[35.2785,-16.326],[35.3135,-16.2075],[35.4055,-16.125],[35.4815,-16.1235],[35.5025,-16.1555],[35.6125,-16.1245],[35.6615,-16.1],[35.704,-16.1025],[35.8175,-16.0275],[35.8065,-15.992],[35.853,-15.419],[35.79,-15.17],[35.9185,-14.8955],[35.872,-14.8955],[35.872,-14.6755],[35.5205,-14.259],[35.487,-14.1705],[35.2275,-13.881],[35.0895,-13.6995],[34.927,-13.5465],[34.867,-13.483],[34.607,-13.483],[34.5615,-13.348],[34.576,-13.232],[34.5305,-12.88],[34.535,-12.7365],[34.5205,-12.6825],[34.4555,-12.571],[34.43,-12.401],[34.4175,-12.2655],[34.378,-12.1715],[34.484,-11.9725],[34.591,-11.856],[34.6345,-11.739],[34.6435,-11.656],[34.637,-11.5735],[34.959,-11.5735],[34.956,-11.4915],[34.9305,-11.4625],[34.928,-11.3985],[34.7895,-11.3135],[34.8005,-11.281],[34.7565,-11.2085],[34.638,-11.118],[34.6375,-11.053],[34.612,-11.029],[34.6545,-10.9535],[34.6705,-10.8945],[34.681,-10.7515],[34.625,-10.597],[34.584,-10.5725],[34.568,-10.5285],[34.5935,-10.49],[34.56,-10.4325],[34.5845,-10.3035],[34.565,-10.258],[34.5695,-10.2065],[34.5195,-10.119],[34.54,-10.0665],[34.416,-9.885],[34.345,-9.8],[34.3265,-9.7575],[34.209,-9.6455],[34.038,-9.4935],[33.9785,-9.522],[33.9455,-9.5725],[33.9555,-9.654],[33.9165,-9.713],[33.871,-9.664],[33.8125,-9.63],[33.7735,-9.5865],[33.7315,-9.5845],[33.699,-9.6145],[33.554,-9.5875],[33.508,-9.626],[33.4435,-9.6145],[33.3905,-9.5335],[33.326,-9.486],[33.2135,-9.506],[33.1435,-9.4925],[33.022,-9.4],[32.9925,-9.3685],[32.9535,-9.4015],[32.9475,-9.487],[33.0145,-9.5025],[32.994,-9.5625],[32.9965,-9.626],[33.0605,-9.616],[33.1065,-9.659],[33.1135,-9.5865],[33.201,-9.601],[33.2275,-9.6295],[33.2425,-9.7055],[33.3065,-9.804],[33.35,-9.815],[33.391,-9.912],[33.355,-9.934],[33.3175,-10.0555],[33.433,-10.1165],[33.467,-10.158],[33.5555,-10.212],[33.561,-10.239],[33.5445,-10.342],[33.5725,-10.401],[33.6335,-10.458],[33.633,-10.4985],[33.6725,-10.5375],[33.6835,-10.6085],[33.598,-10.658],[33.5355,-10.7525],[33.4535,-10.808],[33.418,-10.794],[33.336,-10.821],[33.3165,-10.8615],[33.277,-10.8495],[33.259,-10.889],[33.305,-10.939],[33.328,-11.0705],[33.4045,-11.156],[33.3805,-11.234],[33.3545,-11.255],[33.3335,-11.311],[33.232,-11.444],[33.256,-11.475],[33.2605,-11.539],[33.2455,-11.5915],[33.301,-11.592],[33.331,-11.612],[33.327,-11.6975],[33.3405,-11.823],[33.3285,-11.8955],[33.3485,-11.93],[33.3325,-11.9875],[33.2735,-12.066],[33.257,-12.14],[33.3135,-12.202],[33.3115,-12.2485],[33.376,-12.348],[33.4755,-12.3255],[33.531,-12.34],[33.5485,-12.364],[33.399,-12.516],[33.3755,-12.554],[33.3225,-12.533],[33.272,-12.5485],[33.232,-12.595],[33.1815,-12.6135],[33.0575,-12.5945],[32.9525,-12.7615],[32.946,-12.8465],[32.976,-12.886],[33.0175,-12.8925],[33.017,-12.954],[32.99,-13.037],[32.984,-13.14],[33.008,-13.1935],[32.9305,-13.325],[32.932,-13.3735],[32.8985,-13.4495],[32.86,-13.469],[32.8475,-13.526],[32.7575,-13.5735],[32.6975,-13.559],[32.6705,-13.5745],[32.6785,-13.6255],[32.7185,-13.651],[32.7835,-13.6495],[32.843,-13.722],[32.7725,-13.7695],[32.8075,-13.8005],[32.844,-13.7935],[32.907,-13.8255],[32.9545,-13.8885],[32.9685,-13.9375],[32.998,-13.943],[32.994,-14.007],[33.041,-14.0495],[33.0865,-13.9705],[33.145,-13.939],[33.186,-13.959],[33.2165,-13.9995]]],[[[34.5725,-12.014],[34.5845,-12.069],[34.6195,-12.085],[34.6625,-12.041],[34.64,-11.982],[34.605,-11.9745],[34.5725,-12.014]]],[[[34.675,-12.0845],[34.7065,-12.1365],[34.7825,-12.0815],[34.794,-12.0425],[34.742,-11.9995],[34.706,-12.008],[34.675,-12.0845]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/d1/Flag_of_Malawi.svg","name:en":"Malawi","wikidata":"Q1020","ISO3166-1:alpha2":"MW","ISO3166-1:alpha3":"MWI","ISO3166-1:numeric":"454"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[39.647,-4.681],[39.7125,-4.551],[39.9,-4.145],[39.963,-4.038],[40.336,-3.37],[40.3545,-3.324],[40.4185,-3.0855],[40.751,-2.7635],[41.3265,-2.271],[41.6505,-1.912],[41.718,-1.803],[41.5595,-1.662],[41.559,-1.5985],[41.2765,-1.2165],[40.9935,-0.834],[40.9935,-0.1995],[40.9945,0.5165],[40.9945,0.9305],[40.9935,1.231],[40.9915,2.1765],[40.989,2.8285],[41.1465,2.9855],[41.312,3.141],[41.575,3.5245],[41.7165,3.7155],[41.907,3.9825],[41.8445,3.949],[41.7235,3.987],[41.6745,3.96],[41.6315,3.9825],[41.567,3.9665],[41.5505,3.9815],[41.4795,3.952],[41.427,3.9455],[41.3915,3.963],[41.33,3.9395],[41.271,3.958],[41.1695,3.9425],[41.1055,3.9855],[41.092,4.0135],[40.965,4.132],[40.904,4.1545],[40.8825,4.213],[40.844,4.2465],[40.759,4.279],[40.7175,4.245],[40.652,4.225],[40.376,4.1065],[40.172,4.0275],[39.8695,3.8745],[39.787,3.702],[39.7585,3.659],[39.606,3.503],[39.588,3.492],[39.554,3.3975],[39.515,3.407],[39.498,3.4625],[39.4295,3.451],[39.191,3.4775],[39.0875,3.539],[39.0215,3.51],[38.9065,3.5125],[38.7145,3.5725],[38.6655,3.593],[38.58,3.604],[38.551,3.642],[38.4485,3.602],[38.1915,3.62],[38.13,3.606],[37.994,3.7295],[37.9025,3.7835],[37.7075,3.9105],[37.5015,4.0565],[37.137,4.293],[37.09,4.341],[37.0315,4.3795],[36.988,4.3895],[36.8445,4.4475],[36.681,4.439],[36.6455,4.4515],[36.5475,4.442],[36.234,4.449],[36.0475,4.4465],[35.9645,4.5275],[35.944,4.619],[35.6985,4.6185],[35.608,4.618],[35.5085,4.617],[34.8755,4.613],[34.3875,4.61],[34.0565,4.282],[33.988,4.234],[34.0475,4.179],[34.0495,4.121],[34.0915,4.0615],[34.059,4.0275],[34.1345,3.9615],[34.128,3.872],[34.2155,3.881],[34.2455,3.784],[34.308,3.7115],[34.331,3.733],[34.3825,3.7275],[34.405,3.6925],[34.463,3.6695],[34.4515,3.517],[34.396,3.488],[34.4195,3.4335],[34.4005,3.3705],[34.43,3.3425],[34.4475,3.283],[34.456,3.182],[34.546,3.1365],[34.5725,3.0915],[34.5765,3.0205],[34.599,2.9245],[34.6395,2.9065],[34.653,2.8675],[34.7365,2.855],[34.767,2.811],[34.7835,2.755],[34.7755,2.698],[34.852,2.5835],[34.8975,2.588],[34.913,2.5165],[34.9525,2.461],[34.9165,2.4205],[34.9455,2.2115],[35.0,1.9625],[35.0005,1.7615],[34.991,1.6645],[34.9435,1.5765],[34.864,1.5285],[34.8445,1.4575],[34.794,1.4135],[34.787,1.365],[34.829,1.3095],[34.831,1.269],[34.795,1.223],[34.6685,1.2075],[34.612,1.1595],[34.579,1.1495],[34.575,1.0985],[34.5265,1.107],[34.5025,1.0705],[34.48,0.94],[34.4465,0.864],[34.3615,0.774],[34.315,0.7615],[34.314,0.698],[34.2795,0.646],[34.2005,0.6255],[34.138,0.583],[34.116,0.523],[34.1195,0.4835],[34.0885,0.4555],[34.108,0.3695],[33.91,0.099],[33.9845,-0.1335],[33.929,-0.4575],[33.9255,-0.5605],[33.9335,-0.903],[33.9335,-1.0],[34.019,-1.0],[34.046,-1.046],[34.0805,-1.022],[34.3865,-1.194],[34.776,-1.4145],[35.141,-1.6225],[35.484,-1.8135],[36.001,-2.1055],[36.1455,-2.189],[36.6315,-2.463],[37.004,-2.6715],[37.381,-2.884],[37.512,-2.9545],[37.673,-3.061],[37.712,-3.3105],[37.5845,-3.4405],[37.6175,-3.466],[37.617,-3.52],[37.6655,-3.505],[37.7495,-3.5445],[37.784,-3.6715],[37.99,-3.8155],[38.367,-4.086],[38.8255,-4.405],[39.2195,-4.68],[39.347,-4.832],[39.3645,-4.8635],[39.424,-4.898],[39.478,-4.892],[39.605,-4.681],[39.647,-4.681]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/49/Flag_of_Kenya.svg","name:en":"Kenya","wikidata":"Q114","ISO3166-1:alpha2":"KE","ISO3166-1:alpha3":"KEN","ISO3166-1:numeric":"404"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[35.7735,33.3355],[35.7155,33.3255],[35.658,33.2745],[35.5835,33.2675],[35.5465,33.238],[35.527,33.1415],[35.5035,33.0895],[35.4315,33.0655],[35.354,33.0575],[35.2935,33.108],[35.193,33.0855],[35.0795,33.096],[34.8825,33.172],[34.842,33.0025],[34.794,32.973],[34.745,32.919],[34.7185,32.8445],[34.694,32.7335],[34.678,32.611],[34.595,32.293],[34.4945,32.0295],[34.413,31.904],[34.401,31.8525],[34.295,31.704],[34.488,31.597],[34.565,31.5425],[34.547,31.513],[34.478,31.476],[34.3805,31.3895],[34.3645,31.3615],[34.3665,31.2905],[34.2675,31.22],[34.332,31.041],[34.4035,30.859],[34.497,30.679],[34.519,30.592],[34.5185,30.5325],[34.5575,30.4945],[34.5435,30.413],[34.6115,30.371],[34.707,30.1175],[34.8485,29.759],[34.8565,29.688],[34.8785,29.6435],[34.8665,29.597],[34.8785,29.5435],[34.921,29.4535],[34.9665,29.519],[34.9785,29.577],[35.0145,29.639],[35.012,29.697],[35.03,29.772],[35.0845,29.8855],[35.0785,29.957],[35.1125,30.039],[35.146,30.063],[35.161,30.1345],[35.1445,30.1625],[35.146,30.282],[35.192,30.346],[35.162,30.4415],[35.193,30.499],[35.204,30.582],[35.2615,30.657],[35.296,30.762],[35.341,30.8155],[35.333,30.867],[35.371,30.927],[35.4165,30.951],[35.4275,31.05],[35.4545,31.1045],[35.4495,31.1575],[35.4,31.239],[35.4065,31.2815],[35.4565,31.3625],[35.475,31.4965],[35.3945,31.4915],[35.2305,31.3745],[35.1345,31.355],[35.006,31.3575],[34.92,31.3435],[34.882,31.393],[34.894,31.415],[34.944,31.51],[34.9525,31.5945],[35.0065,31.6525],[35.085,31.6905],[35.127,31.7295],[35.239,31.7095],[35.264,31.8265],[35.178,31.808],[35.1085,31.8235],[35.0835,31.8525],[35.0335,31.859],[35.039,31.907],[34.9905,31.961],[35.005,32.022],[34.985,32.0945],[34.9905,32.142],[34.9595,32.1755],[35.0305,32.266],[35.0165,32.3385],[35.0515,32.367],[35.0655,32.449],[35.2245,32.552],[35.2955,32.5095],[35.358,32.5185],[35.403,32.501],[35.419,32.417],[35.555,32.389],[35.554,32.513],[35.577,32.5525],[35.5735,32.641],[35.633,32.6855],[35.7565,32.745],[35.8375,32.828],[35.851,32.89],[35.895,32.945],[35.8715,32.9815],[35.8505,33.1025],[35.817,33.113],[35.8445,33.1675],[35.815,33.245],[35.7775,33.2765],[35.813,33.317],[35.7735,33.3355]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/d4/Flag_of_Israel.svg","name:en":"Israel","wikidata":"Q801","ISO3166-1:alpha2":"IL","ISO3166-1:alpha3":"ISR","ISO3166-1:numeric":"376"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[9.607,47.061],[9.6345,47.101],[9.626,47.146],[9.573,47.1755],[9.585,47.2055],[9.5305,47.2705],[9.486,47.1805],[9.5195,47.0985],[9.56,47.0485],[9.607,47.061]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/47/Flag_of_Liechtenstein.svg","name:en":"Liechtenstein","wikidata":"Q347","ISO3166-1:alpha2":"LI","ISO3166-1:alpha3":"LIE","ISO3166-1:numeric":"438"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[22.1555,48.4035],[22.121,48.3785],[22.021,48.3925],[21.764,48.339],[21.6685,48.389],[21.621,48.492],[21.525,48.5225],[21.5185,48.547],[21.4395,48.5855],[21.4165,48.5595],[21.3275,48.5595],[21.252,48.532],[21.161,48.5215],[21.1285,48.4925],[21.0665,48.526],[20.956,48.5215],[20.9165,48.56],[20.8365,48.583],[20.654,48.5615],[20.5865,48.536],[20.5065,48.5345],[20.5045,48.4905],[20.416,48.418],[20.4075,48.363],[20.2845,48.262],[20.2495,48.279],[20.07,48.1915],[19.9745,48.166],[19.814,48.167],[19.762,48.213],[19.68,48.213],[19.631,48.25],[19.5085,48.1785],[19.4945,48.11],[19.3995,48.084],[19.301,48.0885],[19.239,48.054],[19.1275,48.0735],[19.058,48.0575],[18.8335,48.048],[18.811,47.9895],[18.767,47.9845],[18.763,47.872],[18.8215,47.8505],[18.739,47.813],[18.682,47.7675],[18.434,47.7565],[18.291,47.7315],[18.087,47.7565],[17.8945,47.739],[17.7785,47.74],[17.7185,47.754],[17.6045,47.8225],[17.454,47.8855],[17.4325,47.921],[17.336,47.9925],[17.202,48.02],[17.161,48.0065],[17.0945,47.971],[17.1125,47.9275],[17.078,47.8775],[17.01,47.8585],[17.072,47.808],[17.0705,47.728],[17.093,47.7085],[16.913,47.688],[16.749,47.6815],[16.721,47.7355],[16.6375,47.756],[16.548,47.7515],[16.552,47.7225],[16.477,47.6905],[16.5145,47.646],[16.59,47.6175],[16.653,47.622],[16.7055,47.523],[16.6525,47.5005],[16.662,47.4555],[16.588,47.423],[16.4455,47.4065],[16.4895,47.2805],[16.442,47.2485],[16.428,47.185],[16.517,47.1495],[16.4645,47.099],[16.5205,47.0615],[16.4525,47.003],[16.3025,46.9985],[16.2465,46.9495],[16.114,46.869],[16.291,46.873],[16.3475,46.8405],[16.313,46.7975],[16.3185,46.754],[16.4285,46.694],[16.392,46.6335],[16.5085,46.5655],[16.5235,46.5055],[16.597,46.476],[16.6645,46.459],[16.7075,46.403],[16.801,46.3855],[16.88,46.334],[16.887,46.28],[16.973,46.225],[17.006,46.223],[17.1595,46.1695],[17.313,45.9665],[17.3745,45.982],[17.3955,45.9305],[17.4455,45.9505],[17.5655,45.9375],[17.6145,45.9095],[17.6725,45.835],[17.746,45.828],[17.833,45.792],[18.0015,45.7945],[18.082,45.7645],[18.191,45.788],[18.244,45.761],[18.4105,45.739],[18.5555,45.7945],[18.628,45.8735],[18.705,45.918],[18.791,45.878],[18.807,45.903],[18.89,45.922],[18.962,45.926],[19.006,45.9585],[19.0795,45.9635],[19.0655,46.0],[19.1045,46.04],[19.1475,45.996],[19.2855,45.997],[19.364,46.052],[19.4155,46.0455],[19.5025,46.142],[19.5675,46.1785],[19.6315,46.1695],[19.6965,46.1875],[19.818,46.128],[19.935,46.176],[20.096,46.177],[20.1375,46.144],[20.182,46.16],[20.2645,46.1265],[20.3555,46.1695],[20.459,46.143],[20.503,46.1895],[20.632,46.128],[20.715,46.167],[20.749,46.251],[20.8735,46.288],[20.922,46.262],[21.0245,46.2665],[21.066,46.243],[21.1155,46.3015],[21.168,46.298],[21.1995,46.348],[21.2065,46.403],[21.2755,46.4065],[21.318,46.4505],[21.2605,46.502],[21.321,46.583],[21.33,46.6315],[21.4165,46.6425],[21.5295,46.721],[21.484,46.765],[21.519,46.836],[21.595,46.8605],[21.6795,46.998],[21.6825,47.0455],[21.726,47.0985],[21.773,47.109],[21.8175,47.173],[21.858,47.187],[21.852,47.239],[21.9385,47.373],[22.012,47.376],[22.0355,47.4275],[22.0075,47.4755],[22.045,47.54],[22.188,47.609],[22.2645,47.731],[22.426,47.75],[22.481,47.811],[22.549,47.772],[22.68,47.788],[22.7685,47.878],[22.8475,47.908],[22.8975,47.954],[22.8365,47.99],[22.8815,48.055],[22.827,48.1155],[22.7205,48.1155],[22.6755,48.092],[22.603,48.104],[22.566,48.179],[22.49,48.253],[22.369,48.245],[22.315,48.3285],[22.2675,48.361],[22.2645,48.404],[22.2155,48.4245],[22.1555,48.4035]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/c1/Flag_of_Hungary.svg","name:en":"Hungary","wikidata":"Q28","ISO3166-1:alpha2":"HU","ISO3166-1:alpha3":"HUN","ISO3166-1:numeric":"348"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[22.5655,49.088],[22.414,49.102],[22.3695,49.1455],[22.3205,49.1355],[22.236,49.1545],[22.0305,49.225],[22.034,49.2785],[21.961,49.349],[21.7635,49.3835],[21.631,49.4475],[21.434,49.4125],[21.2775,49.461],[21.192,49.401],[21.124,49.4365],[21.0565,49.4215],[21.104,49.3765],[21.044,49.3655],[20.994,49.3125],[20.9255,49.296],[20.8655,49.3475],[20.826,49.3345],[20.723,49.4195],[20.6115,49.4135],[20.574,49.3765],[20.464,49.416],[20.408,49.393],[20.3295,49.391],[20.3195,49.347],[20.242,49.3505],[20.1465,49.318],[20.1025,49.253],[20.0755,49.179],[20.0085,49.22],[19.9195,49.236],[19.8445,49.195],[19.763,49.2075],[19.805,49.323],[19.7905,49.4105],[19.7295,49.3915],[19.6345,49.4125],[19.582,49.458],[19.5305,49.536],[19.5295,49.573],[19.469,49.5965],[19.41,49.592],[19.36,49.5355],[19.2815,49.5355],[19.2335,49.511],[19.219,49.4485],[19.1775,49.414],[19.027,49.394],[18.961,49.4545],[18.9715,49.5045],[18.851,49.517],[18.7545,49.4885],[18.7105,49.5025],[18.5455,49.5005],[18.548,49.468],[18.492,49.435],[18.379,49.3305],[18.297,49.3045],[18.184,49.287],[18.1065,49.134],[18.116,49.092],[18.082,49.0465],[18.0245,49.021],[17.9245,49.02],[17.8855,48.9275],[17.7815,48.9255],[17.704,48.861],[17.633,48.855],[17.52,48.813],[17.477,48.8415],[17.3965,48.813],[17.242,48.8685],[17.1925,48.8745],[17.115,48.8335],[17.089,48.786],[17.043,48.7635],[16.94,48.6165],[16.954,48.5435],[16.85,48.4495],[16.843,48.3515],[16.895,48.313],[16.976,48.172],[17.0775,48.106],[17.0675,48.0315],[17.161,48.0065],[17.202,48.02],[17.336,47.9925],[17.4325,47.921],[17.454,47.8855],[17.6045,47.8225],[17.7185,47.754],[17.7785,47.74],[17.8945,47.739],[18.087,47.7565],[18.291,47.7315],[18.434,47.7565],[18.682,47.7675],[18.739,47.813],[18.8215,47.8505],[18.763,47.872],[18.767,47.9845],[18.811,47.9895],[18.8335,48.048],[19.058,48.0575],[19.1275,48.0735],[19.239,48.054],[19.301,48.0885],[19.3995,48.084],[19.4945,48.11],[19.5085,48.1785],[19.631,48.25],[19.68,48.213],[19.762,48.213],[19.814,48.167],[19.9745,48.166],[20.07,48.1915],[20.2495,48.279],[20.2845,48.262],[20.4075,48.363],[20.416,48.418],[20.5045,48.4905],[20.5065,48.5345],[20.5865,48.536],[20.654,48.5615],[20.8365,48.583],[20.9165,48.56],[20.956,48.5215],[21.0665,48.526],[21.1285,48.4925],[21.161,48.5215],[21.252,48.532],[21.3275,48.5595],[21.4165,48.5595],[21.4395,48.5855],[21.5185,48.547],[21.525,48.5225],[21.621,48.492],[21.6685,48.389],[21.764,48.339],[22.021,48.3925],[22.121,48.3785],[22.1555,48.4035],[22.1375,48.4325],[22.161,48.5675],[22.1895,48.61],[22.3395,48.684],[22.3505,48.7715],[22.376,48.834],[22.421,48.8845],[22.4285,48.9315],[22.4775,48.991],[22.5455,49.007],[22.5655,49.088]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/e/e6/Flag_of_Slovakia.svg","name:en":"Slovakia","wikidata":"Q214","ISO3166-1:alpha2":"SK","ISO3166-1:alpha3":"SVK","ISO3166-1:numeric":"703"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[27.3515,57.518],[27.2255,57.5545],[27.1175,57.562],[27.0315,57.6045],[26.9455,57.603],[26.782,57.5725],[26.676,57.5665],[26.6145,57.5295],[26.5,57.5245],[26.4695,57.5755],[26.4015,57.572],[26.275,57.5975],[26.2055,57.715],[26.136,57.751],[26.027,57.775],[26.0585,57.8365],[25.8205,57.865],[25.7725,57.9125],[25.7035,57.9035],[25.486,57.975],[25.467,58.005],[25.3035,58.0345],[25.2165,58.074],[25.106,58.078],[25.0205,58.018],[24.8325,57.972],[24.742,57.982],[24.6285,57.942],[24.585,57.962],[24.4625,57.925],[24.46,57.88],[24.357,57.8745],[24.261,57.917],[24.2095,57.899],[23.601,57.899],[23.6485,57.783],[23.5825,57.6695],[23.406,57.594],[23.181,57.5865],[22.999,57.702],[22.7075,57.941],[22.5835,57.9275],[22.1435,57.779],[21.916,57.7495],[21.843,57.763],[21.656,57.746],[21.465,57.6865],[21.364,57.6135],[21.2635,57.5145],[21.162,57.378],[21.098,57.2195],[21.0645,57.0935],[20.924,56.998],[20.7715,56.931],[20.712,56.8485],[20.6785,56.6775],[20.6715,56.2475],[20.7095,56.0455],[21.2005,56.0765],[21.3225,56.215],[21.4525,56.2485],[21.5025,56.2955],[21.618,56.3245],[21.722,56.3135],[21.8355,56.3715],[21.9195,56.3685],[21.9945,56.4135],[22.1255,56.4325],[22.241,56.4],[22.3455,56.394],[22.423,56.41],[22.6165,56.3825],[22.8405,56.3655],[23.0025,56.4065],[23.027,56.331],[23.0935,56.305],[23.184,56.3375],[23.177,56.3685],[23.388,56.379],[23.439,56.3515],[23.545,56.332],[23.63,56.36],[23.7805,56.3675],[23.795,56.339],[24.019,56.33],[24.1215,56.249],[24.342,56.295],[24.454,56.258],[24.5645,56.289],[24.587,56.3315],[24.699,56.3975],[24.9025,56.418],[24.969,56.366],[24.973,56.3105],[25.056,56.266],[25.092,56.186],[25.2795,56.1585],[25.404,56.158],[25.48,56.143],[25.6505,56.135],[25.6885,56.0865],[25.82,56.055],[25.8605,55.9995],[25.974,55.9815],[26.0455,55.945],[26.1205,55.8795],[26.2035,55.859],[26.2685,55.7675],[26.35,55.7425],[26.3755,55.7095],[26.443,55.709],[26.531,55.677],[26.6305,55.6805],[26.659,55.706],[26.8,55.698],[26.8705,55.714],[26.9205,55.788],[27.015,55.8285],[27.1605,55.85],[27.2875,55.785],[27.378,55.8075],[27.429,55.795],[27.6155,55.787],[27.653,55.9295],[27.8005,55.9845],[27.833,56.0235],[27.906,56.052],[27.972,56.1205],[28.026,56.1195],[28.1515,56.17],[28.24,56.2715],[28.1655,56.3745],[28.1945,56.4425],[28.0975,56.511],[28.125,56.5825],[28.062,56.586],[28.0115,56.6365],[27.981,56.707],[27.901,56.76],[27.9765,56.812],[27.8985,56.838],[27.8475,56.88],[27.6595,56.8345],[27.686,56.9115],[27.7375,56.92],[27.7695,57.005],[27.748,57.053],[27.757,57.131],[27.817,57.1425],[27.8675,57.297],[27.6715,57.395],[27.5175,57.427],[27.5525,57.469],[27.547,57.5195],[27.5005,57.54],[27.3515,57.518]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/84/Flag_of_Latvia.svg","name:en":"Latvia","wikidata":"Q211","ISO3166-1:alpha2":"LV","ISO3166-1:alpha3":"LVA","ISO3166-1:numeric":"428"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[124.9775,37.6875],[125.047,37.6375],[125.2445,37.5835],[125.4265,37.649],[125.5165,37.682],[125.695,37.6915],[125.75,37.7145],[126.0165,37.6585],[126.111,37.7125],[126.1605,37.7175],[126.187,37.749],[126.206,37.823],[126.4135,37.8445],[126.575,37.7625],[126.652,37.781],[126.6915,37.8395],[126.6695,37.9445],[126.7215,37.955],[126.8125,37.999],[126.8565,38.041],[126.87,38.0885],[126.9645,38.135],[126.976,38.199],[127.042,38.259],[127.1105,38.2955],[127.2235,38.328],[127.306,38.3175],[127.3855,38.337],[127.5055,38.301],[127.5735,38.3335],[127.691,38.3245],[127.7425,38.341],[127.8205,38.3065],[127.882,38.331],[128.0675,38.3085],[128.1575,38.343],[128.283,38.4365],[128.3135,38.514],[128.3065,38.57],[128.3745,38.6235],[128.656,38.6175],[128.6225,38.683],[128.597,38.7745],[128.539,38.8175],[128.511,38.8615],[128.4315,38.9285],[128.329,38.962],[128.2755,39.0135],[128.17,39.059],[128.029,39.153],[127.9755,39.233],[127.8215,39.375],[127.788,39.488],[127.8395,39.588],[127.824,39.6555],[127.993,39.7],[128.0965,39.7755],[128.1985,39.775],[128.298,39.7955],[128.473,39.8585],[128.651,39.965],[128.7745,40.006],[128.8365,40.04],[128.9125,40.138],[128.92,40.171],[129.014,40.1985],[129.104,40.2665],[129.154,40.277],[129.2855,40.3385],[129.3205,40.394],[129.3755,40.434],[129.4065,40.486],[129.509,40.538],[129.5285,40.5725],[129.6765,40.6355],[129.7815,40.6345],[129.9175,40.694],[130.007,40.8515],[130.0205,40.943],[129.9915,41.0445],[129.994,41.189],[130.0575,41.3245],[130.055,41.438],[129.996,41.5295],[129.9475,41.5685],[130.048,41.6225],[130.1125,41.723],[130.158,41.757],[130.2325,41.855],[130.3725,41.93],[130.388,41.956],[130.51,42.0285],[130.6435,42.0435],[130.88,42.134],[130.9245,42.1705],[130.702,42.2925],[130.6545,42.325],[130.6695,42.378],[130.637,42.4185],[130.5785,42.43],[130.5785,42.4845],[130.5245,42.547],[130.4145,42.5675],[130.37,42.6205],[130.253,42.7065],[130.2375,42.8205],[130.262,42.9035],[130.1725,42.914],[130.138,42.902],[130.0985,42.9865],[130.063,42.9675],[129.954,42.9785],[129.9005,43.005],[129.8515,42.9615],[129.8365,42.865],[129.808,42.789],[129.76,42.708],[129.785,42.6795],[129.732,42.4985],[129.7445,42.467],[129.704,42.427],[129.607,42.437],[129.5325,42.3745],[129.4945,42.4125],[129.421,42.433],[129.304,42.4155],[129.2235,42.3525],[129.225,42.278],[129.1765,42.2595],[129.203,42.2065],[129.1145,42.139],[129.0515,42.138],[128.915,42.01],[128.745,42.0515],[128.6765,42.012],[128.6305,42.037],[128.5765,42.0],[128.506,41.997],[128.4575,42.0185],[128.285,42.024],[128.0845,42.0205],[128.031,41.9955],[128.0995,41.945],[128.0965,41.838],[128.1085,41.789],[128.1645,41.7105],[128.242,41.679],[128.311,41.589],[128.2965,41.538],[128.2355,41.4985],[128.201,41.4085],[128.108,41.3605],[128.0825,41.393],[128.032,41.391],[127.967,41.4355],[127.8475,41.4195],[127.559,41.43],[127.493,41.4755],[127.4105,41.4555],[127.3375,41.4635],[127.1615,41.54],[127.104,41.64],[127.03,41.672],[127.054,41.7],[126.9445,41.805],[126.725,41.705],[126.5655,41.598],[126.588,41.5625],[126.505,41.435],[126.4865,41.371],[126.433,41.352],[126.3625,41.281],[126.3535,41.243],[126.3095,41.215],[126.274,41.155],[126.2345,41.145],[126.1305,41.058],[126.1035,41.005],[126.0515,40.9635],[126.0185,40.9015],[125.958,40.8805],[125.858,40.8835],[125.7955,40.865],[125.702,40.8635],[125.6295,40.799],[125.5745,40.7825],[125.5245,40.7165],[125.486,40.7215],[125.4515,40.6745],[125.329,40.637],[125.267,40.6475],[125.2575,40.613],[125.186,40.6075],[125.0955,40.5565],[125.0085,40.525],[125.0285,40.492],[124.922,40.4545],[124.8895,40.4755],[124.817,40.4045],[124.7495,40.379],[124.706,40.313],[124.6425,40.301],[124.5095,40.2185],[124.481,40.1725],[124.412,40.139],[124.3505,40.0805],[124.3375,40.0465],[124.372,40.017],[124.354,39.9705],[124.2925,39.968],[124.284,39.9275],[124.2375,39.9265],[124.21,39.8575],[124.173,39.829],[124.1595,39.743],[124.0915,39.612],[124.1805,39.5895],[124.2225,39.5235],[124.327,39.481],[124.33,39.373],[124.3695,39.306],[124.4505,39.249],[124.4935,39.138],[124.582,39.0815],[124.7155,39.0615],[124.811,39.075],[124.8925,39.103],[124.9735,39.209],[125.0295,39.196],[125.022,39.16],[124.9595,39.081],[124.874,38.947],[124.797,38.909],[124.7415,38.859],[124.696,38.7635],[124.6135,38.7185],[124.539,38.645],[124.517,38.5945],[124.5055,38.4925],[124.541,38.3925],[124.5935,38.3305],[124.5525,38.2965],[124.445,38.249],[124.398,38.1885],[124.394,38.131],[124.4165,38.05],[124.6335,38.05],[124.85,38.0],[124.8665,37.7665],[124.9775,37.6875]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/5/51/Flag_of_North_Korea.svg","name:en":"North Korea","wikidata":"Q423","ISO3166-1:alpha2":"KP","ISO3166-1:alpha3":"PRK","ISO3166-1:numeric":"408"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[122.714,24.45],[122.73,24.375],[122.7555,24.332],[122.8145,24.2805],[122.862,24.2575],[122.9505,24.2385],[123.0225,24.2375],[123.1275,24.2675],[123.202,24.322],[123.24,24.37],[123.2625,24.4335],[123.2515,24.531],[123.2135,24.5905],[123.157,24.6345],[123.068,24.667],[123.0045,24.675],[122.887,24.66],[122.7725,24.5855],[122.721,24.499],[122.714,24.45]]],[[[123.2365,25.736],[123.2535,25.6595],[123.302,25.594],[123.374,25.5505],[123.558,25.52],[123.643,25.535],[123.7155,25.579],[123.7635,25.644],[123.777,25.738],[123.847,25.7805],[123.8955,25.8455],[123.9125,25.922],[123.8955,25.9985],[123.8405,26.071],[123.7685,26.1145],[123.683,26.1295],[123.598,26.1145],[123.5255,26.071],[123.4775,26.006],[123.4655,25.952],[123.3875,25.938],[123.315,25.895],[123.2535,25.813],[123.2365,25.736]]],[[[123.3355,24.1925],[123.354,24.112],[123.3955,24.055],[123.484,24.003],[123.545,23.9925],[123.576,23.9355],[123.6455,23.8775],[123.7685,23.8465],[123.864,23.8565],[123.9245,23.8825],[123.9865,23.938],[124.025,24.021],[124.1295,24.052],[124.219,24.1335],[124.329,24.164],[124.4005,24.2105],[124.446,24.2695],[124.4775,24.392],[124.5355,24.489],[124.6075,24.452],[124.7385,24.4405],[124.8315,24.47],[124.8795,24.504],[124.929,24.5725],[124.9475,24.639],[124.945,24.693],[125.042,24.631],[125.1225,24.548],[125.2165,24.5155],[125.3105,24.512],[125.408,24.5265],[125.502,24.521],[125.605,24.5565],[125.666,24.61],[125.693,24.659],[125.703,24.7535],[125.6505,24.8585],[125.5695,24.9175],[125.5765,25.018],[125.552,25.0775],[125.48,25.1475],[125.3595,25.1805],[125.2865,25.169],[125.2235,25.138],[125.117,25.106],[125.062,25.0635],[124.9435,24.9335],[124.915,24.8475],[124.8115,24.93],[124.702,24.961],[124.6045,24.9455],[124.544,24.913],[124.4865,24.849],[124.463,24.7725],[124.4025,24.8025],[124.319,24.818],[124.2125,24.7935],[124.139,24.735],[124.108,24.6845],[124.01,24.6605],[123.9635,24.6295],[123.847,24.675],[123.741,24.665],[123.6695,24.626],[123.547,24.5075],[123.485,24.428],[123.453,24.3695],[123.393,24.327],[123.348,24.259],[123.3355,24.1925]]],[[[124.332,25.9225],[124.341,25.8655],[124.388,25.7875],[124.474,25.7335],[124.554,25.7195],[124.6725,25.7485],[124.748,25.8135],[124.784,25.9195],[124.77,25.991],[124.731,26.0525],[124.692,26.086],[124.622,26.1175],[124.561,26.125],[124.482,26.1125],[124.429,26.088],[124.3635,26.024],[124.332,25.9225]]],[[[126.485,26.3605],[126.518,26.252],[126.555,26.209],[126.696,26.1025],[126.7685,26.074],[126.8215,26.0685],[126.903,26.0825],[127.0005,26.1505],[127.035,26.0685],[127.1175,25.99],[127.2315,25.9465],[127.341,25.9355],[127.3975,25.942],[127.498,25.901],[127.678,25.8745],[127.737,25.882],[127.973,25.9665],[128.093,26.036],[128.142,26.092],[128.417,26.51],[128.538,26.661],[128.558,26.726],[128.5435,26.839],[128.6435,26.912],[128.6785,26.9825],[128.6835,27.083],[128.6565,27.144],[128.7175,27.17],[128.793,27.2225],[128.8965,27.317],[128.9325,27.3865],[128.937,27.4615],[129.0575,27.48],[129.157,27.5385],[129.229,27.6395],[129.254,27.699],[129.2615,27.7975],[129.3225,27.8075],[129.4165,27.857],[129.661,28.0735],[129.742,28.1665],[129.806,28.115],[129.915,28.0765],[130.011,28.0825],[130.106,28.122],[130.152,28.16],[130.2185,28.241],[130.249,28.295],[130.2615,28.3755],[130.2415,28.449],[130.163,28.5345],[130.0765,28.572],[129.948,28.569],[129.9355,28.6135],[129.991,28.687],[130.0055,28.741],[129.9945,28.822],[129.942,28.8975],[129.8295,28.9535],[129.7175,28.951],[129.6385,28.9165],[129.5835,28.8625],[129.5495,28.76],[129.559,28.7005],[129.07,28.4805],[129.0225,28.45],[128.9385,28.3565],[128.9105,28.291],[128.905,28.1085],[128.814,28.0775],[128.7385,28.0335],[128.6765,27.949],[128.6535,27.8175],[128.657,27.6965],[128.6755,27.64],[128.559,27.604],[128.4575,27.5935],[128.3995,27.5665],[128.3455,27.5165],[128.317,27.47],[128.295,27.3755],[128.3085,27.3035],[128.336,27.2505],[128.24,27.1935],[128.1965,27.236],[128.116,27.286],[128.03,27.3015],[127.889,27.2675],[127.764,27.1655],[127.7095,27.086],[127.542,26.8095],[127.462,26.645],[127.3985,26.7405],[127.288,26.796],[127.189,26.798],[127.123,26.7775],[127.0255,26.6965],[126.989,26.7385],[126.8855,26.7895],[126.8095,26.7945],[126.735,26.7755],[126.665,26.7295],[126.623,26.6725],[126.604,26.5915],[126.6095,26.5495],[126.5435,26.502],[126.4955,26.4235],[126.485,26.3605]]],[[[127.8685,32.2465],[127.8975,32.1475],[127.9445,32.097],[127.995,32.0665],[128.1125,32.044],[128.116,31.9395],[128.168,31.853],[128.2385,31.8065],[128.3215,31.786],[128.41,31.7925],[128.4775,31.818],[128.5325,31.8565],[128.631,31.958],[128.6565,32.024],[128.6415,32.127],[128.613,32.17],[128.5475,32.2215],[128.4035,32.259],[128.344,32.2545],[128.3275,32.3225],[128.2525,32.4065],[128.1705,32.441],[128.044,32.441],[127.9635,32.407],[127.895,32.337],[127.8685,32.2465]]],[[[127.991,27.8785],[127.9975,27.8325],[128.0355,27.755],[128.0825,27.7095],[128.17,27.6685],[128.2795,27.6645],[128.3525,27.6895],[128.4235,27.75],[128.458,27.824],[128.457,27.9095],[128.41,28.0005],[128.3405,28.0565],[128.267,28.0815],[128.156,28.077],[128.1055,28.0575],[128.037,28.002],[128.0125,27.9635],[127.991,27.8785]]],[[[128.3515,32.7215],[128.3615,32.5925],[128.386,32.523],[128.446,32.459],[128.5395,32.411],[128.6145,32.3885],[128.805,32.371],[129.21,32.077],[129.5195,31.85],[129.4425,31.7395],[129.1915,31.2305],[129.1825,31.163],[129.19,30.822],[129.2175,30.7355],[129.27,30.679],[129.3865,30.6315],[129.851,30.577],[130.096,30.699],[130.3405,30.6775],[130.4795,30.761],[130.931,31.0425],[131.3795,31.321],[131.659,31.494],[131.701,31.614],[131.7035,31.696],[131.723,31.794],[131.7075,31.8585],[131.7175,31.948],[131.8045,32.1935],[131.8515,32.2625],[132.593,32.5045],[133.0415,32.522],[133.1375,32.548],[133.219,32.6115],[133.2585,32.6895],[133.3015,32.86],[133.728,32.9465],[134.235,33.047],[134.3465,33.099],[134.407,33.1665],[134.6295,33.4365],[135.2045,33.4645],[135.327,33.375],[135.4,33.3415],[135.5125,33.3065],[135.58,33.297],[135.6825,33.244],[135.769,33.2335],[135.9315,33.2675],[135.9975,33.3],[136.057,33.3525],[136.0935,33.4105],[136.1415,33.445],[136.1935,33.523],[136.6765,33.8595],[137.0555,34.122],[137.663,34.468],[137.807,34.445],[137.946,34.466],[138.105,34.414],[138.2125,34.392],[138.952,34.3725],[138.849,34.269],[138.828,34.163],[138.7355,34.145],[138.677,34.1135],[138.6035,34.0425],[138.5805,33.992],[138.5805,33.903],[138.608,33.844],[138.68,33.7785],[138.751,33.7505],[138.8185,33.7425],[138.914,33.7595],[138.993,33.8055],[139.0415,33.8565],[139.0745,33.9255],[139.078,33.98],[139.149,33.9835],[139.202,33.909],[139.3025,33.856],[139.197,33.833],[139.1275,33.7925],[139.0695,33.7125],[139.064,33.6085],[139.115,33.5225],[139.173,33.4805],[139.247,33.456],[139.339,33.454],[139.424,33.48],[139.4965,33.537],[139.5325,33.6035],[139.539,33.658],[139.6225,33.6505],[139.75,33.681],[139.8065,33.7225],[139.8655,33.8225],[139.8725,33.8615],[139.855,33.948],[139.799,34.0255],[139.802,34.1435],[139.763,34.2195],[139.719,34.2615],[139.6265,34.311],[139.5225,34.325],[139.543,34.498],[139.9665,34.706],[140.094,34.757],[140.164,34.8245],[140.199,34.882],[140.262,34.916],[140.391,34.945],[140.469,34.9775],[140.5675,35.055],[140.623,35.1325],[140.643,35.1905],[140.66,35.316],[140.641,35.3895],[140.6865,35.4505],[140.733,35.4855],[140.8055,35.4955],[140.904,35.4915],[140.9825,35.5125],[141.0335,35.541],[141.0865,35.596],[141.1235,35.696],[141.1205,35.7555],[141.07,35.855],[140.996,35.914],[140.9585,35.969],[140.9395,36.0335],[140.865,36.113],[140.8155,36.2205],[140.854,36.293],[140.8825,36.385],[140.8875,36.4955],[141.031,36.7445],[141.155,36.827],[141.225,36.9385],[141.288,37.298],[141.295,37.488],[141.2795,37.6005],[141.2935,37.6615],[141.265,37.7565],[141.7555,38.125],[141.828,38.2145],[141.98,38.588],[142.168,39.046],[142.31,39.411],[142.3305,39.528],[142.3255,39.593],[142.2375,39.9335],[142.2525,40.0015],[142.2375,40.069],[142.158,40.156],[142.0925,40.299],[142.0015,40.4455],[141.904,40.5605],[141.7485,40.6955],[141.696,40.722],[141.6615,40.8675],[141.6705,40.9475],[141.6505,41.013],[141.664,41.104],[141.6585,41.163],[141.6915,41.281],[141.7285,41.359],[141.7365,41.421],[141.716,41.5045],[141.6175,41.601],[140.9345,41.603],[140.8765,41.5995],[140.2335,41.2665],[139.6035,40.931],[139.2995,40.666],[139.254,40.61],[139.2345,40.528],[139.2505,40.465],[139.429,40.002],[139.343,39.593],[139.268,39.231],[139.0465,38.659],[138.513,38.5415],[138.3835,38.5225],[138.2785,38.4645],[138.197,38.382],[138.126,38.3375],[138.0675,38.243],[138.024,38.195],[137.5315,38.135],[136.8505,38.0495],[136.7955,38.0305],[136.69,37.9485],[136.6585,37.8775],[136.4805,37.379],[136.47,37.326],[136.4275,37.2245],[136.4185,37.1385],[136.432,37.08],[136.5015,36.958],[136.5045,36.8865],[136.4385,36.781],[136.3575,36.688],[136.2175,36.5415],[136.1465,36.5105],[136.0815,36.4515],[136.0285,36.4395],[135.475,36.15],[135.11,35.9575],[134.9775,35.9195],[134.859,35.864],[134.7655,35.8745],[134.608,35.862],[134.4875,35.8675],[134.218,35.785],[134.1335,35.744],[134.0645,35.732],[133.943,35.7305],[133.8585,35.7075],[133.768,35.7005],[133.645,35.7265],[133.5285,35.728],[133.44,35.776],[133.3495,35.7895],[133.2225,35.7825],[133.1835,35.8125],[133.2435,35.845],[133.3625,35.9695],[133.4555,35.991],[133.551,36.061],[133.594,36.1205],[133.6345,36.235],[133.6335,36.31],[133.58,36.409],[133.539,36.4475],[133.419,36.522],[133.349,36.548],[133.265,36.5555],[133.1455,36.526],[133.04,36.465],[132.969,36.3935],[132.9365,36.327],[132.871,36.3],[132.796,36.2505],[132.7355,36.1865],[132.7005,36.1045],[132.7015,36.037],[132.7455,35.9485],[132.8205,35.872],[132.967,35.78],[132.898,35.7365],[132.74,35.6905],[132.5305,35.62],[132.435,35.562],[132.398,35.523],[132.369,35.459],[132.3655,35.4045],[132.2745,35.3535],[132.1415,35.2235],[131.643,35.1175],[131.0685,34.9925],[130.996,34.966],[130.398,34.6475],[130.198,34.537],[130.0125,34.4395],[129.889,34.391],[129.8035,34.058],[129.639,33.911],[129.121,33.5055],[128.859,33.5055],[128.616,33.314],[128.5875,33.276],[128.37,32.8015],[128.3515,32.7215]]],[[[128.7445,28.8],[128.7625,28.7245],[128.795,28.674],[128.861,28.6215],[128.9105,28.602],[128.9955,28.5915],[129.0665,28.6015],[129.147,28.6385],[129.192,28.683],[129.2205,28.7355],[129.2335,28.841],[129.2065,28.9265],[129.2875,28.9355],[129.373,28.978],[129.424,29.0345],[129.5145,29.0765],[129.562,29.127],[129.589,29.188],[129.593,29.245],[129.667,29.251],[129.7575,29.2885],[129.7985,29.322],[129.8405,29.3895],[129.8505,29.446],[129.921,29.5115],[129.968,29.619],[130.075,29.67],[130.1345,29.747],[130.1485,29.858],[130.2515,29.933],[130.2905,30.017],[130.295,30.079],[130.381,30.043],[130.4665,30.0285],[130.5665,30.029],[130.652,30.048],[130.7385,30.0885],[130.8115,30.152],[130.909,30.145],[131.057,30.172],[131.147,30.222],[131.194,30.2825],[131.2125,30.35],[131.214,30.424],[131.2645,30.507],[131.3155,30.6815],[131.316,30.784],[131.301,30.8585],[131.26,30.943],[131.1085,30.8685],[131.045,30.89],[130.987,30.8575],[130.948,30.8025],[130.9115,30.789],[130.8755,30.8155],[130.819,30.806],[130.786,30.7665],[130.785,30.701],[130.3205,30.463],[130.27,30.51],[130.1775,30.5495],[130.1055,30.528],[130.0915,30.4635],[129.9415,30.3885],[129.97,30.3495],[130.0755,30.2595],[129.9925,30.25],[129.907,30.208],[129.8235,30.191],[129.761,30.1565],[129.694,30.075],[129.5915,30.1105],[129.537,30.116],[129.4445,30.1005],[129.3465,30.035],[129.31,29.9765],[129.2985,29.899],[129.3315,29.797],[129.2955,29.687],[129.3125,29.6105],[129.371,29.5365],[129.3575,29.43],[129.277,29.424],[129.1935,29.3925],[129.1435,29.353],[129.0765,29.3305],[129.0095,29.281],[128.9625,29.195],[128.9605,29.119],[129.0,29.0365],[128.913,29.0215],[128.8135,28.954],[128.754,28.859],[128.7445,28.8]]],[[[128.998,33.9475],[129.071,33.9085],[129.239,34.038],[129.283,34.059],[129.6855,34.4155],[129.7415,34.6465],[129.7205,34.76],[129.6535,34.8485],[129.5995,34.8915],[129.2685,34.6795],[129.223,34.567],[128.998,33.9475]]],[[[130.961,24.4715],[130.9775,24.395],[131.0155,24.3355],[131.057,24.3005],[131.1245,24.27],[131.1885,24.2615],[131.2725,24.2765],[131.3685,24.344],[131.4055,24.411],[131.4085,24.518],[131.3715,24.5885],[131.317,24.636],[131.2435,24.6655],[131.181,24.672],[131.107,24.6605],[131.0255,24.6135],[130.982,24.5575],[130.961,24.4715]]],[[[130.9915,25.823],[130.999,25.7715],[131.032,25.7085],[131.1125,25.643],[131.1795,25.6185],[131.2715,25.6155],[131.353,25.6375],[131.3985,25.6635],[131.4655,25.739],[131.486,25.796],[131.5385,25.8775],[131.554,25.9515],[131.5365,26.03],[131.496,26.087],[131.437,26.1285],[131.361,26.153],[131.2745,26.1605],[131.1875,26.1405],[131.1055,26.0785],[131.071,26.014],[131.024,25.959],[131.0045,25.9135],[130.9915,25.823]]],[[[135.8535,20.4235],[135.87,20.347],[135.916,20.2825],[135.985,20.239],[136.1025,20.2145],[136.184,20.23],[136.2535,20.273],[136.306,20.346],[136.3225,20.4225],[136.3065,20.4965],[136.26,20.5635],[136.183,20.614],[136.1015,20.629],[135.985,20.608],[135.916,20.5645],[135.87,20.5],[135.8535,20.4235]]],[[[145.6375,44.3015],[145.6135,44.4005],[145.5795,44.4515],[145.5,44.508],[145.3755,44.5425],[145.289,44.543],[145.1755,44.512],[145.09,44.455],[144.9725,44.333],[144.826,44.2465],[144.658,44.119],[144.531,44.127],[144.502,44.1945],[144.435,44.259],[144.3795,44.288],[144.279,44.3115],[144.07,44.3275],[143.8285,44.384],[143.6,44.462],[143.5375,44.518],[143.3825,44.6055],[143.295,44.644],[143.1905,44.7095],[143.133,44.765],[142.9645,44.884],[142.864,45.002],[142.784,45.1235],[142.707,45.1995],[142.648,45.232],[142.4945,45.3615],[142.4325,45.43],[142.039,45.505],[142.018,45.545],[141.9165,45.5765],[141.1845,45.711],[140.9415,45.705],[140.84,45.686],[140.7215,45.613],[140.6815,45.5435],[140.6835,45.401],[140.899,44.7425],[141.0125,44.3885],[141.045,43.842],[140.1735,43.5005],[140.1215,43.4635],[139.8585,43.0975],[139.5945,42.724],[139.213,42.339],[139.159,42.2655],[139.1335,42.199],[139.095,41.804],[139.068,41.498],[139.093,41.419],[139.1215,41.381],[139.201,41.325],[139.6985,41.167],[139.756,41.1545],[139.862,41.157],[140.238,41.356],[140.873,41.692],[140.9445,41.6615],[141.0375,41.6655],[141.0865,41.683],[141.4015,41.6825],[141.4545,41.787],[141.4475,41.86],[141.2975,42.2635],[141.35,42.2845],[141.5875,42.4145],[141.7315,42.383],[141.7835,42.381],[141.916,42.302],[142.0315,42.273],[142.078,42.2355],[142.255,42.14],[142.386,42.082],[142.4675,42.0575],[142.535,42.019],[142.695,41.9625],[142.8265,41.933],[142.9245,41.8905],[143.0125,41.8085],[143.0995,41.754],[143.215,41.718],[143.3655,41.7325],[143.471,41.7945],[143.51,41.8475],[143.5255,41.9285],[143.5675,41.989],[143.605,42.159],[143.604,42.2305],[143.623,42.3145],[143.675,42.3845],[143.7905,42.5005],[144.0725,42.7085],[144.171,42.7615],[144.2505,42.7885],[144.424,42.7425],[144.5925,42.7485],[144.7425,42.733],[144.8365,42.738],[144.97,42.7615],[145.1045,42.805],[145.628,42.981],[145.7995,43.066],[146.0085,43.2255],[145.8425,43.381],[145.7595,43.502],[145.4475,43.6235],[145.279,43.7355],[145.2765,43.8395],[145.32,43.9405],[145.514,44.132],[145.6375,44.3015]]],[[[139.4365,33.132],[139.443,33.0835],[139.492,32.9945],[139.543,32.953],[139.623,32.9215],[139.7405,32.8615],[139.8085,32.8465],[139.887,32.851],[139.9745,32.885],[140.017,32.918],[140.0715,32.9895],[140.0965,33.0625],[140.0925,33.133],[140.0605,33.239],[140.0375,33.277],[139.9675,33.336],[139.871,33.3665],[139.7205,33.3585],[139.5985,33.325],[139.504,33.2745],[139.4585,33.2175],[139.4365,33.132]]],[[[139.5165,32.456],[139.537,32.3725],[139.61,32.2915],[139.7075,32.25],[139.781,32.2435],[139.8525,32.2555],[139.9265,32.291],[139.9755,32.336],[140.011,32.403],[140.0185,32.4575],[139.995,32.544],[139.938,32.61],[139.878,32.6475],[139.801,32.6705],[139.674,32.6605],[139.619,32.6355],[139.5585,32.583],[139.5315,32.537],[139.5165,32.456]]],[[[139.6815,31.888],[139.688,31.8405],[139.725,31.7715],[139.781,31.724],[139.8325,31.7005],[139.944,31.688],[140.0075,31.702],[140.099,31.7585],[140.1505,31.85],[140.152,31.9185],[140.1185,31.995],[140.073,32.0395],[139.9945,32.078],[139.8935,32.0875],[139.801,32.062],[139.7415,32.021],[139.698,31.9615],[139.6815,31.888]]],[[[139.816,31.4395],[139.8545,31.329],[139.913,31.2765],[140.0365,31.2385],[140.155,31.258],[140.24,31.3165],[140.286,31.4095],[140.281,31.4885],[140.229,31.5725],[140.135,31.629],[140.0615,31.642],[140.0,31.6375],[139.9195,31.608],[139.8385,31.527],[139.816,31.4395]]],[[[140.0545,30.4825],[140.07,30.41],[140.1135,30.349],[140.197,30.2925],[140.2745,30.2735],[140.3825,30.285],[140.473,30.3335],[140.516,30.383],[140.5445,30.4555],[140.546,30.509],[140.524,30.574],[140.4665,30.6405],[140.3965,30.6795],[140.339,30.6935],[140.2415,30.689],[140.1435,30.646],[140.083,30.5815],[140.0545,30.4825]]],[[[140.1115,29.794],[140.135,29.706],[140.1665,29.6645],[140.2255,29.621],[140.342,29.5935],[140.411,29.603],[140.4815,29.6345],[140.5285,29.676],[140.566,29.745],[140.5725,29.8035],[140.534,29.905],[140.4505,29.97],[140.3875,29.9895],[140.3185,29.9925],[140.2215,29.964],[140.1695,29.926],[140.1235,29.8575],[140.1115,29.794]]],[[[140.6475,27.247],[140.6605,27.1805],[140.7025,27.1155],[140.7775,27.063],[140.8905,27.0435],[140.9535,27.055],[141.0415,27.1075],[141.0935,27.185],[141.105,27.2515],[141.091,27.3215],[141.021,27.408],[140.902,27.451],[140.7905,27.4375],[140.717,27.394],[140.663,27.3195],[140.6475,27.247]]],[[[141.052,25.4295],[141.0685,25.3535],[141.125,25.2775],[141.1965,25.2345],[141.2805,25.2195],[141.3645,25.2345],[141.45,25.286],[141.4975,25.35],[141.5145,25.426],[141.4935,25.5215],[141.446,25.5855],[141.3655,25.633],[141.2815,25.648],[141.1975,25.633],[141.1175,25.5815],[141.0695,25.517],[141.052,25.4295]]],[[[141.065,24.7985],[141.0825,24.6685],[141.13,24.604],[141.2015,24.5605],[141.2855,24.5455],[141.3695,24.5605],[141.5035,24.639],[141.551,24.7035],[141.568,24.78],[141.546,24.874],[141.4985,24.9385],[141.4075,24.9975],[141.3235,25.0125],[141.2035,24.9915],[141.1325,24.948],[141.0845,24.8835],[141.065,24.7985]]],[[[141.2355,24.2265],[141.252,24.1495],[141.2995,24.0845],[141.371,24.041],[141.455,24.026],[141.554,24.0425],[141.625,24.086],[141.6725,24.151],[141.6925,24.242],[141.676,24.319],[141.6285,24.384],[141.557,24.427],[141.4585,24.445],[141.374,24.43],[141.303,24.3865],[141.2555,24.3215],[141.2355,24.2265]]],[[[141.8675,27.7225],[141.897,27.6175],[141.979,27.5175],[141.988,27.434],[142.043,27.347],[141.99,27.289],[141.942,27.1625],[141.936,27.0935],[141.954,26.9775],[142.0055,26.8955],[141.9355,26.8385],[141.9,26.769],[141.8925,26.7025],[141.9105,26.536],[141.9755,26.417],[142.0395,26.3675],[142.1105,26.3435],[142.168,26.3405],[142.296,26.367],[142.377,26.408],[142.439,26.473],[142.4655,26.557],[142.4565,26.624],[142.367,26.7885],[142.315,26.8505],[142.3775,26.885],[142.4355,26.945],[142.4755,27.0665],[142.463,27.1595],[142.421,27.227],[142.3955,27.294],[142.36,27.3365],[142.431,27.424],[142.444,27.511],[142.4115,27.5995],[142.4025,27.683],[142.35,27.7965],[142.2915,27.867],[142.24,27.9085],[142.184,27.932],[142.095,27.9405],[142.0015,27.914],[141.9415,27.873],[141.892,27.816],[141.8675,27.7225]]],[[[153.752,24.2845],[153.765,24.205],[153.7855,24.1705],[153.8505,24.113],[153.931,24.0815],[154.0235,24.0815],[154.1055,24.114],[154.1745,24.166],[154.199,24.2005],[154.2015,24.3285],[154.169,24.4],[154.0755,24.472],[153.9795,24.49],[153.883,24.4765],[153.8175,24.434],[153.7675,24.371],[153.752,24.2845]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg","name:en":"Japan","wikidata":"Q17","ISO3166-1:alpha2":"JP","ISO3166-1:alpha3":"JPN","ISO3166-1:numeric":"392"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[55.999,41.32],[55.999,43.7535],[55.999,44.437],[55.9985,45.0005],[57.0005,45.2375],[57.9045,45.442],[58.5885,45.5905],[58.9905,45.3695],[59.5055,45.161],[59.9745,44.968],[60.7445,44.644],[61.068,44.3705],[61.1065,44.3605],[61.138,44.226],[61.4255,43.9995],[62.004,43.5055],[62.2425,43.5185],[63.349,43.6505],[63.8575,43.5995],[64.535,43.5705],[64.9325,43.7355],[65.002,43.7155],[65.185,43.495],[65.4955,43.333],[65.5595,43.2895],[65.742,43.0],[65.8655,42.8675],[66.08,42.933],[66.095,42.566],[66.088,42.3465],[66.0,42.36],[65.9995,41.9395],[66.5355,41.8785],[66.6085,41.494],[66.6455,41.3475],[66.7095,41.1425],[67.3125,41.1355],[67.7235,41.197],[67.8665,41.1365],[67.9655,41.149],[67.9885,41.0855],[67.9835,41.025],[68.0205,41.0205],[68.071,41.0805],[68.111,41.036],[68.0555,41.009],[68.088,40.97],[68.0885,40.9255],[68.0125,40.8905],[67.9775,40.831],[68.077,40.789],[68.218,40.6875],[68.371,40.6175],[68.502,40.5795],[68.6105,40.577],[68.652,40.614],[68.644,40.694],[68.584,40.709],[68.586,40.78],[68.5625,40.806],[68.5905,40.865],[68.579,40.925],[68.4905,40.9715],[68.5265,41.0205],[68.5895,41.029],[68.6285,40.9975],[68.6435,40.943],[68.7485,40.9815],[68.714,41.032],[68.804,41.116],[68.9915,41.214],[69.0395,41.255],[69.0415,41.366],[69.1665,41.395],[69.1565,41.4345],[69.25,41.4665],[69.301,41.438],[69.4005,41.5035],[69.4455,41.5635],[69.501,41.547],[69.6175,41.662],[69.696,41.673],[69.7455,41.701],[69.839,41.7205],[69.8825,41.7065],[69.9575,41.734],[69.981,41.781],[70.077,41.8085],[70.1575,41.8495],[70.2615,41.9545],[70.3355,41.9745],[70.32,42.037],[70.476,42.1095],[70.55,42.0675],[70.5595,42.0235],[70.6345,42.0155],[70.687,42.121],[70.7985,42.2075],[70.8835,42.2105],[70.9435,42.2635],[70.891,42.263],[70.8655,42.32],[70.898,42.3665],[70.9555,42.402],[70.9815,42.498],[71.0755,42.4725],[71.0015,42.5855],[71.1795,42.6105],[71.182,42.6635],[71.274,42.743],[71.268,42.778],[71.396,42.7975],[71.464,42.7855],[71.534,42.8015],[71.5705,42.775],[71.637,42.767],[71.6755,42.79],[71.8635,42.833],[72.057,42.769],[72.1205,42.7365],[72.166,42.7545],[72.282,42.7595],[72.499,42.685],[72.588,42.684],[72.7445,42.639],[72.7975,42.5805],[72.911,42.535],[73.12,42.552],[73.3095,42.518],[73.3145,42.458],[73.357,42.4365],[73.487,42.4175],[73.5155,42.435],[73.4485,42.5085],[73.433,42.549],[73.4655,42.7315],[73.501,42.7655],[73.5215,42.8625],[73.516,42.935],[73.5575,42.9825],[73.5595,43.029],[73.612,43.041],[73.766,43.1065],[73.838,43.128],[73.8995,43.119],[73.9575,43.1805],[73.969,43.2225],[74.042,43.172],[74.0765,43.187],[74.222,43.205],[74.1925,43.2555],[74.294,43.242],[74.3085,43.2165],[74.3845,43.1975],[74.432,43.1655],[74.5775,43.133],[74.6155,43.085],[74.7515,42.99],[74.8535,43.0],[75.037,42.9205],[75.2315,42.8535],[75.3365,42.8555],[75.419,42.8395],[75.5705,42.8305],[75.717,42.7975],[75.7615,42.8335],[75.7865,42.899],[75.8235,42.9385],[75.937,42.9555],[76.0285,42.911],[76.1955,42.931],[76.309,42.901],[76.344,42.861],[76.486,42.8885],[76.5225,42.922],[76.709,42.904],[76.8515,42.9785],[76.9165,42.966],[77.0045,42.983],[77.034,42.9475],[77.0845,42.981],[77.155,42.9725],[77.2335,42.912],[77.302,42.9165],[77.3535,42.899],[77.4225,42.9285],[77.55,42.9395],[77.5805,42.9155],[77.697,42.904],[77.7795,42.915],[77.9675,42.851],[78.035,42.865],[78.1715,42.8605],[78.198,42.882],[78.3505,42.855],[78.492,42.9005],[78.642,42.8425],[78.8655,42.8005],[78.9305,42.7745],[79.0565,42.7755],[79.1995,42.804],[79.17,42.7435],[79.182,42.6975],[79.271,42.6215],[79.3465,42.6025],[79.505,42.46],[79.641,42.4545],[79.6735,42.48],[79.787,42.4465],[79.968,42.432],[79.982,42.3775],[80.0305,42.343],[80.0815,42.3395],[80.1745,42.211],[80.2835,42.2355],[80.232,42.349],[80.2335,42.4045],[80.2075,42.4675],[80.267,42.503],[80.2205,42.533],[80.1625,42.625],[80.1765,42.6715],[80.223,42.713],[80.2775,42.838],[80.329,42.8275],[80.5985,42.8945],[80.5395,42.936],[80.4855,42.945],[80.388,43.003],[80.384,43.046],[80.485,43.0705],[80.556,43.102],[80.5865,43.1365],[80.6575,43.15],[80.7815,43.138],[80.8075,43.1775],[80.765,43.267],[80.7785,43.3115],[80.698,43.316],[80.6855,43.3375],[80.735,43.393],[80.751,43.469],[80.6855,43.5795],[80.521,43.8245],[80.506,43.906],[80.4545,43.982],[80.4455,44.071],[80.396,44.11],[80.4065,44.2495],[80.384,44.3775],[80.347,44.4825],[80.4105,44.6105],[80.3135,44.7035],[80.2195,44.7305],[80.173,44.7935],[80.128,44.823],[80.034,44.804],[79.9445,44.85],[79.9535,44.882],[79.882,44.9105],[79.9555,44.9615],[80.013,44.98],[80.062,45.036],[80.1525,45.0525],[80.2135,45.0235],[80.3255,45.0695],[80.382,45.04],[80.4375,45.097],[80.576,45.11],[80.698,45.1335],[80.74,45.1615],[80.8985,45.125],[80.957,45.1675],[81.0245,45.1635],[81.1195,45.215],[81.2035,45.237],[81.282,45.2395],[81.382,45.264],[81.452,45.262],[81.6325,45.3565],[81.7135,45.359],[81.774,45.386],[81.922,45.229],[82.088,45.243],[82.151,45.222],[82.2675,45.2415],[82.3405,45.209],[82.475,45.177],[82.582,45.2215],[82.5875,45.3445],[82.543,45.421],[82.4375,45.4595],[82.28,45.535],[82.259,45.6165],[82.288,45.709],[82.345,45.7955],[82.3355,45.939],[82.3755,45.964],[82.456,45.977],[82.512,46.1545],[82.608,46.2985],[82.725,46.4915],[82.782,46.669],[82.8295,46.7775],[82.869,46.83],[82.9325,46.972],[82.938,47.016],[82.993,47.0645],[83.0515,47.2255],[83.151,47.2345],[83.2395,47.179],[83.354,47.1745],[83.4135,47.116],[83.4575,47.132],[83.578,47.0605],[83.701,47.0225],[83.7835,47.0245],[83.9175,46.973],[83.9845,46.9955],[84.0565,46.9685],[84.1265,46.9675],[84.1655,46.994],[84.2585,47.003],[84.379,46.996],[84.436,47.009],[84.5065,46.9755],[84.5795,46.9995],[84.7095,47.0095],[84.8475,46.954],[84.858,46.9285],[84.944,46.863],[84.983,46.915],[85.0785,46.931],[85.0955,46.964],[85.194,47.0125],[85.217,47.0525],[85.2995,47.065],[85.3825,47.046],[85.4125,47.06],[85.5295,47.0515],[85.5765,47.1375],[85.6825,47.223],[85.6985,47.288],[85.6745,47.312],[85.6805,47.434],[85.608,47.5095],[85.6145,47.54],[85.543,48.0095],[85.5295,48.025],[85.5595,48.149],[85.5935,48.196],[85.6595,48.242],[85.7255,48.373],[85.7875,48.4175],[85.9115,48.436],[86.2325,48.432],[86.3215,48.488],[86.407,48.4785],[86.584,48.54],[86.6355,48.627],[86.773,48.7205],[86.761,48.804],[86.8165,48.8565],[86.7565,48.894],[86.727,48.9505],[86.749,49.0145],[86.8475,49.0655],[86.887,49.1325],[86.996,49.1425],[87.0565,49.1295],[87.104,49.151],[87.199,49.143],[87.286,49.116],[87.3025,49.1695],[87.2695,49.2325],[87.1985,49.2525],[87.0255,49.2575],[87.006,49.299],[86.9265,49.349],[86.93,49.42],[86.8685,49.435],[86.831,49.47],[86.8555,49.499],[86.827,49.5455],[86.7395,49.571],[86.618,49.5705],[86.6025,49.6055],[86.7095,49.6875],[86.779,49.696],[86.7715,49.764],[86.6975,49.8085],[86.5905,49.801],[86.6105,49.772],[86.5825,49.724],[86.5265,49.702],[86.4885,49.658],[86.3715,49.5935],[86.2715,49.5825],[86.267,49.5465],[86.202,49.466],[86.113,49.5245],[86.037,49.522],[85.969,49.487],[85.8835,49.567],[85.841,49.5475],[85.757,49.577],[85.6785,49.551],[85.5835,49.6135],[85.49,49.598],[85.3885,49.635],[85.3215,49.591],[85.2575,49.5885],[85.2105,49.6275],[85.1985,49.738],[85.1505,49.7675],[85.0595,49.885],[84.995,49.9055],[84.9835,49.984],[85.038,50.009],[85.024,50.06],[84.946,50.0965],[84.8565,50.092],[84.7575,50.137],[84.692,50.1885],[84.628,50.2105],[84.5305,50.206],[84.447,50.2465],[84.41,50.209],[84.326,50.2285],[84.2515,50.29],[84.2685,50.3565],[84.204,50.469],[84.2485,50.5155],[84.176,50.5515],[84.1455,50.603],[84.0825,50.6335],[84.023,50.698],[83.951,50.7465],[83.9645,50.801],[83.9105,50.8165],[83.8335,50.88],[83.7115,50.8935],[83.6485,50.955],[83.5935,50.9495],[83.4475,50.977],[83.407,51.013],[83.202,50.9935],[83.121,51.011],[83.1125,50.966],[83.006,50.925],[82.9795,50.884],[82.911,50.9075],[82.733,50.9275],[82.739,50.8505],[82.7015,50.812],[82.5675,50.747],[82.351,50.7755],[82.2705,50.77],[82.2225,50.737],[82.0785,50.751],[81.997,50.788],[81.8855,50.8045],[81.797,50.772],[81.5825,50.7425],[81.4495,50.756],[81.486,50.824],[81.4355,50.863],[81.4125,50.9755],[81.289,50.974],[81.191,50.951],[81.06,50.948],[81.103,51.0605],[81.142,51.079],[81.177,51.1615],[80.92,51.219],[80.9405,51.2595],[80.6775,51.3165],[80.635,51.263],[80.6345,51.207],[80.447,51.2085],[80.4365,51.119],[80.482,51.1095],[80.482,50.9685],[80.421,50.962],[80.376,50.927],[80.2455,50.9185],[80.193,50.9005],[80.185,50.8275],[80.083,50.828],[80.076,50.738],[79.7205,51.217],[79.4115,51.624],[79.1875,51.9235],[78.975,52.1505],[78.7175,52.429],[78.403,52.7815],[78.267,52.924],[78.0255,53.161],[77.9065,53.2915],[77.339,53.595],[76.829,53.8495],[76.538,54.0],[76.4985,54.0715],[76.435,54.1225],[76.4405,54.1675],[76.5825,54.149],[76.645,54.1245],[76.7565,54.162],[76.828,54.225],[76.8285,54.274],[76.8785,54.302],[76.86,54.361],[76.9355,54.4155],[76.929,54.458],[76.7955,54.419],[76.73,54.418],[76.675,54.345],[76.476,54.318],[76.352,54.334],[76.2575,54.3595],[76.1865,54.3015],[76.203,54.26],[75.598,54.099],[75.529,54.115],[75.375,54.07],[75.4345,54.0095],[75.441,53.9725],[75.377,53.9595],[75.0465,53.7925],[74.982,53.8225],[74.7885,53.828],[74.757,53.7445],[74.6675,53.756],[74.635,53.668],[74.457,53.691],[74.421,53.594],[74.4865,53.5725],[74.3935,53.4595],[74.2915,53.4915],[74.2875,53.5605],[74.1615,53.6015],[74.1465,53.555],[74.0515,53.566],[74.072,53.6295],[73.901,53.651],[73.821,53.5785],[73.7475,53.607],[73.6665,53.613],[73.645,53.5525],[73.4385,53.4355],[73.3625,53.4675],[73.3975,53.522],[73.2385,53.5675],[73.277,53.6395],[73.323,53.6755],[73.3555,53.766],[73.449,53.8075],[73.4525,53.876],[73.691,53.856],[73.7675,54.054],[73.657,54.0465],[73.609,54.0085],[73.519,54.004],[73.5045,53.939],[73.276,53.9425],[73.1935,53.9705],[73.067,53.9855],[73.0595,54.0405],[72.9785,54.0495],[72.994,54.0985],[72.8315,54.098],[72.8255,54.1215],[72.6085,54.137],[72.56,54.1165],[72.571,54.0515],[72.68,54.045],[72.7195,53.9995],[72.7145,53.951],[72.543,53.976],[72.4865,53.901],[72.3695,53.9445],[72.4175,53.9985],[72.3965,54.0515],[72.44,54.12],[72.4175,54.151],[72.2995,54.187],[72.2785,54.317],[72.189,54.355],[72.0325,54.3665],[72.0515,54.338],[72.136,54.305],[72.0855,54.219],[72.2185,54.182],[72.1845,54.1205],[72.101,54.1475],[72.0735,54.1995],[71.949,54.2435],[71.886,54.2315],[71.751,54.254],[71.7265,54.1875],[71.764,54.1475],[71.7205,54.1065],[71.61,54.117],[71.488,54.101],[71.491,54.1585],[71.296,54.185],[71.2745,54.147],[71.179,54.095],[71.1225,54.1295],[71.138,54.162],[71.0715,54.2055],[71.073,54.275],[70.9965,54.2755],[70.9985,54.336],[71.1125,54.335],[71.1985,54.3115],[71.2295,54.354],[71.1705,54.461],[71.1675,54.5605],[71.2145,54.61],[71.2915,54.606],[71.293,54.668],[71.2105,54.7],[71.0965,54.713],[71.0305,54.7785],[71.0195,54.852],[70.9565,54.8885],[71.0085,54.9705],[70.993,55.0735],[70.9215,55.1305],[70.789,55.2895],[70.695,55.2895],[70.6205,55.2535],[70.478,55.2725],[70.41,55.2535],[70.402,55.2155],[70.292,55.1925],[70.2275,55.148],[70.1135,55.172],[70.057,55.209],[69.9505,55.21],[69.863,55.3],[69.707,55.3515],[69.442,55.342],[69.4165,55.3815],[69.1995,55.33],[69.1605,55.3905],[69.048,55.427],[68.9325,55.442],[68.916,55.3655],[68.929,55.3185],[68.7485,55.379],[68.7085,55.348],[68.697,55.289],[68.635,55.2655],[68.6355,55.204],[68.4445,55.1965],[68.282,55.205],[68.1895,55.1515],[68.2715,55.085],[68.2375,55.054],[68.2345,54.969],[68.0325,54.9505],[67.9105,54.9835],[67.8195,54.9715],[67.7735,54.886],[67.563,54.8445],[67.5165,54.862],[67.3985,54.8555],[67.3325,54.8735],[67.282,54.8255],[66.994,54.7895],[66.782,54.7685],[66.738,54.7435],[66.654,54.744],[66.3815,54.7035],[65.9985,54.625],[65.964,54.638],[65.982,54.717],[65.8455,54.697],[65.831,54.653],[65.7475,54.6075],[65.633,54.641],[65.4565,54.6245],[65.495,54.5965],[65.306,54.5685],[65.2125,54.532],[65.2015,54.466],[65.239,54.376],[65.121,54.3305],[64.975,54.424],[64.7385,54.354],[64.6,54.375],[64.4815,54.3665],[64.4195,54.3265],[64.359,54.3365],[64.1845,54.309],[64.0985,54.311],[63.984,54.2715],[64.0215,54.2305],[63.9615,54.2005],[63.8975,54.2165],[63.8035,54.271],[63.728,54.261],[63.5185,54.207],[63.357,54.1885],[63.337,54.201],[63.151,54.1825],[63.1515,54.123],[63.0795,54.104],[62.936,54.1165],[62.806,54.112],[62.5965,54.072],[62.569,54.0465],[62.5975,53.995],[62.5545,53.9335],[62.4465,53.927],[62.3965,54.004],[62.339,54.0325],[62.1755,54.0285],[62.0835,54.049],[62.006,54.0375],[62.044,53.9485],[61.857,53.9625],[61.893,54.009],[61.8185,54.019],[61.782,53.9845],[61.7005,54.019],[61.569,54.008],[61.4805,54.03],[61.48,54.083],[61.294,54.074],[61.25,54.0235],[61.28,53.9285],[61.205,53.919],[61.1805,53.972],[61.1,53.975],[61.0295,53.955],[60.9935,53.907],[61.137,53.9045],[61.179,53.8525],[61.237,53.8415],[61.227,53.7955],[61.1145,53.721],[61.0585,53.7215],[60.9955,53.673],[60.896,53.668],[60.9005,53.6285],[61.122,53.615],[61.1265,53.59],[61.2155,53.5635],[61.358,53.5615],[61.391,53.602],[61.553,53.593],[61.565,53.5385],[61.488,53.476],[61.4285,53.4555],[61.2995,53.5125],[61.229,53.484],[61.2165,53.432],[61.1555,53.4055],[61.177,53.312],[61.226,53.2835],[61.4,53.274],[61.527,53.2155],[61.6305,53.223],[61.674,53.2655],[61.7325,53.239],[61.784,53.1845],[61.916,53.142],[62.0275,53.142],[62.1195,53.112],[62.1475,53.068],[62.1305,52.99],[62.0295,52.951],[61.961,52.95],[61.834,52.993],[61.702,52.998],[61.632,52.954],[61.557,53.012],[61.469,53.0365],[61.3905,52.9925],[61.307,52.996],[61.251,53.036],[61.1215,52.9875],[61.0495,52.981],[61.076,52.928],[60.987,52.8865],[60.8345,52.774],[60.712,52.7645],[60.7145,52.663],[60.7615,52.6265],[60.843,52.641],[60.842,52.5225],[60.9825,52.508],[60.992,52.423],[61.067,52.347],[61.0105,52.326],[60.9455,52.2675],[60.772,52.208],[60.7165,52.156],[60.511,52.1565],[60.3395,52.055],[60.1975,51.991],[60.002,51.9935],[60.0325,51.9135],[60.144,51.8705],[60.162,51.892],[60.428,51.7985],[60.5175,51.7975],[60.4315,51.7195],[60.3545,51.6905],[60.4255,51.647],[60.538,51.618],[60.9355,51.6155],[60.911,51.5505],[60.9995,51.4675],[61.203,51.461],[61.2565,51.441],[61.3535,51.439],[61.391,51.42],[61.505,51.407],[61.5495,51.3235],[61.69,51.256],[61.568,51.238],[61.486,50.9585],[61.449,50.806],[60.809,50.6565],[60.741,50.6655],[60.5575,50.661],[60.325,50.6705],[60.183,50.7785],[60.188,50.8385],[60.015,50.822],[59.9725,50.7685],[59.9975,50.675],[59.91,50.6365],[59.813,50.5355],[59.776,50.541],[59.5165,50.5285],[59.4575,50.5435],[59.463,50.5845],[59.569,50.5735],[59.4795,50.6415],[59.418,50.6365],[59.114,50.683],[58.8745,50.7],[58.7745,50.8145],[58.6565,50.8085],[58.6965,50.848],[58.688,50.8855],[58.5935,50.8695],[58.5785,50.94],[58.6425,50.9875],[58.5765,51.056],[58.5205,51.085],[58.384,51.075],[58.3405,51.1455],[58.206,51.1295],[58.177,51.066],[58.1025,51.07],[58.0735,51.123],[57.9515,51.0865],[57.867,51.0995],[57.772,51.1385],[57.754,51.056],[57.7515,50.9395],[57.736,50.9275],[57.559,50.936],[57.507,50.876],[57.415,50.8965],[57.3245,50.943],[57.2825,51.0325],[57.246,51.026],[57.185,51.115],[57.1465,51.0875],[56.9845,51.0625],[56.943,51.0875],[56.8875,51.0605],[56.78,51.094],[56.6995,51.075],[56.751,50.9815],[56.634,50.985],[56.51,51.0805],[56.448,51.057],[56.4605,50.965],[56.3925,50.9455],[56.3615,50.9015],[56.298,50.902],[56.1815,50.938],[56.133,50.8305],[56.137,50.7535],[56.0545,50.695],[55.916,50.6415],[55.83,50.623],[55.7465,50.5795],[55.6615,50.56],[55.6115,50.5985],[55.534,50.6135],[55.5025,50.67],[55.403,50.6815],[55.3835,50.6535],[55.1465,50.797],[55.056,50.8195],[55.1295,50.8795],[55.071,50.924],[55.01,50.9055],[54.894,50.92],[54.898,50.958],[54.7915,50.9855],[54.7185,51.0285],[54.5685,51.0185],[54.566,50.9155],[54.658,50.915],[54.6975,50.8925],[54.6785,50.718],[54.718,50.69],[54.73,50.6175],[54.614,50.5385],[54.545,50.5275],[54.466,50.5665],[54.4135,50.6205],[54.4735,50.7785],[54.5185,50.812],[54.518,50.8545],[54.4415,50.8795],[54.288,50.9025],[54.2885,50.949],[54.1995,50.964],[54.137,51.108],[54.042,51.136],[53.9325,51.1935],[53.7475,51.204],[53.6615,51.231],[53.66,51.26],[53.5955,51.306],[53.575,51.4245],[53.4815,51.444],[53.3925,51.491],[53.255,51.512],[53.144,51.485],[53.0565,51.4895],[52.9045,51.4775],[52.7905,51.5135],[52.747,51.4865],[52.6475,51.4885],[52.5655,51.4635],[52.4505,51.6235],[52.416,51.64],[52.3355,51.7435],[52.2385,51.724],[52.09,51.6585],[51.9995,51.6835],[51.894,51.6835],[51.7705,51.583],[51.8135,51.497],[51.656,51.4485],[51.64,51.5385],[51.566,51.506],[51.4315,51.475],[51.2865,51.488],[51.2855,51.532],[51.3805,51.5635],[51.38,51.641],[51.3035,51.641],[51.272,51.685],[51.204,51.6675],[51.0845,51.6665],[50.8935,51.6815],[50.8715,51.7535],[50.768,51.773],[50.768,51.7145],[50.8125,51.649],[50.812,51.585],[50.7675,51.575],[50.7315,51.6285],[50.636,51.629],[50.5865,51.5905],[50.5375,51.589],[50.547,51.465],[50.497,51.4275],[50.338,51.382],[50.373,51.3325],[50.243,51.28],[50.04,51.2515],[49.911,51.201],[49.776,51.107],[49.5545,51.11],[49.393,51.09],[49.3965,51.049],[49.3385,50.987],[49.408,50.961],[49.4435,50.8775],[49.42,50.849],[49.2625,50.823],[49.126,50.7845],[49.0095,50.682],[48.8145,50.5955],[48.689,50.6125],[48.606,50.662],[48.5705,50.6325],[48.652,50.601],[48.659,50.528],[48.7325,50.257],[48.809,50.1705],[48.7635,50.098],[48.848,50.0915],[48.9035,50.0185],[48.7455,49.9215],[48.4505,49.835],[48.269,49.8595],[48.1315,49.998],[48.095,50.1],[48.009,50.142],[47.939,50.2425],[47.8855,50.2685],[47.8285,50.3275],[47.7625,50.341],[47.7315,50.386],[47.6635,50.4085],[47.6125,50.464],[47.5415,50.4605],[47.4725,50.42],[47.4065,50.3365],[47.3005,50.303],[47.3355,50.238],[47.2575,50.1915],[47.3175,50.152],[47.3535,50.0945],[47.1825,49.935],[46.9575,49.8715],[46.9025,49.864],[46.87,49.743],[46.858,49.6435],[46.8295,49.5655],[46.782,49.34],[46.9145,49.283],[46.996,49.2325],[47.0515,49.1655],[47.0285,49.089],[46.972,49.0275],[46.8925,48.982],[46.779,48.9515],[46.493,48.4325],[46.7475,48.3535],[46.8895,48.3275],[47.123,48.2685],[47.1035,48.212],[47.125,48.158],[47.091,48.103],[47.211,48.082],[47.2005,48.055],[47.05,47.998],[47.101,47.928],[47.181,47.854],[47.122,47.8315],[47.1945,47.761],[47.385,47.6815],[47.412,47.7635],[47.4155,47.8385],[47.6525,47.758],[47.9625,47.7515],[48.028,47.763],[48.1115,47.745],[48.2095,47.6915],[48.319,47.5515],[48.4515,47.4115],[48.5195,47.412],[48.71,47.096],[48.9155,46.8805],[48.996,46.743],[48.92,46.6935],[48.7505,46.6855],[48.7135,46.721],[48.5485,46.711],[48.478,46.6705],[48.5605,46.642],[48.5735,46.6065],[48.545,46.5635],[48.7025,46.563],[48.788,46.541],[48.8195,46.4855],[48.8785,46.4815],[48.912,46.4505],[48.986,46.433],[49.045,46.3965],[49.162,46.384],[49.2625,46.294],[49.5065,46.1935],[49.6,46.1765],[49.7015,46.1865],[49.7785,46.1185],[49.886,46.046],[49.9675,46.081],[50.021,46.129],[50.056,46.2285],[50.086,46.4325],[50.147,46.4775],[50.33,46.5505],[50.6985,46.6735],[50.8125,46.7305],[51.147,46.8095],[51.2385,46.85],[51.3855,46.8395],[51.449,46.6985],[51.5105,46.6335],[51.5665,46.61],[51.775,46.5855],[52.132,46.6405],[52.2585,46.6135],[52.364,46.6195],[52.652,46.7065],[52.7985,46.6055],[52.741,46.4225],[52.7405,46.366],[52.784,46.216],[52.876,46.021],[52.6755,45.8115],[52.568,45.7495],[52.472,45.608],[52.2905,45.5525],[52.1555,45.5345],[51.7785,45.5935],[51.6985,45.5875],[51.3425,45.507],[51.269,45.4625],[51.164,45.3645],[51.0785,45.264],[50.8715,45.1155],[50.7075,45.081],[50.4105,45.1855],[50.3145,45.1985],[50.074,45.1935],[49.962,45.1725],[49.883,45.1345],[49.847,45.0945],[49.8085,44.9755],[49.8225,44.901],[49.8715,44.816],[49.925,44.759],[50.0335,44.5495],[50.05,44.3865],[50.0775,44.317],[50.1225,44.2645],[50.2255,44.207],[50.3105,44.174],[50.41,44.155],[50.549,44.144],[50.7005,43.9605],[50.8595,43.7285],[50.989,43.5595],[51.097,43.451],[51.082,43.228],[51.071,43.1605],[51.1035,43.079],[51.16,43.034],[51.2625,43.004],[51.558,42.9675],[51.6355,42.8935],[51.675,42.8335],[51.767,42.73],[51.8875,42.6855],[52.1955,42.651],[52.393,42.602],[52.4405,42.4695],[52.289,42.2625],[52.2355,42.149],[52.2265,42.089],[52.2405,42.0135],[52.247,41.772],[52.259,41.7245],[52.335,41.7195],[52.45,41.762],[52.497,41.7975],[52.9345,42.093],[52.985,42.121],[53.5705,42.289],[54.218,42.379],[54.7795,42.0525],[54.952,41.9065],[54.95,41.833],[55.066,41.6995],[55.1155,41.611],[55.2115,41.5145],[55.3155,41.391],[55.4995,41.2515],[55.5675,41.2885],[55.613,41.2705],[55.7435,41.302],[55.774,41.284],[55.8765,41.332],[55.999,41.32]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/d3/Flag_of_Kazakhstan.svg","name:en":"Kazakhstan","wikidata":"Q232","ISO3166-1:alpha2":"KZ","ISO3166-1:alpha3":"KAZ","ISO3166-1:numeric":"398"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[105.2065,14.3435],[105.206,14.3125],[105.247,14.26],[105.282,14.171],[105.3245,14.159],[105.3615,14.1065],[105.4435,14.1085],[105.5565,14.1605],[105.699,14.094],[105.7885,14.0775],[105.7925,14.0235],[105.911,13.9305],[105.996,13.9305],[106.1055,13.9095],[106.1,13.979],[106.168,14.0195],[106.1875,14.063],[106.1215,14.1095],[106.1075,14.188],[106.0515,14.2025],[106.027,14.246],[106.023,14.312],[106.0955,14.373],[106.1875,14.3515],[106.2375,14.3985],[106.2415,14.4645],[106.264,14.4785],[106.3295,14.439],[106.4045,14.45],[106.4355,14.4815],[106.438,14.5235],[106.5235,14.5915],[106.546,14.59],[106.5705,14.521],[106.612,14.4975],[106.6395,14.4485],[106.7175,14.422],[106.838,14.294],[106.895,14.3335],[106.967,14.314],[107.0155,14.397],[107.0775,14.4265],[107.0835,14.395],[107.165,14.416],[107.2085,14.4885],[107.2535,14.5225],[107.2875,14.5795],[107.329,14.5915],[107.4375,14.524],[107.469,14.6215],[107.5565,14.686],[107.542,14.7505],[107.5075,14.7925],[107.5895,14.864],[107.4785,14.9575],[107.468,14.9875],[107.54,15.0495],[107.583,15.0285],[107.598,15.088],[107.623,15.1075],[107.6025,15.1835],[107.6215,15.2145],[107.6245,15.311],[107.606,15.3885],[107.5305,15.4055],[107.513,15.473],[107.471,15.4965],[107.386,15.4925],[107.365,15.57],[107.3365,15.6215],[107.291,15.624],[107.2755,15.704],[107.215,15.824],[107.347,15.8935],[107.393,15.887],[107.4155,15.912],[107.464,16.016],[107.4455,16.054],[107.3775,16.074],[107.3385,16.0555],[107.2835,16.1185],[107.242,16.1475],[107.1975,16.144],[107.16,16.1675],[107.1465,16.22],[107.157,16.2565],[107.0865,16.3125],[106.9685,16.307],[106.964,16.355],[106.8975,16.391],[106.8785,16.4685],[106.8865,16.522],[106.831,16.549],[106.8065,16.4785],[106.772,16.4325],[106.726,16.425],[106.6605,16.4745],[106.6475,16.5405],[106.672,16.5625],[106.565,16.643],[106.5515,16.6945],[106.5515,16.865],[106.5145,16.896],[106.548,16.9285],[106.5155,16.9715],[106.4275,17.008],[106.402,17.053],[106.416,17.0785],[106.373,17.112],[106.328,17.18],[106.305,17.258],[106.2355,17.25],[106.0815,17.3715],[105.862,17.6275],[105.78,17.675],[105.701,17.7615],[105.6605,17.8565],[105.608,17.877],[105.6425,17.9625],[105.5805,18.062],[105.5225,18.1255],[105.5015,18.1885],[105.46,18.206],[105.409,18.154],[105.3635,18.164],[105.3195,18.2015],[105.3315,18.2525],[105.256,18.255],[105.2425,18.2965],[105.192,18.319],[105.1715,18.392],[105.1035,18.4475],[105.115,18.539],[105.136,18.593],[105.1805,18.6025],[105.198,18.6405],[105.1065,18.7065],[105.052,18.7085],[105.018,18.7455],[104.941,18.7395],[104.913,18.787],[104.7945,18.783],[104.739,18.801],[104.63,18.886],[104.581,18.901],[104.545,18.97],[104.496,19.004],[104.4455,18.984],[104.3975,19.055],[104.3045,19.0935],[104.272,19.1215],[104.2125,19.1295],[104.179,19.1975],[104.128,19.205],[104.068,19.248],[104.003,19.233],[103.924,19.2855],[103.9085,19.3295],[103.958,19.384],[104.0145,19.402],[104.073,19.4505],[104.1055,19.568],[104.0605,19.613],[104.072,19.682],[104.105,19.662],[104.236,19.7075],[104.3515,19.6925],[104.4125,19.705],[104.4275,19.673],[104.49,19.6555],[104.506,19.626],[104.567,19.6155],[104.6465,19.6545],[104.7125,19.754],[104.7535,19.75],[104.796,19.7905],[104.835,19.802],[104.8465,19.9295],[104.903,19.968],[104.907,19.9985],[104.9765,20.08],[104.9135,20.1555],[104.862,20.1415],[104.7745,20.1985],[104.719,20.201],[104.63,20.2295],[104.6105,20.275],[104.6175,20.3615],[104.7095,20.4105],[104.6615,20.4745],[104.6255,20.462],[104.611,20.423],[104.565,20.4165],[104.4745,20.369],[104.421,20.3765],[104.4135,20.423],[104.376,20.467],[104.5225,20.549],[104.5415,20.5985],[104.601,20.6055],[104.6415,20.6625],[104.5855,20.6805],[104.552,20.719],[104.4935,20.718],[104.483,20.767],[104.428,20.79],[104.3375,20.856],[104.3335,20.881],[104.2815,20.925],[104.1215,20.9705],[104.054,20.95],[104.0485,20.9115],[103.9615,20.8975],[103.9015,20.9035],[103.7805,20.8015],[103.791,20.7465],[103.7335,20.7315],[103.735,20.667],[103.6835,20.6615],[103.6675,20.6985],[103.6015,20.7425],[103.5095,20.753],[103.463,20.826],[103.4415,20.794],[103.39,20.784],[103.2945,20.835],[103.261,20.8235],[103.227,20.8515],[103.2145,20.8995],[103.168,20.9135],[103.1095,20.9005],[103.0345,21.0585],[102.962,21.0775],[102.9495,21.139],[102.909,21.1805],[102.912,21.2295],[102.8585,21.2565],[102.8515,21.2985],[102.897,21.3045],[102.896,21.385],[102.88,21.4245],[102.8865,21.4765],[102.992,21.586],[102.9815,21.647],[102.9885,21.721],[102.973,21.7365],[102.8855,21.712],[102.8565,21.722],[102.8515,21.8425],[102.817,21.84],[102.8265,21.736],[102.7395,21.6595],[102.6665,21.678],[102.648,21.7355],[102.6615,21.7865],[102.642,21.849],[102.5945,21.925],[102.514,21.9665],[102.4875,21.997],[102.5095,22.0365],[102.4455,22.0745],[102.434,22.1125],[102.3125,22.208],[102.2465,22.2365],[102.2345,22.2825],[102.182,22.3235],[102.1445,22.4],[102.126,22.4325],[102.05,22.4565],[101.999,22.4325],[101.9155,22.44],[101.899,22.381],[101.8315,22.4215],[101.823,22.4615],[101.7605,22.5085],[101.6725,22.476],[101.67,22.372],[101.625,22.2755],[101.5695,22.275],[101.5505,22.234],[101.6005,22.135],[101.5735,22.126],[101.596,22.064],[101.632,22.013],[101.6165,21.977],[101.739,21.873],[101.7725,21.817],[101.746,21.7285],[101.7695,21.6595],[101.8095,21.63],[101.824,21.5905],[101.75,21.583],[101.7615,21.5015],[101.7385,21.406],[101.7335,21.323],[101.799,21.2915],[101.8445,21.2525],[101.8305,21.2055],[101.7935,21.206],[101.757,21.144],[101.7185,21.143],[101.671,21.2035],[101.5865,21.189],[101.6075,21.238],[101.483,21.246],[101.446,21.2265],[101.3875,21.228],[101.292,21.1755],[101.2165,21.2315],[101.2505,21.293],[101.185,21.3285],[101.141,21.411],[101.1995,21.436],[101.217,21.4925],[101.217,21.556],[101.1475,21.562],[101.1635,21.5275],[101.0845,21.459],[101.059,21.455],[100.996,21.3855],[100.949,21.3795],[100.8825,21.3465],[100.8475,21.3045],[100.8105,21.2935],[100.732,21.316],[100.7005,21.222],[100.696,21.1735],[100.642,21.0955],[100.6405,21.0665],[100.596,21.029],[100.546,21.0245],[100.5095,20.888],[100.544,20.8705],[100.637,20.898],[100.608,20.841],[100.494,20.815],[100.4235,20.8325],[100.3615,20.825],[100.2965,20.78],[100.2235,20.714],[100.1755,20.6355],[100.1185,20.4335],[100.1235,20.4055],[100.0845,20.3525],[100.113,20.25],[100.1715,20.246],[100.181,20.3065],[100.2175,20.3145],[100.227,20.3555],[100.2725,20.4005],[100.3305,20.398],[100.374,20.352],[100.4185,20.25],[100.456,20.225],[100.5075,20.151],[100.5765,20.17],[100.57,20.099],[100.501,19.8705],[100.4425,19.8355],[100.438,19.791],[100.404,19.7525],[100.446,19.7065],[100.428,19.6725],[100.478,19.6125],[100.4855,19.5435],[100.5805,19.499],[100.608,19.547],[100.6505,19.5565],[100.7405,19.52],[100.779,19.4925],[100.883,19.606],[100.9125,19.627],[101.036,19.6285],[101.123,19.572],[101.198,19.577],[101.2065,19.605],[101.2805,19.5825],[101.264,19.4705],[101.2105,19.4735],[101.215,19.4315],[101.187,19.3995],[101.2595,19.231],[101.245,19.181],[101.257,19.124],[101.3555,19.051],[101.3355,19.004],[101.2925,18.981],[101.297,18.943],[101.246,18.8895],[101.2585,18.8095],[101.2335,18.72],[101.2725,18.6885],[101.225,18.6235],[101.182,18.612],[101.1835,18.5605],[101.1035,18.5215],[101.0915,18.478],[101.0525,18.4265],[101.083,18.3845],[101.1825,18.34],[101.161,18.3045],[101.166,18.217],[101.1925,18.212],[101.161,18.1245],[101.184,18.065],[101.1215,18.0],[101.1165,17.951],[101.02,17.8925],[101.0285,17.829],[100.978,17.7535],[101.007,17.732],[100.9915,17.619],[100.9675,17.5715],[101.0215,17.557],[101.08,17.5025],[101.161,17.467],[101.175,17.5235],[101.2295,17.5365],[101.2645,17.6035],[101.3065,17.6505],[101.3455,17.659],[101.456,17.747],[101.548,17.7875],[101.5645,17.841],[101.6025,17.857],[101.618,17.894],[101.7105,17.902],[101.766,18.054],[101.786,18.071],[101.8745,18.0285],[101.907,18.031],[101.9455,18.0875],[102.0345,18.1615],[102.045,18.1985],[102.0885,18.2205],[102.1645,18.2025],[102.1855,18.148],[102.3,18.053],[102.341,18.0465],[102.46,17.971],[102.594,17.96],[102.613,17.9075],[102.589,17.8495],[102.667,17.8055],[102.679,17.8565],[102.766,17.8995],[102.7805,17.929],[102.862,17.974],[102.969,18.004],[103.009,17.9765],[103.042,17.9825],[103.073,18.0225],[103.0835,18.129],[103.136,18.1605],[103.1685,18.2575],[103.281,18.2935],[103.2465,18.3705],[103.313,18.4335],[103.4035,18.4485],[103.457,18.425],[103.524,18.4255],[103.6035,18.405],[103.6955,18.344],[103.794,18.343],[103.834,18.328],[103.856,18.2845],[103.953,18.3395],[103.973,18.337],[104.057,18.2235],[104.1055,18.1155],[104.213,17.9995],[104.271,17.87],[104.355,17.8225],[104.457,17.667],[104.4965,17.635],[104.708,17.521],[104.744,17.4605],[104.796,17.402],[104.804,17.3715],[104.8015,17.1645],[104.7295,17.0085],[104.733,16.9365],[104.759,16.8415],[104.738,16.794],[104.7625,16.6895],[104.744,16.6375],[104.735,16.5455],[104.768,16.5],[104.83,16.4645],[104.895,16.343],[104.9205,16.3375],[105.015,16.244],[105.011,16.202],[105.0405,16.11],[105.195,16.055],[105.408,16.016],[105.342,15.922],[105.3905,15.8085],[105.4335,15.7555],[105.497,15.767],[105.596,15.7245],[105.6345,15.6625],[105.625,15.5635],[105.5935,15.5125],[105.6025,15.4805],[105.5785,15.408],[105.491,15.3845],[105.4675,15.3475],[105.5085,15.3185],[105.576,15.3225],[105.591,15.271],[105.54,15.252],[105.4745,15.1775],[105.481,15.0985],[105.573,15.001],[105.6195,14.98],[105.557,14.9245],[105.5765,14.897],[105.512,14.801],[105.531,14.6225],[105.5235,14.5495],[105.4305,14.4245],[105.36,14.3875],[105.322,14.398],[105.2815,14.3535],[105.2065,14.3435]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/5/56/Flag_of_Laos.svg","name:en":"Laos","wikidata":"Q819","ISO3166-1:alpha2":"LA","ISO3166-1:alpha3":"LAO","ISO3166-1:numeric":"418"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-170.1595,-19.082],[-170.1515,-19.1305],[-170.1045,-19.235],[-170.054,-19.291],[-169.9465,-19.344],[-169.8355,-19.351],[-169.7185,-19.307],[-169.6225,-19.2085],[-169.5705,-19.108],[-169.5675,-19.0275],[-169.612,-18.89],[-169.69,-18.798],[-169.7675,-18.7645],[-169.8615,-18.7535],[-169.9475,-18.771],[-170.0435,-18.832],[-170.1115,-18.924],[-170.148,-19.01],[-170.1595,-19.082]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/01/Flag_of_Niue.svg","name:en":"Niue","wikidata":"Q34020","ISO3166-1:alpha2":"NU","ISO3166-1:alpha3":"NIU","ISO3166-1:numeric":"570"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[87.8145,49.17],[87.866,49.1115],[87.827,49.051],[87.8765,49.0145],[87.868,48.948],[87.754,48.9285],[87.734,48.881],[87.7815,48.8695],[87.83,48.7985],[87.935,48.7555],[87.9995,48.7605],[88.0675,48.6805],[87.969,48.5755],[88.1425,48.5275],[88.175,48.499],[88.2425,48.501],[88.357,48.4585],[88.3495,48.4355],[88.437,48.387],[88.5135,48.3795],[88.603,48.339],[88.566,48.276],[88.6375,48.1785],[88.715,48.174],[88.824,48.1],[88.911,48.109],[89.0095,48.05],[89.0625,47.9885],[89.156,47.995],[89.234,47.976],[89.291,48.012],[89.4015,48.0305],[89.582,48.03],[89.5925,47.968],[89.6545,47.9055],[89.727,47.895],[89.7565,47.829],[89.954,47.8345],[89.9595,47.887],[90.0675,47.874],[90.0655,47.7925],[90.1395,47.7225],[90.298,47.6925],[90.4,47.539],[90.4715,47.491],[90.458,47.407],[90.5205,47.377],[90.484,47.313],[90.5945,47.168],[90.622,47.155],[90.778,46.992],[90.8295,46.9895],[90.902,46.9575],[90.9555,46.8775],[90.937,46.826],[91.016,46.764],[91.0485,46.72],[91.0145,46.5805],[91.066,46.5755],[91.0525,46.511],[91.0095,46.461],[90.9695,46.3605],[90.8915,46.3125],[90.949,46.229],[90.975,46.1625],[91.0105,46.1245],[91.022,46.0225],[90.848,45.8875],[90.715,45.7275],[90.6785,45.6055],[90.6705,45.487],[90.77,45.4285],[90.8115,45.325],[90.895,45.2505],[90.8645,45.204],[90.931,45.192],[90.995,45.214],[91.122,45.214],[91.2415,45.132],[91.329,45.129],[91.373,45.109],[91.43,45.1565],[91.492,45.1045],[91.609,45.07],[91.691,45.062],[91.801,45.0815],[92.0575,45.083],[92.0995,45.0755],[92.235,45.0135],[92.3135,45.027],[92.4905,45.0],[92.5495,45.0175],[92.645,45.0205],[92.776,45.05],[92.8815,45.0465],[92.9295,45.0155],[93.168,45.0135],[93.2855,44.9825],[93.366,44.988],[93.428,44.9565],[93.5225,44.9575],[93.671,44.91],[93.7305,44.8625],[94.062,44.7325],[94.15,44.6835],[94.2115,44.6675],[94.276,44.605],[94.3265,44.5825],[94.3605,44.515],[94.4625,44.5105],[94.5165,44.476],[94.6105,44.4425],[94.713,44.345],[94.945,44.288],[94.9985,44.251],[95.41,44.294],[95.4065,44.2415],[95.3725,44.2255],[95.3475,44.089],[95.3225,44.0255],[95.442,44.005],[95.523,44.005],[95.623,43.8515],[95.6475,43.7765],[95.736,43.5945],[95.8575,43.4135],[95.877,43.277],[95.909,43.2355],[96.363,42.899],[96.3875,42.7245],[96.7475,42.755],[96.9775,42.7545],[97.1715,42.7945],[97.5555,42.742],[98.1925,42.652],[98.5425,42.6375],[98.9005,42.61],[99.5045,42.5655],[99.964,42.646],[100.268,42.6355],[100.3185,42.687],[100.848,42.672],[101.567,42.5255],[101.8005,42.5035],[102.0485,42.2525],[102.0245,42.224],[102.0965,42.2],[102.1715,42.204],[102.432,42.147],[102.5505,42.159],[102.767,42.1255],[102.976,42.0375],[103.411,41.8815],[103.891,41.7955],[104.078,41.8005],[104.5235,41.8735],[104.4975,41.7725],[104.499,41.6795],[104.517,41.6595],[104.682,41.644],[104.9165,41.6525],[105.013,41.581],[105.108,41.6545],[105.217,41.7255],[105.289,41.747],[105.386,41.795],[105.697,41.931],[106.507,42.194],[106.5595,42.219],[106.786,42.2915],[107.041,42.3145],[107.257,42.363],[107.293,42.408],[107.453,42.4565],[107.496,42.455],[107.566,42.4115],[107.7275,42.412],[107.919,42.4025],[108.0165,42.4315],[108.241,42.4605],[108.306,42.436],[108.5275,42.441],[108.716,42.4095],[108.7955,42.414],[108.8385,42.3955],[108.96,42.4415],[109.0245,42.454],[109.284,42.4345],[109.469,42.4535],[109.5285,42.4675],[109.669,42.5515],[109.9035,42.6305],[110.101,42.639],[110.1365,42.672],[110.334,42.736],[110.436,42.782],[110.464,42.8325],[110.6295,42.9395],[110.6825,43.035],[110.759,43.095],[111.006,43.322],[111.213,43.3995],[111.327,43.425],[111.4015,43.4765],[111.4535,43.4895],[111.573,43.491],[111.799,43.6695],[111.883,43.672],[111.946,43.69],[111.968,43.744],[111.9545,43.8275],[111.874,43.932],[111.788,43.996],[111.693,44.0355],[111.609,44.106],[111.539,44.192],[111.519,44.271],[111.425,44.3175],[111.4095,44.3445],[111.4635,44.4715],[111.561,44.5715],[111.5535,44.6455],[111.605,44.756],[111.7695,44.9805],[111.874,45.038],[112.009,45.092],[112.1115,45.0715],[112.3745,45.0615],[112.4255,45.074],[112.519,45.0125],[112.585,44.936],[112.702,44.881],[112.8635,44.837],[112.931,44.8395],[113.1275,44.7955],[113.506,44.772],[113.6255,44.7425],[113.7765,44.839],[113.877,44.88],[113.907,44.9145],[114.056,44.9255],[114.1335,44.9665],[114.177,45.034],[114.3845,45.1435],[114.456,45.206],[114.528,45.2925],[114.541,45.3845],[114.737,45.4375],[114.9155,45.3815],[114.974,45.376],[115.165,45.396],[115.356,45.3895],[115.5575,45.436],[115.691,45.458],[115.932,45.6295],[116.015,45.656],[116.0305,45.6825],[116.17,45.6885],[116.2145,45.7415],[116.28,45.7705],[116.268,45.852],[116.2375,45.8725],[116.264,45.9615],[116.398,46.126],[116.4345,46.1375],[116.566,46.2535],[116.5775,46.2885],[116.658,46.321],[116.761,46.329],[116.8315,46.3835],[117.0885,46.3545],[117.243,46.365],[117.3685,46.3605],[117.392,46.478],[117.4405,46.5255],[117.415,46.5805],[117.494,46.5985],[117.6325,46.579],[117.702,46.5135],[117.834,46.5315],[117.889,46.5915],[118.0565,46.6345],[118.1155,46.6785],[118.184,46.6815],[118.301,46.7385],[118.4025,46.727],[118.437,46.7065],[118.5755,46.6935],[118.635,46.72],[118.6735,46.696],[118.792,46.687],[118.7835,46.717],[118.8425,46.7705],[118.897,46.776],[118.916,46.724],[119.0,46.751],[119.101,46.6475],[119.245,46.643],[119.3005,46.6085],[119.3835,46.6085],[119.4305,46.6385],[119.6375,46.625],[119.6805,46.5905],[119.7745,46.6255],[119.807,46.6675],[119.89,46.6635],[119.929,46.7205],[119.9015,46.7555],[119.932,46.7955],[119.8985,46.8655],[119.9215,46.9025],[119.855,46.9205],[119.7835,47.0245],[119.799,47.059],[119.708,47.1935],[119.6235,47.244],[119.571,47.2435],[119.5525,47.301],[119.4775,47.3275],[119.4635,47.358],[119.3215,47.425],[119.3575,47.4795],[119.143,47.5425],[119.1215,47.664],[118.755,47.772],[118.555,47.9935],[118.455,47.996],[118.4145,48.014],[118.2885,48.0035],[118.231,48.041],[118.1,48.0315],[118.0345,48.0125],[117.9135,48.0215],[117.805,48.014],[117.482,47.759],[117.375,47.64],[117.087,47.8205],[116.871,47.891],[116.6765,47.889],[116.4395,47.838],[116.2535,47.8785],[116.1115,47.819],[115.9555,47.6875],[115.9355,47.681],[115.742,47.8035],[115.5705,47.919],[115.5455,48.067],[115.5215,48.111],[115.5475,48.1615],[115.8135,48.259],[115.7985,48.4635],[115.811,48.547],[116.0205,48.757],[116.0725,48.8165],[116.0365,48.8675],[116.3255,49.289],[116.609,49.707],[116.7135,49.8455],[116.6215,49.931],[116.527,49.947],[116.3435,49.996],[116.233,50.036],[116.0725,50.0135],[115.983,49.9705],[115.7445,49.8875],[115.6825,49.886],[115.5065,49.907],[115.361,49.94],[115.224,49.9885],[115.0675,50.094],[115.0075,50.164],[114.831,50.2235],[114.617,50.2455],[114.4675,50.2335],[114.339,50.2825],[114.1785,50.243],[113.8785,50.105],[113.7425,50.075],[113.652,49.9995],[113.489,49.9735],[113.474,49.9355],[113.2185,49.837],[113.044,49.608],[112.907,49.5685],[112.8065,49.515],[112.689,49.504],[112.4865,49.524],[112.2785,49.4845],[112.1945,49.4465],[112.0075,49.3945],[111.909,49.3765],[111.788,49.3845],[111.6685,49.38],[111.515,49.323],[111.375,49.3575],[111.277,49.3105],[111.0785,49.262],[110.8195,49.182],[110.6835,49.171],[110.476,49.2015],[110.3795,49.247],[110.328,49.199],[110.226,49.158],[109.9025,49.2055],[109.8535,49.2015],[109.684,49.226],[109.559,49.221],[109.487,49.243],[109.4125,49.3],[109.326,49.329],[109.171,49.353],[109.058,49.323],[108.9555,49.345],[108.718,49.335],[108.6525,49.3475],[108.608,49.3275],[108.5175,49.3225],[108.431,49.372],[108.426,49.4135],[108.3565,49.428],[108.304,49.532],[108.161,49.562],[108.0515,49.6175],[108.0125,49.667],[107.9685,49.655],[107.9345,49.7115],[107.9675,49.735],[107.919,49.8755],[107.969,49.9415],[107.794,49.933],[107.729,49.9825],[107.5985,49.97],[107.383,49.9775],[107.349,49.9995],[107.211,50.0],[107.072,50.0685],[107.0,50.161],[106.9795,50.209],[106.8155,50.298],[106.5915,50.3385],[106.51,50.3415],[106.4475,50.3145],[106.3955,50.32],[106.261,50.298],[106.183,50.3395],[106.084,50.3335],[106.0745,50.3895],[105.989,50.416],[105.899,50.4125],[105.844,50.4405],[105.705,50.4265],[105.609,50.429],[105.525,50.458],[105.4265,50.444],[105.3475,50.476],[105.2985,50.472],[105.198,50.4115],[105.12,50.39],[105.008,50.387],[104.89,50.408],[104.8765,50.375],[104.8115,50.341],[104.699,50.367],[104.65,50.324],[104.557,50.307],[104.3965,50.3125],[104.3655,50.265],[104.3035,50.2445],[104.2785,50.201],[104.108,50.1405],[103.9985,50.1505],[103.9455,50.179],[103.8465,50.1975],[103.8005,50.1515],[103.6085,50.144],[103.514,50.199],[103.425,50.2115],[103.294,50.186],[103.2565,50.193],[103.2765,50.285],[103.238,50.322],[103.1765,50.3325],[102.942,50.3055],[102.7585,50.379],[102.727,50.408],[102.6475,50.402],[102.6105,50.5065],[102.547,50.527],[102.5255,50.5945],[102.479,50.5975],[102.446,50.6455],[102.3955,50.6445],[102.3025,50.682],[102.3405,50.7325],[102.295,50.7795],[102.2095,50.817],[102.211,50.873],[102.241,50.9175],[102.2035,51.0395],[102.151,51.0575],[102.1235,51.139],[102.138,51.1765],[102.1195,51.2795],[102.1685,51.3185],[102.1245,51.3615],[101.928,51.4165],[101.8935,51.401],[101.749,51.4555],[101.6205,51.4435],[101.6225,51.469],[101.5,51.5035],[101.439,51.4555],[101.37,51.456],[101.243,51.5475],[101.1435,51.52],[100.99,51.613],[100.93,51.607],[100.739,51.678],[100.688,51.7115],[100.529,51.75],[100.4105,51.73],[100.3535,51.7415],[100.201,51.743],[100.1035,51.7545],[100.033,51.7335],[99.978,51.7535],[99.9095,51.7455],[99.8195,51.848],[99.801,51.9155],[99.6255,51.8925],[99.52,51.9685],[99.4985,51.9515],[99.3055,51.9575],[99.276,52.0185],[99.1735,52.0355],[99.1325,52.024],[99.0715,52.0695],[98.9975,52.0865],[98.969,52.1425],[98.8615,52.136],[98.8415,52.059],[98.8065,52.0255],[98.809,51.958],[98.78,51.942],[98.7645,51.87],[98.6125,51.8065],[98.5215,51.7785],[98.4525,51.7365],[98.3785,51.74],[98.327,51.692],[98.234,51.5475],[98.2565,51.5115],[98.224,51.4565],[98.126,51.4715],[98.05,51.45],[98.017,51.3895],[97.9535,51.334],[97.962,51.276],[97.9395,51.202],[97.899,51.1495],[97.866,51.046],[97.828,51.019],[97.858,50.9595],[97.998,50.876],[98.0085,50.8365],[97.9785,50.784],[98.008,50.669],[98.1465,50.575],[98.274,50.538],[98.3275,50.474],[98.2725,50.41],[98.308,50.3235],[98.253,50.2945],[98.2285,50.236],[98.1695,50.202],[98.1825,50.158],[98.11,50.1315],[98.1205,50.1],[98.0635,50.07],[98.07,50.036],[97.982,50.019],[97.898,49.984],[97.8295,49.923],[97.7805,49.9935],[97.555,49.9225],[97.5805,49.8585],[97.5105,49.8145],[97.4215,49.7805],[97.3575,49.7815],[97.318,49.752],[97.231,49.743],[97.123,49.795],[97.117,49.82],[97.01,49.8335],[96.999,49.8885],[96.741,49.9075],[96.71,49.9285],[96.6005,49.8775],[96.549,49.9435],[96.5145,49.943],[96.417,49.877],[96.3485,49.9055],[96.2605,49.9765],[96.0175,50.0035],[95.9675,49.971],[95.9155,50.0215],[95.844,50.0435],[95.7655,50.017],[95.7955,49.964],[95.666,49.9645],[95.5725,49.9445],[95.531,49.8975],[95.426,49.9575],[95.0815,49.963],[95.0165,49.9805],[94.999,50.0445],[94.7605,50.055],[94.615,50.0355],[94.5435,50.1175],[94.522,50.1725],[94.4215,50.1915],[94.389,50.215],[94.344,50.4915],[94.2835,50.572],[94.2405,50.588],[94.031,50.5965],[93.941,50.59],[93.856,50.601],[93.7035,50.586],[93.636,50.607],[93.5445,50.602],[93.3975,50.6345],[93.249,50.594],[93.05,50.601],[92.975,50.6695],[93.023,50.716],[93.032,50.768],[92.854,50.81],[92.7875,50.8055],[92.754,50.7275],[92.628,50.7035],[92.6185,50.768],[92.571,50.798],[92.477,50.7865],[92.432,50.803],[92.373,50.88],[92.313,50.8765],[92.316,50.754],[92.172,50.7065],[92.0725,50.6965],[91.855,50.734],[91.7235,50.6975],[91.661,50.64],[91.65,50.586],[91.5345,50.5815],[91.455,50.5485],[91.459,50.5085],[91.4005,50.4765],[91.2935,50.4695],[91.16,50.42],[91.093,50.436],[90.9695,50.4295],[90.903,50.4085],[90.911,50.353],[90.8195,50.3545],[90.7065,50.313],[90.731,50.2435],[90.6735,50.2145],[90.5805,50.244],[90.504,50.235],[90.453,50.197],[90.389,50.1925],[90.285,50.111],[90.165,50.108],[90.0025,50.054],[90.0175,49.9905],[89.883,49.953],[89.7335,49.948],[89.6295,49.919],[89.6115,49.8635],[89.629,49.8085],[89.719,49.772],[89.719,49.7285],[89.661,49.7],[89.459,49.665],[89.36,49.5845],[89.241,49.645],[89.189,49.6325],[89.1915,49.586],[89.2325,49.5535],[89.201,49.523],[88.9845,49.4635],[88.9325,49.517],[88.88,49.478],[88.733,49.4515],[88.591,49.501],[88.495,49.472],[88.411,49.4935],[88.331,49.4935],[88.2965,49.471],[88.222,49.4795],[88.1655,49.4455],[88.185,49.4185],[88.1195,49.3915],[88.1605,49.363],[88.169,49.2925],[88.018,49.2265],[87.9885,49.183],[87.8145,49.17]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/4c/Flag_of_Mongolia.svg","name:en":"Mongolia","wikidata":"Q711","ISO3166-1:alpha2":"MN","ISO3166-1:alpha3":"MNG","ISO3166-1:numeric":"496"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-118.599,29.163],[-118.582,29.02],[-118.542,28.9555],[-118.5285,28.8485],[-118.4795,28.739],[-118.4185,28.685],[-118.3015,28.649],[-118.189,28.666],[-118.111,28.716],[-118.055,28.7865],[-118.003,28.886],[-117.9915,28.955],[-118.0035,29.115],[-118.03,29.1725],[-118.032,29.2265],[-118.0585,29.295],[-118.091,29.334],[-118.169,29.3815],[-118.294,29.395],[-118.4105,29.3675],[-118.486,29.3365],[-118.54,29.2975],[-118.5835,29.2355],[-118.599,29.163]]],[[[-117.465,32.5905],[-117.5175,32.527],[-117.5375,32.4415],[-117.5115,32.349],[-117.47,32.2975],[-117.358,32.214],[-117.2455,32.1875],[-117.205,32.1395],[-117.122,32.081],[-117.113,31.9795],[-117.0705,31.8975],[-117.0365,31.866],[-117.04,31.764],[-117.0035,31.6935],[-116.924,31.609],[-116.926,31.529],[-116.9005,31.459],[-116.769,31.3175],[-116.698,31.2765],[-116.648,31.2115],[-116.5755,31.1505],[-116.5515,31.107],[-116.568,30.941],[-116.541,30.87],[-116.457,30.791],[-116.3785,30.76],[-116.275,30.68],[-116.2665,30.652],[-116.3265,30.594],[-116.3545,30.5345],[-116.354,30.4375],[-116.321,30.3705],[-116.224,30.2975],[-116.155,30.2115],[-116.031,30.161],[-116.021,30.071],[-116.044,29.934],[-116.018,29.8555],[-116.034,29.792],[-116.0045,29.6715],[-115.9315,29.5825],[-115.838,29.533],[-115.7425,29.524],[-115.7025,29.5065],[-115.6405,29.4495],[-115.537,29.4125],[-115.4565,29.369],[-115.4045,29.3575],[-115.34,29.2765],[-115.272,29.2405],[-115.1465,29.2215],[-115.0925,29.1975],[-115.0535,29.1475],[-114.9395,29.046],[-114.8675,28.958],[-114.818,28.927],[-114.7815,28.857],[-114.667,28.757],[-114.6035,28.728],[-114.5135,28.594],[-114.4155,28.505],[-114.363,28.4775],[-114.2985,28.4095],[-114.3465,28.308],[-114.353,28.2435],[-114.3385,28.1855],[-114.4715,28.031],[-114.5355,27.9875],[-114.613,27.9805],[-114.672,28.002],[-114.8435,28.0295],[-114.9495,28.037],[-114.925,28.184],[-114.9605,28.343],[-115.027,28.477],[-115.0925,28.5375],[-115.196,28.577],[-115.288,28.5755],[-115.3965,28.534],[-115.44,28.4975],[-115.495,28.5135],[-115.6355,28.517],[-115.7515,28.467],[-115.804,28.405],[-115.824,28.3495],[-115.8255,28.272],[-115.806,28.216],[-115.764,28.1625],[-115.679,28.112],[-115.6095,28.097],[-115.5815,28.0165],[-115.5315,27.9595],[-115.451,27.9155],[-115.4405,27.836],[-115.401,27.7715],[-115.324,27.7015],[-115.2325,27.6585],[-115.1705,27.579],[-115.0265,27.4935],[-114.9445,27.435],[-114.89,27.375],[-114.843,27.346],[-114.7145,27.2925],[-114.713,27.224],[-114.694,27.148],[-114.6535,27.09],[-114.586,27.027],[-114.4855,26.965],[-114.343,26.9035],[-114.2345,26.9045],[-114.1505,26.818],[-114.0355,26.772],[-113.964,26.7735],[-113.93,26.7005],[-113.8785,26.6455],[-113.766,26.5625],[-113.7005,26.53],[-113.5905,26.5045],[-113.48,26.5265],[-113.4205,26.556],[-113.371,26.5235],[-113.2945,26.502],[-113.214,26.4505],[-113.108,26.3675],[-113.024,26.3235],[-112.8745,26.2125],[-112.824,26.16],[-112.7085,26.1165],[-112.6225,26.0635],[-112.528,26.0305],[-112.5125,25.988],[-112.45,25.912],[-112.3875,25.8735],[-112.3245,25.7155],[-112.3245,25.4645],[-112.34,25.365],[-112.3725,25.2245],[-112.42,25.06],[-112.4685,24.9425],[-112.5075,24.8855],[-112.5245,24.7855],[-112.495,24.693],[-112.381,24.5815],[-112.3055,24.4895],[-112.2715,24.4315],[-112.1905,24.373],[-112.092,24.3265],[-111.9015,24.2025],[-111.8645,24.1605],[-111.7845,24.1135],[-111.6975,24.1015],[-111.6415,24.1105],[-111.5635,24.1515],[-111.351,24.051],[-111.181,23.9475],[-111.0645,23.8555],[-110.8395,23.621],[-110.745,23.5455],[-110.643,23.4855],[-110.498,23.4265],[-110.451,23.37],[-110.417,23.2975],[-110.3765,23.245],[-110.3655,23.1805],[-110.3005,22.942],[-110.244,22.8345],[-110.1785,22.7635],[-110.042,22.6815],[-109.959,22.6705],[-109.8455,22.679],[-109.7155,22.742],[-109.6355,22.8165],[-109.5425,22.8835],[-109.5015,22.8935],[-109.4135,22.9425],[-109.369,22.9815],[-109.2745,23.0925],[-109.2285,23.186],[-109.1985,23.3625],[-109.2,23.444],[-109.2175,23.5125],[-109.2515,23.5745],[-109.276,23.6495],[-109.3215,23.7035],[-109.4275,23.7675],[-109.4825,23.7885],[-109.486,23.8365],[-109.519,23.9105],[-109.589,23.9825],[-109.5925,24.071],[-109.5755,24.1845],[-109.6145,24.295],[-109.7305,24.4765],[-109.7955,24.5425],[-109.9075,24.5805],[-110.02,24.5625],[-110.086,24.5195],[-110.1125,24.598],[-110.1885,24.676],[-110.25,24.7535],[-110.341,24.7965],[-110.3145,24.9045],[-110.3535,25.0135],[-110.3365,25.08],[-110.352,25.171],[-110.4145,25.2505],[-110.483,25.287],[-110.487,25.3605],[-110.515,25.4215],[-110.605,25.4955],[-110.582,25.5425],[-110.5745,25.6285],[-110.608,25.7765],[-110.6555,25.8375],[-110.7415,25.8855],[-110.822,25.8965],[-110.8785,25.888],[-110.8595,25.963],[-110.8635,26.0805],[-110.8785,26.1425],[-110.95,26.2275],[-110.9965,26.252],[-111.112,26.267],[-111.159,26.2975],[-111.1735,26.384],[-111.225,26.4735],[-111.1955,26.5565],[-111.1845,26.624],[-111.192,26.679],[-111.2255,26.746],[-111.266,26.786],[-111.3435,26.825],[-111.3975,26.8345],[-111.462,26.8775],[-111.5725,26.9805],[-111.697,27.068],[-111.7175,27.1355],[-111.815,27.2455],[-111.724,27.289],[-111.686,27.3265],[-111.6475,27.406],[-111.6585,27.518],[-111.7195,27.597],[-111.776,27.6315],[-111.8775,27.6615],[-112.008,27.6415],[-112.081,27.592],[-112.1355,27.619],[-112.2155,27.708],[-112.3065,27.766],[-112.457,27.827],[-112.5015,27.8675],[-112.5315,27.9325],[-112.5315,28.012],[-112.5725,28.1295],[-112.562,28.231],[-112.587,28.2945],[-112.6265,28.3415],[-112.617,28.441],[-112.5645,28.4215],[-112.568,28.337],[-112.524,28.245],[-112.4385,28.182],[-112.317,28.163],[-112.2405,28.1825],[-112.166,28.233],[-112.122,28.2975],[-112.104,28.3855],[-112.14,28.4915],[-112.178,28.533],[-112.101,28.596],[-112.053,28.5485],[-111.967,28.486],[-111.915,28.367],[-111.839,28.2905],[-111.664,28.233],[-111.5675,28.112],[-111.606,28.05],[-111.617,27.96],[-111.5685,27.847],[-111.5185,27.8005],[-111.421,27.758],[-111.3535,27.753],[-111.25,27.7815],[-110.963,27.6495],[-110.858,27.6395],[-110.8565,27.5905],[-110.8185,27.49],[-110.833,27.3465],[-110.8085,27.236],[-110.7625,27.174],[-110.699,27.1305],[-110.6,27.0935],[-110.5495,27.0855],[-110.4695,27.011],[-110.344,26.952],[-110.21,26.9235],[-110.138,26.887],[-110.097,26.8345],[-110.0455,26.6885],[-110.0055,26.6325],[-109.8955,26.545],[-109.7765,26.493],[-109.699,26.474],[-109.5885,26.4865],[-109.535,26.4735],[-109.482,26.429],[-109.479,26.3825],[-109.5145,26.2875],[-109.6035,26.158],[-109.6615,26.0215],[-109.672,25.93],[-109.651,25.854],[-109.6555,25.7815],[-109.6245,25.6985],[-109.623,25.616],[-109.5935,25.5335],[-109.5405,25.478],[-109.4745,25.445],[-109.3435,25.437],[-109.265,25.377],[-109.221,25.322],[-109.125,25.256],[-108.988,25.2315],[-108.853,25.1705],[-108.7545,25.1605],[-108.602,25.1045],[-108.564,25.026],[-108.4045,24.901],[-108.345,24.8015],[-108.334,24.736],[-108.301,24.679],[-108.23,24.622],[-108.1845,24.5415],[-108.1305,24.486],[-107.9915,24.396],[-107.927,24.328],[-107.829,24.2755],[-107.6935,24.1895],[-107.5225,24.061],[-107.415,23.9995],[-107.269,23.894],[-107.1575,23.8035],[-107.0955,23.7415],[-107.028,23.626],[-106.997,23.546],[-106.9575,23.502],[-106.8685,23.4355],[-106.7975,23.351],[-106.713,23.275],[-106.675,23.1585],[-106.6275,23.0795],[-106.581,23.03],[-106.477,22.98],[-106.2905,22.809],[-106.1815,22.684],[-106.082,22.619],[-105.9925,22.527],[-105.98,22.469],[-105.8925,22.315],[-105.8715,22.2305],[-105.8695,22.09],[-105.984,22.077],[-106.0565,22.0335],[-106.097,21.9825],[-106.123,21.9005],[-106.115,21.8225],[-106.097,21.779],[-106.032,21.706],[-105.9225,21.6645],[-105.838,21.6715],[-105.7375,21.73],[-105.7085,21.684],[-105.73,21.634],[-105.7365,21.565],[-105.6905,21.4575],[-105.641,21.4145],[-105.5725,21.386],[-105.46,21.388],[-105.459,21.3065],[-105.4395,21.241],[-105.449,21.1925],[-105.518,21.1015],[-105.611,21.0125],[-105.7275,20.8665],[-105.8245,20.811],[-105.857,20.769],[-105.8835,20.67],[-105.8755,20.616],[-105.8435,20.5545],[-105.884,20.5025],[-105.908,20.403],[-105.8815,20.285],[-105.8275,20.1975],[-105.7615,20.128],[-105.761,20.0635],[-105.7405,20.0035],[-105.6655,19.8715],[-105.558,19.738],[-105.5085,19.6385],[-105.3435,19.4685],[-105.279,19.419],[-105.2335,19.3155],[-105.1995,19.262],[-105.1165,19.1675],[-105.0515,19.123],[-104.999,19.107],[-104.925,19.0505],[-104.838,19.024],[-104.747,18.9795],[-104.629,18.951],[-104.581,18.9205],[-104.4955,18.89],[-104.431,18.84],[-104.23,18.7715],[-104.0665,18.681],[-103.9325,18.584],[-103.924,18.5335],[-103.866,18.4435],[-103.7705,18.381],[-103.733,18.2605],[-103.684,18.1915],[-103.5835,18.1245],[-103.5285,18.111],[-103.4545,18.0715],[-103.3745,18.055],[-103.153,17.98],[-103.0815,17.978],[-102.853,17.8935],[-102.725,17.859],[-102.67,17.8575],[-102.581,17.821],[-102.3265,17.754],[-102.1145,17.719],[-101.9985,17.7535],[-101.959,17.73],[-101.9265,17.6795],[-101.868,17.623],[-101.8295,17.547],[-101.749,17.478],[-101.6865,17.4465],[-101.609,17.3635],[-101.5085,17.3315],[-101.3385,17.2605],[-101.273,17.21],[-101.2155,17.1205],[-101.15,17.0805],[-100.3915,16.835],[-100.2015,16.7595],[-100.1075,16.734],[-100.0475,16.663],[-99.881,16.567],[-99.7335,16.5065],[-99.621,16.4875],[-99.5075,16.4895],[-99.3495,16.4435],[-99.1035,16.403],[-99.0365,16.3735],[-98.8735,16.335],[-98.751,16.228],[-98.715,16.183],[-98.6495,16.141],[-98.4655,16.072],[-98.298,16.0425],[-98.1615,15.987],[-97.9065,15.787],[-97.8445,15.7625],[-97.6955,15.741],[-97.537,15.7385],[-97.3745,15.7065],[-97.295,15.713],[-97.231,15.7005],[-97.173,15.648],[-97.1035,15.6075],[-97.0355,15.5885],[-96.934,15.536],[-96.746,15.502],[-96.61,15.4495],[-96.5005,15.439],[-96.39,15.4675],[-96.2445,15.462],[-96.1675,15.473],[-95.9615,15.571],[-95.865,15.641],[-95.703,15.6835],[-95.5165,15.7575],[-95.348,15.796],[-95.2585,15.8485],[-95.189,15.9205],[-95.1255,15.9645],[-94.897,16.0125],[-94.8135,16.015],[-94.573,15.9945],[-94.454,15.972],[-94.3285,15.9245],[-94.1615,15.8315],[-93.9965,15.781],[-93.951,15.7765],[-93.8055,15.69],[-93.5465,15.5],[-93.256,15.246],[-93.044,15.044],[-93.0165,15.0095],[-92.769,14.76],[-92.3745,14.3885],[-92.3105,14.451],[-92.186,14.5725],[-92.147,14.6585],[-92.159,14.769],[-92.185,14.8285],[-92.136,14.893],[-92.1485,14.9485],[-92.133,15.0115],[-92.102,15.011],[-92.0595,15.071],[-92.2105,15.2605],[-92.017,15.5895],[-91.7315,16.074],[-90.961,16.074],[-90.442,16.074],[-90.4265,16.1625],[-90.455,16.189],[-90.4395,16.3045],[-90.4105,16.3095],[-90.3985,16.3745],[-90.42,16.4245],[-90.4885,16.4285],[-90.5035,16.4685],[-90.586,16.47],[-90.637,16.5135],[-90.659,16.6425],[-90.683,16.6895],[-90.7645,16.7635],[-90.847,16.796],[-90.8825,16.825],[-90.92,16.821],[-90.9575,16.897],[-91.009,16.887],[-91.0645,16.925],[-91.2035,17.045],[-91.2325,17.1],[-91.2685,17.11],[-91.278,17.179],[-91.3255,17.1825],[-91.429,17.2185],[-91.439,17.251],[-90.9875,17.2515],[-90.9875,17.8155],[-90.2455,17.816],[-89.5155,17.8155],[-89.152,17.8155],[-89.152,17.9395],[-89.1325,17.9685],[-89.0375,18.005],[-88.993,17.9595],[-88.9455,17.9525],[-88.9205,17.916],[-88.8575,17.9245],[-88.8165,17.9495],[-88.767,18.016],[-88.7165,18.061],[-88.7185,18.108],[-88.6735,18.194],[-88.6155,18.2235],[-88.606,18.2915],[-88.548,18.355],[-88.517,18.464],[-88.478,18.4935],[-88.4435,18.48],[-88.3275,18.4905],[-88.25,18.473],[-88.2495,18.4155],[-88.0305,18.415],[-88.031,18.1675],[-87.9325,18.1675],[-87.91,18.1505],[-87.868,18.198],[-87.744,18.1165],[-87.435,17.924],[-87.375,17.917],[-87.385,18.198],[-87.538,18.223],[-87.6205,18.2465],[-87.563,18.348],[-87.548,18.4575],[-87.4435,18.3945],[-87.3645,18.375],[-87.3045,18.378],[-87.2115,18.4165],[-87.134,18.5025],[-87.113,18.5895],[-87.1245,18.667],[-87.102,18.7675],[-87.129,18.858],[-87.162,18.901],[-87.223,18.943],[-87.338,18.9625],[-87.385,18.952],[-87.349,19.031],[-87.3355,19.1425],[-87.271,19.221],[-87.2485,19.282],[-87.257,19.383],[-87.21,19.543],[-87.21,19.6425],[-87.2565,19.7465],[-87.221,19.8315],[-87.212,19.8935],[-87.231,19.999],[-87.263,20.0665],[-87.2435,20.112],[-87.192,20.177],[-87.138,20.12],[-87.0885,20.0875],[-87.02,20.0685],[-86.9555,20.0705],[-86.872,20.101],[-86.776,20.173],[-86.649,20.316],[-86.577,20.413],[-86.54,20.485],[-86.514,20.573],[-86.528,20.6705],[-86.587,20.75],[-86.6655,20.7915],[-86.6275,20.889],[-86.5955,20.93],[-86.4965,21.1655],[-86.494,21.2175],[-86.511,21.2805],[-86.5765,21.392],[-86.5755,21.505],[-86.6205,21.6405],[-86.693,21.7075],[-86.76,21.732],[-86.864,21.729],[-86.9485,21.773],[-87.044,21.8035],[-87.1485,21.8075],[-87.262,21.754],[-87.3655,21.7635],[-87.422,21.751],[-87.516,21.691],[-87.7305,21.737],[-87.929,21.806],[-88.109,21.8285],[-88.206,21.82],[-88.3135,21.767],[-88.4425,21.7665],[-88.5695,21.733],[-88.6655,21.721],[-88.747,21.687],[-88.822,21.6225],[-88.9235,21.5945],[-89.1675,21.556],[-89.4145,21.534],[-89.618,21.4985],[-89.7155,21.4895],[-89.9075,21.4435],[-90.03,21.396],[-90.0785,21.3665],[-90.214,21.3275],[-90.436,21.196],[-90.4965,21.1425],[-90.554,21.063],[-90.6605,20.7795],[-90.6695,20.669],[-90.6995,20.577],[-90.7085,20.506],[-90.699,20.4175],[-90.7085,20.3755],[-90.71,20.1575],[-90.7015,20.103],[-90.722,20.063],[-90.732,19.968],[-90.812,19.9085],[-90.847,19.8645],[-90.894,19.7735],[-90.911,19.7185],[-90.909,19.63],[-90.9205,19.563],[-90.9165,19.48],[-90.933,19.428],[-91.025,19.3515],[-91.329,19.155],[-91.486,19.092],[-91.6005,19.0135],[-91.642,18.969],[-91.7375,18.93],[-91.8385,18.874],[-91.901,18.9065],[-92.0,18.9185],[-92.369,18.8785],[-92.511,18.852],[-92.635,18.8145],[-92.7325,18.8145],[-92.793,18.791],[-92.8715,18.721],[-92.8995,18.6735],[-92.9915,18.637],[-93.337,18.653],[-93.46,18.648],[-93.5225,18.6355],[-93.9135,18.4945],[-94.2005,18.4065],[-94.366,18.365],[-94.4245,18.3595],[-94.4585,18.414],[-94.539,18.5],[-94.598,18.6155],[-94.6675,18.6945],[-94.709,18.72],[-94.804,18.75],[-94.8945,18.7535],[-94.9445,18.806],[-95.097,18.901],[-95.1965,18.9215],[-95.305,18.9255],[-95.458,18.915],[-95.581,18.9275],[-95.712,18.9935],[-95.7485,19.021],[-95.736,19.0755],[-95.762,19.189],[-95.844,19.2665],[-95.871,19.3315],[-95.9315,19.393],[-95.9965,19.4245],[-96.103,19.436],[-96.1055,19.5045],[-96.129,19.5765],[-96.1655,19.6365],[-96.191,19.7915],[-96.26,19.954],[-96.3585,20.0565],[-96.394,20.1225],[-96.452,20.1785],[-96.5385,20.29],[-96.6395,20.3985],[-96.769,20.5255],[-96.8085,20.582],[-96.961,20.733],[-97.041,20.933],[-97.081,20.9885],[-97.2015,21.2295],[-97.1865,21.309],[-97.113,21.3295],[-97.0715,21.3555],[-97.0205,21.4145],[-96.9945,21.5195],[-97.0105,21.587],[-97.045,21.6405],[-97.1225,21.714],[-97.215,21.7505],[-97.3965,21.9045],[-97.5325,22.0955],[-97.5725,22.2095],[-97.5665,22.2675],[-97.585,22.3425],[-97.621,22.42],[-97.635,22.4875],[-97.6305,22.6005],[-97.57,22.761],[-97.5455,22.866],[-97.5395,23.0615],[-97.548,23.259],[-97.544,23.4215],[-97.5175,23.756],[-97.5105,24.0665],[-97.487,24.3145],[-97.4645,24.457],[-97.411,24.6625],[-97.3195,24.948],[-97.2305,25.1475],[-96.989,25.578],[-96.969,25.63],[-96.933,25.7925],[-96.924,25.9755],[-97.178,25.962],[-97.2755,25.952],[-97.367,25.9035],[-97.3715,25.842],[-97.4435,25.848],[-97.456,25.884],[-97.5105,25.8875],[-97.556,25.937],[-97.6675,26.0245],[-97.779,26.03],[-97.793,26.0535],[-97.875,26.0635],[-97.9645,26.052],[-98.0005,26.0655],[-98.0385,26.0415],[-98.105,26.0675],[-98.1585,26.0535],[-98.249,26.072],[-98.3225,26.1195],[-98.3385,26.153],[-98.3845,26.157],[-98.4805,26.22],[-98.678,26.2435],[-98.7445,26.3155],[-98.789,26.3305],[-98.825,26.3705],[-98.889,26.357],[-98.9785,26.4],[-99.04,26.413],[-99.0835,26.3975],[-99.111,26.427],[-99.0915,26.476],[-99.1275,26.525],[-99.1675,26.5365],[-99.178,26.6205],[-99.2,26.656],[-99.209,26.725],[-99.24,26.746],[-99.2685,26.8435],[-99.3285,26.8785],[-99.3305,26.9205],[-99.388,26.9425],[-99.3835,26.9775],[-99.445,27.02],[-99.453,27.063],[-99.4285,27.092],[-99.426,27.1755],[-99.442,27.251],[-99.4965,27.2735],[-99.504,27.339],[-99.4785,27.4795],[-99.528,27.499],[-99.511,27.565],[-99.539,27.603],[-99.6005,27.6415],[-99.7215,27.666],[-99.8135,27.7745],[-99.875,27.7965],[-99.8935,27.899],[-99.9375,27.9415],[-99.9335,27.9815],[-99.9905,27.9935],[-100.018,28.065],[-100.0525,28.0845],[-100.0885,28.148],[-100.212,28.1945],[-100.294,28.2845],[-100.288,28.316],[-100.3495,28.404],[-100.336,28.43],[-100.411,28.5495],[-100.3985,28.5855],[-100.447,28.609],[-100.5005,28.662],[-100.5145,28.752],[-100.5465,28.825],[-100.6515,28.946],[-100.6455,28.988],[-100.664,29.075],[-100.685,29.1115],[-100.76,29.1575],[-100.795,29.2435],[-100.8785,29.281],[-100.8865,29.3075],[-101.005,29.3655],[-101.06,29.4585],[-101.1485,29.4755],[-101.193,29.5205],[-101.2505,29.5195],[-101.2415,29.5645],[-101.312,29.5865],[-101.3005,29.638],[-101.3645,29.6655],[-101.3945,29.711],[-101.3995,29.76],[-101.6615,29.771],[-101.71,29.7615],[-101.774,29.789],[-101.8035,29.78],[-101.9545,29.796],[-101.9815,29.815],[-102.0735,29.7865],[-102.144,29.8035],[-102.3005,29.8775],[-102.34,29.8695],[-102.404,29.7655],[-102.4875,29.7865],[-102.548,29.7445],[-102.677,29.7415],[-102.6935,29.6765],[-102.742,29.633],[-102.7785,29.5435],[-102.8085,29.523],[-102.8395,29.359],[-102.877,29.355],[-102.9065,29.2615],[-102.868,29.223],[-102.955,29.1775],[-102.99,29.1835],[-103.032,29.104],[-103.08,29.0875],[-103.098,29.0265],[-103.1525,28.972],[-103.2505,28.9805],[-103.3115,29.0135],[-103.416,29.038],[-103.474,29.0705],[-103.5005,29.116],[-103.557,29.1555],[-103.5925,29.15],[-103.719,29.181],[-103.783,29.264],[-103.975,29.296],[-104.1605,29.39],[-104.209,29.481],[-104.262,29.5135],[-104.3375,29.5195],[-104.3985,29.5715],[-104.5125,29.6465],[-104.5445,29.681],[-104.5655,29.7695],[-104.6335,29.8705],[-104.68,29.9205],[-104.6905,30.016],[-104.687,30.179],[-104.761,30.3],[-104.812,30.333],[-104.811,30.363],[-104.8595,30.3905],[-104.872,30.5105],[-104.8995,30.571],[-104.9715,30.61],[-105.007,30.6865],[-105.0525,30.6815],[-105.13,30.7505],[-105.196,30.792],[-105.2665,30.8085],[-105.387,30.8535],[-105.4,30.8895],[-105.556,30.989],[-105.606,31.085],[-105.649,31.116],[-105.7695,31.165],[-105.8705,31.29],[-105.9315,31.313],[-105.955,31.3655],[-106.0055,31.3925],[-106.0775,31.398],[-106.219,31.4795],[-106.245,31.539],[-106.2795,31.561],[-106.308,31.6295],[-106.382,31.7325],[-106.455,31.7645],[-106.49,31.7485],[-106.529,31.784],[-107.2905,31.7835],[-107.8655,31.7835],[-108.2085,31.7835],[-108.2085,31.3335],[-108.851,31.3325],[-109.2785,31.334],[-109.7465,31.334],[-110.456,31.333],[-111.075,31.332],[-111.864,31.5845],[-112.3995,31.752],[-113.1485,31.9805],[-113.924,32.2235],[-114.4385,32.381],[-114.8135,32.494],[-114.8105,32.61],[-114.765,32.643],[-114.72,32.7185],[-115.1805,32.6875],[-115.718,32.6485],[-116.3375,32.6],[-117.1245,32.5345],[-117.239,32.5275],[-117.264,32.5535],[-117.465,32.5905]]],[[[-115.9705,24.952],[-115.9505,24.868],[-115.9005,24.805],[-115.8455,24.7705],[-115.7525,24.7505],[-115.663,24.767],[-115.599,24.8055],[-115.5415,24.8845],[-115.53,24.975],[-115.569,25.068],[-115.607,25.1065],[-115.6705,25.141],[-115.726,25.153],[-115.801,25.149],[-115.884,25.113],[-115.9375,25.059],[-115.9705,24.952]]],[[[-114.9845,18.363],[-114.9775,18.302],[-114.929,18.2135],[-114.8635,18.164],[-114.8225,18.149],[-114.7115,18.146],[-114.627,18.165],[-114.5485,18.214],[-114.486,18.3085],[-114.4735,18.381],[-114.482,18.4385],[-114.54,18.528],[-114.646,18.5815],[-114.777,18.5825],[-114.8355,18.5715],[-114.9095,18.5325],[-114.942,18.499],[-114.977,18.429],[-114.9845,18.363]]],[[[-112.2835,18.9985],[-112.27,18.93],[-112.233,18.87],[-112.143,18.811],[-112.071,18.799],[-111.999,18.8115],[-111.9355,18.847],[-111.889,18.9005],[-111.864,18.966],[-111.8645,19.036],[-111.89,19.1015],[-111.9375,19.1545],[-112.001,19.189],[-112.0735,19.201],[-112.1455,19.1885],[-112.209,19.153],[-112.271,19.0675],[-112.2835,18.9985]]],[[[-111.279,18.8385],[-111.2655,18.7405],[-111.2245,18.6565],[-111.144,18.585],[-111.0455,18.5245],[-110.9835,18.5085],[-110.9015,18.514],[-110.793,18.564],[-110.7375,18.6305],[-110.69,18.7545],[-110.7045,18.848],[-110.77,18.9855],[-110.8115,19.0365],[-110.905,19.0865],[-110.969,19.092],[-111.0315,19.0795],[-111.188,19.0045],[-111.2565,18.9295],[-111.279,18.8385]]],[[[-111.044,19.3035],[-111.025,19.2165],[-110.9475,19.1295],[-110.8655,19.097],[-110.788,19.0945],[-110.7345,19.107],[-110.6665,19.1475],[-110.6055,19.2375],[-110.595,19.3555],[-110.624,19.4315],[-110.681,19.493],[-110.756,19.5275],[-110.8495,19.5315],[-110.9165,19.51],[-110.9675,19.4735],[-111.021,19.397],[-111.044,19.3035]]],[[[-106.925,21.7435],[-106.912,21.674],[-106.8645,21.6035],[-106.7975,21.4725],[-106.703,21.404],[-106.6535,21.3245],[-106.5805,21.269],[-106.4845,21.2305],[-106.453,21.1805],[-106.3765,21.117],[-106.2885,21.083],[-106.2355,21.0745],[-106.1465,21.088],[-106.079,21.128],[-106.0445,21.166],[-106.0145,21.2315],[-106.005,21.314],[-106.0155,21.383],[-106.055,21.454],[-106.155,21.5215],[-106.197,21.596],[-106.258,21.65],[-106.3025,21.67],[-106.367,21.786],[-106.4185,21.831],[-106.479,21.863],[-106.512,21.9085],[-106.612,21.97],[-106.696,21.9785],[-106.7935,21.948],[-106.881,21.866],[-106.909,21.8205],[-106.925,21.7435]]],[[[-92.5245,20.977],[-92.5025,20.887],[-92.404,20.7665],[-92.311,20.707],[-92.2055,20.6985],[-92.134,20.7225],[-92.067,20.7715],[-92.017,20.8415],[-92.004,20.9525],[-92.0535,21.051],[-92.18,21.1445],[-92.262,21.177],[-92.383,21.1675],[-92.462,21.119],[-92.505,21.061],[-92.5245,20.977]]],[[[-92.1865,20.212],[-92.1695,20.133],[-92.097,20.044],[-92.03,20.0115],[-91.91,20.009],[-91.819,20.057],[-91.7765,20.1085],[-91.751,20.2],[-91.76,20.2655],[-91.8035,20.344],[-91.8765,20.4],[-91.9385,20.4185],[-92.023,20.415],[-92.116,20.368],[-92.1625,20.3095],[-92.1865,20.212]]],[[[-91.6295,22.13],[-91.6115,22.049],[-91.565,21.985],[-91.5185,21.952],[-91.4455,21.928],[-91.351,21.928],[-91.243,21.976],[-91.188,22.045],[-91.169,22.1175],[-91.186,22.21],[-91.2375,22.278],[-91.294,22.3145],[-91.3865,22.334],[-91.478,22.3235],[-91.5665,22.273],[-91.609,22.217],[-91.6295,22.13]]],[[[-90.013,22.574],[-89.9955,22.4935],[-89.9185,22.3165],[-89.8055,22.213],[-89.6995,22.1725],[-89.579,22.1845],[-89.5205,22.2175],[-89.456,22.302],[-89.4405,22.37],[-89.4505,22.4395],[-89.488,22.5075],[-89.5515,22.561],[-89.5585,22.631],[-89.6,22.706],[-89.6575,22.752],[-89.7645,22.783],[-89.882,22.7615],[-89.95,22.7175],[-90.0055,22.627],[-90.013,22.574]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/fc/Flag_of_Mexico.svg","name:en":"Mexico","wikidata":"Q96","ISO3166-1:alpha2":"MX","ISO3166-1:alpha3":"MEX","ISO3166-1:numeric":"484"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-62.4475,16.7575],[-62.4435,16.671],[-62.4095,16.604],[-62.3055,16.509],[-62.2095,16.476],[-62.1405,16.477],[-62.057,16.503],[-62.0065,16.541],[-61.9585,16.605],[-61.9405,16.653],[-61.9425,16.775],[-61.9615,16.8375],[-62.109,17.0055],[-62.14,17.0155],[-62.4475,16.7575]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/d0/Flag_of_Montserrat.svg","name:en":"Montserrat","wikidata":"Q13353","ISO3166-1:alpha2":"MS","ISO3166-1:alpha3":"MSR","ISO3166-1:numeric":"500"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-174.7435,-4.66],[-174.7185,-4.765],[-174.677,-4.822],[-174.622,-4.861],[-174.5315,-4.893],[-174.457,-4.893],[-174.369,-4.854],[-174.323,-4.804],[-174.298,-4.747],[-174.2955,-4.653],[-174.3155,-4.597],[-174.373,-4.525],[-174.4355,-4.483],[-174.5035,-4.458],[-174.5615,-4.456],[-174.6385,-4.48],[-174.717,-4.558],[-174.7435,-4.66]]],[[[-174.3265,-3.592],[-174.3025,-3.691],[-174.252,-3.753],[-174.1585,-3.796],[-174.1005,-3.798],[-174.0235,-3.774],[-173.9455,-3.696],[-173.9215,-3.63],[-173.9245,-3.548],[-173.945,-3.495],[-174.0235,-3.417],[-174.1005,-3.393],[-174.16,-3.395],[-174.231,-3.422],[-174.3065,-3.506],[-174.3265,-3.592]]],[[[-172.426,-4.515],[-172.417,-4.577],[-172.3835,-4.644],[-172.3,-4.714],[-172.2335,-4.738],[-172.1685,-4.741],[-172.0435,-4.693],[-171.986,-4.647],[-171.959,-4.608],[-171.9355,-4.535],[-171.938,-4.451],[-171.9575,-4.399],[-172.0145,-4.334],[-172.0965,-4.295],[-172.185,-4.288],[-172.2375,-4.299],[-172.3515,-4.359],[-172.4035,-4.424],[-172.426,-4.515]]],[[[-171.9235,-2.789],[-171.895,-2.905],[-171.8675,-2.952],[-171.8195,-2.998],[-171.6555,-3.067],[-171.5765,-3.066],[-171.503,-3.035],[-171.456,-2.99],[-171.421,-2.916],[-171.415,-2.854],[-171.4435,-2.748],[-171.482,-2.679],[-171.5205,-2.643],[-171.6335,-2.579],[-171.6955,-2.566],[-171.758,-2.569],[-171.829,-2.598],[-171.9015,-2.681],[-171.9235,-2.789]]],[[[-171.7215,-3.58],[-171.695,-3.681],[-171.653,-3.736],[-171.556,-3.786],[-171.481,-3.787],[-171.43,-3.771],[-171.37,-3.728],[-171.3205,-3.64],[-171.3135,-3.584],[-171.33,-3.504],[-171.3645,-3.45],[-171.451,-3.392],[-171.514,-3.381],[-171.5865,-3.392],[-171.66,-3.437],[-171.7115,-3.52],[-171.7215,-3.58]]],[[[-171.4635,-4.456],[-171.4595,-4.496],[-171.424,-4.576],[-171.389,-4.615],[-171.331,-4.651],[-171.241,-4.668],[-171.1755,-4.66],[-171.099,-4.62],[-171.063,-4.582],[-171.033,-4.52],[-171.0295,-4.418],[-171.066,-4.337],[-171.138,-4.267],[-171.2065,-4.242],[-171.265,-4.24],[-171.33,-4.258],[-171.4145,-4.321],[-171.459,-4.41],[-171.4635,-4.456]]],[[[-171.292,-3.109],[-171.289,-3.173],[-171.2525,-3.263],[-171.2065,-3.309],[-171.1335,-3.342],[-171.0495,-3.344],[-170.9795,-3.32],[-170.9325,-3.284],[-170.8915,-3.223],[-170.8765,-3.113],[-170.9075,-3.006],[-170.9825,-2.931],[-171.0805,-2.904],[-171.1535,-2.915],[-171.2435,-2.977],[-171.279,-3.037],[-171.292,-3.109]]],[[[-170.9185,-3.716],[-170.91,-3.776],[-170.8735,-3.846],[-170.7975,-3.907],[-170.747,-3.923],[-170.676,-3.923],[-170.612,-3.9],[-170.5325,-3.82],[-170.509,-3.749],[-170.526,-3.637],[-170.5645,-3.581],[-170.6575,-3.525],[-170.711,-3.517],[-170.7835,-3.528],[-170.8295,-3.551],[-170.8995,-3.632],[-170.9185,-3.716]]],[[[-160.61,4.689],[-160.5865,4.596],[-160.5295,4.528],[-160.4545,4.486],[-160.3935,4.471],[-160.3235,4.473],[-160.2305,4.514],[-160.1655,4.597],[-160.149,4.677],[-160.157,4.735],[-160.183,4.794],[-160.2505,4.859],[-160.321,4.888],[-160.403,4.9],[-160.466,4.889],[-160.5555,4.831],[-160.5855,4.789],[-160.61,4.689]]],[[[-159.595,3.899],[-159.5785,3.817],[-159.511,3.71],[-159.4355,3.639],[-159.3665,3.612],[-159.2885,3.607],[-159.196,3.629],[-159.1045,3.691],[-159.051,3.779],[-159.041,3.873],[-159.0685,3.962],[-159.098,4.004],[-159.1965,4.087],[-159.27,4.127],[-159.339,4.14],[-159.4315,4.125],[-159.492,4.092],[-159.541,4.046],[-159.5855,3.961],[-159.595,3.899]]],[[[-157.7615,1.877],[-157.7475,1.799],[-157.686,1.708],[-157.634,1.669],[-157.4985,1.599],[-157.4055,1.576],[-157.328,1.522],[-157.2335,1.494],[-157.138,1.5],[-157.0455,1.542],[-156.9945,1.599],[-156.971,1.655],[-156.966,1.761],[-156.9885,1.841],[-157.051,1.919],[-157.1015,1.951],[-157.116,2.045],[-157.1445,2.097],[-157.19,2.145],[-157.289,2.188],[-157.334,2.219],[-157.4285,2.248],[-157.5495,2.238],[-157.605,2.211],[-157.6685,2.144],[-157.6925,2.083],[-157.697,2.025],[-157.744,1.957],[-157.7615,1.877]]],[[[-156.1355,-5.631],[-156.1205,-5.709],[-156.0745,-5.778],[-155.9495,-5.85],[-155.855,-5.862],[-155.7945,-5.846],[-155.6995,-5.787],[-155.6525,-5.717],[-155.6385,-5.665],[-155.6575,-5.551],[-155.718,-5.476],[-155.783,-5.438],[-155.888,-5.421],[-156.006,-5.445],[-156.093,-5.509],[-156.1225,-5.561],[-156.1355,-5.631]]],[[[-155.171,-4.014],[-155.1415,-4.12],[-155.1085,-4.161],[-155.009,-4.233],[-154.9585,-4.249],[-154.876,-4.247],[-154.802,-4.217],[-154.7305,-4.145],[-154.707,-4.085],[-154.691,-3.977],[-154.7015,-3.925],[-154.734,-3.865],[-154.777,-3.824],[-154.85,-3.792],[-154.934,-3.79],[-155.011,-3.804],[-155.0685,-3.827],[-155.132,-3.885],[-155.1575,-3.934],[-155.171,-4.014]]],[[[-152.515,-10.063],[-152.487,-10.164],[-152.407,-10.2385],[-152.3165,-10.2615],[-152.246,-10.2505],[-152.1685,-10.2025],[-152.12,-10.1235],[-152.1105,-10.069],[-152.121,-9.998],[-152.1755,-9.9145],[-152.2755,-9.8655],[-152.3465,-9.8655],[-152.422,-9.895],[-152.4745,-9.9435],[-152.499,-9.986],[-152.515,-10.063]]],[[[-152.0305,-11.427],[-152.0075,-11.518],[-151.9565,-11.588],[-151.8995,-11.627],[-151.848,-11.643],[-151.775,-11.643],[-151.7095,-11.62],[-151.6295,-11.539],[-151.606,-11.448],[-151.614,-11.39],[-151.655,-11.301],[-151.694,-11.26],[-151.789,-11.217],[-151.871,-11.219],[-151.944,-11.251],[-151.9945,-11.302],[-152.018,-11.347],[-152.0305,-11.427]]],[[[-150.4375,-10.001],[-150.4235,-10.077],[-150.3505,-10.169],[-150.2785,-10.203],[-150.189,-10.207],[-150.1205,-10.182],[-150.056,-10.122],[-150.0135,-10.047],[-149.9925,-9.945],[-150.0015,-9.873],[-150.0395,-9.789],[-150.097,-9.736],[-150.1675,-9.708],[-150.2735,-9.714],[-150.368,-9.778],[-150.402,-9.839],[-150.4375,-10.001]]],[[[169.3205,-0.854],[169.3245,-0.894],[169.3605,-0.978],[169.399,-1.02],[169.4765,-1.063],[169.5465,-1.074],[169.6095,-1.063],[169.6775,-1.023],[169.712,-0.984],[169.746,-0.899],[169.7445,-0.811],[169.72,-0.749],[169.648,-0.676],[169.558,-0.646],[169.4895,-0.649],[169.4375,-0.667],[169.3735,-0.715],[169.336,-0.776],[169.3205,-0.854]]],[[[172.4805,3.273],[172.523,3.069],[172.5795,2.95],[172.608,2.908],[172.665,2.863],[172.756,2.84],[172.8285,2.851],[172.897,2.891],[172.9745,2.906],[173.025,2.935],[173.1505,3.087],[173.1725,3.168],[173.165,3.242],[173.209,3.365],[173.2025,3.447],[173.181,3.496],[173.1275,3.555],[173.052,3.59],[172.9935,3.595],[172.911,3.576],[172.851,3.534],[172.79,3.447],[172.7215,3.472],[172.641,3.472],[172.5545,3.431],[172.507,3.375],[172.4805,3.273]]],[[[172.58,1.898],[172.6065,1.797],[172.6515,1.741],[172.7485,1.691],[172.744,1.608],[172.781,1.503],[172.7405,1.448],[172.7195,1.34],[172.7365,1.272],[172.7705,1.22],[172.8505,1.166],[172.8125,1.109],[172.794,1.015],[172.8015,0.967],[172.776,0.904],[172.7715,0.848],[172.7875,0.774],[172.8125,0.729],[172.874,0.671],[172.981,0.639],[173.0945,0.67],[173.1535,0.721],[173.2595,0.896],[173.272,0.96],[173.26,1.044],[173.2265,1.104],[173.1705,1.159],[173.269,1.191],[173.343,1.273],[173.365,1.357],[173.361,1.413],[173.3375,1.475],[173.301,1.522],[173.1935,1.612],[173.2255,1.666],[173.249,1.773],[173.3475,1.776],[173.409,1.801],[173.449,1.833],[173.4925,1.898],[173.5065,2.012],[173.469,2.122],[173.437,2.178],[173.352,2.244],[173.293,2.259],[173.2235,2.255],[173.13,2.205],[173.089,2.153],[173.064,2.09],[172.9965,2.136],[172.911,2.168],[172.845,2.172],[172.751,2.14],[172.648,2.051],[172.6085,2.003],[172.58,1.898]]],[[[173.1795,0.26],[173.195,0.184],[173.2585,0.077],[173.313,0.026],[173.39,-0.003],[173.4535,-0.005],[173.533,-0.065],[173.617,-0.082],[173.68,-0.071],[173.7605,-0.023],[173.8005,0.025],[173.838,0.119],[173.935,0.105],[174.0275,0.128],[174.0885,0.176],[174.119,0.22],[174.1455,0.315],[174.1435,0.373],[174.098,0.515],[174.057,0.575],[173.9665,0.651],[173.893,0.687],[173.828,0.694],[173.7165,0.661],[173.6625,0.614],[173.582,0.478],[173.561,0.392],[173.459,0.458],[173.3665,0.47],[173.2995,0.451],[173.2545,0.421],[173.1965,0.342],[173.1795,0.26]]],[[[173.9845,-0.553],[174.01,-0.652],[174.081,-0.737],[174.13,-0.764],[174.227,-0.777],[174.2435,-0.861],[174.3225,-0.964],[174.38,-1.0],[174.4795,-1.014],[174.454,-1.084],[174.45,-1.162],[174.482,-1.261],[174.567,-1.35],[174.5945,-1.426],[174.6525,-1.517],[174.7165,-1.565],[174.776,-1.583],[174.866,-1.63],[174.9605,-1.711],[175.0635,-1.733],[175.168,-1.708],[175.23,-1.66],[175.2765,-1.586],[175.288,-1.522],[175.2795,-1.424],[175.255,-1.371],[175.171,-1.287],[175.0485,-1.228],[174.986,-1.174],[174.9505,-1.109],[174.888,-1.027],[174.802,-0.95],[174.709,-0.911],[174.649,-0.906],[174.676,-0.836],[174.6815,-0.78],[174.659,-0.646],[174.6305,-0.558],[174.592,-0.508],[174.478,-0.409],[174.3805,-0.365],[174.279,-0.336],[174.188,-0.334],[174.084,-0.376],[174.025,-0.433],[173.9995,-0.477],[173.9845,-0.553]]],[[[175.309,-1.811],[175.3255,-1.933],[175.347,-1.978],[175.427,-2.087],[175.526,-2.139],[175.634,-2.14],[175.7205,-2.102],[175.8015,-1.994],[175.819,-1.928],[175.817,-1.85],[175.776,-1.752],[175.6965,-1.66],[175.6015,-1.597],[175.5065,-1.584],[175.43,-1.608],[175.384,-1.643],[175.3205,-1.743],[175.309,-1.811]]],[[[175.7445,-1.29],[175.7705,-1.391],[175.851,-1.496],[175.9105,-1.541],[175.9875,-1.572],[176.062,-1.571],[176.163,-1.519],[176.196,-1.481],[176.226,-1.4085],[176.344,-1.544],[176.4365,-1.597],[176.4955,-1.604],[176.576,-1.586],[176.644,-1.535],[176.6745,-1.489],[176.693,-1.425],[176.69,-1.359],[176.653,-1.272],[176.5975,-1.19],[176.5045,-1.126],[176.4185,-1.112],[176.351,-1.12],[176.298,-1.143],[176.237,-1.202],[176.2065,-1.275],[176.125,-1.154],[176.0635,-1.101],[176.019,-1.08],[175.9515,-1.07],[175.9015,-1.077],[175.8395,-1.106],[175.793,-1.151],[175.7485,-1.246],[175.7445,-1.29]]],[[[175.765,-2.486],[175.774,-2.55],[175.796,-2.597],[175.8595,-2.666],[175.9215,-2.702],[175.972,-2.714],[176.0755,-2.7],[176.133,-2.664],[176.192,-2.57],[176.199,-2.488],[176.1745,-2.412],[176.1045,-2.332],[176.055,-2.302],[175.9745,-2.284],[175.915,-2.291],[175.8555,-2.318],[175.787,-2.395],[175.765,-2.486]]],[[[176.59,-2.612],[176.601,-2.68],[176.6245,-2.726],[176.721,-2.828],[176.825,-2.87],[176.9285,-2.854],[176.9845,-2.817],[177.039,-2.73],[177.0465,-2.646],[177.007,-2.54],[176.9545,-2.476],[176.8825,-2.431],[176.813,-2.414],[176.7275,-2.423],[176.659,-2.462],[176.6155,-2.515],[176.59,-2.612]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/d3/Flag_of_Kiribati.svg","name:en":"Kiribati","wikidata":"Q710","ISO3166-1:alpha2":"KI","ISO3166-1:alpha3":"KIR","ISO3166-1:numeric":"296"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-166.0855,-10.888],[-166.0585,-10.993],[-166.0105,-11.048],[-165.942,-11.093],[-165.857,-11.115],[-165.757,-11.1],[-165.6845,-11.054],[-165.6445,-10.999],[-165.626,-10.941],[-165.6295,-10.812],[-165.653,-10.749],[-165.7115,-10.6855],[-165.801,-10.649],[-165.868,-10.6485],[-165.951,-10.6765],[-166.002,-10.716],[-166.052,-10.7845],[-166.0855,-10.888]]],[[[-165.628,-11.559],[-165.594,-11.6685],[-165.5405,-11.7245],[-165.4375,-11.7655],[-165.3575,-11.7595],[-165.2765,-11.7185],[-165.2135,-11.632],[-165.202,-11.542],[-165.242,-11.442],[-165.3015,-11.388],[-165.395,-11.357],[-165.464,-11.3615],[-165.5175,-11.3815],[-165.5745,-11.425],[-165.614,-11.4865],[-165.628,-11.559]]],[[[-163.408,-13.2745],[-163.3965,-13.3395],[-163.3295,-13.4315],[-163.2065,-13.5115],[-163.1385,-13.531],[-163.0665,-13.5275],[-163.0015,-13.501],[-162.933,-13.456],[-162.861,-13.377],[-162.838,-13.2995],[-162.844,-13.228],[-162.8755,-13.163],[-163.005,-13.0435],[-163.0995,-13.007],[-163.168,-13.0095],[-163.298,-13.072],[-163.3475,-13.117],[-163.386,-13.1815],[-163.408,-13.2745]]],[[[-163.4015,-18.056],[-163.376,-18.1545],[-163.307,-18.243],[-163.2445,-18.277],[-163.19,-18.29],[-163.118,-18.2885],[-163.05,-18.2635],[-162.9695,-18.194],[-162.9365,-18.1465],[-162.911,-18.077],[-162.917,-17.9745],[-162.951,-17.912],[-163.017,-17.8445],[-163.0915,-17.8015],[-163.1665,-17.7905],[-163.2315,-17.801],[-163.29,-17.8315],[-163.334,-17.8755],[-163.3895,-17.9895],[-163.4015,-18.056]]],[[[-161.311,-10.032],[-161.2955,-10.11],[-161.256,-10.17],[-161.1705,-10.245],[-161.2265,-10.3395],[-161.2445,-10.4515],[-161.2285,-10.517],[-161.195,-10.5705],[-161.1455,-10.6115],[-161.065,-10.652],[-161.006,-10.662],[-160.8975,-10.643],[-160.836,-10.611],[-160.7895,-10.567],[-160.7535,-10.494],[-160.7565,-10.3695],[-160.794,-10.301],[-160.867,-10.223],[-160.946,-10.18],[-160.8965,-10.114],[-160.874,-10.0465],[-160.8715,-9.9825],[-160.9015,-9.899],[-160.927,-9.8665],[-161.0255,-9.807],[-161.112,-9.7965],[-161.2045,-9.826],[-161.2585,-9.872],[-161.29,-9.9245],[-161.311,-10.032]]],[[[-160.045,-18.9185],[-160.0205,-19.0075],[-159.9645,-19.0725],[-159.9095,-19.102],[-159.771,-19.1475],[-159.6965,-19.1475],[-159.6315,-19.125],[-159.567,-19.0705],[-159.536,-19.015],[-159.5215,-18.8925],[-159.534,-18.8355],[-159.579,-18.739],[-159.612,-18.6935],[-159.674,-18.647],[-159.735,-18.627],[-159.8035,-18.6265],[-159.871,-18.648],[-159.953,-18.7175],[-160.0225,-18.823],[-160.045,-18.9185]]],[[[-160.038,-21.2145],[-160.0135,-21.329],[-159.9345,-21.4215],[-159.794,-21.4695],[-159.711,-21.4685],[-159.627,-21.437],[-159.577,-21.398],[-159.5425,-21.3505],[-159.5175,-21.2645],[-159.523,-21.197],[-159.57,-21.095],[-159.6385,-21.0375],[-159.6825,-21.016],[-159.7875,-20.9995],[-159.8985,-21.018],[-159.9725,-21.0695],[-160.022,-21.1415],[-160.038,-21.2145]]],[[[-159.1775,-19.2845],[-159.157,-19.3575],[-159.1015,-19.4285],[-159.0485,-19.465],[-158.976,-19.4865],[-158.902,-19.4835],[-158.8205,-19.4565],[-158.7625,-19.4135],[-158.72,-19.3455],[-158.707,-19.2615],[-158.726,-19.1825],[-158.75,-19.143],[-158.8095,-19.087],[-158.89,-19.057],[-158.9585,-19.0555],[-159.0265,-19.072],[-159.0895,-19.1025],[-159.1395,-19.1505],[-159.17,-19.212],[-159.1775,-19.2845]]],[[[-158.5045,-19.8125],[-158.48,-19.9065],[-158.4105,-19.9795],[-158.3485,-20.007],[-158.3185,-20.1045],[-158.255,-20.18],[-158.198,-20.2135],[-158.1305,-20.2285],[-158.0645,-20.2225],[-157.975,-20.1805],[-157.897,-20.096],[-157.876,-20.019],[-157.835,-20.0575],[-157.769,-20.089],[-157.6955,-20.0965],[-157.576,-20.0565],[-157.4965,-19.9705],[-157.474,-19.89],[-157.492,-19.771],[-157.534,-19.7095],[-157.583,-19.673],[-157.6875,-19.641],[-157.7695,-19.648],[-157.838,-19.68],[-157.894,-19.737],[-157.922,-19.804],[-157.9295,-19.862],[-158.004,-19.7975],[-158.079,-19.7705],[-158.0975,-19.7185],[-158.1385,-19.6655],[-158.1895,-19.6305],[-158.257,-19.6095],[-158.334,-19.6125],[-158.409,-19.643],[-158.46,-19.688],[-158.493,-19.7465],[-158.5045,-19.8125]]],[[[-158.263,-8.975],[-158.251,-9.0465],[-158.1995,-9.1385],[-158.0935,-9.243],[-158.0255,-9.276],[-157.9025,-9.2825],[-157.8395,-9.266],[-157.775,-9.222],[-157.7135,-9.1485],[-157.6795,-9.0725],[-157.6765,-9.001],[-157.7,-8.932],[-157.7545,-8.8315],[-157.808,-8.777],[-157.874,-8.744],[-157.9535,-8.7215],[-158.079,-8.722],[-158.1485,-8.7455],[-158.2295,-8.82],[-158.2565,-8.888],[-158.263,-8.975]]],[[[-158.1675,-21.937],[-158.1505,-22.016],[-158.108,-22.081],[-158.0335,-22.1335],[-157.9645,-22.1555],[-157.8555,-22.154],[-157.8005,-22.14],[-157.7415,-22.1045],[-157.6955,-22.051],[-157.6675,-21.96],[-157.673,-21.8925],[-157.6985,-21.8295],[-157.7915,-21.7255],[-157.8555,-21.6975],[-157.974,-21.698],[-158.055,-21.729],[-158.134,-21.813],[-158.1675,-21.937]]],[[[-157.5735,-20.15],[-157.566,-20.219],[-157.5025,-20.3235],[-157.434,-20.368],[-157.351,-20.3885],[-157.242,-20.367],[-157.176,-20.322],[-157.125,-20.2475],[-157.109,-20.154],[-157.1225,-20.0845],[-157.1785,-20.0005],[-157.2275,-19.967],[-157.3295,-19.934],[-157.4285,-19.9455],[-157.5025,-19.9895],[-157.541,-20.036],[-157.5735,-20.15]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/35/Flag_of_the_Cook_Islands.svg","name:en":"Cook Islands","wikidata":"Q26988","ISO3166-1:alpha2":"CK","ISO3166-1:alpha3":"COK","ISO3166-1:numeric":"184"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-57.649,-30.194],[-57.584,-30.177],[-57.4805,-30.123],[-57.414,-30.037],[-57.3625,-30.013],[-57.328,-29.972],[-57.326,-29.876],[-57.242,-29.788],[-57.121,-29.765],[-57.033,-29.696],[-56.9665,-29.6295],[-56.97,-29.604],[-56.899,-29.532],[-56.819,-29.488],[-56.7805,-29.439],[-56.766,-29.3775],[-56.7015,-29.359],[-56.648,-29.2585],[-56.644,-29.196],[-56.5915,-29.124],[-56.5005,-29.0925],[-56.4255,-29.082],[-56.3985,-29.021],[-56.3905,-28.955],[-56.302,-28.901],[-56.301,-28.8155],[-56.259,-28.7785],[-56.192,-28.7735],[-56.1185,-28.6815],[-56.002,-28.596],[-56.022,-28.52],[-55.986,-28.4975],[-55.881,-28.4695],[-55.9025,-28.412],[-55.8515,-28.355],[-55.739,-28.3765],[-55.6915,-28.4175],[-55.67,-28.331],[-55.776,-28.271],[-55.769,-28.2405],[-55.7,-28.222],[-55.635,-28.1785],[-55.6115,-28.1185],[-55.552,-28.1605],[-55.536,-28.119],[-55.4835,-28.0775],[-55.4475,-28.099],[-55.3815,-28.0395],[-55.385,-27.985],[-55.3365,-27.9615],[-55.31,-27.9215],[-55.269,-27.931],[-55.197,-27.857],[-55.1255,-27.859],[-55.0325,-27.825],[-55.043,-27.775],[-54.9345,-27.769],[-54.903,-27.721],[-54.907,-27.6465],[-54.858,-27.629],[-54.814,-27.533],[-54.786,-27.576],[-54.742,-27.561],[-54.689,-27.574],[-54.614,-27.5315],[-54.5715,-27.4545],[-54.52,-27.5025],[-54.4495,-27.476],[-54.4645,-27.424],[-54.3965,-27.4125],[-54.3535,-27.4665],[-54.3085,-27.423],[-54.2175,-27.386],[-54.192,-27.3075],[-54.1585,-27.2935],[-54.08,-27.2985],[-54.021,-27.2485],[-54.0055,-27.197],[-53.959,-27.158],[-53.9,-27.173],[-53.8455,-27.161],[-53.806,-27.1125],[-53.7965,-27.0395],[-53.7665,-27.044],[-53.718,-26.9845],[-53.726,-26.9585],[-53.682,-26.9165],[-53.7145,-26.7535],[-53.749,-26.7415],[-53.717,-26.6815],[-53.742,-26.648],[-53.7225,-26.5815],[-53.731,-26.5095],[-53.698,-26.4865],[-53.689,-26.4435],[-53.7075,-26.3955],[-53.6855,-26.335],[-53.646,-26.2865],[-53.6435,-26.2165],[-53.711,-26.1305],[-53.742,-26.1155],[-53.7355,-26.042],[-53.772,-26.0315],[-53.8425,-25.9325],[-53.825,-25.871],[-53.849,-25.835],[-53.8225,-25.793],[-53.8645,-25.7455],[-53.862,-25.659],[-54.0285,-25.566],[-54.0835,-25.561],[-54.1045,-25.4945],[-54.166,-25.543],[-54.1905,-25.5345],[-54.255,-25.596],[-54.28,-25.556],[-54.3745,-25.594],[-54.4255,-25.663],[-54.5545,-25.5875],[-54.5935,-25.593],[-54.581,-25.658],[-54.6495,-25.6635],[-54.658,-25.6875],[-54.6225,-25.7835],[-54.5915,-25.818],[-54.6225,-25.9145],[-54.6085,-25.955],[-54.655,-25.979],[-54.677,-26.017],[-54.647,-26.075],[-54.6695,-26.164],[-54.6185,-26.209],[-54.6795,-26.2645],[-54.649,-26.312],[-54.698,-26.382],[-54.7155,-26.4595],[-54.7815,-26.51],[-54.807,-26.554],[-54.7845,-26.605],[-54.8125,-26.668],[-54.86,-26.656],[-54.9165,-26.6685],[-54.9485,-26.702],[-54.9635,-26.7875],[-55.0525,-26.7975],[-55.1435,-26.8685],[-55.135,-26.9485],[-55.195,-26.9685],[-55.238,-26.9425],[-55.306,-26.9625],[-55.3705,-26.9645],[-55.423,-26.9955],[-55.481,-27.1115],[-55.549,-27.098],[-55.5745,-27.169],[-55.6155,-27.21],[-55.581,-27.235],[-55.6005,-27.279],[-55.599,-27.3375],[-55.675,-27.373],[-55.737,-27.445],[-55.787,-27.4405],[-55.8395,-27.407],[-55.8965,-27.3425],[-55.9845,-27.353],[-56.037,-27.3125],[-56.0875,-27.3085],[-56.176,-27.3435],[-56.243,-27.4045],[-56.2945,-27.42],[-56.2935,-27.494],[-56.339,-27.5245],[-56.3565,-27.567],[-56.401,-27.599],[-56.463,-27.5695],[-56.542,-27.4385],[-56.6065,-27.4315],[-56.6495,-27.4605],[-56.721,-27.468],[-56.6765,-27.5505],[-56.689,-27.579],[-56.747,-27.605],[-56.796,-27.587],[-56.8495,-27.6065],[-56.942,-27.5585],[-56.9655,-27.502],[-57.0425,-27.481],[-57.1425,-27.4835],[-57.232,-27.4665],[-57.3115,-27.418],[-57.4125,-27.425],[-57.4875,-27.444],[-57.667,-27.356],[-57.702,-27.3245],[-57.8145,-27.334],[-57.8775,-27.2785],[-57.9145,-27.2655],[-58.0595,-27.2625],[-58.198,-27.2735],[-58.26,-27.257],[-58.3035,-27.274],[-58.4135,-27.2865],[-58.489,-27.2735],[-58.599,-27.3],[-58.5925,-27.23],[-58.6565,-27.192],[-58.6625,-27.1625],[-58.6315,-27.115],[-58.555,-27.109],[-58.555,-27.058],[-58.5195,-27.004],[-58.4685,-26.9865],[-58.4935,-26.94],[-58.325,-26.8695],[-58.337,-26.817],[-58.282,-26.7915],[-58.246,-26.7425],[-58.2635,-26.6515],[-58.197,-26.6535],[-58.193,-26.5945],[-58.2225,-26.5425],[-58.2085,-26.505],[-58.2235,-26.4635],[-58.2105,-26.3775],[-58.1655,-26.3575],[-58.158,-26.2605],[-58.1065,-26.2375],[-58.1195,-26.1525],[-58.0845,-26.112],[-58.0415,-26.1125],[-57.9495,-26.0675],[-57.926,-26.037],[-57.8555,-26.009],[-57.8935,-25.964],[-57.842,-25.921],[-57.8585,-25.858],[-57.7965,-25.825],[-57.8275,-25.759],[-57.774,-25.758],[-57.733,-25.725],[-57.7675,-25.6995],[-57.7405,-25.6505],[-57.6705,-25.6505],[-57.677,-25.6055],[-57.6085,-25.6065],[-57.5795,-25.569],[-57.555,-25.4485],[-57.601,-25.398],[-57.6365,-25.3855],[-57.6985,-25.3165],[-57.695,-25.2885],[-57.752,-25.2275],[-57.7765,-25.1555],[-57.8215,-25.142],[-57.8825,-25.076],[-57.9885,-25.0815],[-58.0105,-25.038],[-58.077,-25.038],[-58.1345,-25.01],[-58.153,-24.973],[-58.194,-24.968],[-58.236,-24.927],[-58.341,-24.9965],[-58.393,-24.9515],[-58.4405,-24.8795],[-58.573,-24.821],[-58.6725,-24.832],[-58.726,-24.7745],[-58.804,-24.7735],[-58.8785,-24.7335],[-58.9705,-24.663],[-59.0235,-24.66],[-59.0565,-24.6315],[-59.13,-24.617],[-59.186,-24.5635],[-59.239,-24.5465],[-59.354,-24.478],[-59.373,-24.423],[-59.4215,-24.409],[-59.4745,-24.3315],[-59.7555,-24.1705],[-60.039,-24.0115],[-60.197,-24.045],[-60.309,-24.038],[-60.436,-23.9665],[-60.4875,-23.951],[-60.572,-23.96],[-60.595,-23.9175],[-60.7095,-23.892],[-60.732,-23.872],[-60.8595,-23.8695],[-60.9215,-23.823],[-60.99,-23.818],[-61.0125,-23.7615],[-61.0805,-23.691],[-61.096,-23.613],[-61.1735,-23.5605],[-61.2195,-23.5575],[-61.3255,-23.4665],[-61.417,-23.4485],[-61.445,-23.42],[-61.501,-23.4105],[-61.5235,-23.3675],[-61.627,-23.2775],[-61.736,-23.2345],[-61.753,-23.173],[-61.7905,-23.1645],[-61.85,-23.1045],[-61.9975,-23.0075],[-61.997,-22.9485],[-62.036,-22.8785],[-62.099,-22.806],[-62.158,-22.76],[-62.1985,-22.706],[-62.2025,-22.6705],[-62.2545,-22.6115],[-62.228,-22.5445],[-62.2815,-22.5245],[-62.2875,-22.4775],[-62.336,-22.4815],[-62.4505,-22.4195],[-62.4655,-22.383],[-62.51,-22.3805],[-62.571,-22.327],[-62.63,-22.303],[-62.6405,-22.236],[-62.717,-22.2035],[-62.813,-22.0965],[-62.799,-22.06],[-62.811,-21.999],[-63.3505,-21.9995],[-63.9315,-21.9995],[-63.986,-22.0935],[-64.009,-22.1655],[-64.0625,-22.2385],[-64.1165,-22.362],[-64.1155,-22.4045],[-64.1995,-22.491],[-64.2425,-22.56],[-64.272,-22.71],[-64.2655,-22.7665],[-64.2825,-22.8245],[-64.329,-22.8565],[-64.3445,-22.739],[-64.393,-22.7195],[-64.397,-22.6835],[-64.4335,-22.6485],[-64.4125,-22.5375],[-64.4455,-22.523],[-64.4905,-22.4385],[-64.5655,-22.372],[-64.542,-22.279],[-64.651,-22.1895],[-64.7375,-22.1935],[-64.8625,-22.123],[-64.8855,-22.129],[-64.9935,-22.0825],[-65.475,-22.0895],[-65.5745,-22.076],[-65.5825,-22.094],[-65.6755,-22.1115],[-65.7485,-22.109],[-65.805,-22.075],[-65.925,-21.9335],[-66.048,-21.919],[-66.0435,-21.872],[-66.0765,-21.835],[-66.241,-21.789],[-66.236,-21.8495],[-66.2605,-21.906],[-66.2925,-22.0345],[-66.288,-22.086],[-66.348,-22.128],[-66.686,-22.2095],[-66.7395,-22.2385],[-66.7825,-22.438],[-66.9285,-22.492],[-66.973,-22.5405],[-67.027,-22.541],[-67.014,-22.655],[-67.1275,-22.722],[-67.1805,-22.814],[-66.9905,-23.0005],[-67.112,-23.3805],[-67.3225,-24.0345],[-67.961,-24.285],[-68.2455,-24.396],[-68.2965,-24.455],[-68.309,-24.492],[-68.387,-24.484],[-68.431,-24.5775],[-68.475,-24.6215],[-68.5155,-24.703],[-68.5445,-24.7245],[-68.568,-24.7975],[-68.531,-24.8585],[-68.4865,-24.8955],[-68.432,-24.9055],[-68.407,-25.0285],[-68.3795,-25.0415],[-68.3435,-25.1105],[-68.4095,-25.1455],[-68.4595,-25.126],[-68.511,-25.181],[-68.5435,-25.3025],[-68.5225,-25.3745],[-68.5865,-25.4275],[-68.573,-25.4935],[-68.525,-25.567],[-68.5415,-25.6385],[-68.479,-25.708],[-68.381,-26.178],[-68.5575,-26.287],[-68.5875,-26.493],[-68.3655,-26.801],[-68.281,-26.9035],[-68.315,-26.974],[-68.2985,-27.039],[-68.3475,-27.0335],[-68.4325,-27.0655],[-68.4965,-27.135],[-68.5565,-27.1145],[-68.573,-27.175],[-68.6185,-27.17],[-68.6685,-27.104],[-68.778,-27.099],[-68.8085,-27.1465],[-68.841,-27.1545],[-68.8685,-27.2605],[-68.8245,-27.294],[-68.8685,-27.317],[-68.9365,-27.4445],[-68.9635,-27.4685],[-68.943,-27.515],[-68.9765,-27.5605],[-69.053,-27.617],[-69.0455,-27.699],[-69.0935,-27.7175],[-69.089,-27.7855],[-69.134,-27.909],[-69.182,-27.972],[-69.2105,-27.9645],[-69.2675,-28.0105],[-69.264,-28.0465],[-69.299,-28.0695],[-69.3275,-28.1555],[-69.3795,-28.1815],[-69.384,-28.213],[-69.457,-28.1835],[-69.5325,-28.3345],[-69.65,-28.396],[-69.642,-28.442],[-69.6645,-28.482],[-69.6645,-28.5815],[-69.6955,-28.599],[-69.7265,-28.6705],[-69.7295,-28.736],[-69.693,-28.771],[-69.7665,-28.924],[-69.7535,-28.957],[-69.787,-29.0285],[-69.787,-29.13],[-69.883,-29.144],[-69.9335,-29.189],[-69.946,-29.263],[-69.9855,-29.277],[-70.0205,-29.3305],[-70.0215,-29.3835],[-69.967,-29.4145],[-69.9815,-29.452],[-69.948,-29.491],[-69.9555,-29.535],[-69.9315,-29.5845],[-69.942,-29.646],[-69.8795,-29.7335],[-69.9135,-29.807],[-69.8775,-29.8615],[-69.896,-29.8795],[-69.8985,-29.958],[-69.926,-30.0005],[-69.912,-30.028],[-69.961,-30.0685],[-69.905,-30.1065],[-69.8095,-30.1455],[-69.8355,-30.219],[-69.8855,-30.2185],[-69.9035,-30.3435],[-69.955,-30.3855],[-70.0705,-30.391],[-70.1035,-30.3565],[-70.144,-30.372],[-70.117,-30.431],[-70.195,-30.4915],[-70.1795,-30.5115],[-70.247,-30.635],[-70.278,-30.81],[-70.3215,-30.9245],[-70.2985,-30.9625],[-70.319,-31.043],[-70.408,-31.1665],[-70.432,-31.102],[-70.4985,-31.125],[-70.5235,-31.19],[-70.517,-31.234],[-70.545,-31.3065],[-70.53,-31.3755],[-70.5695,-31.4735],[-70.553,-31.51],[-70.567,-31.583],[-70.513,-31.6895],[-70.4675,-31.7005],[-70.455,-31.8485],[-70.392,-31.8795],[-70.272,-31.8905],[-70.2085,-31.978],[-70.2485,-32.024],[-70.322,-32.0505],[-70.3415,-32.1095],[-70.305,-32.1425],[-70.301,-32.207],[-70.319,-32.2735],[-70.2225,-32.325],[-70.2365,-32.429],[-70.149,-32.466],[-70.123,-32.5355],[-70.1705,-32.6255],[-70.108,-32.8005],[-70.0545,-32.832],[-70.0445,-32.87],[-70.001,-32.8845],[-70.0015,-32.946],[-70.0215,-33.008],[-70.081,-33.029],[-70.066,-33.104],[-70.0645,-33.205],[-70.0275,-33.2325],[-70.039,-33.27],[-70.003,-33.323],[-69.9175,-33.267],[-69.7995,-33.2885],[-69.7705,-33.361],[-69.82,-33.4325],[-69.835,-33.515],[-69.872,-33.5395],[-69.8655,-33.583],[-69.8845,-33.6845],[-69.865,-33.715],[-69.904,-33.7715],[-69.899,-33.8475],[-69.8555,-33.8925],[-69.892,-33.925],[-69.8395,-34.007],[-69.869,-34.1405],[-69.7915,-34.2005],[-69.795,-34.243],[-69.9315,-34.2815],[-69.967,-34.251],[-70.031,-34.288],[-70.0145,-34.3385],[-70.015,-34.413],[-70.1035,-34.482],[-70.223,-34.64],[-70.2145,-34.681],[-70.309,-34.768],[-70.257,-34.8205],[-70.3195,-34.9315],[-70.3345,-34.9915],[-70.3755,-35.046],[-70.362,-35.1365],[-70.388,-35.171],[-70.4705,-35.203],[-70.5425,-35.2025],[-70.583,-35.28],[-70.4965,-35.323],[-70.439,-35.316],[-70.4185,-35.3545],[-70.4525,-35.3925],[-70.4465,-35.464],[-70.382,-35.5125],[-70.4135,-35.529],[-70.3865,-35.604],[-70.418,-35.63],[-70.3695,-35.7375],[-70.3795,-35.787],[-70.3155,-35.819],[-70.421,-35.874],[-70.425,-35.9135],[-70.3905,-35.951],[-70.3715,-36.0435],[-70.4105,-36.056],[-70.421,-36.156],[-70.4905,-36.179],[-70.5345,-36.1415],[-70.5835,-36.147],[-70.6395,-36.243],[-70.705,-36.2725],[-70.6845,-36.3045],[-70.7125,-36.3395],[-70.6795,-36.3895],[-70.713,-36.427],[-70.7875,-36.429],[-70.89,-36.4035],[-70.894,-36.4715],[-70.956,-36.5045],[-71.0385,-36.4775],[-71.0555,-36.5665],[-71.0405,-36.6495],[-71.013,-36.6975],[-71.1115,-36.7285],[-71.1325,-36.8155],[-71.122,-36.864],[-71.1445,-36.929],[-71.1065,-36.9715],[-71.1705,-36.9965],[-71.0925,-37.1145],[-71.136,-37.1645],[-71.114,-37.205],[-71.2155,-37.2725],[-71.199,-37.3795],[-71.15,-37.4025],[-71.1195,-37.4865],[-71.1265,-37.5825],[-71.194,-37.6305],[-71.212,-37.689],[-71.156,-37.7575],[-71.1705,-37.78],[-71.108,-37.8925],[-71.1145,-37.953],[-71.051,-37.9925],[-71.053,-38.0455],[-70.9865,-38.1045],[-71.0435,-38.124],[-70.997,-38.17],[-71.0195,-38.218],[-70.985,-38.361],[-70.976,-38.442],[-70.911,-38.5035],[-70.8405,-38.5415],[-70.829,-38.5995],[-70.904,-38.667],[-70.892,-38.721],[-70.925,-38.763],[-71.0275,-38.7585],[-71.1075,-38.772],[-71.2065,-38.8175],[-71.2605,-38.815],[-71.2675,-38.8515],[-71.4255,-38.9215],[-71.441,-38.9775],[-71.4075,-39.096],[-71.3885,-39.2655],[-71.4015,-39.352],[-71.4465,-39.3965],[-71.473,-39.4935],[-71.5345,-39.5305],[-71.461,-39.583],[-71.518,-39.6255],[-71.61,-39.628],[-71.618,-39.5985],[-71.6985,-39.588],[-71.684,-39.692],[-71.7125,-39.7245],[-71.6805,-39.769],[-71.691,-39.8425],[-71.6465,-39.853],[-71.5925,-39.901],[-71.6895,-40.0365],[-71.6665,-40.0745],[-71.7,-40.117],[-71.814,-40.0805],[-71.7995,-40.136],[-71.828,-40.208],[-71.736,-40.3055],[-71.6715,-40.311],[-71.7085,-40.4225],[-71.8035,-40.406],[-71.8415,-40.452],[-71.87,-40.5725],[-71.8375,-40.61],[-71.866,-40.658],[-71.9495,-40.719],[-71.9595,-40.7585],[-71.923,-40.783],[-71.9275,-40.8335],[-71.8685,-40.892],[-71.855,-40.9445],[-71.9085,-40.973],[-71.8195,-41.0605],[-71.8515,-41.0985],[-71.841,-41.15],[-71.888,-41.161],[-71.8575,-41.212],[-71.8755,-41.2965],[-71.911,-41.358],[-71.8345,-41.4335],[-71.851,-41.515],[-71.837,-41.566],[-71.886,-41.605],[-71.784,-41.735],[-71.7645,-41.817],[-71.7895,-41.831],[-71.775,-41.9075],[-71.7935,-41.9625],[-71.73,-42.122],[-71.927,-42.19],[-71.9705,-42.145],[-72.049,-42.116],[-72.0925,-42.154],[-72.173,-42.1405],[-72.1585,-42.1935],[-72.168,-42.2605],[-72.137,-42.328],[-72.133,-42.384],[-72.023,-42.4175],[-72.04,-42.4595],[-72.028,-42.515],[-72.1035,-42.6005],[-72.096,-42.642],[-72.1795,-42.698],[-72.129,-42.7325],[-72.165,-42.799],[-72.143,-42.898],[-72.076,-42.949],[-72.0365,-43.0135],[-71.9445,-43.046],[-71.924,-43.101],[-71.8875,-43.1265],[-71.7605,-43.1645],[-71.73,-43.201],[-71.757,-43.228],[-71.7315,-43.3075],[-71.7915,-43.298],[-71.8425,-43.335],[-71.8965,-43.32],[-71.889,-43.45],[-71.8485,-43.4835],[-71.871,-43.553],[-71.7765,-43.5385],[-71.716,-43.5775],[-71.69,-43.6265],[-71.608,-43.6285],[-71.581,-43.6515],[-71.6105,-43.701],[-71.703,-43.7395],[-71.7515,-43.7855],[-71.759,-43.8445],[-71.6655,-43.902],[-71.649,-43.9455],[-71.682,-43.9745],[-71.752,-44.094],[-71.8515,-44.1295],[-71.8075,-44.1875],[-71.811,-44.254],[-71.791,-44.3145],[-71.8405,-44.35],[-71.8075,-44.4205],[-71.695,-44.384],[-71.6545,-44.4095],[-71.5725,-44.409],[-71.4755,-44.391],[-71.3645,-44.3895],[-71.332,-44.429],[-71.24,-44.4175],[-71.137,-44.4695],[-71.092,-44.533],[-71.1215,-44.597],[-71.1865,-44.593],[-71.2355,-44.641],[-71.198,-44.689],[-71.207,-44.75],[-71.2765,-44.8095],[-71.396,-44.79],[-71.494,-44.737],[-71.6755,-44.7865],[-71.7835,-44.751],[-71.8565,-44.802],[-71.9135,-44.777],[-72.0065,-44.7835],[-72.069,-44.851],[-72.05,-44.882],[-71.979,-44.9035],[-71.933,-44.9425],[-71.812,-44.921],[-71.6845,-44.9695],[-71.5605,-44.9785],[-71.5565,-45.0325],[-71.511,-45.061],[-71.4705,-45.1485],[-71.4185,-45.1755],[-71.331,-45.2505],[-71.333,-45.319],[-71.3845,-45.3495],[-71.532,-45.397],[-71.477,-45.497],[-71.5605,-45.5235],[-71.6815,-45.514],[-71.746,-45.5415],[-71.727,-45.577],[-71.7955,-45.6645],[-71.798,-45.711],[-71.741,-45.807],[-71.769,-45.8465],[-71.656,-45.886],[-71.6145,-45.9625],[-71.6465,-45.983],[-71.676,-46.049],[-71.762,-46.112],[-71.889,-46.1275],[-71.8645,-46.1895],[-71.7995,-46.1915],[-71.751,-46.229],[-71.724,-46.2845],[-71.757,-46.346],[-71.669,-46.528],[-71.6685,-46.613],[-71.6485,-46.689],[-71.839,-46.799],[-71.9485,-46.81],[-71.931,-46.8685],[-71.9705,-46.904],[-71.9525,-46.959],[-71.88,-47.011],[-71.9495,-47.087],[-71.881,-47.107],[-71.8505,-47.162],[-71.8905,-47.1865],[-71.879,-47.2295],[-71.9735,-47.2095],[-72.0155,-47.25],[-71.997,-47.295],[-72.046,-47.3405],[-72.127,-47.328],[-72.1985,-47.416],[-72.266,-47.4155],[-72.31,-47.479],[-72.291,-47.512],[-72.3455,-47.6325],[-72.4205,-47.661],[-72.4345,-47.7345],[-72.504,-47.7635],[-72.467,-47.8135],[-72.475,-47.865],[-72.523,-47.902],[-72.503,-47.9585],[-72.427,-47.966],[-72.414,-48.079],[-72.361,-48.0745],[-72.2985,-48.16],[-72.3155,-48.2355],[-72.2345,-48.316],[-72.277,-48.3635],[-72.4055,-48.417],[-72.3735,-48.4495],[-72.44,-48.514],[-72.5025,-48.5175],[-72.586,-48.4875],[-72.542,-48.631],[-72.534,-48.8005],[-72.6965,-48.8965],[-72.747,-48.908],[-72.7945,-48.9645],[-72.85,-48.965],[-72.923,-48.9345],[-73.001,-49.0595],[-73.042,-49.0775],[-73.0785,-49.1405],[-73.1395,-49.178],[-73.149,-49.284],[-73.473,-49.2045],[-73.4965,-49.2685],[-73.432,-49.314],[-73.4275,-49.3935],[-73.489,-49.4345],[-73.4635,-49.4825],[-73.5445,-49.5045],[-73.5355,-49.564],[-73.4605,-49.6245],[-73.506,-49.666],[-73.504,-49.7095],[-73.4385,-49.758],[-73.4905,-49.8165],[-73.5105,-49.8795],[-73.5585,-49.947],[-73.477,-49.97],[-73.436,-50.011],[-73.522,-50.1535],[-73.4615,-50.185],[-73.4525,-50.2415],[-73.3615,-50.3015],[-73.3975,-50.3705],[-73.3575,-50.429],[-73.3645,-50.518],[-73.2875,-50.59],[-73.1935,-50.6155],[-73.153,-50.658],[-73.1965,-50.7415],[-73.094,-50.773],[-72.957,-50.741],[-72.893,-50.67],[-72.7325,-50.6155],[-72.697,-50.645],[-72.5835,-50.6585],[-72.4955,-50.602],[-72.4105,-50.6375],[-72.286,-50.66],[-72.349,-50.7545],[-72.2605,-50.836],[-72.246,-50.9],[-72.267,-50.965],[-72.2655,-51.035],[-72.374,-51.023],[-72.4015,-51.1355],[-72.347,-51.2025],[-72.2585,-51.244],[-72.274,-51.286],[-72.3575,-51.318],[-72.308,-51.3775],[-72.337,-51.4215],[-72.3245,-51.476],[-72.391,-51.515],[-72.441,-51.584],[-72.3385,-51.584],[-72.2875,-51.6325],[-72.299,-51.6975],[-72.2,-51.713],[-72.121,-51.7445],[-71.949,-51.8735],[-71.9385,-51.9085],[-72.0265,-51.9555],[-71.9225,-52.0],[-71.0645,-52.0],[-70.667,-52.0],[-69.9955,-52.0005],[-69.4865,-52.1515],[-69.19,-52.1505],[-68.987,-52.2035],[-68.838,-52.278],[-68.7095,-52.2855],[-68.586,-52.3065],[-68.5735,-52.325],[-68.4185,-52.3325],[-68.4325,-52.3975],[-68.607,-52.659],[-68.6065,-52.9755],[-68.6065,-53.48],[-68.608,-54.1885],[-68.6075,-54.5555],[-68.5955,-54.8085],[-68.6095,-54.9135],[-68.4115,-54.8825],[-68.253,-54.8855],[-67.9505,-54.8735],[-67.705,-54.9055],[-67.5725,-54.8945],[-67.477,-54.9235],[-67.273,-54.905],[-67.1325,-54.9275],[-67.032,-54.9765],[-66.958,-54.9715],[-66.8525,-54.988],[-66.7915,-55.0135],[-66.671,-55.119],[-66.4165,-55.1215],[-66.0785,-55.1835],[-65.9115,-55.1715],[-65.646,-55.1775],[-65.438,-55.1385],[-65.254,-55.1265],[-65.0735,-55.065],[-65.0095,-55.0165],[-64.883,-55.0885],[-64.7515,-55.1145],[-64.606,-55.1155],[-64.347,-55.0955],[-64.0325,-55.061],[-63.783,-54.9845],[-63.736,-54.978],[-63.5895,-54.921],[-63.491,-54.8365],[-63.4535,-54.7275],[-63.474,-54.659],[-63.5425,-54.592],[-63.688,-54.533],[-63.857,-54.517],[-64.02,-54.4575],[-64.115,-54.4445],[-64.224,-54.45],[-64.439,-54.4995],[-64.502,-54.5265],[-64.6595,-54.5335],[-64.776,-54.572],[-64.903,-54.5],[-65.081,-54.441],[-65.21,-54.42],[-65.421,-54.4425],[-65.6575,-54.459],[-66.0845,-54.3545],[-66.261,-54.303],[-66.363,-54.2375],[-66.429,-54.157],[-66.5295,-54.104],[-66.708,-54.048],[-66.924,-53.9565],[-67.045,-53.922],[-67.071,-53.8925],[-67.2095,-53.828],[-67.218,-53.7875],[-67.2835,-53.7145],[-67.4685,-53.6255],[-67.6555,-53.5215],[-67.728,-53.44],[-67.7525,-53.349],[-67.811,-53.2595],[-67.884,-53.2005],[-67.881,-53.0845],[-67.992,-52.868],[-68.275,-52.614],[-68.308,-52.578],[-68.219,-52.549],[-68.071,-52.4345],[-68.0325,-52.37],[-68.037,-52.27],[-68.1395,-52.1545],[-68.2875,-52.024],[-68.4155,-51.896],[-68.5595,-51.692],[-68.6295,-51.6075],[-68.635,-51.5],[-68.7165,-51.3255],[-68.776,-51.165],[-68.8175,-51.0805],[-68.843,-50.967],[-68.8205,-50.925],[-68.8245,-50.751],[-68.77,-50.6245],[-68.7025,-50.526],[-68.622,-50.469],[-68.252,-50.3615],[-68.158,-50.316],[-68.034,-50.2935],[-67.886,-50.243],[-67.695,-50.1465],[-67.624,-50.0975],[-67.522,-49.987],[-67.4415,-49.85],[-67.4145,-49.758],[-67.412,-49.6695],[-67.3825,-49.5025],[-67.301,-49.3175],[-67.313,-49.1685],[-67.293,-49.126],[-67.1805,-49.0515],[-67.023,-48.994],[-66.919,-48.8995],[-66.8675,-48.812],[-66.6865,-48.7535],[-66.548,-48.631],[-66.409,-48.6115],[-66.161,-48.5165],[-66.0725,-48.4435],[-66.0435,-48.3755],[-65.9275,-48.3165],[-65.832,-48.3065],[-65.7305,-48.2685],[-65.6405,-48.186],[-65.6105,-48.119],[-65.5005,-48.041],[-65.4695,-47.966],[-65.481,-47.8545],[-65.551,-47.774],[-65.481,-47.6305],[-65.451,-47.549],[-65.4255,-47.3345],[-65.45,-47.2375],[-65.458,-47.141],[-65.514,-47.0725],[-65.565,-47.0425],[-65.4075,-46.04],[-65.3245,-45.4895],[-65.2465,-44.9635],[-65.2565,-44.8565],[-65.3105,-44.788],[-65.183,-44.7405],[-65.0295,-44.608],[-65.0035,-44.496],[-64.9565,-44.4375],[-64.939,-44.3805],[-64.961,-44.273],[-64.982,-44.239],[-64.9495,-44.1815],[-64.911,-44.0495],[-64.9255,-43.971],[-65.0255,-43.8395],[-65.059,-43.719],[-65.0085,-43.6885],[-64.923,-43.5925],[-64.807,-43.493],[-64.7715,-43.3955],[-64.5785,-43.313],[-64.3345,-43.244],[-64.147,-43.151],[-64.073,-43.0785],[-63.637,-43.0045],[-63.537,-42.9665],[-63.4475,-42.916],[-63.3785,-42.8465],[-63.354,-42.777],[-63.362,-42.7235],[-63.316,-42.6175],[-63.341,-42.422],[-63.331,-42.331],[-63.355,-42.24],[-63.466,-42.0795],[-63.4085,-42.0035],[-62.48,-41.317],[-62.12,-41.0215],[-62.0735,-40.967],[-61.995,-40.7845],[-61.7815,-40.65],[-61.7365,-40.5995],[-61.712,-40.5275],[-61.708,-40.3935],[-61.7105,-40.172],[-61.7195,-40.122],[-61.852,-39.8035],[-61.8375,-39.7165],[-61.8395,-39.6285],[-61.804,-39.5825],[-61.402,-39.1895],[-61.205,-39.202],[-61.0945,-39.2005],[-60.9785,-39.184],[-60.7865,-39.1765],[-60.6605,-39.1515],[-60.39,-39.121],[-60.223,-39.0885],[-60.049,-39.0625],[-59.732,-39.0245],[-59.5845,-38.9855],[-59.3455,-38.95],[-59.184,-38.915],[-59.0435,-38.896],[-58.936,-38.8725],[-58.6625,-38.784],[-58.4405,-38.7365],[-58.181,-38.652],[-57.954,-38.5655],[-57.838,-38.5115],[-57.7585,-38.485],[-57.522,-38.3595],[-57.4225,-38.277],[-57.3615,-38.239],[-57.312,-38.175],[-57.269,-38.032],[-57.2755,-37.929],[-57.213,-37.8605],[-57.073,-37.748],[-56.9355,-37.6235],[-56.878,-37.554],[-56.786,-37.4035],[-56.488,-37.029],[-56.4355,-36.9505],[-56.4225,-36.9055],[-56.4295,-36.699],[-56.4575,-36.3935],[-56.471,-36.336],[-55.7035,-35.7825],[-55.869,-35.632],[-56.705,-35.173],[-57.0,-35.189],[-57.328,-34.863],[-57.508,-34.781],[-57.9345,-34.685],[-57.9345,-34.452],[-58.0,-34.3765],[-58.1805,-34.233],[-58.295,-34.178],[-58.3445,-34.007],[-58.377,-34.0],[-58.4235,-33.9165],[-58.4345,-33.7205],[-58.474,-33.6525],[-58.494,-33.5815],[-58.4435,-33.5375],[-58.432,-33.366],[-58.3905,-33.277],[-58.41,-33.231],[-58.4045,-33.1805],[-58.3605,-33.12],[-58.257,-33.1025],[-58.176,-33.077],[-58.0845,-33.001],[-58.1145,-32.924],[-58.1205,-32.8115],[-58.15,-32.727],[-58.1455,-32.667],[-58.1605,-32.5725],[-58.204,-32.465],[-58.182,-32.3745],[-58.103,-32.3095],[-58.109,-32.24],[-58.18,-32.1655],[-58.168,-32.0935],[-58.142,-32.0565],[-58.1385,-32.002],[-58.207,-31.871],[-58.191,-31.853],[-58.0845,-31.82],[-58.0385,-31.7595],[-57.981,-31.5905],[-58.004,-31.532],[-58.075,-31.492],[-58.0815,-31.4545],[-57.98,-31.3895],[-57.997,-31.36],[-57.9385,-31.2755],[-57.913,-31.212],[-57.9165,-31.1225],[-57.8715,-31.0705],[-57.8615,-31.0325],[-57.915,-30.921],[-57.822,-30.908],[-57.7995,-30.853],[-57.809,-30.6955],[-57.844,-30.6585],[-57.848,-30.6185],[-57.883,-30.593],[-57.8885,-30.509],[-57.7675,-30.4185],[-57.6435,-30.3425],[-57.615,-30.256],[-57.649,-30.194]]],[[[-57.593,-27.392],[-57.4925,-27.4385],[-57.4885,-27.406],[-57.593,-27.392]]],[[[-57.032,-27.481],[-56.967,-27.495],[-56.911,-27.5315],[-56.8735,-27.5815],[-56.833,-27.596],[-56.749,-27.5615],[-56.726,-27.5125],[-56.77,-27.502],[-56.885,-27.4245],[-56.9225,-27.4225],[-57.032,-27.481]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/1a/Flag_of_Argentina.svg","name:en":"Argentina","wikidata":"Q414","ISO3166-1:alpha2":"AR","ISO3166-1:alpha3":"ARG","ISO3166-1:numeric":"032"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-92.207,1.6835],[-92.2045,1.6485],[-91.848,-0.431],[-91.6835,-1.038],[-91.646,-1.1115],[-91.5585,-1.1735],[-90.975,-1.385],[-90.522,-1.5495],[-90.4665,-1.561],[-89.639,-1.612],[-89.564,-1.602],[-89.505,-1.5705],[-89.4535,-1.51],[-89.266,-1.1755],[-89.064,-0.8155],[-89.0475,-0.7775],[-89.0395,-0.696],[-89.0725,-0.6045],[-89.2765,-0.3],[-89.787,0.46],[-89.8275,0.504],[-89.9225,0.55],[-90.3765,0.7145],[-90.662,0.8175],[-91.061,1.1515],[-91.8795,1.837],[-91.9255,1.866],[-91.996,1.8835],[-92.053,1.8785],[-92.1195,1.849],[-92.1815,1.7815],[-92.207,1.6835]]],[[[-75.258,-0.116],[-75.3665,-0.091],[-75.427,-0.087],[-75.469,-0.05],[-75.667,0.0455],[-75.7525,0.037],[-75.8145,0.075],[-75.8615,0.1345],[-75.952,0.2015],[-76.009,0.3005],[-76.0565,0.333],[-76.1205,0.324],[-76.129,0.368],[-76.1785,0.372],[-76.2615,0.427],[-76.314,0.434],[-76.3345,0.387],[-76.412,0.38],[-76.411,0.2425],[-76.504,0.2365],[-76.533,0.2585],[-76.5825,0.2295],[-76.6255,0.262],[-76.733,0.2885],[-76.769,0.243],[-76.7975,0.2645],[-76.8475,0.239],[-76.905,0.2455],[-76.9445,0.269],[-76.985,0.266],[-77.011,0.294],[-77.078,0.2855],[-77.1135,0.3725],[-77.178,0.3905],[-77.2145,0.363],[-77.302,0.3675],[-77.3265,0.3885],[-77.412,0.409],[-77.421,0.436],[-77.521,0.4165],[-77.522,0.5195],[-77.481,0.6045],[-77.4915,0.662],[-77.548,0.649],[-77.698,0.7415],[-77.6635,0.812],[-77.713,0.8505],[-77.7745,0.8415],[-77.8195,0.8085],[-77.8685,0.802],[-77.936,0.8165],[-77.9845,0.8535],[-78.0675,0.8955],[-78.1245,0.9365],[-78.1855,0.938],[-78.202,0.997],[-78.282,1.056],[-78.2765,1.109],[-78.3115,1.191],[-78.417,1.1605],[-78.437,1.1905],[-78.4885,1.186],[-78.5525,1.2505],[-78.615,1.246],[-78.71,1.359],[-78.7795,1.392],[-78.7995,1.4245],[-78.8685,1.4695],[-79.174,1.4695],[-79.56,1.4695],[-80.174,0.985],[-80.2295,0.9165],[-81.2605,-1.169],[-81.281,-1.274],[-81.2125,-2.1855],[-81.343,-3.37],[-81.3445,-3.392],[-80.671,-3.392],[-80.3065,-3.3925],[-80.2495,-3.4125],[-80.243,-3.4665],[-80.2065,-3.5345],[-80.212,-3.592],[-80.1855,-3.648],[-80.1995,-3.689],[-80.182,-3.7855],[-80.159,-3.809],[-80.1585,-3.8715],[-80.14,-3.913],[-80.1865,-3.929],[-80.299,-4.0175],[-80.3385,-3.993],[-80.398,-3.981],[-80.469,-4.038],[-80.4845,-4.09],[-80.449,-4.125],[-80.45,-4.2095],[-80.41,-4.218],[-80.372,-4.198],[-80.3315,-4.2255],[-80.3675,-4.28],[-80.412,-4.316],[-80.4535,-4.3825],[-80.4405,-4.4555],[-80.3885,-4.486],[-80.3295,-4.4655],[-80.2825,-4.4065],[-80.1555,-4.304],[-80.1065,-4.2915],[-80.0615,-4.311],[-80.0335,-4.3495],[-79.9525,-4.398],[-79.92,-4.386],[-79.8715,-4.413],[-79.8135,-4.492],[-79.745,-4.483],[-79.6555,-4.434],[-79.6175,-4.4455],[-79.5445,-4.525],[-79.505,-4.5175],[-79.477,-4.5685],[-79.488,-4.6275],[-79.463,-4.6545],[-79.458,-4.702],[-79.4315,-4.737],[-79.399,-4.829],[-79.361,-4.844],[-79.352,-4.8805],[-79.3065,-4.901],[-79.2655,-4.967],[-79.1805,-4.9605],[-79.102,-4.9785],[-79.076,-4.97],[-79.0125,-5.012],[-78.9725,-4.894],[-78.917,-4.892],[-78.891,-4.8085],[-78.889,-4.715],[-78.8425,-4.6545],[-78.805,-4.638],[-78.706,-4.624],[-78.661,-4.586],[-78.661,-4.53],[-78.6375,-4.501],[-78.634,-4.415],[-78.6525,-4.3325],[-78.618,-4.294],[-78.5985,-4.208],[-78.5785,-4.198],[-78.5815,-4.1355],[-78.541,-4.074],[-78.5625,-4.05],[-78.566,-3.9935],[-78.5245,-3.9375],[-78.4885,-3.9335],[-78.4765,-3.8585],[-78.414,-3.7925],[-78.4025,-3.7355],[-78.4225,-3.691],[-78.401,-3.6515],[-78.3875,-3.555],[-78.365,-3.5295],[-78.359,-3.4695],[-78.324,-3.391],[-78.248,-3.398],[-78.229,-3.5055],[-78.148,-3.479],[-78.155,-3.4265],[-78.1975,-3.365],[-78.17,-3.35],[-78.107,-3.2765],[-78.0785,-3.2265],[-78.0325,-3.189],[-77.971,-3.118],[-77.944,-3.0655],[-77.844,-3.0005],[-77.7105,-2.951],[-77.1745,-2.7715],[-76.6325,-2.591],[-76.0445,-2.125],[-75.5865,-1.5535],[-75.5555,-1.547],[-75.386,-0.9375],[-75.3135,-0.9845],[-75.26,-0.989],[-75.195,-0.9705],[-75.2315,-0.939],[-75.225,-0.8625],[-75.243,-0.7975],[-75.2775,-0.73],[-75.2515,-0.6915],[-75.2575,-0.6435],[-75.2235,-0.629],[-75.2415,-0.5245],[-75.313,-0.4945],[-75.3275,-0.4595],[-75.3855,-0.437],[-75.4735,-0.297],[-75.482,-0.237],[-75.531,-0.181],[-75.6105,-0.1925],[-75.6105,-0.1135],[-75.567,-0.1305],[-75.504,-0.127],[-75.4035,-0.17],[-75.3045,-0.154],[-75.258,-0.116]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/e/e8/Flag_of_Ecuador.svg","name:en":"Ecuador","wikidata":"Q736","ISO3166-1:alpha2":"EC","ISO3166-1:alpha3":"ECU","ISO3166-1:numeric":"218"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-5.4005,36.1485],[-5.364,36.061],[-5.2905,36.0855],[-5.277,36.1495],[-5.4005,36.1485]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/02/Flag_of_Gibraltar.svg","name:en":"Gibraltar","wikidata":"Q1410","ISO3166-1:alpha2":"GI","ISO3166-1:alpha3":"GIB","ISO3166-1:numeric":"292"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-58.1695,-20.167],[-58.055,-20.109],[-58.0215,-20.0585],[-57.9795,-20.057],[-57.961,-20.0245],[-57.905,-20.043],[-57.858,-19.9705],[-58.131,-19.758],[-57.9875,-19.46],[-57.784,-19.033],[-57.71,-19.0345],[-57.719,-18.899],[-57.766,-18.899],[-57.557,-18.24],[-57.505,-18.2005],[-57.574,-18.131],[-57.6,-18.046],[-57.723,-17.8305],[-57.685,-17.8105],[-57.791,-17.5865],[-57.746,-17.551],[-57.883,-17.449],[-57.98,-17.51],[-58.043,-17.492],[-58.06,-17.45],[-58.116,-17.451],[-58.151,-17.384],[-58.202,-17.357],[-58.254,-17.352],[-58.276,-17.3],[-58.317,-17.268],[-58.356,-17.212],[-58.396,-17.181],[-58.398,-17.104],[-58.425,-17.112],[-58.431,-16.99],[-58.462,-16.958],[-58.461,-16.841],[-58.476,-16.827],[-58.47,-16.703],[-58.436,-16.592],[-58.343,-16.517],[-58.334,-16.478],[-58.356,-16.428],[-58.344,-16.389],[-58.308,-16.3715],[-58.3035,-16.31],[-58.3295,-16.272],[-58.3665,-16.2745],[-58.431,-16.3225],[-58.785,-16.306],[-59.47,-16.279],[-60.174,-16.2665],[-60.203,-15.885],[-60.239,-15.475],[-60.575,-15.0975],[-60.245,-15.0975],[-60.2735,-14.621],[-60.323,-14.6105],[-60.34,-14.51],[-60.379,-14.4645],[-60.407,-14.4015],[-60.3945,-14.369],[-60.4545,-14.3135],[-60.4845,-14.1145],[-60.4475,-14.0845],[-60.4045,-13.9985],[-60.4185,-13.9375],[-60.4505,-13.927],[-60.453,-13.881],[-60.5205,-13.77],[-60.569,-13.7685],[-60.6245,-13.719],[-60.654,-13.7355],[-60.687,-13.7005],[-60.771,-13.6795],[-60.832,-13.627],[-60.877,-13.62],[-60.927,-13.5395],[-61.009,-13.5495],[-61.0425,-13.5085],[-61.086,-13.492],[-61.149,-13.532],[-61.2345,-13.5255],[-61.2545,-13.4965],[-61.331,-13.5035],[-61.4665,-13.554],[-61.578,-13.5115],[-61.6645,-13.503],[-61.7865,-13.5375],[-61.869,-13.526],[-61.8885,-13.441],[-61.926,-13.4285],[-61.976,-13.367],[-62.017,-13.35],[-62.115,-13.256],[-62.1215,-13.151],[-62.1985,-13.152],[-62.2155,-13.1105],[-62.2645,-13.147],[-62.394,-13.1335],[-62.459,-13.077],[-62.539,-13.074],[-62.6145,-13.038],[-62.631,-12.99],[-62.6615,-12.9685],[-62.7005,-13.002],[-62.7965,-12.993],[-62.8045,-12.943],[-62.8745,-12.905],[-62.9215,-12.84],[-62.9705,-12.8595],[-63.0465,-12.741],[-63.084,-12.7165],[-63.09,-12.638],[-63.1825,-12.6275],[-63.24,-12.6905],[-63.297,-12.6825],[-63.3885,-12.6495],[-63.436,-12.5665],[-63.507,-12.5645],[-63.559,-12.504],[-63.623,-12.4725],[-63.7835,-12.428],[-63.831,-12.461],[-63.8765,-12.445],[-63.901,-12.503],[-63.9455,-12.528],[-63.99,-12.503],[-64.0365,-12.517],[-64.0555,-12.4935],[-64.174,-12.503],[-64.1725,-12.47],[-64.228,-12.4545],[-64.277,-12.4985],[-64.2995,-12.4565],[-64.3625,-12.4605],[-64.428,-12.432],[-64.4555,-12.3865],[-64.5035,-12.3655],[-64.4955,-12.2675],[-64.509,-12.2285],[-64.5605,-12.2365],[-64.693,-12.1895],[-64.7405,-12.1445],[-64.7605,-12.0945],[-64.8035,-12.0865],[-64.832,-12.016],[-64.9175,-12.0265],[-64.944,-11.995],[-64.9805,-12.0175],[-65.035,-11.9945],[-65.0275,-11.892],[-65.0725,-11.857],[-65.064,-11.7715],[-65.099,-11.703],[-65.1845,-11.721],[-65.221,-11.7415],[-65.2585,-11.697],[-65.22,-11.6635],[-65.234,-11.605],[-65.224,-11.516],[-65.3085,-11.496],[-65.339,-11.311],[-65.3585,-11.2685],[-65.353,-11.124],[-65.287,-11.094],[-65.2985,-11.026],[-65.2515,-10.99],[-65.2705,-10.96],[-65.275,-10.873],[-65.321,-10.8225],[-65.363,-10.801],[-65.343,-10.7675],[-65.354,-10.6615],[-65.4055,-10.6395],[-65.399,-10.5815],[-65.4295,-10.4795],[-65.381,-10.429],[-65.3905,-10.371],[-65.324,-10.301],[-65.2885,-10.2145],[-65.306,-10.165],[-65.301,-10.098],[-65.329,-10.046],[-65.32,-10.001],[-65.331,-9.929],[-65.2885,-9.869],[-65.355,-9.7225],[-65.393,-9.687],[-65.442,-9.6905],[-65.5015,-9.7305],[-65.5125,-9.7935],[-65.627,-9.838],[-65.6695,-9.7815],[-65.727,-9.7585],[-65.7845,-9.7875],[-65.8205,-9.7675],[-65.855,-9.7955],[-65.886,-9.752],[-65.975,-9.7765],[-65.984,-9.8045],[-66.0385,-9.785],[-66.173,-9.7925],[-66.212,-9.835],[-66.2375,-9.8135],[-66.284,-9.844],[-66.312,-9.831],[-66.3585,-9.864],[-66.4885,-9.868],[-66.62,-9.8935],[-66.6365,-9.943],[-66.7285,-9.98],[-66.8335,-10.061],[-66.8435,-10.087],[-66.898,-10.111],[-66.9825,-10.1965],[-67.016,-10.2585],[-67.079,-10.2895],[-67.125,-10.2905],[-67.17,-10.3375],[-67.232,-10.315],[-67.2625,-10.331],[-67.3165,-10.32],[-67.318,-10.3665],[-67.4195,-10.388],[-67.4135,-10.427],[-67.451,-10.4585],[-67.579,-10.503],[-67.612,-10.5635],[-67.6755,-10.605],[-67.7075,-10.71],[-67.73,-10.7135],[-67.8275,-10.6515],[-67.866,-10.6405],[-67.977,-10.662],[-68.015,-10.649],[-68.105,-10.715],[-68.0975,-10.7485],[-68.1255,-10.7985],[-68.196,-10.8605],[-68.236,-10.9605],[-68.2765,-10.99],[-68.429,-11.036],[-68.4835,-11.0775],[-68.5905,-11.1155],[-68.7155,-11.1475],[-68.73,-11.0985],[-68.7655,-11.0665],[-68.748,-11.009],[-68.8345,-10.993],[-68.9125,-11.0215],[-68.9685,-10.9875],[-68.9975,-11.0025],[-69.0715,-10.967],[-69.148,-10.972],[-69.2325,-10.94],[-69.2915,-10.95],[-69.401,-10.9305],[-69.479,-10.955],[-69.522,-10.936],[-69.572,-10.9455],[-69.379,-11.264],[-69.255,-11.459],[-68.9705,-11.913],[-68.652,-12.498],[-68.713,-12.603],[-68.7415,-12.6355],[-68.713,-12.6815],[-68.743,-12.726],[-68.788,-12.757],[-68.8345,-12.813],[-68.836,-12.859],[-68.8715,-12.8855],[-68.8705,-13.019],[-68.85,-13.037],[-68.8745,-13.1155],[-68.8455,-13.246],[-68.917,-13.4865],[-68.993,-13.65],[-69.061,-13.657],[-69.066,-13.6885],[-68.977,-13.758],[-68.9805,-13.7835],[-68.9175,-13.8135],[-68.951,-13.8785],[-68.982,-13.894],[-68.9785,-13.976],[-68.942,-14.0215],[-68.8955,-14.0415],[-68.856,-14.1625],[-68.828,-14.22],[-68.9625,-14.22],[-69.015,-14.3145],[-68.9855,-14.3745],[-69.031,-14.426],[-69.084,-14.452],[-69.1405,-14.5135],[-69.15,-14.5805],[-69.22,-14.5815],[-69.2295,-14.6565],[-69.258,-14.683],[-69.2255,-14.7405],[-69.301,-14.7655],[-69.354,-14.8015],[-69.344,-14.8825],[-69.3615,-14.949],[-69.299,-15.0495],[-69.285,-15.095],[-69.236,-15.1205],[-69.133,-15.221],[-69.1315,-15.246],[-69.2155,-15.317],[-69.2485,-15.371],[-69.2535,-15.469],[-69.29,-15.437],[-69.3295,-15.537],[-69.402,-15.606],[-69.1965,-16.168],[-69.1025,-16.225],[-69.0555,-16.1975],[-69.013,-16.22],[-68.9615,-16.1945],[-68.893,-16.2595],[-68.7955,-16.3315],[-68.8005,-16.349],[-68.9885,-16.4255],[-69.04,-16.5735],[-69.017,-16.638],[-69.0455,-16.6885],[-69.17,-16.7275],[-69.219,-16.836],[-69.3045,-16.916],[-69.3435,-16.987],[-69.3945,-17.024],[-69.3735,-17.073],[-69.4065,-17.1005],[-69.449,-17.098],[-69.512,-17.146],[-69.557,-17.1595],[-69.616,-17.2615],[-69.4685,-17.374],[-69.4685,-17.4985],[-69.468,-17.605],[-69.337,-17.7315],[-69.3075,-17.8055],[-69.3085,-17.896],[-69.281,-17.9695],[-69.121,-18.005],[-69.057,-18.0615],[-69.146,-18.163],[-69.064,-18.2325],[-69.075,-18.2925],[-69.053,-18.347],[-69.0475,-18.4265],[-69.0045,-18.476],[-69.0325,-18.629],[-68.988,-18.674],[-68.977,-18.738],[-68.9255,-18.843],[-68.92,-18.885],[-68.9505,-18.9365],[-68.8895,-19.0435],[-68.806,-19.0835],[-68.6285,-19.251],[-68.62,-19.2765],[-68.5425,-19.297],[-68.4515,-19.368],[-68.405,-19.416],[-68.441,-19.4405],[-68.557,-19.5965],[-68.5985,-19.641],[-68.625,-19.702],[-68.6825,-19.718],[-68.69,-19.75],[-68.6205,-19.7895],[-68.5995,-19.828],[-68.5285,-19.8455],[-68.5425,-19.8895],[-68.5215,-19.9245],[-68.5665,-20.05],[-68.64,-20.049],[-68.7625,-20.0785],[-68.7735,-20.1295],[-68.705,-20.1335],[-68.7135,-20.23],[-68.6605,-20.3195],[-68.672,-20.355],[-68.7415,-20.3685],[-68.7385,-20.457],[-68.6665,-20.5165],[-68.6135,-20.5365],[-68.5735,-20.575],[-68.535,-20.5695],[-68.4505,-20.6475],[-68.526,-20.6965],[-68.5535,-20.7285],[-68.541,-20.7965],[-68.553,-20.8765],[-68.493,-20.946],[-68.4125,-20.9345],[-68.295,-21.0975],[-68.179,-21.3025],[-68.1805,-21.6045],[-68.1175,-21.6785],[-68.0655,-21.7675],[-68.063,-21.8525],[-68.0715,-21.979],[-67.971,-22.0545],[-67.939,-22.108],[-67.957,-22.1515],[-67.933,-22.2015],[-67.9215,-22.2755],[-67.9385,-22.2945],[-67.9335,-22.391],[-67.903,-22.4035],[-67.893,-22.4995],[-67.8455,-22.531],[-67.8385,-22.5885],[-67.874,-22.64],[-67.8675,-22.6795],[-67.89,-22.719],[-67.8675,-22.745],[-67.8815,-22.834],[-67.7985,-22.881],[-67.5675,-22.8985],[-67.1805,-22.814],[-67.1275,-22.722],[-67.014,-22.655],[-67.027,-22.541],[-66.973,-22.5405],[-66.9285,-22.492],[-66.7825,-22.438],[-66.7395,-22.2385],[-66.686,-22.2095],[-66.348,-22.128],[-66.288,-22.086],[-66.2925,-22.0345],[-66.2605,-21.906],[-66.236,-21.8495],[-66.241,-21.789],[-66.0765,-21.835],[-66.0435,-21.872],[-66.048,-21.919],[-65.925,-21.9335],[-65.805,-22.075],[-65.7485,-22.109],[-65.6755,-22.1115],[-65.5825,-22.094],[-65.5745,-22.076],[-65.475,-22.0895],[-64.9935,-22.0825],[-64.8855,-22.129],[-64.8625,-22.123],[-64.7375,-22.1935],[-64.651,-22.1895],[-64.542,-22.279],[-64.5655,-22.372],[-64.4905,-22.4385],[-64.4455,-22.523],[-64.4125,-22.5375],[-64.4335,-22.6485],[-64.397,-22.6835],[-64.393,-22.7195],[-64.3445,-22.739],[-64.329,-22.8565],[-64.2825,-22.8245],[-64.2655,-22.7665],[-64.272,-22.71],[-64.2425,-22.56],[-64.1995,-22.491],[-64.1155,-22.4045],[-64.1165,-22.362],[-64.0625,-22.2385],[-64.009,-22.1655],[-63.986,-22.0935],[-63.9315,-21.9995],[-63.3505,-21.9995],[-62.811,-21.999],[-62.799,-22.06],[-62.813,-22.0965],[-62.717,-22.2035],[-62.6405,-22.236],[-62.458,-21.6725],[-62.261,-21.0585],[-62.258,-20.9895],[-62.2665,-20.563],[-61.9225,-20.089],[-61.735,-19.6345],[-60.9985,-19.519],[-60.6045,-19.4565],[-59.978,-19.2945],[-59.5,-19.291],[-59.069,-19.2875],[-58.6965,-19.5055],[-58.236,-19.775],[-58.164,-19.827],[-58.202,-19.8625],[-58.197,-19.925],[-58.1655,-20.0645],[-58.138,-20.124],[-58.1695,-20.167]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/48/Flag_of_Bolivia.svg","name:en":"Bolivia","wikidata":"Q750","ISO3166-1:alpha2":"BO","ISO3166-1:alpha3":"BOL","ISO3166-1:numeric":"068"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-87.295,5.519],[-87.288,5.4665],[-87.2525,5.3925],[-87.201,5.342],[-87.1505,5.3135],[-87.074,5.298],[-86.985,5.319],[-86.911,5.3655],[-86.864,5.4155],[-86.838,5.468],[-86.827,5.5345],[-86.859,5.65],[-86.911,5.709],[-87.009,5.7545],[-87.1145,5.747],[-87.1915,5.7085],[-87.25,5.6535],[-87.2765,5.608],[-87.295,5.519]]],[[[-82.506,9.654],[-82.5555,9.6985],[-82.7035,9.721],[-82.728,9.7955],[-82.753,9.8125],[-82.9185,10.0215],[-82.9975,10.072],[-83.2485,10.4015],[-83.307,10.4585],[-83.4525,10.7655],[-83.489,10.899],[-83.5405,10.9685],[-83.6285,10.998],[-83.658,11.0295],[-83.7035,10.9425],[-83.667,10.8815],[-83.671,10.797],[-83.7945,10.7675],[-83.8625,10.7175],[-83.9135,10.711],[-83.9685,10.731],[-84.006,10.7665],[-84.0705,10.76],[-84.14,10.7875],[-84.222,10.8005],[-84.226,10.8745],[-84.319,10.916],[-84.3585,10.996],[-84.4205,10.9555],[-84.485,11.0],[-84.606,11.0385],[-84.6805,11.0845],[-84.91,10.9435],[-85.23,11.064],[-85.357,11.126],[-85.4235,11.129],[-85.5235,11.168],[-85.5605,11.21],[-85.61,11.2195],[-85.693,11.079],[-85.706,11.069],[-85.898,11.076],[-86.042,10.919],[-86.045,10.82],[-86.0005,10.7635],[-85.883,10.751],[-85.802,10.7175],[-85.8,10.651],[-85.9375,10.529],[-85.952,10.4585],[-85.9915,10.369],[-85.9865,10.317],[-85.929,10.0835],[-85.769,9.8845],[-85.7385,9.836],[-85.6895,9.7995],[-85.5715,9.7835],[-85.389,9.732],[-85.3705,9.6995],[-85.2725,9.591],[-85.2445,9.5345],[-85.139,9.463],[-85.055,9.4725],[-85.0105,9.5235],[-84.9695,9.6015],[-84.9165,9.6255],[-84.8395,9.688],[-84.776,9.7605],[-84.7555,9.7345],[-84.7825,9.6695],[-84.7675,9.566],[-84.551,9.409],[-84.464,9.4175],[-84.25,9.359],[-84.2105,9.3015],[-84.0735,9.2425],[-83.9065,9.109],[-83.796,9.0415],[-83.765,8.9685],[-83.7595,8.764],[-83.7815,8.75],[-83.869,8.773],[-83.9395,8.7395],[-83.9465,8.6935],[-83.8395,8.5695],[-83.8055,8.5045],[-83.634,8.3475],[-83.5585,8.3175],[-83.497,8.3345],[-83.2775,8.2595],[-83.2275,8.294],[-83.2085,8.252],[-83.0875,8.1855],[-83.0125,8.0655],[-82.991,7.9635],[-82.9455,7.9355],[-82.8875,8.077],[-82.9295,8.2455],[-82.975,8.2895],[-83.046,8.318],[-82.9355,8.424],[-82.8685,8.4395],[-82.832,8.5045],[-82.822,8.567],[-82.83,8.636],[-82.8705,8.6985],[-82.916,8.7415],[-82.9145,8.7695],[-82.8665,8.8055],[-82.855,8.856],[-82.7605,8.885],[-82.712,8.9225],[-82.7505,8.9925],[-82.874,9.0575],[-82.887,9.088],[-82.936,9.0785],[-82.936,9.473],[-82.8445,9.5],[-82.885,9.5705],[-82.857,9.62],[-82.7595,9.587],[-82.6845,9.5065],[-82.6355,9.494],[-82.565,9.572],[-82.506,9.654]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/f2/Flag_of_Costa_Rica.svg","name:en":"Costa Rica","wikidata":"Q800","ISO3166-1:alpha2":"CR","ISO3166-1:alpha3":"CRI","ISO3166-1:numeric":"188"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-88.1755,15.9075],[-88.4985,16.07],[-88.686,16.051],[-88.7705,15.9585],[-88.9575,15.8885],[-89.022,15.9115],[-89.103,15.9125],[-89.2275,15.896],[-89.2085,16.1795],[-89.1735,16.7115],[-89.15,17.0575],[-89.151,17.4485],[-89.152,17.8155],[-89.5155,17.8155],[-90.2455,17.816],[-90.9875,17.8155],[-90.9875,17.2515],[-91.439,17.251],[-91.429,17.2185],[-91.3255,17.1825],[-91.278,17.179],[-91.2685,17.11],[-91.2325,17.1],[-91.2035,17.045],[-91.0645,16.925],[-91.009,16.887],[-90.9575,16.897],[-90.92,16.821],[-90.8825,16.825],[-90.847,16.796],[-90.7645,16.7635],[-90.683,16.6895],[-90.659,16.6425],[-90.637,16.5135],[-90.586,16.47],[-90.5035,16.4685],[-90.4885,16.4285],[-90.42,16.4245],[-90.3985,16.3745],[-90.4105,16.3095],[-90.4395,16.3045],[-90.455,16.189],[-90.4265,16.1625],[-90.442,16.074],[-90.961,16.074],[-91.7315,16.074],[-92.017,15.5895],[-92.2105,15.2605],[-92.0595,15.071],[-92.102,15.011],[-92.133,15.0115],[-92.1485,14.9485],[-92.136,14.893],[-92.185,14.8285],[-92.159,14.769],[-92.147,14.6585],[-92.186,14.5725],[-92.3105,14.451],[-92.1135,14.281],[-91.9455,14.13],[-91.7395,14.0025],[-91.5005,13.88],[-91.272,13.8145],[-91.111,13.7895],[-90.733,13.7995],[-90.536,13.7735],[-90.179,13.6345],[-90.118,13.789],[-90.113,13.824],[-90.023,13.939],[-89.9615,13.9705],[-89.8915,14.0435],[-89.8165,14.063],[-89.776,14.0345],[-89.746,14.0635],[-89.714,14.138],[-89.667,14.1855],[-89.523,14.2245],[-89.5605,14.3125],[-89.588,14.346],[-89.574,14.417],[-89.4295,14.415],[-89.3895,14.449],[-89.356,14.4205],[-89.355,14.47],[-89.303,14.4965],[-89.2385,14.585],[-89.1595,14.5745],[-89.1575,14.67],[-89.1315,14.7125],[-89.1655,14.731],[-89.169,14.775],[-89.224,14.8345],[-89.228,14.8825],[-89.1815,14.911],[-89.1565,14.98],[-89.1845,15.0025],[-89.1535,15.0685],[-88.974,15.136],[-88.8455,15.243],[-88.678,15.3425],[-88.605,15.413],[-88.5525,15.4465],[-88.3455,15.6175],[-88.3255,15.6705],[-88.2475,15.69],[-88.2215,15.7235],[-88.1755,15.9075]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/e/ec/Flag_of_Guatemala.svg","name:en":"Guatemala","wikidata":"Q774","ISO3166-1:alpha2":"GT","ISO3166-1:alpha3":"GTM","ISO3166-1:numeric":"320"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-131.435,54.6895],[-131.436,54.567],[-131.391,54.483],[-131.288,54.41],[-131.2495,54.355],[-131.125,54.277],[-131.164,54.183],[-131.1655,54.129],[-131.1265,54.058],[-131.05,54.002],[-131.0675,53.916],[-131.037,53.796],[-130.895,53.665],[-130.9105,53.601],[-130.9535,53.537],[-130.963,53.475],[-130.927,53.393],[-130.8745,53.347],[-130.7525,53.289],[-130.5735,53.263],[-130.4645,53.207],[-130.3915,53.185],[-130.352,53.143],[-130.2055,53.03],[-130.125,52.992],[-130.032,52.97],[-129.9405,52.872],[-129.817,52.789],[-129.726,52.761],[-129.7525,52.658],[-129.742,52.494],[-129.6975,52.413],[-129.6225,52.36],[-129.54,52.33],[-129.402,52.314],[-129.2775,52.324],[-129.213,52.279],[-128.9935,52.199],[-128.9035,52.136],[-128.823,52.102],[-128.7625,52.033],[-128.8025,51.927],[-128.7835,51.845],[-128.7245,51.779],[-128.637,51.733],[-128.5245,51.695],[-128.47,51.651],[-128.4565,51.545],[-128.3925,51.424],[-128.325,51.347],[-128.1515,51.272],[-128.856,51.0155],[-128.9905,51.0665],[-129.1645,51.068],[-129.292,51.024],[-129.3755,50.9585],[-129.403,50.9065],[-129.4075,50.819],[-129.3365,50.7235],[-129.25,50.6785],[-128.986,50.6185],[-128.829,50.621],[-128.7555,50.604],[-128.6145,50.547],[-128.453,50.406],[-128.3,50.317],[-128.257,50.237],[-128.212,50.193],[-128.2315,50.133],[-128.2155,50.055],[-128.1705,49.995],[-128.032,49.92],[-127.8885,49.885],[-127.8035,49.88],[-127.6915,49.892],[-127.589,49.825],[-127.4635,49.796],[-127.406,49.74],[-127.2655,49.671],[-127.212,49.609],[-127.0475,49.485],[-126.964,49.442],[-126.8795,49.418],[-126.83,49.306],[-126.756,49.248],[-126.614,49.191],[-126.4915,49.178],[-126.4455,49.14],[-126.3395,49.086],[-126.284,49.036],[-125.881,48.847],[-125.7475,48.775],[-125.6475,48.736],[-125.5225,48.719],[-125.4105,48.635],[-125.217,48.542],[-125.0035,48.495],[-124.8405,48.506],[-124.727,48.4935],[-124.012,48.2965],[-123.679,48.24],[-123.541,48.2245],[-123.2485,48.284],[-123.115,48.423],[-123.16,48.4535],[-123.219,48.5485],[-123.268,48.694],[-123.0085,48.767],[-123.0085,48.831],[-123.322,49.002],[-122.787,49.002],[-122.098,49.0025],[-121.7595,48.9975],[-121.335,49.001],[-120.6695,49.0],[-120.0025,48.9995],[-119.047,49.0],[-118.3895,49.0],[-117.992,49.0005],[-117.135,48.999],[-116.499,49.0],[-115.8615,49.001],[-115.2625,48.9995],[-114.362,49.001],[-113.6945,48.9975],[-112.924,48.9985],[-112.393,48.9985],[-111.5755,48.9965],[-110.88,48.998],[-110.326,48.999],[-109.4205,49.0005],[-108.8355,48.9995],[-107.886,49.0],[-106.986,49.0],[-106.2295,48.9995],[-105.561,48.9995],[-104.685,48.999],[-103.807,48.9995],[-103.3775,48.999],[-102.4565,48.999],[-101.981,48.999],[-101.17,48.9995],[-100.471,48.9995],[-99.5405,48.9995],[-98.98,49.0],[-98.2105,49.0005],[-97.4815,49.0005],[-96.6525,49.0],[-95.633,48.9995],[-95.153,48.999],[-95.1535,49.3845],[-95.0585,49.3535],[-94.9575,49.37],[-94.854,49.3245],[-94.8255,49.2945],[-94.773,49.1205],[-94.7495,49.099],[-94.6835,48.884],[-94.7045,48.824],[-94.691,48.778],[-94.5875,48.7175],[-94.439,48.695],[-94.416,48.711],[-94.261,48.6965],[-94.2445,48.6535],[-93.848,48.631],[-93.804,48.57],[-93.7935,48.5165],[-93.6475,48.5175],[-93.4675,48.5465],[-93.467,48.5885],[-93.3485,48.6265],[-93.2075,48.6425],[-93.1785,48.6235],[-92.9845,48.624],[-92.7285,48.5395],[-92.635,48.5425],[-92.637,48.4995],[-92.7125,48.463],[-92.656,48.4365],[-92.5075,48.448],[-92.4565,48.401],[-92.47,48.352],[-92.375,48.226],[-92.2805,48.2445],[-92.3015,48.2885],[-92.289,48.343],[-92.055,48.3595],[-92.0,48.321],[-92.0065,48.2655],[-91.9585,48.233],[-91.893,48.238],[-91.8645,48.207],[-91.7155,48.1995],[-91.7115,48.1145],[-91.5695,48.0935],[-91.5755,48.049],[-91.488,48.0685],[-91.4295,48.0485],[-91.371,48.0695],[-91.2495,48.084],[-91.0825,48.181],[-90.8855,48.246],[-90.8395,48.2395],[-90.8325,48.1735],[-90.7615,48.0985],[-90.6415,48.1035],[-90.375,48.091],[-90.306,48.105],[-90.1325,48.1115],[-90.0235,48.085],[-89.994,48.028],[-89.899,47.988],[-89.7675,48.023],[-89.5855,48.002],[-89.489,48.0145],[-89.3375,47.9745],[-88.6775,48.2455],[-88.37,48.306],[-87.6475,48.029],[-87.1125,47.818],[-85.319,47.0795],[-84.86,46.889],[-84.763,46.6345],[-84.557,46.461],[-84.4755,46.453],[-84.445,46.489],[-84.374,46.509],[-84.2935,46.493],[-84.226,46.534],[-84.129,46.5305],[-84.111,46.504],[-84.146,46.419],[-84.108,46.2415],[-84.077,46.1875],[-84.006,46.1495],[-83.9555,46.057],[-83.9035,46.0605],[-83.8265,46.119],[-83.76,46.1025],[-83.655,46.1215],[-83.572,46.106],[-83.434,45.998],[-83.597,45.8215],[-82.757,45.4455],[-82.5185,45.3385],[-82.4085,44.8585],[-82.25,44.165],[-82.123,43.591],[-82.414,43.011],[-82.413,42.9775],[-82.4555,42.927],[-82.482,42.8085],[-82.4675,42.7625],[-82.5235,42.6075],[-82.6055,42.5485],[-82.668,42.5335],[-82.83,42.3735],[-83.0635,42.318],[-83.128,42.2385],[-83.1215,42.1255],[-83.1495,42.041],[-83.069,41.8635],[-82.6795,41.6765],[-82.3975,41.6765],[-82.269,41.7415],[-81.8545,41.933],[-81.799,41.953],[-81.2455,42.2075],[-80.521,42.323],[-80.08,42.3935],[-79.5705,42.5875],[-78.9355,42.8285],[-78.906,42.9],[-78.9325,42.956],[-79.0165,42.984],[-79.011,43.066],[-79.074,43.078],[-79.0425,43.1435],[-79.056,43.2545],[-79.0775,43.2725],[-79.2005,43.4505],[-78.6905,43.631],[-77.928,43.631],[-77.442,43.631],[-76.7965,43.631],[-76.439,44.094],[-76.353,44.1345],[-76.3125,44.199],[-76.2455,44.204],[-76.1645,44.24],[-76.162,44.2805],[-76.001,44.348],[-75.913,44.368],[-75.8215,44.432],[-75.767,44.5155],[-75.505,44.7055],[-75.2185,44.878],[-75.14,44.897],[-74.9725,44.9835],[-74.908,44.9835],[-74.8265,45.016],[-74.731,44.9905],[-74.6835,44.9995],[-74.15,44.9915],[-73.883,45.001],[-73.65,45.003],[-73.0655,45.016],[-72.6345,45.0145],[-72.312,45.004],[-71.914,45.0075],[-71.501,45.0135],[-71.4955,45.065],[-71.4295,45.1225],[-71.3975,45.2055],[-71.3565,45.254],[-71.288,45.301],[-71.2305,45.2495],[-71.133,45.2445],[-71.098,45.3015],[-70.989,45.334],[-70.918,45.3115],[-70.8845,45.235],[-70.806,45.3215],[-70.8255,45.4005],[-70.7815,45.431],[-70.712,45.3905],[-70.6505,45.377],[-70.6245,45.406],[-70.681,45.452],[-70.7225,45.5135],[-70.6455,45.6065],[-70.553,45.668],[-70.4005,45.7195],[-70.417,45.7955],[-70.254,45.9025],[-70.2395,45.94],[-70.3125,45.962],[-70.3135,46.0225],[-70.2895,46.0945],[-70.2395,46.149],[-70.2925,46.1915],[-70.209,46.3295],[-70.149,46.359],[-70.095,46.41],[-70.0565,46.4165],[-69.997,46.6955],[-69.587,47.1045],[-69.2245,47.46],[-69.176,47.457],[-69.0355,47.415],[-69.0545,47.3765],[-69.041,47.245],[-68.905,47.1805],[-68.8115,47.215],[-68.687,47.2445],[-68.6075,47.247],[-68.58,47.287],[-68.517,47.296],[-68.378,47.2875],[-68.3845,47.324],[-68.3355,47.3595],[-68.2235,47.3445],[-67.952,47.1945],[-67.883,47.1045],[-67.79,47.067],[-67.7885,46.6015],[-67.782,46.263],[-67.7815,45.9435],[-67.751,45.918],[-67.8045,45.869],[-67.7555,45.8235],[-67.802,45.803],[-67.8035,45.6775],[-67.713,45.681],[-67.675,45.6305],[-67.499,45.5865],[-67.4565,45.6045],[-67.4205,45.5495],[-67.4275,45.501],[-67.5,45.491],[-67.4725,45.423],[-67.427,45.39],[-67.429,45.3445],[-67.4765,45.2755],[-67.464,45.245],[-67.3805,45.152],[-67.321,45.1315],[-67.291,45.1875],[-67.2275,45.1635],[-67.159,45.162],[-67.1125,45.1125],[-67.0215,44.954],[-66.9665,44.91],[-66.9655,44.829],[-66.8855,44.794],[-66.987,44.6955],[-67.039,44.6245],[-67.157,44.5825],[-67.2525,44.4965],[-67.304,44.3935],[-67.301,44.3595],[-67.165,44.305],[-67.05,44.303],[-66.947,44.3325],[-66.871,44.3855],[-66.788,44.37],[-66.61,44.378],[-66.6495,44.335],[-66.677,44.263],[-66.6695,44.193],[-66.6425,44.139],[-66.5435,44.057],[-66.482,44.032],[-66.449,43.977],[-66.4495,43.791],[-66.434,43.739],[-66.334,43.609],[-66.29,43.535],[-66.204,43.473],[-66.06,43.442],[-66.0485,43.385],[-65.958,43.326],[-65.7615,43.222],[-65.701,43.204],[-65.5935,43.197],[-65.5275,43.208],[-65.3465,43.276],[-65.1935,43.347],[-65.1425,43.381],[-65.087,43.452],[-64.9785,43.473],[-64.8785,43.511],[-64.7805,43.588],[-64.662,43.655],[-64.584,43.718],[-64.4915,43.829],[-64.354,43.926],[-64.294,43.987],[-64.1805,44.024],[-64.05,44.106],[-63.9425,44.202],[-63.906,44.262],[-63.8165,44.24],[-63.6215,44.232],[-63.476,44.247],[-63.403,44.273],[-63.3365,44.32],[-63.2655,44.427],[-63.188,44.439],[-63.0995,44.476],[-62.8775,44.472],[-62.726,44.505],[-62.616,44.555],[-62.4045,44.615],[-62.2255,44.68],[-62.1805,44.705],[-62.1125,44.709],[-61.901,44.761],[-61.752,44.845],[-61.7075,44.881],[-61.4545,44.939],[-61.3945,44.968],[-61.191,45.016],[-61.101,45.022],[-60.9135,45.062],[-60.8105,45.109],[-60.7115,45.2],[-60.677,45.276],[-60.6845,45.372],[-60.594,45.385],[-60.486,45.433],[-60.308,45.471],[-60.08,45.56],[-60.012,45.608],[-59.8895,45.669],[-59.8345,45.724],[-59.779,45.754],[-59.698,45.77],[-59.611,45.806],[-59.493,45.88],[-59.414,45.998],[-59.408,46.07],[-59.457,46.159],[-59.542,46.229],[-59.6005,46.311],[-59.6795,46.361],[-59.916,46.434],[-60.0895,46.471],[-60.129,46.499],[-60.0785,46.581],[-60.0685,46.669],[-60.0225,46.847],[-60.0415,46.929],[-60.068,46.968],[-59.9295,47.075],[-59.309,47.383],[-59.212,47.368],[-58.972,47.374],[-58.856,47.397],[-58.671,47.406],[-58.49,47.447],[-58.3025,47.454],[-58.145,47.479],[-57.961,47.457],[-57.8615,47.428],[-57.655,47.402],[-57.604,47.364],[-57.5165,47.329],[-57.3815,47.317],[-57.213,47.347],[-57.1465,47.377],[-57.069,47.38],[-56.92,47.335],[-56.8045,47.334],[-56.705,47.351],[-56.5915,47.391],[-56.4885,47.41],[-56.4945,47.365],[-56.255,47.3055],[-56.105,47.1005],[-56.1295,46.931],[-56.0995,46.86],[-55.9825,46.803],[-55.9035,46.646],[-55.7085,46.654],[-55.5545,46.69],[-55.46,46.679],[-55.263,46.694],[-55.173,46.721],[-55.044,46.799],[-54.929,46.88],[-54.8075,47.039],[-54.653,47.076],[-54.589,47.118],[-54.4465,47.157],[-54.3905,47.136],[-54.479,47.01],[-54.4965,46.95],[-54.5035,46.838],[-54.481,46.754],[-54.411,46.685],[-54.3145,46.637],[-54.1965,46.608],[-54.066,46.6],[-53.9305,46.623],[-53.895,46.555],[-53.8125,46.484],[-53.6985,46.434],[-53.625,46.418],[-53.5155,46.419],[-53.353,46.458],[-53.2085,46.429],[-53.09,46.436],[-52.9255,46.491],[-52.876,46.526],[-52.7565,46.645],[-52.69,46.723],[-52.6395,46.813],[-52.631,46.865],[-52.5795,46.997],[-52.5685,47.08],[-52.542,47.119],[-52.4565,47.297],[-52.3655,47.4],[-52.3275,47.49],[-52.328,47.56],[-52.373,47.694],[-52.4535,47.836],[-52.558,47.939],[-52.6,47.966],[-52.5265,48.035],[-52.5015,48.101],[-52.506,48.187],[-52.531,48.245],[-52.638,48.328],[-52.795,48.361],[-52.722,48.484],[-52.715,48.602],[-52.748,48.704],[-52.794,48.767],[-52.879,48.839],[-52.9435,48.872],[-53.0355,48.895],[-53.157,48.895],[-53.3005,48.848],[-53.3095,48.894],[-53.273,49.014],[-53.2005,49.126],[-53.1655,49.24],[-53.172,49.3],[-53.2285,49.384],[-53.272,49.419],[-53.4785,49.518],[-53.46,49.626],[-53.5055,49.702],[-53.581,49.754],[-53.6955,49.788],[-53.7705,49.793],[-53.919,49.902],[-54.0225,49.936],[-54.202,49.946],[-54.4465,49.895],[-54.5995,49.896],[-54.6745,49.88],[-54.8775,49.878],[-54.981,49.849],[-55.0435,49.813],[-55.1105,49.744],[-55.3005,49.741],[-55.1925,49.879],[-55.172,49.991],[-55.1945,50.045],[-55.498,50.358],[-55.638,50.419],[-55.718,50.431],[-55.989,50.427],[-55.9525,50.477],[-55.8665,50.539],[-55.6845,50.505],[-55.5395,50.496],[-55.4595,50.508],[-55.3355,50.559],[-55.2445,50.626],[-55.195,50.681],[-55.153,50.789],[-55.1785,50.877],[-55.234,50.931],[-55.2365,51.007],[-55.283,51.087],[-55.3575,51.14],[-55.32,51.191],[-55.2335,51.247],[-55.1795,51.321],[-55.0985,51.539],[-55.098,51.669],[-55.1365,51.73],[-55.0665,51.787],[-54.967,51.93],[-54.9555,52.044],[-55.0225,52.131],[-55.134,52.186],[-55.258,52.207],[-55.2475,52.265],[-55.294,52.367],[-55.2995,52.475],[-55.373,52.571],[-55.421,52.713],[-55.471,52.809],[-55.4075,53.043],[-55.407,53.123],[-55.3635,53.219],[-55.3735,53.295],[-55.4195,53.378],[-55.3865,53.464],[-55.391,53.534],[-55.4325,53.608],[-55.5445,53.683],[-55.571,53.749],[-55.6675,53.831],[-55.805,53.875],[-55.911,53.883],[-56.017,53.873],[-56.056,53.91],[-56.298,54.079],[-56.477,54.138],[-56.6135,54.14],[-56.7815,54.092],[-56.7845,54.186],[-56.8355,54.263],[-56.681,54.31],[-56.5795,54.398],[-56.564,54.496],[-56.63,54.586],[-56.5325,54.69],[-56.525,54.74],[-56.5615,54.821],[-56.6875,54.902],[-56.8785,54.933],[-57.0275,54.913],[-57.308,54.835],[-57.485,54.857],[-57.5565,54.978],[-57.6545,55.052],[-57.772,55.095],[-57.9315,55.122],[-58.045,55.174],[-58.15,55.203],[-58.402,55.251],[-58.4905,55.345],[-58.568,55.38],[-58.6745,55.403],[-58.8905,55.423],[-59.017,55.424],[-59.085,55.462],[-59.2175,55.501],[-59.3085,55.509],[-59.478,55.565],[-59.5765,55.652],[-59.6795,55.69],[-59.7755,55.705],[-59.7965,55.775],[-59.8515,55.832],[-59.939,55.879],[-60.017,55.969],[-60.0985,56.009],[-60.282,56.045],[-60.3935,56.139],[-60.3315,56.251],[-60.374,56.353],[-60.4505,56.407],[-60.5275,56.438],[-60.5335,56.496],[-60.58,56.562],[-60.5205,56.728],[-60.527,56.792],[-60.587,56.868],[-60.7685,57.007],[-60.828,57.04],[-60.9785,57.082],[-60.9655,57.15],[-60.9905,57.21],[-61.0915,57.293],[-61.11,57.333],[-61.0485,57.417],[-60.9675,57.482],[-60.9365,57.56],[-60.986,57.668],[-61.0425,57.708],[-61.18,57.766],[-61.279,57.794],[-61.263,57.9],[-61.277,57.964],[-61.3545,58.045],[-61.4335,58.085],[-61.5465,58.114],[-61.7435,58.119],[-61.7095,58.209],[-61.7735,58.315],[-61.9005,58.382],[-62.044,58.409],[-62.1015,58.469],[-62.1895,58.519],[-62.214,58.561],[-62.3245,58.666],[-62.472,58.738],[-62.5555,58.902],[-62.7405,59.032],[-62.747,59.084],[-62.8125,59.162],[-62.9695,59.232],[-63.0215,59.352],[-63.104,59.415],[-63.295,59.525],[-63.424,59.646],[-63.509,59.692],[-63.554,59.811],[-63.687,59.952],[-63.748,59.995],[-63.77,60.077],[-63.81,60.127],[-63.8785,60.281],[-63.9365,60.343],[-64.0225,60.388],[-64.175,60.724],[-64.334,61.2815],[-64.163,61.441],[-64.1235,61.495],[-64.132,61.587],[-64.2765,61.8075],[-64.0545,62.192],[-63.743,62.408],[-63.3925,62.653],[-63.3305,62.7195],[-63.257,62.8675],[-63.2465,62.9205],[-63.455,63.4645],[-63.4725,63.629],[-63.4935,63.6805],[-63.7065,63.971],[-63.821,64.1115],[-63.9625,64.2535],[-62.9225,64.7355],[-62.82,64.807],[-62.52,65.17],[-61.7935,65.493],[-61.6925,65.5595],[-61.6435,65.6295],[-61.4755,65.9395],[-61.0395,66.254],[-60.9985,66.2915],[-60.779,66.563],[-60.7605,66.639],[-60.844,66.769],[-61.313,67.0535],[-61.6905,67.243],[-62.1325,67.388],[-62.2575,67.4165],[-62.785,67.4995],[-63.5445,67.7805],[-64.3085,68.1075],[-64.679,68.2165],[-65.366,68.3585],[-66.093,68.6415],[-66.1,69.2455],[-66.1385,69.329],[-66.5465,69.794],[-66.6425,69.909],[-66.6595,70.0085],[-66.784,70.1265],[-66.894,70.1725],[-67.1175,70.2975],[-67.2545,70.3435],[-67.6735,70.606],[-67.8675,70.6965],[-68.088,70.7645],[-68.501,70.8325],[-68.6935,70.8825],[-68.8715,70.946],[-69.4575,71.0365],[-70.3575,71.2675],[-70.5755,71.3445],[-70.7685,71.4825],[-70.956,71.5795],[-71.2315,71.668],[-71.5885,71.7375],[-71.9165,71.7735],[-72.208,71.8295],[-72.43,71.8565],[-72.9355,71.885],[-73.143,71.923],[-73.695,72.19],[-74.193,72.3645],[-74.447,72.4175],[-74.5095,72.54],[-74.687,72.632],[-75.026,72.6945],[-75.3755,72.913],[-75.4265,73.0155],[-75.568,73.076],[-75.5715,73.125],[-75.665,73.1995],[-75.8795,73.2675],[-76.0445,73.3955],[-76.2305,73.476],[-76.439,73.5135],[-76.505,73.5735],[-76.7535,73.669],[-77.102,73.733],[-77.3255,73.7555],[-77.7345,73.839],[-77.923,73.862],[-78.274,73.872],[-78.945,73.864],[-79.2375,73.8445],[-79.335,73.8565],[-79.452,74.5295],[-78.98,74.6665],[-78.6955,74.769],[-78.5845,74.8285],[-78.5595,74.912],[-78.709,75.196],[-78.655,75.2935],[-78.697,75.35],[-78.068,75.7735],[-78.016,75.841],[-78.0055,76.0245],[-77.6055,76.377],[-77.368,76.475],[-77.0865,76.548],[-76.949,76.6275],[-76.871,76.7995],[-76.9085,76.885],[-77.1165,77.038],[-77.2705,77.347],[-77.0605,77.453],[-75.252,77.8075],[-75.055,77.8565],[-74.726,77.976],[-74.6715,78.0285],[-74.155,78.2395],[-73.8875,78.3835],[-73.7165,78.4765],[-73.5015,78.5555],[-73.11,78.754],[-73.362,79.081],[-73.449,79.1355],[-72.372,79.388],[-71.504,79.5045],[-70.9685,79.5345],[-70.259,79.6475],[-70.0965,79.6885],[-69.8155,79.807],[-68.713,80.183],[-68.647,80.2245],[-68.335,80.416],[-67.1205,80.749],[-66.2685,80.834],[-64.1855,81.2995],[-62.1625,81.8675],[-59.995,82.2175],[-59.6265,82.2995],[-59.646,82.3965],[-59.8905,82.5055],[-60.267,82.5885],[-62.253,82.9475],[-62.806,83.006],[-64.148,83.0885],[-64.54,83.1045],[-66.2235,83.1425],[-69.0405,83.2955],[-69.7645,83.311],[-71.4855,83.3],[-73.953,83.335],[-74.3235,83.335],[-77.1625,83.286],[-77.4615,83.2765],[-80.77,83.1155],[-82.39,82.983],[-86.676,82.621],[-87.103,82.5595],[-87.962,82.356],[-88.778,82.277],[-91.2055,82.125],[-91.7335,82.064],[-92.7695,81.8605],[-95.2835,81.4715],[-95.5205,81.416],[-96.4145,81.081],[-97.2605,80.746],[-97.438,80.5795],[-97.5495,80.514],[-99.7445,80.372],[-100.4285,80.313],[-102.829,80.017],[-106.1455,79.546],[-107.6465,79.3935],[-110.008,79.1295],[-111.3205,78.969],[-112.77,78.789],[-113.1865,78.725],[-113.718,78.6265],[-114.7045,78.513],[-115.02,78.4535],[-115.852,78.2],[-116.259,78.006],[-116.633,77.9035],[-116.8755,77.79],[-117.3265,77.7255],[-117.717,77.696],[-118.5525,77.595],[-119.025,77.568],[-119.643,77.496],[-119.878,77.451],[-120.47,77.284],[-121.9,76.864],[-122.718,76.6095],[-123.3535,76.535],[-123.6085,76.4885],[-123.775,76.4185],[-123.8135,76.3615],[-123.8205,76.223],[-123.9045,76.0795],[-123.897,76.014],[-123.798,75.936],[-123.6,75.8645],[-124.517,75.1865],[-125.3745,74.4895],[-125.55,74.4545],[-125.766,74.363],[-125.7845,74.2485],[-125.694,74.191],[-125.3015,74.019],[-125.267,73.938],[-125.4135,73.76],[-125.415,73.673],[-125.234,73.569],[-125.0205,73.522],[-125.1995,73.379],[-125.2285,73.3155],[-125.3495,73.271],[-125.5325,73.16],[-125.723,72.976],[-125.858,72.9095],[-125.895,72.8305],[-125.7655,72.725],[-125.806,72.668],[-125.931,72.631],[-126.034,72.5725],[-126.1215,72.401],[-126.289,72.316],[-126.3305,72.2455],[-126.437,72.1645],[-126.4455,72.1275],[-126.6025,72.0485],[-127.3685,71.6125],[-128.0355,71.2135],[-128.7405,70.771],[-130.03,70.452],[-130.4955,70.4075],[-130.785,70.4025],[-131.001,70.3685],[-131.1905,70.315],[-131.806,70.1095],[-132.5705,69.9395],[-132.8235,69.911],[-133.452,69.787],[-133.883,69.9255],[-134.0575,69.964],[-134.3345,69.9865],[-134.643,69.965],[-135.132,69.8825],[-135.6485,69.8305],[-135.852,69.793],[-136.258,69.626],[-136.33,69.5875],[-136.588,69.403],[-138.033,69.4815],[-138.3845,69.698],[-138.6575,69.7905],[-138.956,69.8325],[-139.1665,69.838],[-140.1795,69.8055],[-140.3555,69.79],[-140.5285,69.801],[-140.873,69.8405],[-141.0025,69.846],[-141.0005,69.419],[-141.001,68.8115],[-141.001,68.095],[-141.001,67.5985],[-141.001,66.8875],[-141.0015,66.179],[-141.0015,65.494],[-141.0015,64.992],[-141.0015,64.543],[-141.0015,63.9315],[-141.0015,63.5185],[-141.0015,63.022],[-141.0015,62.615],[-141.0015,62.224],[-141.0015,61.597],[-141.002,61.249],[-141.002,60.8185],[-141.002,60.3065],[-140.769,60.26],[-140.5205,60.22],[-140.458,60.308],[-139.981,60.182],[-139.693,60.335],[-139.075,60.3525],[-139.072,60.3195],[-139.199,60.0885],[-139.0535,59.995],[-138.7075,59.9065],[-138.6685,59.8095],[-138.626,59.7685],[-137.6075,59.244],[-137.542,59.1065],[-137.5,58.9855],[-137.526,58.9065],[-137.4515,58.9085],[-137.283,59.0],[-136.9695,59.101],[-136.8285,59.16],[-136.5845,59.166],[-136.469,59.284],[-136.477,59.466],[-136.368,59.449],[-136.305,59.4645],[-136.2385,59.5245],[-136.24,59.5595],[-136.3465,59.6005],[-136.193,59.64],[-135.9525,59.662],[-135.479,59.798],[-135.253,59.6985],[-135.1575,59.6255],[-135.029,59.5635],[-135.0275,59.4745],[-135.101,59.4275],[-134.9895,59.387],[-135.0305,59.3465],[-134.96,59.281],[-134.7005,59.249],[-134.679,59.1925],[-134.5655,59.131],[-134.4835,59.1315],[-134.382,59.039],[-134.407,58.979],[-134.3135,58.962],[-134.3365,58.9235],[-134.258,58.861],[-133.8405,58.7295],[-133.707,58.6125],[-133.558,58.523],[-133.3775,58.4305],[-133.4615,58.3875],[-133.3455,58.2765],[-133.1725,58.1535],[-133.07,58.0005],[-132.8695,57.8395],[-132.751,57.696],[-132.661,57.6165],[-132.5535,57.4965],[-132.37,57.3495],[-132.248,57.2115],[-132.369,57.0915],[-132.045,57.045],[-132.1235,56.8735],[-131.873,56.806],[-131.901,56.7535],[-131.8605,56.703],[-131.8355,56.599],[-131.581,56.612],[-131.472,56.5525],[-131.1735,56.4495],[-131.0875,56.406],[-130.782,56.367],[-130.6235,56.267],[-130.468,56.243],[-130.426,56.1415],[-130.246,56.0965],[-130.104,56.123],[-130.0035,56.008],[-130.0175,55.912],[-130.0835,55.8215],[-130.1525,55.7665],[-130.1115,55.683],[-130.128,55.581],[-130.09,55.498],[-130.041,55.4515],[-130.021,55.338],[-129.974,55.282],[-130.103,55.1925],[-130.1875,55.063],[-130.2735,54.974],[-130.346,54.9175],[-130.568,54.792],[-130.659,54.763],[-130.6155,54.7075],[-131.435,54.6895]]],[[[-133.527,53.937],[-133.509,53.867],[-133.4565,53.803],[-133.42,53.699],[-133.3355,53.602],[-133.338,53.506],[-133.2915,53.438],[-133.2335,53.388],[-133.0955,53.309],[-133.0765,53.247],[-132.9975,53.145],[-132.9175,53.091],[-132.894,53.027],[-132.8415,52.965],[-132.736,52.888],[-132.667,52.855],[-132.4735,52.669],[-132.2025,52.499],[-132.161,52.461],[-132.012,52.369],[-131.91,52.324],[-131.8685,52.254],[-131.659,52.08],[-131.477,51.962],[-131.287,51.815],[-131.1645,51.761],[-131.0845,51.744],[-130.955,51.744],[-130.857,51.767],[-130.7615,51.819],[-130.723,51.859],[-130.629,52.012],[-130.61,52.094],[-130.6815,52.266],[-130.714,52.312],[-130.907,52.457],[-130.9455,52.536],[-131.0505,52.654],[-131.1515,52.804],[-131.1645,52.92],[-131.195,52.97],[-131.277,53.038],[-131.329,53.167],[-131.438,53.265],[-131.484,53.34],[-131.576,53.412],[-131.5965,53.518],[-131.588,53.585],[-131.5445,53.65],[-131.5295,53.741],[-131.457,53.815],[-131.37,53.933],[-131.31,54.143],[-131.331,54.247],[-131.368,54.287],[-131.476,54.345],[-131.572,54.367],[-131.708,54.369],[-131.861,54.33],[-131.9695,54.252],[-132.02,54.238],[-132.085,54.268],[-132.2445,54.308],[-132.428,54.302],[-132.5545,54.342],[-132.6755,54.35],[-132.7905,54.415],[-132.8565,54.436],[-132.9975,54.455],[-133.12,54.451],[-133.2775,54.405],[-133.375,54.336],[-133.407,54.278],[-133.4295,54.082],[-133.518,53.985],[-133.527,53.937]]],[[[-60.442,43.9835],[-60.425,43.908],[-60.3735,43.845],[-60.2875,43.791],[-60.119,43.7375],[-60.0255,43.7265],[-59.901,43.7255],[-59.7395,43.7485],[-59.6455,43.781],[-59.4395,43.912],[-59.3855,43.971],[-59.364,44.0325],[-59.374,44.106],[-59.416,44.168],[-59.4845,44.2155],[-59.6075,44.2485],[-59.732,44.239],[-59.809,44.2095],[-59.9315,44.137],[-59.9955,44.1355],[-60.0725,44.1655],[-60.218,44.1735],[-60.3135,44.146],[-60.3885,44.0955],[-60.433,44.029],[-60.442,43.9835]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/cf/Flag_of_Canada.svg","name:en":"Canada","wikidata":"Q16","ISO3166-1:alpha2":"CA","ISO3166-1:alpha3":"CAN","ISO3166-1:numeric":"124"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-82.1245,12.1245],[-81.9155,11.9625],[-81.867,11.9485],[-81.77,11.957],[-81.7105,11.9845],[-81.6395,12.0625],[-81.6255,12.127],[-81.638,12.198],[-81.43,12.1995],[-81.3595,12.2235],[-81.295,12.279],[-81.261,12.334],[-81.2455,12.4025],[-81.252,12.4655],[-81.2985,12.5665],[-81.366,12.642],[-81.429,12.672],[-81.498,12.6805],[-81.5345,12.7455],[-81.594,12.798],[-81.6665,12.8265],[-81.743,12.827],[-81.812,12.8015],[-81.869,12.752],[-81.9325,12.643],[-81.9485,12.558],[-81.942,12.4585],[-81.9215,12.407],[-82.0335,12.3425],[-82.096,12.252],[-82.1245,12.1245]]],[[[-81.8155,3.977],[-81.7985,3.9105],[-81.7335,3.831],[-81.684,3.8045],[-81.616,3.7925],[-81.5475,3.8045],[-81.462,3.86],[-81.418,3.9275],[-81.4025,4.005],[-81.4135,4.074],[-81.453,4.145],[-81.54,4.204],[-81.633,4.214],[-81.696,4.1945],[-81.749,4.156],[-81.8095,4.046],[-81.8155,3.977]]],[[[-81.624,13.376],[-81.618,13.278],[-81.573,13.181],[-81.518,13.1325],[-81.4465,13.105],[-81.3655,13.103],[-81.286,13.1245],[-81.2125,13.1735],[-81.171,13.223],[-81.142,13.286],[-81.1295,13.386],[-81.103,13.493],[-81.119,13.5955],[-81.1585,13.654],[-81.216,13.6955],[-81.3235,13.728],[-81.3915,13.723],[-81.485,13.675],[-81.5315,13.617],[-81.5515,13.5585],[-81.5995,13.483],[-81.624,13.376]]],[[[-81.368,14.307],[-81.3535,14.209],[-81.3545,14.1405],[-81.3225,14.042],[-81.282,13.9875],[-81.2205,13.946],[-81.13,13.9255],[-81.059,13.9345],[-80.9865,13.9735],[-80.928,14.052],[-80.9115,14.126],[-80.917,14.1875],[-80.8735,14.3035],[-80.876,14.483],[-80.889,14.547],[-80.9255,14.6125],[-80.976,14.6565],[-81.038,14.682],[-81.109,14.687],[-81.1785,14.667],[-81.2375,14.625],[-81.29,14.5505],[-81.3245,14.483],[-81.353,14.3925],[-81.368,14.307]]],[[[-80.504,14.2915],[-80.495,14.2205],[-80.463,14.1525],[-80.423,14.111],[-80.304,14.064],[-80.223,14.0685],[-80.135,14.1175],[-80.0745,14.2055],[-80.063,14.276],[-80.022,14.2985],[-79.966,14.375],[-79.9495,14.4475],[-79.966,14.5445],[-80.0215,14.619],[-80.0825,14.6555],[-80.163,14.6725],[-80.255,14.6575],[-80.321,14.6175],[-80.3655,14.56],[-80.445,14.4815],[-80.504,14.2915]]],[[[-80.3,13.5685],[-80.287,13.499],[-80.233,13.381],[-80.1755,13.3205],[-80.1105,13.289],[-80.011,13.2825],[-79.9195,13.3225],[-79.8665,13.38],[-79.845,13.4225],[-79.83,13.5015],[-79.841,13.577],[-79.871,13.6375],[-79.9425,13.7165],[-80.019,13.761],[-80.1115,13.7715],[-80.1805,13.753],[-80.239,13.713],[-80.2885,13.635],[-80.3,13.5685]]],[[[-79.9675,15.835],[-79.9595,15.7725],[-79.933,15.7145],[-79.891,15.6665],[-79.8365,15.6315],[-79.774,15.6125],[-79.7085,15.6115],[-79.6455,15.6285],[-79.5895,15.6615],[-79.546,15.7085],[-79.5175,15.7655],[-79.5075,15.828],[-79.5155,15.8905],[-79.542,15.948],[-79.584,15.9965],[-79.6385,16.0315],[-79.701,16.05],[-79.7665,16.051],[-79.83,16.0345],[-79.8855,16.001],[-79.929,15.954],[-79.9575,15.8975],[-79.9675,15.835]]],[[[-71.147,12.5235],[-71.2105,12.5575],[-71.47,12.637],[-71.663,12.6655],[-71.7315,12.653],[-71.8155,12.62],[-72.2235,12.427],[-74.289,11.525],[-74.895,11.31],[-74.975,11.2735],[-75.3785,10.968],[-75.504,10.8805],[-75.6585,10.711],[-75.695,10.655],[-75.9665,10.2885],[-75.9845,10.2585],[-76.345,9.5365],[-77.272,8.976],[-77.3245,8.8105],[-77.3705,8.661],[-77.448,8.5465],[-77.4475,8.4725],[-77.412,8.475],[-77.3555,8.387],[-77.3495,8.296],[-77.247,8.1755],[-77.218,8.085],[-77.2135,8.0095],[-77.164,7.9705],[-77.1795,7.917],[-77.2535,7.92],[-77.3125,7.8975],[-77.364,7.825],[-77.3365,7.78],[-77.391,7.76],[-77.401,7.722],[-77.461,7.6565],[-77.491,7.567],[-77.519,7.5745],[-77.548,7.522],[-77.5835,7.5135],[-77.63,7.5945],[-77.645,7.6515],[-77.692,7.693],[-77.742,7.6795],[-77.7485,7.6165],[-77.7015,7.507],[-77.7745,7.46],[-77.818,7.4725],[-77.889,7.2285],[-78.0365,7.051],[-77.8785,6.711],[-77.6965,6.168],[-77.7485,5.4845],[-77.73,4.257],[-78.343,3.1005],[-78.3915,3.045],[-78.6045,2.698],[-78.621,2.6635],[-78.6765,2.6245],[-78.763,2.525],[-78.8045,2.452],[-78.8535,2.292],[-79.2115,1.73],[-79.232,1.687],[-79.2375,1.574],[-79.2075,1.5075],[-79.174,1.4695],[-78.8685,1.4695],[-78.7995,1.4245],[-78.7795,1.392],[-78.71,1.359],[-78.615,1.246],[-78.5525,1.2505],[-78.4885,1.186],[-78.437,1.1905],[-78.417,1.1605],[-78.3115,1.191],[-78.2765,1.109],[-78.282,1.056],[-78.202,0.997],[-78.1855,0.938],[-78.1245,0.9365],[-78.0675,0.8955],[-77.9845,0.8535],[-77.936,0.8165],[-77.8685,0.802],[-77.8195,0.8085],[-77.7745,0.8415],[-77.713,0.8505],[-77.6635,0.812],[-77.698,0.7415],[-77.548,0.649],[-77.4915,0.662],[-77.481,0.6045],[-77.522,0.5195],[-77.521,0.4165],[-77.421,0.436],[-77.412,0.409],[-77.3265,0.3885],[-77.302,0.3675],[-77.2145,0.363],[-77.178,0.3905],[-77.1135,0.3725],[-77.078,0.2855],[-77.011,0.294],[-76.985,0.266],[-76.9445,0.269],[-76.905,0.2455],[-76.8475,0.239],[-76.7975,0.2645],[-76.769,0.243],[-76.733,0.2885],[-76.6255,0.262],[-76.5825,0.2295],[-76.533,0.2585],[-76.504,0.2365],[-76.411,0.2425],[-76.412,0.38],[-76.3345,0.387],[-76.314,0.434],[-76.2615,0.427],[-76.1785,0.372],[-76.129,0.368],[-76.1205,0.324],[-76.0565,0.333],[-76.009,0.3005],[-75.952,0.2015],[-75.8615,0.1345],[-75.8145,0.075],[-75.7525,0.037],[-75.667,0.0455],[-75.469,-0.05],[-75.427,-0.087],[-75.3665,-0.091],[-75.258,-0.116],[-75.2095,-0.046],[-75.162,-0.0445],[-75.1315,-0.0705],[-75.0775,-0.082],[-75.012,-0.1485],[-74.9725,-0.155],[-74.931,-0.2215],[-74.8835,-0.2435],[-74.845,-0.231],[-74.7935,-0.189],[-74.7615,-0.2235],[-74.729,-0.2985],[-74.732,-0.334],[-74.676,-0.3655],[-74.6115,-0.351],[-74.544,-0.419],[-74.537,-0.4585],[-74.487,-0.4885],[-74.4195,-0.504],[-74.4245,-0.55],[-74.3865,-0.555],[-74.374,-0.6535],[-74.338,-0.6775],[-74.37,-0.737],[-74.318,-0.778],[-74.2655,-0.8415],[-74.2795,-0.899],[-74.262,-0.941],[-74.2725,-0.979],[-74.2255,-1.0085],[-74.1725,-1.0055],[-74.126,-1.0325],[-74.027,-1.0615],[-74.006,-1.099],[-73.958,-1.131],[-73.904,-1.1245],[-73.8955,-1.1695],[-73.853,-1.2335],[-73.674,-1.2405],[-73.6195,-1.264],[-73.611,-1.3185],[-73.5815,-1.346],[-73.531,-1.4375],[-73.491,-1.4835],[-73.4905,-1.571],[-73.463,-1.589],[-73.5165,-1.64],[-73.5385,-1.7005],[-73.466,-1.735],[-73.4325,-1.7875],[-73.3775,-1.776],[-73.3345,-1.802],[-73.3,-1.7775],[-73.252,-1.7805],[-73.212,-1.752],[-73.1945,-1.7885],[-73.1465,-1.8055],[-73.1505,-1.863],[-73.11,-1.877],[-73.1115,-1.95],[-73.1295,-1.9945],[-73.092,-2.0415],[-73.1135,-2.072],[-73.0705,-2.1055],[-73.1165,-2.1305],[-73.1255,-2.173],[-73.173,-2.195],[-73.155,-2.2585],[-73.096,-2.324],[-73.0435,-2.3575],[-73.003,-2.3605],[-72.9315,-2.418],[-72.8575,-2.4395],[-72.777,-2.3855],[-72.735,-2.424],[-72.6865,-2.4205],[-72.6065,-2.3625],[-72.5765,-2.3935],[-72.38,-2.453],[-72.3685,-2.491],[-72.2985,-2.4745],[-72.2595,-2.432],[-72.227,-2.447],[-72.129,-2.4095],[-72.06,-2.343],[-72.0055,-2.3705],[-71.9695,-2.3675],[-71.927,-2.3085],[-71.872,-2.2965],[-71.829,-2.1875],[-71.718,-2.1665],[-71.713,-2.23],[-71.6375,-2.202],[-71.599,-2.239],[-71.4675,-2.272],[-71.392,-2.355],[-71.3535,-2.3795],[-71.266,-2.377],[-71.231,-2.336],[-71.1935,-2.3825],[-71.1715,-2.3745],[-71.1435,-2.297],[-71.046,-2.265],[-70.978,-2.2125],[-70.9415,-2.2555],[-70.898,-2.224],[-70.8635,-2.226],[-70.843,-2.2855],[-70.768,-2.298],[-70.7615,-2.3205],[-70.6615,-2.363],[-70.674,-2.4105],[-70.626,-2.4075],[-70.6425,-2.4585],[-70.601,-2.4845],[-70.472,-2.454],[-70.4445,-2.512],[-70.4115,-2.526],[-70.354,-2.49],[-70.3335,-2.578],[-70.2675,-2.5455],[-70.229,-2.5815],[-70.219,-2.6455],[-70.1565,-2.647],[-70.1605,-2.691],[-70.1145,-2.697],[-70.0675,-2.6755],[-70.061,-2.7595],[-70.0805,-2.795],[-70.3355,-3.1975],[-70.713,-3.7955],[-70.6505,-3.8305],[-70.5605,-3.827],[-70.5235,-3.88],[-70.4535,-3.863],[-70.415,-3.828],[-70.3475,-3.8005],[-70.284,-3.824],[-70.2475,-3.8965],[-70.1805,-3.9305],[-70.161,-3.9875],[-70.1265,-4.035],[-70.062,-4.0825],[-70.0405,-4.125],[-69.9695,-4.1955],[-69.948,-4.2315],[-69.9335,-4.2195],[-69.836,-3.686],[-69.714,-3.0025],[-69.613,-2.44],[-69.535,-2.003],[-69.4505,-1.53],[-69.4565,-1.491],[-69.4325,-1.454],[-69.436,-1.402],[-69.3975,-1.365],[-69.407,-1.29],[-69.43,-1.235],[-69.397,-1.1145],[-69.4425,-1.034],[-69.4725,-0.9575],[-69.5295,-0.9175],[-69.5265,-0.8675],[-69.573,-0.8385],[-69.574,-0.81],[-69.622,-0.733],[-69.563,-0.6405],[-69.6015,-0.5965],[-69.591,-0.561],[-69.6085,-0.5045],[-69.6675,-0.4655],[-69.736,-0.4375],[-69.7735,-0.3915],[-69.8435,-0.3385],[-69.888,-0.3415],[-70.043,-0.19],[-70.043,0.069],[-70.047,0.26],[-70.047,0.563],[-69.935,0.553],[-69.9155,0.5795],[-69.8095,0.5765],[-69.6875,0.664],[-69.6335,0.6365],[-69.483,0.733],[-69.415,0.688],[-69.349,0.618],[-69.298,0.649],[-69.2705,0.602],[-69.213,0.61],[-69.1945,0.65],[-69.118,0.6555],[-69.19,0.7405],[-69.149,0.7675],[-69.1815,0.9025],[-69.207,0.965],[-69.1975,0.998],[-69.2585,1.054],[-69.321,1.0885],[-69.3825,1.0735],[-69.4875,1.079],[-69.5735,1.073],[-69.61,1.0985],[-69.703,1.075],[-69.7015,1.1175],[-69.746,1.1135],[-69.816,1.063],[-69.8425,1.0725],[-69.843,1.715],[-69.809,1.695],[-69.7445,1.7295],[-69.655,1.7175],[-69.534,1.7765],[-69.4825,1.751],[-69.391,1.7295],[-68.735,1.731],[-68.1865,1.73],[-68.178,1.7675],[-68.2445,1.7835],[-68.2375,1.8215],[-68.2855,1.836],[-68.245,1.9195],[-68.1845,1.986],[-68.1495,1.9825],[-68.096,1.903],[-68.0335,1.891],[-67.9885,1.849],[-67.9435,1.843],[-67.9015,1.8115],[-67.889,1.8645],[-67.8365,1.9025],[-67.835,1.947],[-67.762,2.014],[-67.729,2.029],[-67.6215,2.0275],[-67.551,2.0475],[-67.497,2.161],[-67.449,2.1695],[-67.4405,2.2155],[-67.3735,2.217],[-67.351,2.16],[-67.358,2.0965],[-67.3255,2.0545],[-67.351,2.012],[-67.346,1.974],[-67.3085,1.9085],[-67.2285,1.8415],[-67.154,1.8315],[-67.146,1.762],[-67.16,1.735],[-67.155,1.665],[-67.1275,1.64],[-67.128,1.543],[-67.0855,1.4635],[-67.083,1.373],[-67.134,1.344],[-67.135,1.3],[-67.0995,1.2585],[-67.087,1.167],[-66.851,1.229],[-66.881,1.2905],[-66.8555,1.3215],[-66.854,1.3675],[-66.913,1.4335],[-66.9075,1.4875],[-66.959,1.625],[-67.033,1.7865],[-67.0355,1.8455],[-67.0655,1.9205],[-67.123,1.977],[-67.097,2.0515],[-67.1145,2.1335],[-67.1615,2.133],[-67.2205,2.2505],[-67.2135,2.3095],[-67.188,2.3505],[-67.216,2.3925],[-67.2975,2.4425],[-67.352,2.5295],[-67.3935,2.5745],[-67.4705,2.624],[-67.5195,2.673],[-67.5685,2.666],[-67.563,2.723],[-67.584,2.7735],[-67.6215,2.814],[-67.6585,2.7965],[-67.735,2.817],[-67.7505,2.8375],[-67.824,2.826],[-67.864,2.7895],[-67.8645,2.866],[-67.435,3.2485],[-67.3825,3.2455],[-67.3815,3.2925],[-67.3345,3.3355],[-67.312,3.391],[-67.339,3.451],[-67.4015,3.48],[-67.412,3.539],[-67.444,3.585],[-67.439,3.6325],[-67.483,3.712],[-67.5015,3.7675],[-67.61,3.754],[-67.644,3.813],[-67.6445,3.8525],[-67.69,3.9365],[-67.7035,4.0395],[-67.742,4.139],[-67.7725,4.1655],[-67.797,4.2295],[-67.8055,4.315],[-67.773,4.419],[-67.798,4.437],[-67.8035,4.4895],[-67.857,4.5245],[-67.839,4.562],[-67.845,4.645],[-67.818,4.707],[-67.8235,4.84],[-67.8375,4.947],[-67.806,5.055],[-67.8545,5.138],[-67.8265,5.1915],[-67.8235,5.247],[-67.8495,5.304],[-67.797,5.3605],[-67.683,5.427],[-67.625,5.476],[-67.599,5.544],[-67.619,5.564],[-67.639,5.653],[-67.631,5.7325],[-67.597,5.828],[-67.527,5.9085],[-67.412,5.9885],[-67.4275,6.038],[-67.456,6.0585],[-67.4945,6.131],[-67.457,6.1935],[-67.535,6.26],[-67.584,6.262],[-67.6255,6.2915],[-67.7215,6.3005],[-67.769,6.294],[-67.811,6.324],[-67.845,6.3125],[-67.9245,6.2405],[-67.9775,6.2085],[-68.0415,6.198],[-68.101,6.232],[-68.2545,6.1975],[-68.2975,6.1655],[-68.3735,6.186],[-68.446,6.1875],[-68.5135,6.176],[-68.5335,6.1515],[-68.597,6.1635],[-68.6445,6.129],[-68.7065,6.152],[-68.7925,6.1475],[-68.8345,6.18],[-68.886,6.168],[-68.974,6.1965],[-69.017,6.194],[-69.0435,6.2215],[-69.123,6.1915],[-69.1775,6.1475],[-69.2375,6.08],[-69.312,6.0905],[-69.3355,6.1375],[-69.4305,6.108],[-69.763,6.528],[-70.118,6.9795],[-70.2245,6.9745],[-70.2935,6.934],[-70.344,6.9445],[-70.3715,6.98],[-70.4305,7.007],[-70.503,7.006],[-70.549,7.0745],[-70.6085,7.064],[-70.697,7.094],[-70.8395,7.079],[-70.927,7.0465],[-70.995,6.983],[-71.1115,6.99],[-71.131,7.033],[-71.1915,7.019],[-71.2675,7.0325],[-71.379,7.018],[-71.4295,7.038],[-71.459,7.0135],[-71.4915,7.031],[-71.593,7.031],[-71.633,7.056],[-71.656,7.0365],[-71.7145,7.0345],[-71.746,7.0655],[-71.811,7.0635],[-71.835,7.0255],[-71.941,7.0095],[-72.0475,7.039],[-72.174,7.252],[-72.156,7.33],[-72.1965,7.382],[-72.4395,7.4035],[-72.442,7.446],[-72.4765,7.4895],[-72.4525,7.563],[-72.476,7.629],[-72.47,7.789],[-72.4445,7.858],[-72.487,7.945],[-72.425,7.99],[-72.411,8.0345],[-72.3505,8.004],[-72.351,8.0805],[-72.371,8.094],[-72.367,8.185],[-72.392,8.256],[-72.382,8.3045],[-72.393,8.3585],[-72.4275,8.3815],[-72.6105,8.5785],[-72.655,8.6145],[-72.698,8.8065],[-72.719,8.9345],[-72.767,9.1065],[-72.881,9.133],[-72.8865,9.1035],[-72.9475,9.0915],[-72.973,9.1365],[-72.962,9.1845],[-73.011,9.2915],[-73.0735,9.243],[-73.1315,9.2285],[-73.1775,9.1765],[-73.248,9.1595],[-73.3475,9.1735],[-73.2655,9.3265],[-73.241,9.403],[-73.19,9.4445],[-73.2035,9.4675],[-73.128,9.5545],[-73.0855,9.556],[-73.055,9.6785],[-73.0055,9.741],[-72.994,9.783],[-72.9455,9.8375],[-72.971,9.855],[-72.999,9.924],[-72.953,10.0265],[-72.9545,10.065],[-72.9115,10.1125],[-72.9215,10.138],[-72.8975,10.2175],[-72.9065,10.353],[-72.8935,10.4465],[-72.8455,10.486],[-72.8205,10.57],[-72.735,10.6515],[-72.689,10.757],[-72.674,10.8215],[-72.64,10.8845],[-72.575,10.915],[-72.485,11.0615],[-72.4845,11.099],[-72.3495,11.1515],[-72.2455,11.145],[-71.9715,11.6465],[-71.7825,11.687],[-71.644,11.734],[-71.3835,11.8105],[-71.345,11.848],[-70.927,11.961],[-70.927,12.1575],[-71.0135,12.2345],[-71.0615,12.315],[-71.08,12.402],[-71.147,12.5235]]],[[[-78.9045,15.828],[-78.884,15.7435],[-78.8315,15.673],[-78.755,15.627],[-78.666,15.613],[-78.621,15.6185],[-78.539,15.6545],[-78.4775,15.7175],[-78.4455,15.799],[-78.4485,15.8855],[-78.4855,15.9645],[-78.5515,16.0235],[-78.6355,16.054],[-78.7255,16.0515],[-78.808,16.016],[-78.8695,15.9525],[-78.9015,15.8715],[-78.9045,15.828]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/21/Flag_of_Colombia.svg","name:en":"Colombia","wikidata":"Q739","ISO3166-1:alpha2":"CO","ISO3166-1:alpha3":"COL","ISO3166-1:numeric":"170"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-89.356,14.4205],[-89.3895,14.449],[-89.4295,14.415],[-89.574,14.417],[-89.588,14.346],[-89.5605,14.3125],[-89.523,14.2245],[-89.667,14.1855],[-89.714,14.138],[-89.746,14.0635],[-89.776,14.0345],[-89.8165,14.063],[-89.8915,14.0435],[-89.9615,13.9705],[-90.023,13.939],[-90.113,13.824],[-90.118,13.789],[-90.179,13.6345],[-89.9515,13.5375],[-89.9085,13.4595],[-89.8445,13.399],[-89.7215,13.402],[-89.5525,13.3625],[-89.333,13.343],[-88.8005,13.1085],[-88.4025,13.0285],[-88.2535,13.041],[-88.149,13.041],[-87.94,12.9935],[-87.9015,12.976],[-87.811,13.055],[-87.72,13.109],[-87.663,13.1275],[-87.635,13.1975],[-87.678,13.235],[-87.739,13.3245],[-87.7435,13.349],[-87.799,13.3815],[-87.7905,13.414],[-87.723,13.4435],[-87.722,13.506],[-87.792,13.5265],[-87.7555,13.603],[-87.7545,13.691],[-87.7085,13.804],[-87.7465,13.854],[-87.831,13.9185],[-87.854,13.8945],[-87.9625,13.8975],[-88.0125,13.8715],[-88.063,13.9435],[-88.0725,13.9925],[-88.16,13.9835],[-88.23,14.0],[-88.227,13.938],[-88.2655,13.937],[-88.3175,13.89],[-88.417,13.8845],[-88.452,13.859],[-88.4925,13.8625],[-88.5055,13.9085],[-88.5,13.967],[-88.569,13.978],[-88.6075,14.0055],[-88.709,14.0465],[-88.7375,14.131],[-88.799,14.1645],[-88.831,14.108],[-88.8665,14.1785],[-88.9025,14.2055],[-88.97,14.212],[-88.9925,14.259],[-89.026,14.2725],[-89.0355,14.332],[-89.083,14.3415],[-89.109,14.4085],[-89.1685,14.366],[-89.216,14.389],[-89.356,14.4205]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/34/Flag_of_El_Salvador.svg","name:en":"El Salvador","wikidata":"Q792","ISO3166-1:alpha2":"SV","ISO3166-1:alpha3":"SLV","ISO3166-1:numeric":"222"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-89.152,17.8155],[-89.151,17.4485],[-89.15,17.0575],[-89.1735,16.7115],[-89.2085,16.1795],[-89.2275,15.896],[-89.103,15.9125],[-89.022,15.9115],[-88.9575,15.8885],[-88.7705,15.9585],[-88.686,16.051],[-88.4985,16.07],[-88.2465,16.3725],[-88.145,16.417],[-88.147,16.622],[-88.11,16.779],[-88.019,16.913],[-87.9325,17.057],[-87.6315,17.008],[-87.427,17.063],[-87.359,17.129],[-87.3205,17.237],[-87.31,17.5055],[-87.453,17.632],[-87.7055,17.739],[-87.9605,17.753],[-87.9105,17.868],[-87.84,17.9545],[-87.809,18.031],[-87.744,18.1165],[-87.868,18.198],[-87.91,18.1505],[-87.9325,18.1675],[-88.031,18.1675],[-88.0305,18.415],[-88.2495,18.4155],[-88.25,18.473],[-88.3275,18.4905],[-88.4435,18.48],[-88.478,18.4935],[-88.517,18.464],[-88.548,18.355],[-88.606,18.2915],[-88.6155,18.2235],[-88.6735,18.194],[-88.7185,18.108],[-88.7165,18.061],[-88.767,18.016],[-88.8165,17.9495],[-88.8575,17.9245],[-88.9205,17.916],[-88.9455,17.9525],[-88.993,17.9595],[-89.0375,18.005],[-89.1325,17.9685],[-89.152,17.9395],[-89.152,17.8155]]],[[[-87.891,16.7245],[-87.8665,16.7075],[-87.7675,16.7545],[-87.736,16.803],[-87.6965,16.9165],[-87.7965,16.9235],[-87.8455,16.8395],[-87.891,16.7245]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/e/e7/Flag_of_Belize.svg","name:en":"Belize","wikidata":"Q242","ISO3166-1:alpha2":"BZ","ISO3166-1:alpha3":"BLZ","ISO3166-1:numeric":"084"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-72.0315,19.9245],[-72.125,19.936],[-72.251,19.9335],[-72.456,20.071],[-72.6845,20.1955],[-72.8425,20.218],[-73.229,20.0675],[-73.497,19.966],[-73.6715,19.8755],[-73.728,19.7005],[-73.664,19.547],[-73.4805,19.415],[-73.221,19.4285],[-73.117,19.444],[-72.944,19.3715],[-72.9595,19.19],[-73.021,19.071],[-73.283,19.106],[-73.3545,19.0805],[-73.446,18.9725],[-73.446,18.869],[-73.3435,18.7635],[-73.4335,18.693],[-73.775,18.7585],[-74.135,18.8195],[-74.446,18.765],[-74.5505,18.705],[-74.618,18.6425],[-74.6575,18.4225],[-74.589,18.247],[-74.476,18.182],[-74.381,18.1365],[-74.2025,18.175],[-74.0145,17.9535],[-73.928,17.91],[-73.772,17.91],[-73.6905,17.966],[-73.618,17.9955],[-73.5335,17.9985],[-73.476,18.0735],[-73.494,18.163],[-73.352,18.117],[-73.1675,18.102],[-72.8885,18.041],[-72.2635,18.09],[-72.098,18.107],[-71.977,18.091],[-71.8295,17.954],[-71.744,18.053],[-71.745,18.137],[-71.7835,18.17],[-71.768,18.2205],[-71.696,18.3405],[-71.83,18.399],[-71.844,18.429],[-71.9045,18.457],[-71.881,18.504],[-71.9815,18.612],[-71.9665,18.6565],[-71.8445,18.629],[-71.807,18.6355],[-71.804,18.6855],[-71.738,18.722],[-71.722,18.804],[-71.725,18.8755],[-71.768,18.907],[-71.783,18.9485],[-71.8355,18.97],[-71.771,19.0315],[-71.723,19.0535],[-71.6525,19.139],[-71.631,19.1835],[-71.639,19.2315],[-71.691,19.239],[-71.7405,19.277],[-71.778,19.3345],[-71.712,19.3715],[-71.6795,19.434],[-71.7135,19.552],[-71.743,19.5845],[-71.7455,19.634],[-71.7735,19.7315],[-71.804,19.733],[-71.914,19.7965],[-72.0315,19.9245]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/5/56/Flag_of_Haiti.svg","name:en":"Haiti","wikidata":"Q790","ISO3166-1:alpha2":"HT","ISO3166-1:alpha3":"HTI","ISO3166-1:numeric":"332"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-57.015,6.225],[-57.045,6.271],[-57.1465,6.374],[-57.2805,6.469],[-57.349,6.502],[-57.432,6.523],[-57.4775,6.579],[-57.684,6.776],[-57.8825,6.946],[-57.94,6.982],[-58.0545,7.02],[-58.1415,7.027],[-58.2685,7.144],[-58.2795,7.224],[-58.2745,7.32],[-58.2835,7.376],[-58.3135,7.452],[-58.5305,7.737],[-58.6375,7.804],[-58.7135,7.896],[-58.7915,7.962],[-58.866,8.051],[-58.9895,8.179],[-59.0555,8.229],[-59.3805,8.423],[-59.5,8.483],[-59.6515,8.574],[-59.7705,8.604],[-59.955,8.5405],[-59.981,8.5185],[-59.815,8.3115],[-59.8015,8.275],[-59.8485,8.225],[-59.946,8.2135],[-59.995,8.154],[-60.006,8.06],[-60.066,8.024],[-60.1005,8.0355],[-60.1835,7.9645],[-60.219,7.9575],[-60.2455,7.913],[-60.333,7.8415],[-60.405,7.821],[-60.4375,7.836],[-60.4995,7.834],[-60.563,7.761],[-60.57,7.7035],[-60.618,7.6425],[-60.6605,7.5645],[-60.7045,7.56],[-60.7055,7.4955],[-60.614,7.395],[-60.588,7.3145],[-60.6155,7.2985],[-60.638,7.246],[-60.6245,7.211],[-60.5585,7.1545],[-60.4495,7.205],[-60.4205,7.1765],[-60.367,7.185],[-60.2935,7.1335],[-60.2875,7.0875],[-60.3205,7.0215],[-60.3665,6.998],[-60.4015,6.948],[-60.461,6.9245],[-60.5005,6.882],[-60.5555,6.856],[-60.6635,6.8295],[-60.7185,6.7555],[-60.8095,6.794],[-60.846,6.7805],[-60.895,6.811],[-60.9235,6.807],[-60.9095,6.747],[-60.9555,6.7155],[-61.013,6.7285],[-61.0855,6.7045],[-61.1385,6.7215],[-61.183,6.671],[-61.2195,6.566],[-61.1725,6.5195],[-61.1825,6.472],[-61.1525,6.4575],[-61.148,6.413],[-61.1755,6.327],[-61.126,6.262],[-61.142,6.215],[-61.1795,6.187],[-61.2095,6.112],[-61.2745,6.105],[-61.312,6.052],[-61.331,5.999],[-61.392,5.944],[-61.0845,5.599],[-60.749,5.2225],[-60.7375,5.202],[-60.682,5.232],[-60.614,5.219],[-60.569,5.196],[-60.527,5.208],[-60.434,5.182],[-60.384,5.222],[-60.313,5.211],[-60.2195,5.269],[-60.183,5.2275],[-60.132,5.225],[-60.106,5.194],[-60.094,5.14],[-59.9825,5.0825],[-59.9795,5.0155],[-60.0135,4.843],[-60.026,4.7055],[-60.0755,4.6555],[-60.07,4.618],[-60.1235,4.605],[-60.161,4.5175],[-60.071,4.4935],[-60.0015,4.495],[-59.971,4.5095],[-59.911,4.4765],[-59.805,4.466],[-59.735,4.4235],[-59.6755,4.3465],[-59.732,4.286],[-59.7305,4.181],[-59.685,4.147],[-59.6195,4.133],[-59.6425,4.0675],[-59.602,4.03],[-59.5865,3.9755],[-59.5265,3.969],[-59.523,3.932],[-59.593,3.8855],[-59.5775,3.832],[-59.5955,3.7955],[-59.6655,3.7815],[-59.6685,3.703],[-59.7425,3.66],[-59.7655,3.626],[-59.8505,3.6045],[-59.859,3.571],[-59.802,3.493],[-59.84,3.4435],[-59.805,3.357],[-59.8815,3.259],[-59.8745,3.229],[-59.9125,3.195],[-59.9015,3.1605],[-59.9555,3.082],[-59.9475,3.003],[-59.984,2.9295],[-59.9935,2.7825],[-59.991,2.683],[-59.978,2.642],[-59.93,2.5655],[-59.8935,2.4645],[-59.905,2.3755],[-59.7805,2.2855],[-59.741,2.293],[-59.72,2.237],[-59.7405,2.1795],[-59.723,2.0985],[-59.7425,2.068],[-59.73,2.0305],[-59.745,1.929],[-59.746,1.852],[-59.691,1.854],[-59.678,1.807],[-59.69,1.757],[-59.632,1.741],[-59.617,1.716],[-59.566,1.736],[-59.493,1.674],[-59.483,1.627],[-59.447,1.62],[-59.431,1.567],[-59.378,1.521],[-59.339,1.519],[-59.253,1.389],[-59.048,1.323],[-58.918,1.317],[-58.904,1.251],[-58.8545,1.1835],[-58.821,1.171],[-58.7395,1.2],[-58.71,1.2835],[-58.6285,1.2885],[-58.5885,1.27],[-58.496,1.268],[-58.471,1.3195],[-58.47,1.371],[-58.505,1.403],[-58.5085,1.463],[-58.3855,1.47],[-58.3935,1.52],[-58.317,1.5685],[-58.1605,1.56],[-58.1295,1.499],[-58.061,1.5255],[-58.0055,1.517],[-57.9785,1.573],[-57.981,1.6595],[-57.927,1.645],[-57.895,1.6745],[-57.8,1.685],[-57.7925,1.7265],[-57.705,1.731],[-57.6505,1.6825],[-57.6295,1.6985],[-57.553,1.6925],[-57.4975,1.767],[-57.451,1.8065],[-57.432,1.8585],[-57.4335,1.906],[-57.3675,1.9235],[-57.3455,1.9805],[-57.277,1.983],[-57.2555,1.9505],[-57.12,2.01],[-57.071,1.9965],[-57.071,1.9685],[-57.0005,1.9075],[-56.9195,1.9305],[-56.8935,1.8995],[-56.774,1.869],[-56.721,1.926],[-56.651,1.917],[-56.6215,1.946],[-56.58,1.906],[-56.469,1.949],[-56.537,2.0085],[-56.586,2.028],[-56.691,2.026],[-56.7265,2.0865],[-56.821,2.211],[-56.8265,2.2655],[-56.886,2.302],[-56.8855,2.3575],[-56.9345,2.397],[-56.93,2.436],[-56.9895,2.5025],[-56.997,2.5555],[-57.023,2.583],[-57.018,2.6345],[-57.0605,2.6715],[-57.103,2.7345],[-57.089,2.766],[-57.1465,2.7825],[-57.2085,2.8525],[-57.226,2.956],[-57.2045,3.0255],[-57.221,3.076],[-57.2465,3.088],[-57.2905,3.1815],[-57.2945,3.2785],[-57.279,3.3245],[-57.3,3.384],[-57.358,3.358],[-57.4275,3.361],[-57.4735,3.3385],[-57.5205,3.3645],[-57.5975,3.3415],[-57.6465,3.361],[-57.6655,3.401],[-57.637,3.4555],[-57.6565,3.5235],[-57.7065,3.556],[-57.755,3.623],[-57.821,3.653],[-57.8455,3.6895],[-57.849,3.741],[-57.876,3.8095],[-57.957,3.9205],[-58.0435,3.998],[-58.049,4.079],[-58.071,4.1595],[-58.034,4.217],[-57.9535,4.288],[-57.9585,4.4035],[-57.928,4.441],[-57.877,4.574],[-57.8445,4.6335],[-57.844,4.682],[-57.8905,4.772],[-57.9245,4.8165],[-57.844,4.9245],[-57.776,4.921],[-57.746,4.9675],[-57.688,5.0105],[-57.608,4.992],[-57.5495,5.004],[-57.476,4.991],[-57.4105,4.993],[-57.3515,5.0155],[-57.3005,5.1385],[-57.299,5.1735],[-57.251,5.1855],[-57.23,5.1365],[-57.183,5.168],[-57.227,5.262],[-57.2515,5.2765],[-57.2925,5.2405],[-57.2915,5.3215],[-57.327,5.351],[-57.2695,5.4035],[-57.2705,5.464],[-57.1985,5.553],[-57.1735,5.5995],[-57.1605,5.6995],[-57.183,5.74],[-57.1675,5.8095],[-57.135,5.8935],[-57.1435,5.989],[-57.1625,6.0515],[-57.0785,6.0845],[-57.032,6.1695],[-57.015,6.225]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/99/Flag_of_Guyana.svg","name:en":"Guyana","wikidata":"Q734","ISO3166-1:alpha2":"GY","ISO3166-1:alpha3":"GUY","ISO3166-1:numeric":"328"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-62.5535,16.8995],[-62.509,16.806],[-62.4475,16.7575],[-62.14,17.0155],[-62.1785,17.078],[-62.268,17.136],[-62.3305,17.147],[-62.5535,16.8995]]],[[[-61.9615,16.8375],[-61.899,16.815],[-61.7765,16.799],[-61.654,16.818],[-61.56,16.874],[-61.5195,16.911],[-61.463,16.994],[-61.4505,17.102],[-61.5075,17.217],[-61.582,17.296],[-61.625,17.326],[-61.6365,17.366],[-61.5835,17.403],[-61.5255,17.508],[-61.5255,17.646],[-61.5485,17.72],[-61.5805,17.772],[-61.643,17.84],[-61.7565,17.911],[-61.8685,17.928],[-61.935,17.911],[-62.0025,17.871],[-62.066,17.802],[-62.0965,17.704],[-62.0705,17.6],[-62.06,17.522],[-62.0335,17.47],[-61.9815,17.419],[-61.8695,17.371],[-61.979,17.331],[-62.022,17.297],[-62.0955,17.19],[-62.123,17.098],[-62.109,17.0055],[-61.9615,16.8375]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/89/Flag_of_Antigua_and_Barbuda.svg","name:en":"Antigua and Barbuda","wikidata":"Q781","ISO3166-1:alpha2":"AG","ISO3166-1:alpha3":"ATG","ISO3166-1:numeric":"028"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-78.773,22.8685],[-79.3055,23.023],[-79.672,23.131],[-80.2245,23.404],[-80.3035,23.4265],[-80.876,23.4815],[-81.109,23.4665],[-81.6885,23.4135],[-81.9965,23.3855],[-82.238,23.3805],[-82.316,23.373],[-82.4215,23.3455],[-83.2595,23.1915],[-83.6655,23.096],[-83.707,23.082],[-84.109,22.8985],[-84.22,22.8585],[-84.317,22.803],[-84.384,22.743],[-84.5755,22.6525],[-84.6205,22.623],[-84.819,22.448],[-84.9175,22.3325],[-84.9485,22.2435],[-85.1185,22.008],[-85.1505,21.946],[-85.168,21.8665],[-85.1565,21.797],[-85.108,21.715],[-85.018,21.65],[-84.952,21.629],[-84.822,21.611],[-84.555,21.5575],[-84.457,21.5575],[-84.3705,21.577],[-84.0465,21.689],[-83.566,21.469],[-83.168,21.2865],[-83.1095,21.269],[-82.933,21.2405],[-82.82,21.2435],[-82.203,21.273],[-82.17,21.2765],[-81.725,21.3625],[-81.488,21.3955],[-81.0725,21.4275],[-80.623,21.421],[-79.956,21.4115],[-79.7315,21.105],[-79.5995,20.9695],[-79.546,20.9305],[-79.452,20.882],[-79.179,20.7065],[-79.06,20.6245],[-78.82,20.4795],[-78.7785,20.46],[-78.4605,20.3495],[-77.9135,19.7095],[-77.814,19.644],[-77.7025,19.6275],[-77.522,19.6445],[-77.3965,19.646],[-77.31,19.6565],[-77.123,19.69],[-77.016,19.6845],[-76.927,19.6935],[-76.7465,19.736],[-76.346,19.7545],[-76.194,19.7785],[-76.0295,19.7555],[-75.8825,19.761],[-75.641,19.696],[-75.5465,19.6825],[-75.3445,19.6765],[-75.1415,19.6895],[-74.991,19.708],[-74.923,19.727],[-74.2665,19.8675],[-74.147,19.9015],[-74.092,19.941],[-73.9885,20.0425],[-73.943,20.109],[-73.926,20.1575],[-73.9245,20.2575],[-73.9495,20.3325],[-73.99,20.391],[-74.0705,20.4635],[-74.5665,20.7455],[-74.618,20.7865],[-74.809,20.872],[-75.5115,21.2445],[-75.61,21.301],[-75.667,21.322],[-76.28,21.4575],[-77.008,21.8225],[-77.215,22.033],[-77.5715,22.2585],[-77.6295,22.292],[-77.8015,22.42],[-78.1155,22.596],[-78.213,22.6425],[-78.4825,22.7535],[-78.773,22.8685]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/bd/Flag_of_Cuba.svg","name:en":"Cuba","wikidata":"Q241","ISO3166-1:alpha2":"CU","ISO3166-1:alpha3":"CUB","ISO3166-1:numeric":"192"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-10.28,8.485],[-10.2265,8.4805],[-10.12,8.5345],[-10.043,8.489],[-10.038,8.4285],[-9.9895,8.4455],[-9.9235,8.496],[-9.806,8.5015],[-9.7755,8.55],[-9.725,8.5255],[-9.734,8.472],[-9.6635,8.5015],[-9.62,8.453],[-9.6575,8.405],[-9.5675,8.4095],[-9.5525,8.382],[-9.497,8.3735],[-9.507,8.3295],[-9.489,8.2655],[-9.512,8.2415],[-9.494,8.1755],[-9.441,8.084],[-9.4055,8.0495],[-9.4375,7.988],[-9.432,7.8595],[-9.3785,7.809],[-9.349,7.7465],[-9.3745,7.6915],[-9.359,7.613],[-9.3785,7.5885],[-9.4205,7.484],[-9.468,7.43],[-9.3845,7.394],[-9.3605,7.4335],[-9.2955,7.4275],[-9.286,7.377],[-9.2025,7.386],[-9.203,7.3185],[-9.072,7.202],[-9.026,7.2465],[-8.9705,7.253],[-8.93,7.2885],[-8.872,7.257],[-8.8375,7.2765],[-8.8535,7.347],[-8.81,7.4045],[-8.7095,7.5135],[-8.723,7.5575],[-8.7065,7.6445],[-8.6765,7.6955],[-8.554,7.696],[-8.559,7.626],[-8.471,7.557],[-8.407,7.6235],[-8.3545,7.5875],[-8.308,7.612],[-8.2185,7.5385],[-8.1705,7.5845],[-8.185,7.608],[-8.143,7.662],[-8.0955,7.7975],[-8.1245,7.835],[-8.135,7.883],[-8.0685,8.002],[-8.0625,8.0365],[-7.9945,8.047],[-7.95,8.0325],[-7.995,8.124],[-7.9975,8.198],[-8.062,8.157],[-8.1005,8.182],[-8.1735,8.185],[-8.24,8.2345],[-8.2175,8.2965],[-8.215,8.358],[-8.238,8.4155],[-8.189,8.5065],[-8.111,8.4835],[-8.063,8.511],[-7.9755,8.4895],[-7.908,8.4905],[-7.9075,8.4405],[-7.865,8.424],[-7.8285,8.44],[-7.798,8.4855],[-7.742,8.3785],[-7.65,8.378],[-7.6765,8.4415],[-7.659,8.4985],[-7.6955,8.557],[-7.6715,8.618],[-7.692,8.6495],[-7.7325,8.659],[-7.7615,8.731],[-7.809,8.7685],[-7.911,8.7745],[-7.9485,8.7885],[-7.9745,8.831],[-7.9375,8.849],[-7.9395,8.9025],[-7.9165,8.9355],[-7.9345,8.982],[-7.8565,9.0325],[-7.8405,9.066],[-7.7825,9.106],[-7.85,9.179],[-7.8825,9.1615],[-7.9195,9.221],[-7.875,9.298],[-7.882,9.3395],[-7.8495,9.4215],[-7.9165,9.422],[-7.975,9.3985],[-8.036,9.3965],[-8.0845,9.44],[-8.1295,9.5105],[-8.144,9.5925],[-8.1155,9.651],[-8.1255,9.6785],[-8.0955,9.8085],[-8.095,9.8635],[-8.1605,9.9315],[-8.121,10.05],[-8.032,10.091],[-7.9795,10.1705],[-7.945,10.2525],[-7.985,10.3435],[-8.071,10.341],[-8.105,10.3935],[-8.1005,10.4495],[-8.1825,10.415],[-8.2305,10.4195],[-8.246,10.5135],[-8.2875,10.5955],[-8.325,10.5905],[-8.32,10.674],[-8.2885,10.6985],[-8.2895,10.758],[-8.3295,10.7715],[-8.3035,10.818],[-8.306,10.8565],[-8.26,10.8915],[-8.2785,10.994],[-8.3425,11.0625],[-8.481,11.0715],[-8.5115,10.999],[-8.5795,10.9605],[-8.665,10.953],[-8.675,11.0035],[-8.6345,11.039],[-8.601,11.0955],[-8.6045,11.1305],[-8.559,11.138],[-8.5505,11.2115],[-8.4735,11.2315],[-8.4655,11.29],[-8.391,11.276],[-8.3535,11.3155],[-8.404,11.332],[-8.372,11.3885],[-8.498,11.4165],[-8.52,11.484],[-8.601,11.4755],[-8.655,11.523],[-8.6415,11.548],[-8.7015,11.6455],[-8.751,11.6245],[-8.849,11.6545],[-8.82,11.781],[-8.7985,11.8285],[-8.772,11.977],[-8.8285,12.0395],[-8.8625,12.0305],[-8.9065,12.0575],[-8.9115,12.0945],[-8.8835,12.1515],[-8.918,12.1975],[-8.971,12.1925],[-8.9885,12.239],[-8.9335,12.325],[-9.007,12.396],[-9.0145,12.4205],[-9.0835,12.441],[-9.135,12.48],[-9.25,12.506],[-9.284,12.4855],[-9.3555,12.5015],[-9.3795,12.4305],[-9.302,12.367],[-9.3185,12.281],[-9.3735,12.2505],[-9.4225,12.2645],[-9.4845,12.257],[-9.5325,12.199],[-9.572,12.1975],[-9.6465,12.1685],[-9.683,12.1185],[-9.6885,12.0345],[-9.7445,12.0305],[-9.8295,12.057],[-9.872,12.058],[-9.914,12.104],[-9.968,12.103],[-10.091,12.1695],[-10.149,12.1765],[-10.1925,12.2055],[-10.342,12.223],[-10.3585,12.178],[-10.396,12.1825],[-10.41,12.145],[-10.453,12.12],[-10.513,12.126],[-10.5265,12.0375],[-10.5795,12.025],[-10.5675,11.9895],[-10.609,11.9745],[-10.634,11.906],[-10.7075,11.909],[-10.7735,11.9475],[-10.765,11.9715],[-10.8015,12.0415],[-10.792,12.1155],[-10.841,12.1305],[-10.9225,12.2255],[-10.9855,12.2155],[-11.0475,12.2215],[-11.0735,12.137],[-11.1755,12.024],[-11.225,11.998],[-11.311,12.024],[-11.3585,12.0665],[-11.367,12.1075],[-11.4545,12.134],[-11.493,12.179],[-11.4955,12.2135],[-11.4305,12.283],[-11.4365,12.3825],[-11.377,12.4125],[-11.476,12.4525],[-11.668,12.426],[-11.686,12.405],[-11.77,12.382],[-11.805,12.4035],[-11.8445,12.3925],[-11.9,12.449],[-11.968,12.4055],[-12.0105,12.4015],[-12.0595,12.433],[-12.118,12.4135],[-12.1775,12.3605],[-12.302,12.3505],[-12.3565,12.315],[-12.403,12.385],[-12.486,12.4045],[-12.565,12.3665],[-12.6265,12.436],[-12.765,12.4335],[-12.752,12.467],[-12.845,12.495],[-12.895,12.554],[-12.942,12.5375],[-12.9445,12.4755],[-13.0615,12.485],[-13.0465,12.5755],[-13.0515,12.6255],[-13.1385,12.645],[-13.2185,12.6515],[-13.332,12.645],[-13.345,12.6585],[-13.4835,12.674],[-13.708,12.6755],[-13.7095,12.608],[-13.6715,12.52],[-13.6415,12.49],[-13.6365,12.433],[-13.666,12.3905],[-13.6565,12.324],[-13.687,12.308],[-13.718,12.249],[-13.7645,12.275],[-13.851,12.2825],[-13.857,12.2425],[-13.916,12.2355],[-13.9495,12.1595],[-13.876,12.137],[-13.868,12.108],[-13.8065,12.0885],[-13.762,12.03],[-13.6965,12.008],[-13.7125,11.8805],[-13.7055,11.8325],[-13.708,11.7075],[-13.772,11.682],[-13.856,11.705],[-13.872,11.6605],[-13.918,11.68],[-13.9885,11.6415],[-14.039,11.655],[-14.081,11.6275],[-14.135,11.6645],[-14.267,11.677],[-14.3195,11.6025],[-14.4505,11.537],[-14.5115,11.4965],[-14.6635,11.505],[-14.69,11.483],[-14.7725,11.3645],[-14.8375,11.2025],[-14.936,11.0265],[-14.9575,10.977],[-15.002,10.9555],[-15.074,10.892],[-15.1015,10.8845],[-15.3415,10.6665],[-15.562,10.6665],[-15.563,10.5685],[-15.537,10.509],[-15.495,10.461],[-15.4395,10.4285],[-15.377,10.415],[-15.313,10.4215],[-15.233,10.462],[-15.187,10.507],[-15.1575,10.5655],[-15.1485,10.6295],[-15.078,10.589],[-14.9865,10.57],[-14.9145,10.573],[-14.871,10.531],[-14.8615,10.425],[-14.8095,10.318],[-14.7655,10.282],[-14.6835,10.253],[-14.6745,10.199],[-14.6315,10.111],[-14.5755,10.048],[-14.474,10.009],[-14.408,10.011],[-14.247,9.871],[-14.1575,9.841],[-14.0605,9.794],[-13.9955,9.748],[-13.939,9.667],[-13.995,9.605],[-14.034,9.525],[-14.0405,9.439],[-14.008,9.352],[-13.957,9.292],[-13.8615,9.241],[-13.7655,9.233],[-13.688,9.249],[-13.634,9.279],[-13.608,9.171],[-13.5795,9.132],[-13.521,9.088],[-13.518,9.028],[-13.496,8.966],[-13.301,9.036],[-13.2755,9.063],[-13.185,9.095],[-13.141,9.0565],[-13.082,9.0485],[-13.0735,9.08],[-13.0015,9.1165],[-12.9715,9.227],[-12.9415,9.2905],[-12.907,9.262],[-12.8795,9.2935],[-12.807,9.29],[-12.7855,9.3035],[-12.7555,9.392],[-12.684,9.417],[-12.654,9.54],[-12.6175,9.604],[-12.5875,9.6015],[-12.5645,9.7025],[-12.5285,9.717],[-12.471,9.85],[-12.4355,9.881],[-12.2225,9.933],[-12.2175,9.909],[-12.12,9.8725],[-11.907,9.94],[-11.8945,10.0],[-11.208,10.0],[-11.1725,9.961],[-11.1575,9.868],[-11.096,9.8575],[-11.039,9.7875],[-10.993,9.7525],[-10.964,9.664],[-10.918,9.655],[-10.911,9.602],[-10.881,9.5915],[-10.8365,9.4395],[-10.815,9.39],[-10.7315,9.3795],[-10.7085,9.332],[-10.6635,9.3105],[-10.667,9.1995],[-10.722,9.187],[-10.731,9.0815],[-10.6675,9.0855],[-10.574,9.0445],[-10.5905,8.9775],[-10.559,8.8445],[-10.562,8.818],[-10.52,8.7825],[-10.511,8.7425],[-10.466,8.674],[-10.4925,8.6255],[-10.5765,8.596],[-10.616,8.542],[-10.641,8.4745],[-10.6425,8.3545],[-10.5775,8.334],[-10.556,8.3055],[-10.491,8.35],[-10.478,8.3765],[-10.3995,8.4495],[-10.386,8.488],[-10.322,8.506],[-10.28,8.485]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/e/ed/Flag_of_Guinea.svg","name:en":"Guinea","wikidata":"Q1006","ISO3166-1:alpha2":"GN","ISO3166-1:alpha3":"GIN","ISO3166-1:numeric":"324"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-7.527,4.162],[-7.4095,4.1715],[-7.3365,4.196],[-7.1015,4.332],[-6.981,4.3535],[-6.915,4.3865],[-6.8,4.481],[-6.672,4.492],[-6.555,4.533],[-6.486,4.581],[-6.38,4.6055],[-6.3285,4.6325],[-6.1225,4.7],[-5.9785,4.775],[-5.798,4.842],[-5.5555,4.882],[-5.1835,4.924],[-4.745,4.955],[-4.524,4.988],[-4.232,5.0175],[-4.0265,5.0435],[-3.9295,5.041],[-3.8485,5.013],[-3.758,4.994],[-3.541,4.9675],[-3.358,4.937],[-3.1485,4.896],[-3.1035,5.086],[-3.1105,5.1185],[-3.0685,5.1345],[-2.97,5.1035],[-2.9485,5.127],[-2.8075,5.1065],[-2.7275,5.1325],[-2.7745,5.261],[-2.766,5.317],[-2.724,5.343],[-2.724,5.388],[-2.749,5.4375],[-2.768,5.5555],[-2.7615,5.6],[-2.864,5.6525],[-2.9365,5.6215],[-2.9665,5.6415],[-2.954,5.716],[-3.0265,5.709],[-3.02,5.857],[-3.074,5.985],[-3.1025,6.153],[-3.17,6.283],[-3.236,6.5415],[-3.2335,6.6015],[-3.259,6.6165],[-3.216,6.7255],[-3.2305,6.8235],[-3.0875,7.0525],[-3.032,7.072],[-3.024,7.142],[-2.953,7.2375],[-2.9755,7.27],[-2.97,7.3315],[-2.931,7.4945],[-2.922,7.612],[-2.831,7.82],[-2.791,7.8625],[-2.7815,7.952],[-2.7375,7.9475],[-2.6795,8.0205],[-2.6045,8.0305],[-2.626,8.102],[-2.6085,8.152],[-2.5515,8.1455],[-2.493,8.2065],[-2.4955,8.3025],[-2.5845,8.7865],[-2.623,8.8785],[-2.618,8.9215],[-2.652,8.9445],[-2.664,9.019],[-2.762,9.0375],[-2.773,9.1435],[-2.7255,9.17],[-2.7175,9.2015],[-2.664,9.24],[-2.7205,9.333],[-2.68,9.3625],[-2.687,9.4915],[-2.758,9.4115],[-2.824,9.451],[-2.9265,9.5685],[-3.0055,9.743],[-3.0565,9.7255],[-3.09,9.765],[-3.092,9.81],[-3.193,9.885],[-3.2335,9.8975],[-3.272,9.8465],[-3.345,9.9015],[-3.4065,9.93],[-3.5975,9.937],[-3.638,9.956],[-3.6675,9.9285],[-3.7755,9.927],[-3.81,9.9015],[-3.896,9.9055],[-3.9125,9.883],[-3.9675,9.875],[-3.995,9.831],[-4.051,9.803],[-4.127,9.847],[-4.189,9.774],[-4.2475,9.7645],[-4.287,9.6695],[-4.2935,9.6185],[-4.3405,9.625],[-4.4,9.6035],[-4.4305,9.664],[-4.505,9.647],[-4.521,9.6765],[-4.5025,9.7265],[-4.5835,9.695],[-4.651,9.7095],[-4.6875,9.6775],[-4.7455,9.7535],[-4.791,9.757],[-4.786,9.8355],[-4.9125,9.891],[-4.97,9.8985],[-4.964,9.9465],[-4.987,9.9885],[-4.96,10.0095],[-4.9735,10.0485],[-5.0185,10.101],[-5.0735,10.112],[-5.0615,10.181],[-5.1075,10.241],[-5.127,10.309],[-5.156,10.2865],[-5.2215,10.314],[-5.3685,10.2845],[-5.404,10.2965],[-5.462,10.3475],[-5.513,10.431],[-5.5625,10.464],[-5.621,10.452],[-5.6495,10.468],[-5.704,10.431],[-5.7655,10.439],[-5.8075,10.419],[-5.874,10.3555],[-5.874,10.3145],[-5.9015,10.263],[-5.9495,10.274],[-5.9845,10.1985],[-6.108,10.205],[-6.178,10.227],[-6.218,10.264],[-6.2305,10.305],[-6.1635,10.3665],[-6.181,10.4115],[-6.193,10.4975],[-6.242,10.5445],[-6.2105,10.569],[-6.246,10.74],[-6.3165,10.6855],[-6.395,10.709],[-6.415,10.698],[-6.3975,10.5985],[-6.4215,10.574],[-6.505,10.5795],[-6.59,10.623],[-6.6335,10.6735],[-6.669,10.6255],[-6.661,10.5885],[-6.682,10.528],[-6.6625,10.457],[-6.626,10.439],[-6.648,10.371],[-6.6785,10.3385],[-6.789,10.371],[-6.8675,10.344],[-6.945,10.3505],[-7.013,10.2425],[-6.977,10.2165],[-6.995,10.1725],[-7.049,10.148],[-7.0755,10.1965],[-7.1415,10.2495],[-7.2705,10.2595],[-7.3415,10.236],[-7.363,10.2745],[-7.3585,10.3345],[-7.421,10.342],[-7.4525,10.4015],[-7.4495,10.4445],[-7.514,10.4605],[-7.55,10.4125],[-7.626,10.462],[-7.718,10.3955],[-7.7215,10.3485],[-7.754,10.3415],[-7.8005,10.2445],[-7.8545,10.2005],[-7.8925,10.2],[-7.932,10.1545],[-7.9795,10.1705],[-8.032,10.091],[-8.121,10.05],[-8.1605,9.9315],[-8.095,9.8635],[-8.0955,9.8085],[-8.1255,9.6785],[-8.1155,9.651],[-8.144,9.5925],[-8.1295,9.5105],[-8.0845,9.44],[-8.036,9.3965],[-7.975,9.3985],[-7.9165,9.422],[-7.8495,9.4215],[-7.882,9.3395],[-7.875,9.298],[-7.9195,9.221],[-7.8825,9.1615],[-7.85,9.179],[-7.7825,9.106],[-7.8405,9.066],[-7.8565,9.0325],[-7.9345,8.982],[-7.9165,8.9355],[-7.9395,8.9025],[-7.9375,8.849],[-7.9745,8.831],[-7.9485,8.7885],[-7.911,8.7745],[-7.809,8.7685],[-7.7615,8.731],[-7.7325,8.659],[-7.692,8.6495],[-7.6715,8.618],[-7.6955,8.557],[-7.659,8.4985],[-7.6765,8.4415],[-7.65,8.378],[-7.742,8.3785],[-7.798,8.4855],[-7.8285,8.44],[-7.865,8.424],[-7.9075,8.4405],[-7.908,8.4905],[-7.9755,8.4895],[-8.063,8.511],[-8.111,8.4835],[-8.189,8.5065],[-8.238,8.4155],[-8.215,8.358],[-8.2175,8.2965],[-8.24,8.2345],[-8.1735,8.185],[-8.1005,8.182],[-8.062,8.157],[-7.9975,8.198],[-7.995,8.124],[-7.95,8.0325],[-7.9945,8.047],[-8.0625,8.0365],[-8.0685,8.002],[-8.135,7.883],[-8.1245,7.835],[-8.0955,7.7975],[-8.143,7.662],[-8.185,7.608],[-8.1705,7.5845],[-8.2185,7.5385],[-8.308,7.612],[-8.3545,7.5875],[-8.407,7.6235],[-8.471,7.557],[-8.423,7.528],[-8.3975,7.397],[-8.396,7.3285],[-8.36,7.278],[-8.365,7.2405],[-8.3315,7.203],[-8.288,7.1875],[-8.303,7.1355],[-8.2935,7.0255],[-8.326,6.972],[-8.3335,6.8915],[-8.3105,6.855],[-8.419,6.676],[-8.534,6.6],[-8.5695,6.5575],[-8.5715,6.523],[-8.482,6.434],[-8.4565,6.471],[-8.4055,6.447],[-8.385,6.386],[-8.334,6.373],[-8.1665,6.2795],[-8.0925,6.307],[-8.006,6.3225],[-7.9035,6.278],[-7.836,6.2045],[-7.852,6.1025],[-7.803,6.0935],[-7.7845,5.979],[-7.688,5.898],[-7.5865,5.8995],[-7.476,5.812],[-7.4305,5.8395],[-7.431,5.696],[-7.3755,5.613],[-7.3975,5.546],[-7.384,5.522],[-7.4195,5.4835],[-7.424,5.385],[-7.368,5.33],[-7.468,5.281],[-7.4825,5.2125],[-7.4705,5.1645],[-7.4835,5.1265],[-7.557,5.0755],[-7.5355,4.9585],[-7.55,4.924],[-7.592,4.908],[-7.5835,4.8335],[-7.5605,4.783],[-7.5625,4.649],[-7.548,4.612],[-7.5725,4.5815],[-7.5525,4.4885],[-7.567,4.4565],[-7.5655,4.3905],[-7.5295,4.3625],[-7.527,4.162]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/fe/Flag_of_C%C3%B4te_d%27Ivoire.svg","name:en":"Côte d'Ivoire","wikidata":"Q1008","ISO3166-1:alpha2":"CI","ISO3166-1:alpha3":"CIV","ISO3166-1:numeric":"384"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[0.912,10.996],[1.013,11.0875],[1.0275,11.0525],[1.101,11.068],[1.0745,11.132],[1.1925,11.2635],[1.284,11.266],[1.294,11.2985],[1.347,11.3065],[1.326,11.3525],[1.392,11.4115],[1.3955,11.453],[1.4745,11.471],[1.5835,11.447],[1.6015,11.3975],[1.7735,11.4195],[1.8725,11.446],[1.982,11.42],[2.0195,11.4275],[2.184,11.594],[2.3145,11.6795],[2.2985,11.716],[2.372,11.798],[2.3805,11.8575],[2.409,11.9025],[2.3975,11.91],[2.2055,12.1675],[2.0655,12.3475],[2.078,12.386],[2.118,12.387],[2.1615,12.4155],[2.2615,12.4145],[2.264,12.4735],[2.2255,12.5165],[2.221,12.5935],[2.201,12.631],[2.1545,12.6515],[2.146,12.691],[2.096,12.7255],[2.0385,12.7165],[1.989,12.731],[1.928,12.7005],[1.8685,12.6055],[1.5665,12.6115],[1.33,12.8315],[1.1595,13.0075],[0.974,13.0075],[0.992,13.1035],[0.992,13.3745],[1.115,13.3315],[1.1855,13.321],[1.283,13.3545],[1.2445,13.393],[1.2035,13.387],[1.124,13.4135],[1.0315,13.4625],[1.019,13.523],[0.977,13.57],[0.902,13.623],[0.833,13.625],[0.7745,13.644],[0.773,13.6885],[0.625,13.684],[0.598,13.731],[0.618,13.767],[0.526,13.8435],[0.465,13.9135],[0.473,13.951],[0.424,13.9835],[0.417,14.023],[0.381,14.051],[0.213,14.418],[0.169,14.522],[0.236,14.7355],[0.1965,14.8265],[0.2445,14.914],[0.232,15.0],[0.1295,14.978],[0.0615,14.9745],[-0.2455,15.079],[-0.39,15.004],[-0.4315,15.0835],[-0.724,15.084],[-1.069,14.785],[-1.093,14.785],[-1.3185,14.73],[-1.678,14.5015],[-1.7775,14.4825],[-1.907,14.4895],[-1.9805,14.4755],[-1.998,14.1915],[-2.1035,14.147],[-2.178,14.192],[-2.2975,14.249],[-2.4735,14.2995],[-2.589,14.216],[-2.6765,14.135],[-2.806,14.077],[-2.839,14.0545],[-2.836,13.993],[-2.8805,13.867],[-2.9065,13.821],[-2.9065,13.7335],[-2.874,13.654],[-2.9525,13.6245],[-3.0075,13.6545],[-3.0295,13.6145],[-3.108,13.689],[-3.247,13.682],[-3.2505,13.5855],[-3.278,13.5575],[-3.255,13.3655],[-3.234,13.289],[-3.3385,13.288],[-3.4375,13.2765],[-3.4225,13.1785],[-3.4635,13.156],[-3.5235,13.166],[-3.5875,13.201],[-3.6725,13.275],[-3.7225,13.2925],[-3.798,13.372],[-3.8195,13.3605],[-3.9135,13.3825],[-3.9595,13.473],[-4.053,13.407],[-4.1005,13.387],[-4.1075,13.3345],[-4.1405,13.2935],[-4.2075,13.2695],[-4.259,13.2335],[-4.34,13.143],[-4.346,13.114],[-4.275,13.0395],[-4.2645,12.99],[-4.2255,12.974],[-4.2155,12.92],[-4.226,12.866],[-4.209,12.8165],[-4.233,12.734],[-4.2675,12.7045],[-4.3245,12.7115],[-4.347,12.744],[-4.3995,12.7185],[-4.453,12.7165],[-4.4805,12.6585],[-4.4115,12.61],[-4.4025,12.5605],[-4.3645,12.533],[-4.419,12.487],[-4.439,12.4045],[-4.3965,12.3105],[-4.472,12.332],[-4.4715,12.286],[-4.569,12.2085],[-4.544,12.1415],[-4.6075,12.139],[-4.6285,12.1135],[-4.63,12.0595],[-4.7005,12.066],[-4.7405,11.999],[-4.843,12.0145],[-4.9275,12.005],[-5.127,11.957],[-5.1725,11.927],[-5.245,11.84],[-5.319,11.8415],[-5.3555,11.825],[-5.285,11.7765],[-5.2595,11.736],[-5.268,11.6765],[-5.294,11.617],[-5.24,11.6045],[-5.2,11.528],[-5.21,11.4575],[-5.1985,11.429],[-5.2425,11.3965],[-5.255,11.359],[-5.256,11.244],[-5.3265,11.201],[-5.343,11.1295],[-5.392,11.1025],[-5.4895,11.0815],[-5.452,10.976],[-5.4455,10.8945],[-5.4025,10.8545],[-5.431,10.778],[-5.463,10.728],[-5.4575,10.556],[-5.508,10.461],[-5.513,10.431],[-5.462,10.3475],[-5.404,10.2965],[-5.3685,10.2845],[-5.2215,10.314],[-5.156,10.2865],[-5.127,10.309],[-5.1075,10.241],[-5.0615,10.181],[-5.0735,10.112],[-5.0185,10.101],[-4.9735,10.0485],[-4.96,10.0095],[-4.987,9.9885],[-4.964,9.9465],[-4.97,9.8985],[-4.9125,9.891],[-4.786,9.8355],[-4.791,9.757],[-4.7455,9.7535],[-4.6875,9.6775],[-4.651,9.7095],[-4.5835,9.695],[-4.5025,9.7265],[-4.521,9.6765],[-4.505,9.647],[-4.4305,9.664],[-4.4,9.6035],[-4.3405,9.625],[-4.2935,9.6185],[-4.287,9.6695],[-4.2475,9.7645],[-4.189,9.774],[-4.127,9.847],[-4.051,9.803],[-3.995,9.831],[-3.9675,9.875],[-3.9125,9.883],[-3.896,9.9055],[-3.81,9.9015],[-3.7755,9.927],[-3.6675,9.9285],[-3.638,9.956],[-3.5975,9.937],[-3.4065,9.93],[-3.345,9.9015],[-3.272,9.8465],[-3.2335,9.8975],[-3.193,9.885],[-3.092,9.81],[-3.09,9.765],[-3.0565,9.7255],[-3.0055,9.743],[-2.9265,9.5685],[-2.824,9.451],[-2.758,9.4115],[-2.687,9.4915],[-2.7605,9.555],[-2.772,9.6],[-2.7475,9.634],[-2.7835,9.6895],[-2.7905,9.7435],[-2.73,9.8385],[-2.7625,9.8885],[-2.743,9.9565],[-2.775,10.01],[-2.7905,10.0695],[-2.7965,10.1985],[-2.761,10.2265],[-2.766,10.2655],[-2.832,10.295],[-2.8505,10.319],[-2.8315,10.388],[-2.7775,10.4255],[-2.863,10.452],[-2.941,10.6365],[-2.91,10.6985],[-2.9405,10.7105],[-2.8955,10.764],[-2.8635,10.8645],[-2.8175,10.9255],[-2.841,10.971],[-2.8335,11.0065],[-2.6895,11.0045],[-2.5005,10.99],[-2.2245,10.994],[-2.1315,10.986],[-1.6165,10.985],[-1.6155,11.021],[-1.425,11.021],[-1.3825,10.997],[-1.115,10.9855],[-1.115,11.004],[-1.0005,11.008],[-0.9165,11.002],[-0.87,10.9665],[-0.855,10.998],[-0.684,10.9975],[-0.6715,10.961],[-0.5935,10.9235],[-0.5685,10.9925],[-0.5105,10.993],[-0.5005,11.0185],[-0.4335,11.037],[-0.4275,11.1145],[-0.381,11.126],[-0.336,11.107],[-0.2735,11.1235],[-0.2755,11.175],[-0.136,11.1395],[0.039,11.101],[0.5005,11.009],[0.4945,10.931],[0.6565,10.9975],[0.912,10.996]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/31/Flag_of_Burkina_Faso.svg","name:en":"Burkina Faso","wikidata":"Q965","ISO3166-1:alpha2":"BF","ISO3166-1:alpha3":"BFA","ISO3166-1:numeric":"854"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-25.573,17.0455],[-25.5595,16.971],[-25.5145,16.856],[-25.4575,16.771],[-25.3865,16.7235],[-24.6905,16.428],[-24.575,16.3755],[-24.8835,15.1815],[-24.9525,14.913],[-24.962,14.7985],[-24.9345,14.728],[-24.8535,14.6515],[-24.779,14.617],[-24.705,14.6065],[-24.358,14.615],[-23.4955,14.6975],[-23.3795,14.7355],[-22.9935,14.983],[-22.9465,15.024],[-22.908,15.086],[-22.5955,15.7635],[-22.4845,16.004],[-22.455,16.157],[-22.487,16.264],[-22.699,16.896],[-22.7485,16.9745],[-22.803,17.017],[-22.8745,17.05],[-22.954,17.055],[-23.245,17.019],[-24.2865,16.8905],[-24.902,17.3385],[-25.0525,17.4025],[-25.123,17.406],[-25.191,17.387],[-25.4335,17.2725],[-25.4955,17.2275],[-25.561,17.1245],[-25.573,17.0455]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/38/Flag_of_Cape_Verde.svg","name:en":"Cape Verde","wikidata":"Q1011","ISO3166-1:alpha2":"CV","ISO3166-1:alpha3":"CPV","ISO3166-1:numeric":"132"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-2.099,49.4595],[-2.139,49.54],[-2.066,49.681],[-2.0505,49.8085],[-2.0545,49.92],[-2.1185,49.933],[-2.2805,49.939],[-2.4675,49.9145],[-2.5935,49.868],[-2.6675,49.801],[-2.692,49.703],[-2.807,49.6705],[-2.893,49.6195],[-2.988,49.533],[-3.0205,49.4315],[-3.0,49.3685],[-2.933,49.3035],[-2.7785,49.279],[-2.5605,49.22],[-2.48,49.2645],[-2.295,49.326],[-2.1335,49.4075],[-2.099,49.4595]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/fa/Flag_of_Guernsey.svg","name:en":"Guernsey","wikidata":"Q25230","ISO3166-1:alpha2":"GG","ISO3166-1:alpha3":"GGY","ISO3166-1:numeric":"831"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-61.6655,12.5965],[-61.7025,12.494],[-61.794,12.389],[-61.867,12.327],[-61.909,12.269],[-62.0045,12.03],[-61.9995,11.95],[-61.972,11.892],[-61.9275,11.84],[-61.87,11.803],[-61.8085,11.787],[-61.703,11.792],[-61.6175,11.815],[-61.518,11.876],[-61.4585,11.944],[-61.3655,12.12],[-61.3475,12.178],[-61.3495,12.25],[-61.215,12.393],[-61.1895,12.436],[-61.173,12.5165],[-61.3825,12.53],[-61.6655,12.5965]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/bc/Flag_of_Grenada.svg","name:en":"Grenada","wikidata":"Q769","ISO3166-1:alpha2":"GD","ISO3166-1:alpha3":"GRD","ISO3166-1:numeric":"308"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-180.0,-19.8005],[-179.094,-20.819],[-179.058,-21.0565],[-179.0355,-21.122],[-178.9905,-21.1765],[-178.9285,-21.2135],[-178.857,-21.2285],[-178.7845,-21.22],[-178.679,-21.19],[-178.6085,-21.155],[-178.556,-21.098],[-178.53,-21.027],[-178.484,-20.725],[-178.0815,-19.981],[-178.0185,-19.8515],[-178.0135,-19.771],[-178.0995,-19.212],[-178.1185,-18.945],[-178.133,-18.8795],[-178.0085,-18.3525],[-178.0035,-18.298],[-178.024,-17.915],[-178.045,-17.837],[-178.4305,-17.079],[-178.5055,-16.966],[-178.743,-16.655],[-178.945,-16.032],[-178.98,-15.9675],[-179.037,-15.919],[-179.3105,-15.7635],[-179.8935,-15.5235],[-180.0,-15.509],[-180.0,-15.563],[-180.0,-15.6155],[-180.0,-15.668],[-180.0,-15.7205],[-180.0,-15.773],[-180.0,-15.8775],[-180.0,-16.1415],[-180.0,-16.155],[-180.0,-16.1685],[-180.0,-16.3255],[-180.0,-16.3775],[-180.0,-16.43],[-180.0,-16.4825],[-180.0,-16.505],[-180.0,-16.5275],[-180.0,-16.572],[-180.0,-16.6165],[-180.0,-16.6605],[-180.0,-16.705],[-180.0,-16.749],[-180.0,-16.7935],[-180.0,-16.795],[-180.0,-16.7965],[-180.0,-16.818],[-180.0,-16.839],[-180.0,-16.86],[-180.0,-16.8815],[-180.0,-16.9025],[-180.0,-16.9235],[-180.0,-16.945],[-180.0,-16.9665],[-180.0,-17.105],[-180.0,-17.1515],[-180.0,-17.1975],[-180.0,-17.783],[-180.0,-18.3665],[-180.0,-18.419],[-180.0,-18.4715],[-180.0,-18.524],[-180.0,-18.5765],[-180.0,-18.629],[-180.0,-18.6815],[-180.0,-18.734],[-180.0,-18.7865],[-180.0,-18.839],[-180.0,-18.8915],[-180.0,-18.944],[-180.0,-18.9965],[-180.0,-19.0485],[-180.0,-19.101],[-180.0,-19.1535],[-180.0,-19.206],[-180.0,-19.489],[-180.0,-19.8005]]],[[[174.4215,-21.733],[174.4325,-21.8025],[174.4605,-21.8555],[174.5335,-21.9175],[174.625,-21.943],[174.702,-21.9355],[174.8015,-21.8775],[174.842,-21.818],[174.8585,-21.74],[174.845,-21.6685],[174.8105,-21.6095],[174.725,-21.5485],[174.652,-21.533],[174.5325,-21.5595],[174.4555,-21.6275],[174.4215,-21.733]]],[[[176.67,-17.2115],[176.676,-17.2475],[176.794,-17.6975],[176.8235,-17.761],[177.0305,-18.052],[177.142,-18.228],[177.479,-18.7095],[177.777,-19.253],[177.799,-19.28],[177.901,-19.3555],[177.9705,-19.377],[178.0975,-19.3925],[179.648,-19.4055],[180.0,-19.8005],[180.0,-19.489],[180.0,-19.206],[180.0,-19.1535],[180.0,-19.101],[180.0,-19.0485],[180.0,-18.9965],[180.0,-18.944],[180.0,-18.8915],[180.0,-18.839],[180.0,-18.7865],[180.0,-18.734],[180.0,-18.6815],[180.0,-18.629],[180.0,-18.5765],[180.0,-18.524],[180.0,-18.4715],[180.0,-18.419],[180.0,-18.3665],[180.0,-17.783],[180.0,-17.1975],[180.0,-17.145],[180.0,-17.0925],[180.0,-17.04],[180.0,-16.9875],[180.0,-16.9665],[180.0,-16.9455],[180.0,-16.924],[180.0,-16.903],[180.0,-16.8815],[180.0,-16.8605],[180.0,-16.839],[180.0,-16.818],[180.0,-16.7965],[180.0,-16.795],[180.0,-16.7935],[180.0,-16.7775],[180.0,-16.7245],[180.0,-16.672],[180.0,-16.6195],[180.0,-16.567],[180.0,-16.5275],[180.0,-16.505],[180.0,-16.4825],[180.0,-16.43],[180.0,-16.3775],[180.0,-16.3255],[180.0,-16.273],[180.0,-16.221],[180.0,-16.1685],[180.0,-16.155],[180.0,-16.1415],[180.0,-16.141],[180.0,-16.1405],[180.0,-16.14],[180.0,-16.1395],[180.0,-16.087],[180.0,-16.035],[180.0,-15.9825],[180.0,-15.93],[180.0,-15.8775],[180.0,-15.8255],[180.0,-15.773],[180.0,-15.7205],[180.0,-15.668],[180.0,-15.6155],[180.0,-15.563],[180.0,-15.509],[179.932,-15.529],[178.994,-15.9855],[178.4035,-16.1285],[178.0305,-16.2495],[177.4935,-16.4665],[177.195,-16.6015],[177.142,-16.636],[176.769,-16.9675],[176.7395,-16.9995],[176.6925,-17.0975],[176.67,-17.2115]]],[[[176.7295,-12.515],[176.7475,-12.582],[176.7885,-12.64],[176.8505,-12.6825],[176.984,-12.7175],[177.1435,-12.7325],[177.2055,-12.7225],[177.2735,-12.687],[177.325,-12.6275],[177.3515,-12.537],[177.3485,-12.4835],[177.3215,-12.403],[177.2815,-12.349],[177.222,-12.3015],[177.149,-12.2785],[177.0165,-12.263],[176.954,-12.2645],[176.886,-12.2865],[176.7875,-12.357],[176.7475,-12.414],[176.7295,-12.515]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/ba/Flag_of_Fiji.svg","name:en":"Fiji","wikidata":"Q712","ISO3166-1:alpha2":"FJ","ISO3166-1:alpha3":"FJI","ISO3166-1:numeric":"242"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[71.0365,-6.39],[71.041,-6.43],[71.098,-6.542],[71.123,-6.723],[71.1785,-6.8085],[71.2885,-6.8755],[71.3525,-6.885],[71.471,-6.878],[71.5195,-6.8505],[71.576,-6.7915],[71.598,-6.7215],[71.5945,-6.6555],[71.5675,-6.58],[71.506,-6.553],[71.434,-6.4575],[71.4425,-6.3845],[71.4645,-6.364],[71.5335,-6.3725],[71.5985,-6.362],[71.6615,-6.324],[71.7405,-6.2325],[71.746,-6.179],[71.729,-6.1],[71.686,-6.034],[71.561,-5.9545],[71.505,-5.9365],[71.4295,-5.9505],[71.238,-6.0035],[71.1615,-6.0735],[71.1085,-6.1595],[71.093,-6.2275],[71.05,-6.3215],[71.0365,-6.39]]],[[[71.5315,-5.2865],[71.5525,-5.459],[71.5965,-5.5675],[71.6515,-5.6225],[71.7165,-5.655],[71.8335,-5.6645],[71.906,-5.64],[72.0665,-5.5475],[72.107,-5.5355],[72.1715,-5.5605],[72.2185,-5.563],[72.3255,-5.5385],[72.379,-5.51],[72.452,-5.431],[72.473,-5.3865],[72.4675,-5.272],[72.4295,-5.1955],[72.388,-5.146],[72.312,-5.11],[72.2495,-5.1],[72.1565,-5.1125],[71.961,-5.0415],[71.7735,-5.0415],[71.681,-5.069],[71.583,-5.156],[71.5475,-5.2235],[71.5315,-5.2865]]],[[[72.151,-7.2845],[72.155,-7.3215],[72.2395,-7.492],[72.2595,-7.5595],[72.3415,-7.621],[72.4485,-7.6455],[72.5185,-7.6235],[72.5865,-7.5795],[72.636,-7.4815],[72.697,-7.3915],[72.6985,-7.321],[72.682,-7.248],[72.6455,-7.1695],[72.563,-7.0785],[72.487,-7.0385],[72.4185,-7.0275],[72.32,-7.055],[72.2025,-7.1395],[72.161,-7.209],[72.151,-7.2845]]],[[[72.221,-5.6735],[72.226,-5.7115],[72.2765,-5.7675],[72.3515,-5.7715],[72.408,-5.7215],[72.412,-5.6465],[72.362,-5.591],[72.3245,-5.581],[72.2535,-5.606],[72.221,-5.6735]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/6e/Flag_of_the_British_Indian_Ocean_Territory.svg","name:en":"British Indian Ocean Territory","wikidata":"Q43448","ISO3166-1:alpha2":"IO","ISO3166-1:alpha3":"IOT","ISO3166-1:numeric":"086"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-7.7985,62.0955],[-7.7815,62.069],[-7.3935,61.7775],[-6.958,61.447],[-6.7545,61.3095],[-6.6825,61.2885],[-6.5565,61.3185],[-6.5475,61.3505],[-6.3165,61.9145],[-6.1435,62.331],[-6.1675,62.375],[-6.2635,62.402],[-6.5685,62.4475],[-7.225,62.4245],[-7.3235,62.3835],[-7.3255,62.3275],[-7.7615,62.1345],[-7.7985,62.0955]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/3c/Flag_of_the_Faroe_Islands.svg","name:en":"Faroe Islands","wikidata":"Q4628","ISO3166-1:alpha2":"FO","ISO3166-1:alpha3":"FRO","ISO3166-1:numeric":"234"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-59.856,13.308],[-59.843,13.124],[-59.832,13.056],[-59.807,12.997],[-59.745,12.926],[-59.7045,12.9],[-59.5945,12.856],[-59.5235,12.845],[-59.4595,12.855],[-59.381,12.892],[-59.293,12.968],[-59.236,13.056],[-59.218,13.114],[-59.2175,13.182],[-59.247,13.26],[-59.2805,13.302],[-59.38,13.368],[-59.408,13.422],[-59.504,13.505],[-59.592,13.534],[-59.6705,13.528],[-59.755,13.49],[-59.7915,13.458],[-59.841,13.382],[-59.856,13.308]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/e/ef/Flag_of_Barbados.svg","name:en":"Barbados","wikidata":"Q244","ISO3166-1:alpha2":"BB","ISO3166-1:alpha3":"BRB","ISO3166-1:numeric":"052"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-68.647,80.2245],[-68.518,80.099],[-68.258,80.023],[-69.1075,79.319],[-69.259,79.1885],[-69.8085,79.0965],[-70.551,78.9475],[-71.098,78.8745],[-71.8705,78.8065],[-73.1305,78.666],[-73.5015,78.5555],[-73.7165,78.4765],[-73.8875,78.3835],[-73.9965,78.153],[-73.674,77.4265],[-73.4905,77.3185],[-72.1115,76.9005],[-72.722,76.942],[-73.1905,76.951],[-73.567,76.932],[-73.9485,76.864],[-74.06,76.8175],[-74.1175,76.708],[-74.001,76.628],[-73.7035,76.542],[-73.506,76.5075],[-73.164,76.4805],[-72.662,76.4845],[-72.1815,76.517],[-71.9435,76.5505],[-71.762,76.601],[-71.641,76.676],[-70.928,76.3285],[-70.6455,76.2535],[-69.2715,75.932],[-68.9675,75.8875],[-66.7635,75.7175],[-66.5525,75.7065],[-65.126,75.7495],[-64.385,75.679],[-60.734,75.3275],[-58.699,74.595],[-58.569,74.024],[-58.5375,73.9735],[-57.59,72.984],[-57.274,72.712],[-56.6775,72.099],[-56.4895,71.6635],[-56.433,71.6015],[-56.114,71.4085],[-55.6135,70.324],[-55.507,69.839],[-55.548,69.737],[-55.536,69.661],[-55.4875,69.6095],[-55.2325,69.469],[-54.763,69.282],[-54.305,68.2805],[-54.4925,67.817],[-54.576,67.3635],[-54.6385,67.007],[-54.6335,66.9615],[-54.4125,66.4],[-54.278,66.1765],[-53.713,65.4395],[-52.79,64.37],[-52.6405,63.9695],[-52.574,63.8905],[-51.7765,63.3055],[-51.58,63.067],[-51.54,63.0305],[-51.359,62.9215],[-50.947,62.615],[-50.7565,62.397],[-50.65,62.3],[-50.195,61.8475],[-49.9935,61.658],[-49.7145,61.4055],[-49.311,61.1415],[-48.8475,60.6545],[-48.7855,60.612],[-48.6485,60.5515],[-48.537,60.5255],[-47.7415,60.3935],[-45.5725,59.807],[-45.2165,59.681],[-45.0905,59.6505],[-44.1235,59.5225],[-44.009,59.5155],[-43.8955,59.5255],[-43.594,59.5795],[-42.99,59.7445],[-42.848,59.8085],[-42.718,59.9045],[-42.653,59.978],[-42.2095,60.8365],[-41.82,61.4875],[-41.6545,61.77],[-41.2535,62.5795],[-41.1485,62.7875],[-40.8055,63.0095],[-40.234,63.4655],[-40.0715,63.6485],[-39.755,64.284],[-39.339,64.849],[-36.8785,65.3075],[-36.486,65.3695],[-36.3335,65.4075],[-35.7985,65.6075],[-34.3175,66.233],[-33.829,66.4525],[-33.425,66.6185],[-33.33,66.6725],[-33.152,66.8215],[-32.1145,67.4585],[-30.2835,67.901],[-29.97,67.9395],[-29.215,68.046],[-27.4295,68.313],[-26.207,68.5175],[-26.1285,68.5335],[-25.361,68.721],[-23.698,69.262],[-22.853,69.517],[-21.896,69.858],[-21.5805,69.9965],[-21.5095,70.0565],[-20.98,70.423],[-20.902,70.4875],[-20.801,70.6145],[-20.785,70.6945],[-21.0095,71.3445],[-21.0375,71.568],[-21.3375,72.2555],[-21.028,72.5915],[-20.572,73.0375],[-19.8285,73.375],[-19.7575,73.4155],[-19.394,73.691],[-18.7125,74.1745],[-18.5915,74.224],[-17.754,74.5005],[-16.718,74.9045],[-16.588,74.9885],[-16.528,75.1175],[-16.575,75.209],[-16.6835,75.261],[-17.254,75.486],[-17.642,76.0235],[-17.631,76.0995],[-17.716,76.1955],[-17.735,76.295],[-17.8425,76.3945],[-17.8755,76.4775],[-17.4515,76.758],[-17.3335,76.8475],[-17.2845,77.0235],[-17.305,77.2145],[-16.844,77.535],[-16.761,77.5685],[-16.545,77.728],[-16.512,77.805],[-16.6695,77.927],[-16.907,78.7435],[-16.6065,78.981],[-16.5145,79.1225],[-16.3945,79.1675],[-16.0485,79.134],[-15.812,79.1285],[-15.4245,79.1435],[-15.062,79.196],[-14.864,79.266],[-14.81,79.3265],[-14.9225,79.432],[-15.191,79.4985],[-15.379,79.5215],[-15.772,79.5395],[-16.1725,79.5235],[-16.4725,79.4825],[-16.7035,79.4175],[-16.835,79.638],[-16.2575,79.8605],[-15.2955,80.1345],[-15.0155,80.2245],[-14.7765,80.2775],[-13.0985,80.449],[-12.719,80.5],[-12.477,80.557],[-12.3815,80.607],[-12.048,80.915],[-11.623,80.987],[-11.3485,81.0605],[-10.8935,81.1185],[-10.4145,81.2045],[-10.1445,81.289],[-10.029,81.369],[-10.0825,81.427],[-10.349,81.4995],[-10.64,81.63],[-11.5805,81.786],[-12.2735,81.867],[-16.7905,82.284],[-18.3475,82.6695],[-18.5455,82.725],[-19.1105,82.8345],[-19.851,82.948],[-20.4645,83.009],[-23.1415,83.3635],[-24.2025,83.5415],[-24.5665,83.5855],[-25.7185,83.6855],[-26.3025,83.7235],[-27.201,83.7565],[-30.116,83.866],[-30.5455,83.875],[-34.078,83.857],[-37.278,83.7985],[-39.2155,83.735],[-39.7555,83.7055],[-40.736,83.613],[-44.433,83.42],[-45.7815,83.3525],[-47.124,83.2585],[-49.8315,83.0135],[-51.3735,82.9415],[-51.7815,82.912],[-55.9525,82.5155],[-58.403,82.357],[-59.6265,82.2995],[-59.995,82.2175],[-62.1625,81.8675],[-64.1855,81.2995],[-66.2685,80.834],[-67.1205,80.749],[-68.335,80.416],[-68.647,80.2245]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/09/Flag_of_Greenland.svg","name:en":"Greenland","wikidata":"Q223","ISO3166-1:alpha2":"GL","ISO3166-1:alpha3":"GRL","ISO3166-1:numeric":"304"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[24.0,-10.89],[23.9615,-10.935],[23.8975,-10.9765],[23.863,-11.0355],[23.778,-10.994],[23.6685,-11.003],[23.597,-10.9865],[23.5315,-10.9455],[23.484,-10.9385],[23.3975,-10.9605],[23.299,-11.0215],[23.2555,-11.0715],[23.196,-11.108],[23.1515,-11.0815],[23.08,-11.113],[23.041,-11.0905],[22.9065,-11.0865],[22.8515,-11.065],[22.7735,-11.1185],[22.71,-11.1135],[22.647,-11.079],[22.6275,-11.047],[22.5775,-11.028],[22.489,-11.0645],[22.5025,-11.112],[22.4385,-11.177],[22.346,-11.1825],[22.344,-11.2025],[22.271,-11.263],[22.254,-11.213],[22.2685,-11.1805],[22.2175,-11.1125],[22.203,-10.9305],[22.1675,-10.8635],[22.209,-10.819],[22.2675,-10.785],[22.3075,-10.7795],[22.323,-10.719],[22.307,-10.531],[22.2715,-10.5075],[22.324,-10.383],[22.275,-10.2575],[22.235,-10.2165],[22.215,-10.1585],[22.2155,-10.0535],[22.193,-9.993],[22.1915,-9.933],[22.1455,-9.886],[22.0695,-9.875],[22.013,-9.82],[22.0015,-9.762],[21.935,-9.707],[21.86,-9.5945],[21.8645,-9.5595],[21.8335,-9.51],[21.8315,-9.464],[21.791,-9.4075],[21.81,-9.3295],[21.862,-9.1945],[21.8395,-9.1305],[21.8345,-9.0605],[21.8525,-8.949],[21.8965,-8.7835],[21.892,-8.7],[21.9245,-8.567],[21.9525,-8.504],[21.9485,-8.442],[21.9225,-8.397],[21.925,-8.307],[21.8925,-8.293],[21.8915,-8.253],[21.8235,-8.0705],[21.7745,-8.025],[21.7525,-7.945],[21.776,-7.9085],[21.7835,-7.829],[21.7755,-7.7735],[21.8525,-7.6045],[21.842,-7.5305],[21.8605,-7.4475],[21.8345,-7.4085],[21.8435,-7.374],[21.789,-7.2835],[21.242,-7.2835],[20.553,-7.2835],[20.548,-7.229],[20.5615,-7.1175],[20.5955,-7.0605],[20.627,-6.917],[20.322,-6.9165],[20.303,-7.0],[19.548,-7.0],[19.562,-7.0555],[19.4985,-7.168],[19.505,-7.249],[19.488,-7.3105],[19.4945,-7.3635],[19.5225,-7.3935],[19.53,-7.4625],[19.486,-7.5045],[19.4735,-7.572],[19.383,-7.572],[19.3695,-7.597],[19.406,-7.6705],[19.3835,-7.789],[19.3635,-7.8075],[19.3585,-7.9495],[19.3815,-8.0],[18.7965,-8.0],[18.762,-7.9165],[18.5305,-7.9165],[18.532,-8.0],[18.4075,-8.0],[18.3715,-8.0245],[18.3115,-8.0155],[18.2835,-7.987],[18.1965,-7.986],[18.1425,-8.0355],[18.093,-8.056],[18.1035,-8.0965],[17.976,-8.096],[17.874,-8.0805],[17.7965,-8.1135],[17.7625,-8.1005],[17.6795,-8.101],[17.614,-8.131],[17.539,-8.1115],[17.5035,-8.066],[17.514,-8.0165],[17.4805,-8.0015],[17.484,-7.9615],[17.45,-7.942],[17.42,-7.8555],[17.377,-7.7765],[17.335,-7.782],[17.316,-7.7155],[17.2905,-7.687],[17.302,-7.6335],[17.2125,-7.572],[17.195,-7.496],[17.15,-7.471],[17.1735,-7.424],[17.135,-7.4055],[17.1085,-7.362],[17.0365,-7.317],[17.0205,-7.2925],[16.941,-7.236],[16.955,-7.2115],[16.925,-7.141],[16.9555,-7.1045],[16.9665,-7.0525],[16.9,-6.983],[16.9105,-6.912],[16.8735,-6.8755],[16.846,-6.884],[16.8365,-6.8145],[16.802,-6.7935],[16.7975,-6.7265],[16.7655,-6.713],[16.754,-6.6315],[16.7325,-6.586],[16.7445,-6.511],[16.7055,-6.4765],[16.718,-6.451],[16.678,-6.382],[16.7195,-6.331],[16.7035,-6.2655],[16.704,-6.203],[16.7305,-6.167],[16.7135,-6.1295],[16.663,-6.091],[16.624,-6.0395],[16.596,-6.033],[16.6005,-5.9785],[16.577,-5.937],[16.5835,-5.878],[16.492,-5.844],[16.4345,-5.866],[16.1745,-5.86],[16.153,-5.864],[15.8145,-5.878],[15.68,-5.862],[15.4195,-5.87],[14.9445,-5.8655],[14.6995,-5.878],[14.596,-5.9045],[14.5055,-5.8875],[14.4125,-5.897],[14.3105,-5.883],[14.2775,-5.8605],[14.239,-5.881],[14.1795,-5.8395],[14.146,-5.8495],[14.013,-5.839],[13.774,-5.8695],[13.617,-5.873],[13.572,-5.883],[13.5145,-5.8625],[13.431,-5.86],[13.3775,-5.8725],[13.365,-5.902],[13.2225,-5.862],[13.1135,-5.9035],[13.084,-5.871],[13.0425,-5.8635],[12.951,-5.9125],[12.856,-5.9245],[12.785,-5.986],[12.625,-6.0195],[12.4445,-6.078],[12.3895,-6.068],[12.3125,-6.006],[12.1145,-5.99],[12.078,-6.0725],[12.0805,-6.1955],[12.1135,-6.268],[12.219,-6.42],[12.3345,-6.6615],[12.4175,-6.8055],[12.573,-6.973],[12.6295,-7.06],[12.6425,-7.1275],[12.653,-7.2905],[12.6675,-7.3445],[12.7265,-7.428],[12.8095,-7.669],[12.86,-7.7775],[12.916,-7.928],[12.956,-7.998],[13.0905,-8.2745],[13.1635,-8.3835],[13.145,-8.4865],[13.158,-8.5445],[13.1065,-8.628],[12.991,-8.7315],[12.9005,-8.8245],[12.838,-8.9075],[12.806,-8.9655],[12.7905,-9.051],[12.8065,-9.1685],[12.957,-9.4125],[13.0005,-9.6205],[12.9995,-9.733],[13.0265,-9.799],[13.111,-9.9175],[13.109,-9.9965],[13.135,-10.078],[13.2195,-10.189],[13.257,-10.2235],[13.304,-10.328],[13.3295,-10.358],[13.3445,-10.4695],[13.397,-10.5435],[13.465,-10.6095],[13.5285,-10.689],[13.517,-10.753],[13.5245,-10.8115],[13.5535,-10.873],[13.6545,-11.009],[13.622,-11.233],[13.595,-11.311],[13.589,-11.436],[13.5665,-11.5615],[13.5915,-11.761],[13.5725,-11.859],[13.538,-11.9125],[13.5105,-12.025],[13.4575,-12.1565],[13.3555,-12.2495],[13.2805,-12.3825],[13.136,-12.406],[13.036,-12.4685],[12.969,-12.5445],[12.8115,-12.6785],[12.745,-12.7735],[12.733,-12.8635],[12.744,-12.926],[12.6455,-13.022],[12.5695,-13.066],[12.511,-13.123],[12.442,-13.234],[12.38,-13.283],[12.338,-13.351],[12.3165,-13.4345],[12.334,-13.5485],[12.324,-13.7025],[12.272,-13.741],[12.2215,-13.829],[12.2,-13.9345],[12.169,-13.988],[12.1265,-14.204],[12.15,-14.3035],[12.133,-14.4225],[12.112,-14.485],[12.066,-14.7055],[12.0335,-14.749],[12.006,-14.84],[11.977,-14.8925],[11.918,-15.061],[11.862,-15.1635],[11.8445,-15.296],[11.8245,-15.375],[11.815,-15.509],[11.7415,-15.587],[11.703,-15.598],[11.623,-15.649],[11.586,-15.695],[11.5385,-15.802],[11.5235,-15.874],[11.5405,-15.9735],[11.587,-16.0525],[11.589,-16.2045],[11.498,-16.424],[11.4615,-16.531],[11.4685,-16.6155],[11.5215,-16.753],[11.561,-16.811],[11.57,-16.8675],[11.5585,-16.909],[11.5415,-17.093],[11.542,-17.25],[11.7495,-17.25],[11.7985,-17.268],[11.9325,-17.19],[12.079,-17.142],[12.102,-17.161],[12.162,-17.1625],[12.184,-17.1965],[12.25,-17.2405],[12.2835,-17.242],[12.4235,-17.2075],[12.4505,-17.2545],[12.5945,-17.235],[12.6175,-17.207],[12.6965,-17.169],[12.8725,-17.0645],[12.9155,-17.021],[12.9865,-16.982],[13.0905,-16.98],[13.17,-16.964],[13.2725,-16.9985],[13.352,-16.974],[13.4645,-17.013],[13.5225,-17.0905],[13.5415,-17.147],[13.68,-17.247],[13.8685,-17.343],[13.9165,-17.378],[13.9555,-17.433],[14.017,-17.415],[14.101,-17.439],[14.2125,-17.41],[14.2225,-17.3915],[14.637,-17.3915],[15.2015,-17.391],[15.578,-17.3905],[16.107,-17.3905],[16.8945,-17.39],[17.6265,-17.3895],[18.4215,-17.3895],[18.5335,-17.5205],[18.5685,-17.5845],[18.598,-17.5835],[18.624,-17.636],[18.7905,-17.7665],[18.834,-17.772],[18.8945,-17.816],[19.0345,-17.835],[19.118,-17.8365],[19.138,-17.8075],[19.231,-17.828],[19.2715,-17.8205],[19.331,-17.852],[19.4085,-17.8675],[19.508,-17.8605],[19.5665,-17.874],[19.6735,-17.8495],[19.7425,-17.9075],[19.8065,-17.8685],[19.863,-17.8835],[19.912,-17.862],[20.028,-17.9055],[20.057,-17.8855],[20.116,-17.9095],[20.1745,-17.877],[20.233,-17.8845],[20.2755,-17.865],[20.3325,-17.8665],[20.368,-17.8965],[20.4385,-17.9065],[20.4765,-17.952],[20.56,-17.9845],[20.6455,-17.977],[20.719,-18.013],[20.749,-18.0035],[20.8025,-18.0375],[20.8665,-18.0295],[20.9055,-17.995],[20.977,-17.958],[21.095,-17.9495],[21.1145,-17.9355],[21.21,-17.929],[21.268,-17.967],[21.423,-18.026],[22.5,-17.821],[22.9965,-17.724],[23.434,-17.638],[23.391,-17.5765],[23.3415,-17.554],[23.2215,-17.5325],[23.1775,-17.475],[23.136,-17.4665],[23.087,-17.4135],[22.9955,-17.274],[22.9095,-17.2225],[22.8965,-17.201],[22.802,-17.1655],[22.7915,-17.12],[22.729,-17.075],[22.716,-17.0425],[22.6285,-16.961],[22.599,-16.9185],[22.492,-16.835],[22.42,-16.7455],[22.264,-16.602],[22.185,-16.546],[22.1355,-16.49],[22.1395,-16.459],[22.1205,-16.348],[22.03,-16.2185],[22.0,-16.2075],[22.0005,-15.8865],[22.0005,-15.4065],[22.0005,-14.7385],[22.0005,-14.146],[22.0005,-13.73],[22.001,-13.3095],[22.0035,-12.9995],[22.6525,-12.9995],[23.229,-13.0005],[23.6725,-13.001],[24.058,-13.001],[24.025,-12.9705],[23.9835,-12.8985],[23.945,-12.8955],[23.8935,-12.8415],[23.898,-12.7695],[23.933,-12.698],[23.9205,-12.6815],[23.96,-12.592],[23.947,-12.5595],[24.0405,-12.4345],[24.064,-12.426],[24.078,-12.362],[24.0595,-12.2635],[24.0,-12.208],[23.9825,-12.1715],[23.9805,-12.0775],[23.998,-11.856],[24.023,-11.83],[23.993,-11.743],[23.9755,-11.6505],[24.038,-11.531],[24.024,-11.446],[24.0875,-11.4035],[24.056,-11.3085],[24.0315,-11.2745],[24.032,-11.134],[24.0105,-11.0185],[24.018,-10.942],[24.0,-10.89]]],[[[11.8475,-5.149],[11.934,-5.2685],[12.005,-5.456],[11.9525,-5.583],[11.9475,-5.683],[11.9685,-5.766],[11.9955,-5.8275],[12.039,-5.8895],[12.202,-5.774],[12.219,-5.7525],[12.2785,-5.742],[12.5285,-5.742],[12.528,-5.167],[12.494,-5.14],[12.4695,-5.0825],[12.518,-5.0465],[12.6055,-5.0265],[12.626,-4.9505],[12.72,-4.95],[12.7285,-4.911],[12.8155,-4.839],[12.828,-4.782],[12.8965,-4.735],[12.923,-4.7475],[12.9805,-4.7055],[13.03,-4.7155],[13.0515,-4.675],[13.1025,-4.684],[13.0075,-4.59],[12.9385,-4.5015],[12.853,-4.43],[12.816,-4.4375],[12.7585,-4.4175],[12.781,-4.4875],[12.765,-4.507],[12.71,-4.4775],[12.638,-4.5635],[12.5635,-4.5635],[12.536,-4.588],[12.487,-4.565],[12.4465,-4.602],[12.391,-4.611],[12.399,-4.666],[12.3715,-4.7335],[12.312,-4.8035],[12.2085,-4.8035],[12.166,-4.896],[12.0885,-4.9595],[12.016,-5.041],[11.8475,-5.149]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9d/Flag_of_Angola.svg","name:en":"Angola","wikidata":"Q916","ISO3166-1:alpha2":"AO","ISO3166-1:alpha3":"AGO","ISO3166-1:numeric":"024"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[9.1495,0.7535],[9.1085,0.597],[9.103,0.367],[8.8095,-0.0945],[8.551,-0.502],[8.5155,-0.5655],[8.501,-0.6845],[8.511,-0.7355],[8.575,-0.852],[8.6435,-1.0025],[8.682,-1.113],[8.7815,-1.248],[8.791,-1.325],[8.844,-1.4435],[8.872,-1.4855],[9.0295,-1.6835],[9.0475,-1.7195],[9.0725,-1.917],[9.135,-2.0405],[9.2465,-2.173],[9.3875,-2.318],[9.392,-2.3815],[9.412,-2.438],[9.4845,-2.547],[9.5735,-2.6275],[9.6945,-2.7525],[9.7305,-2.8185],[9.765,-2.854],[10.0005,-3.0255],[10.274,-3.2345],[10.358,-3.327],[10.385,-3.377],[10.442,-3.429],[10.4695,-3.5395],[10.5035,-3.5825],[10.615,-3.6645],[10.743,-3.7725],[10.808,-3.841],[10.842,-3.948],[10.881,-4.001],[11.005,-4.101],[11.1395,-3.9235],[11.1845,-3.8165],[11.223,-3.698],[11.348,-3.604],[11.431,-3.591],[11.483,-3.514],[11.5515,-3.5125],[11.5805,-3.5315],[11.6525,-3.636],[11.6835,-3.6945],[11.74,-3.6865],[11.8685,-3.71],[11.926,-3.637],[11.8525,-3.5895],[11.8395,-3.556],[11.9155,-3.386],[11.9635,-3.3515],[11.954,-3.2885],[11.871,-3.276],[11.801,-3.2145],[11.699,-3.173],[11.701,-3.089],[11.732,-3.038],[11.766,-3.047],[11.8055,-3.018],[11.7485,-2.946],[11.7135,-2.9185],[11.6545,-2.827],[11.628,-2.8205],[11.549,-2.8655],[11.546,-2.794],[11.612,-2.716],[11.647,-2.627],[11.6295,-2.5505],[11.5935,-2.504],[11.602,-2.4455],[11.593,-2.3745],[11.618,-2.3325],[11.677,-2.354],[11.6885,-2.394],[11.7635,-2.4025],[11.8015,-2.372],[11.9415,-2.3355],[11.98,-2.344],[12.0345,-2.4065],[12.091,-2.407],[12.478,-2.327],[12.4635,-2.3135],[12.496,-2.221],[12.484,-2.164],[12.517,-2.095],[12.479,-2.082],[12.448,-2.0245],[12.45,-1.9195],[12.507,-1.9215],[12.5185,-1.877],[12.585,-1.827],[12.65,-1.8225],[12.7165,-1.852],[12.7475,-1.8895],[12.8185,-1.9085],[12.8455,-1.9545],[12.8715,-2.0485],[12.9005,-2.0745],[12.901,-2.143],[12.944,-2.195],[13.0065,-2.2405],[13.011,-2.2955],[13.0415,-2.328],[13.153,-2.3745],[13.186,-2.359],[13.3875,-2.4285],[13.4085,-2.4175],[13.487,-2.4355],[13.501,-2.401],[13.552,-2.3695],[13.5855,-2.328],[13.727,-2.184],[13.727,-2.151],[13.758,-2.0915],[13.8095,-2.1445],[13.8465,-2.256],[13.891,-2.3305],[13.928,-2.363],[13.869,-2.414],[13.866,-2.469],[13.9315,-2.49],[13.968,-2.471],[14.001,-2.4985],[14.063,-2.475],[14.114,-2.4885],[14.1495,-2.4345],[14.157,-2.3915],[14.253,-2.3375],[14.194,-2.286],[14.1585,-2.2285],[14.2255,-2.1905],[14.2535,-2.1265],[14.2695,-2.033],[14.2645,-1.966],[14.317,-1.938],[14.3815,-1.9255],[14.4295,-1.8915],[14.4145,-1.857],[14.429,-1.793],[14.416,-1.7505],[14.424,-1.6715],[14.389,-1.6025],[14.4805,-1.5455],[14.4545,-1.497],[14.49,-1.3745],[14.451,-1.3525],[14.4475,-1.3145],[14.4765,-1.289],[14.482,-1.213],[14.4455,-1.1605],[14.4545,-1.127],[14.4175,-1.034],[14.433,-0.9595],[14.43,-0.9065],[14.488,-0.8475],[14.466,-0.785],[14.4745,-0.72],[14.534,-0.6395],[14.5155,-0.572],[14.47,-0.4935],[14.418,-0.4445],[14.347,-0.405],[14.232,-0.3975],[14.1845,-0.414],[14.19,-0.34],[14.1465,-0.253],[14.089,-0.221],[14.019,-0.2085],[13.9845,-0.18],[13.9465,-0.1815],[13.9065,-0.222],[13.876,-0.102],[13.952,-0.018],[13.9355,0.048],[13.904,0.1115],[13.9065,0.1745],[13.8805,0.2505],[13.9355,0.326],[13.973,0.4065],[14.0555,0.4605],[14.0835,0.508],[14.064,0.537],[14.107,0.583],[14.2385,0.567],[14.2965,0.6185],[14.3785,0.6705],[14.3765,0.742],[14.413,0.7735],[14.4275,0.819],[14.4605,0.8265],[14.484,0.8725],[14.4695,0.905],[14.4955,0.963],[14.4405,1.011],[14.399,1.0935],[14.392,1.143],[14.347,1.142],[14.3035,1.2705],[14.3055,1.323],[14.287,1.359],[14.2355,1.397],[14.147,1.3965],[14.074,1.3755],[14.0065,1.4345],[13.9815,1.414],[13.811,1.4295],[13.7905,1.374],[13.7605,1.3495],[13.661,1.3515],[13.6055,1.3285],[13.56,1.277],[13.4765,1.269],[13.437,1.296],[13.372,1.287],[13.31,1.223],[13.1835,1.225],[13.1865,1.286],[13.2275,1.286],[13.2575,1.3165],[13.233,1.4385],[13.1325,1.5605],[13.144,1.626],[13.14,1.707],[13.1815,1.755],[13.1995,1.8065],[13.1865,1.928],[13.208,1.9835],[13.264,2.0215],[13.2965,2.0635],[13.294,2.1705],[13.3055,2.207],[13.248,2.2735],[13.2195,2.261],[13.157,2.286],[13.0535,2.2395],[12.9975,2.252],[12.8615,2.2275],[12.8185,2.2525],[12.7515,2.2245],[12.6835,2.244],[12.6415,2.24],[12.5745,2.2705],[12.528,2.253],[12.4545,2.252],[12.3665,2.2675],[12.304,2.2905],[12.249,2.2565],[12.2075,2.282],[12.156,2.2765],[12.015,2.2905],[11.8695,2.2845],[11.754,2.271],[11.7015,2.319],[11.61,2.2955],[11.3965,2.3025],[11.352,2.2225],[11.36,2.172],[11.355,2.1595],[11.3465,1.8315],[11.3495,1.4715],[11.3535,1.002],[10.7185,1.0025],[9.992,1.0025],[9.9935,0.9385],[9.958,0.929],[9.895,0.953],[9.8795,0.9885],[9.798,1.0],[9.749,1.063],[9.668,1.062],[9.62,1.0295],[9.5475,1.0225],[9.519,0.963],[9.355,0.8465],[9.1495,0.7535]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/04/Flag_of_Gabon.svg","name:en":"Gabon","wikidata":"Q1000","ISO3166-1:alpha2":"GA","ISO3166-1:alpha3":"GAB","ISO3166-1:numeric":"266"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[13.1025,-4.684],[13.105,-4.6025],[13.1405,-4.594],[13.1855,-4.6665],[13.2815,-4.7655],[13.3735,-4.8],[13.373,-4.8585],[13.4285,-4.913],[13.441,-4.863],[13.495,-4.802],[13.515,-4.7475],[13.5775,-4.803],[13.6995,-4.745],[13.7255,-4.6895],[13.7175,-4.6375],[13.734,-4.506],[13.7235,-4.4555],[13.7795,-4.424],[13.8445,-4.4435],[13.88,-4.509],[13.9445,-4.5155],[14.07,-4.4045],[14.099,-4.415],[14.176,-4.398],[14.2525,-4.3575],[14.2885,-4.3195],[14.4015,-4.2785],[14.393,-4.3555],[14.4255,-4.3975],[14.4805,-4.432],[14.4625,-4.465],[14.3595,-4.561],[14.3905,-4.6335],[14.4195,-4.6515],[14.407,-4.7035],[14.3975,-4.8515],[14.415,-4.896],[14.472,-4.8505],[14.5615,-4.865],[14.591,-4.9035],[14.651,-4.922],[14.7005,-4.9065],[14.7535,-4.862],[14.848,-4.807],[14.8985,-4.688],[14.9865,-4.603],[15.0315,-4.539],[15.1,-4.489],[15.144,-4.4185],[15.1755,-4.391],[15.1965,-4.325],[15.2565,-4.316],[15.3285,-4.269],[15.404,-4.2855],[15.4795,-4.229],[15.517,-4.078],[15.5645,-4.0355],[15.7195,-3.989],[15.803,-3.9815],[15.8865,-3.9545],[15.906,-3.9335],[15.927,-3.8595],[15.9675,-3.7685],[15.9995,-3.725],[16.039,-3.627],[16.0915,-3.5565],[16.1245,-3.472],[16.164,-3.423],[16.2015,-3.352],[16.2135,-3.287],[16.1815,-3.2565],[16.187,-3.192],[16.1715,-3.118],[16.192,-3.0],[16.179,-2.904],[16.208,-2.7235],[16.2355,-2.6545],[16.236,-2.602],[16.1745,-2.3445],[16.1935,-2.1805],[16.2655,-2.0935],[16.3665,-2.0365],[16.4065,-1.98],[16.441,-1.96],[16.508,-1.8905],[16.576,-1.7865],[16.663,-1.62],[16.681,-1.562],[16.74,-1.428],[16.807,-1.3165],[16.9535,-1.167],[17.0455,-1.109],[17.1495,-1.0565],[17.2485,-1.036],[17.344,-0.99],[17.5295,-0.7445],[17.582,-0.6945],[17.6355,-0.6695],[17.6755,-0.6105],[17.694,-0.5575],[17.7165,-0.4145],[17.7135,-0.356],[17.677,-0.3005],[17.6635,-0.231],[17.6765,-0.168],[17.734,-0.064],[17.774,0.1225],[17.8215,0.2335],[17.92,0.3145],[17.954,0.3615],[17.9685,0.453],[17.932,0.534],[17.8855,0.571],[17.868,0.614],[17.869,0.702],[17.889,0.776],[17.8775,0.8525],[17.8405,0.9245],[17.845,1.021],[17.926,1.1455],[17.962,1.3195],[18.0705,1.5285],[18.078,1.729],[18.0655,1.875],[18.084,1.938],[18.072,2.0425],[18.0945,2.139],[18.091,2.218],[18.1105,2.2805],[18.1685,2.3315],[18.2245,2.4185],[18.2265,2.4845],[18.243,2.5295],[18.3205,2.581],[18.402,2.73],[18.4445,2.8665],[18.491,2.9495],[18.539,3.0755],[18.62,3.144],[18.6415,3.2045],[18.633,3.2745],[18.6435,3.3115],[18.626,3.471],[18.594,3.485],[18.5335,3.599],[18.4715,3.641],[18.4425,3.5955],[18.265,3.577],[18.222,3.4905],[18.178,3.4835],[18.16,3.533],[18.1195,3.5605],[18.0435,3.566],[17.995,3.5395],[17.9475,3.573],[17.854,3.5375],[17.834,3.6105],[17.723,3.6265],[17.6155,3.6295],[17.564,3.6535],[17.5025,3.706],[17.4595,3.7085],[17.414,3.6795],[17.3605,3.618],[17.3035,3.6265],[17.2565,3.617],[17.234,3.5845],[17.0715,3.5755],[17.0335,3.5405],[16.988,3.5355],[16.9605,3.556],[16.8765,3.566],[16.862,3.5245],[16.7975,3.526],[16.767,3.55],[16.6595,3.5335],[16.589,3.482],[16.572,3.444],[16.561,3.339],[16.529,3.2755],[16.5355,3.2485],[16.484,3.162],[16.4825,3.132],[16.512,3.0605],[16.469,2.981],[16.466,2.9225],[16.496,2.8845],[16.499,2.843],[16.207,2.221],[16.184,2.2055],[16.0815,2.1905],[16.0835,2.0475],[16.0515,2.0045],[16.0835,1.8995],[16.134,1.8045],[16.145,1.6905],[16.0825,1.6905],[16.0575,1.652],[16.019,1.6785],[16.021,1.766],[15.96,1.7665],[15.8855,1.7905],[15.8685,1.8285],[15.8055,1.856],[15.7475,1.92],[15.616,1.9385],[15.4855,1.9835],[15.347,1.912],[15.3035,1.9425],[15.305,1.969],[15.2495,2.028],[15.2015,2.0385],[15.122,2.014],[15.105,1.983],[15.045,1.9795],[14.979,2.0355],[14.9685,2.008],[14.8935,2.0155],[14.911,2.064],[14.8565,2.1015],[14.808,2.0595],[14.718,2.1275],[14.644,2.1325],[14.595,2.202],[14.572,2.179],[14.443,2.1575],[14.413,2.1815],[14.3555,2.1855],[14.292,2.172],[13.8195,2.172],[13.294,2.1705],[13.2965,2.0635],[13.264,2.0215],[13.208,1.9835],[13.1865,1.928],[13.1995,1.8065],[13.1815,1.755],[13.14,1.707],[13.144,1.626],[13.1325,1.5605],[13.233,1.4385],[13.2575,1.3165],[13.2275,1.286],[13.1865,1.286],[13.1835,1.225],[13.31,1.223],[13.372,1.287],[13.437,1.296],[13.4765,1.269],[13.56,1.277],[13.6055,1.3285],[13.661,1.3515],[13.7605,1.3495],[13.7905,1.374],[13.811,1.4295],[13.9815,1.414],[14.0065,1.4345],[14.074,1.3755],[14.147,1.3965],[14.2355,1.397],[14.287,1.359],[14.3055,1.323],[14.3035,1.2705],[14.347,1.142],[14.392,1.143],[14.399,1.0935],[14.4405,1.011],[14.4955,0.963],[14.4695,0.905],[14.484,0.8725],[14.4605,0.8265],[14.4275,0.819],[14.413,0.7735],[14.3765,0.742],[14.3785,0.6705],[14.2965,0.6185],[14.2385,0.567],[14.107,0.583],[14.064,0.537],[14.0835,0.508],[14.0555,0.4605],[13.973,0.4065],[13.9355,0.326],[13.8805,0.2505],[13.9065,0.1745],[13.904,0.1115],[13.9355,0.048],[13.952,-0.018],[13.876,-0.102],[13.9065,-0.222],[13.9465,-0.1815],[13.9845,-0.18],[14.019,-0.2085],[14.089,-0.221],[14.1465,-0.253],[14.19,-0.34],[14.1845,-0.414],[14.232,-0.3975],[14.347,-0.405],[14.418,-0.4445],[14.47,-0.4935],[14.5155,-0.572],[14.534,-0.6395],[14.4745,-0.72],[14.466,-0.785],[14.488,-0.8475],[14.43,-0.9065],[14.433,-0.9595],[14.4175,-1.034],[14.4545,-1.127],[14.4455,-1.1605],[14.482,-1.213],[14.4765,-1.289],[14.4475,-1.3145],[14.451,-1.3525],[14.49,-1.3745],[14.4545,-1.497],[14.4805,-1.5455],[14.389,-1.6025],[14.424,-1.6715],[14.416,-1.7505],[14.429,-1.793],[14.4145,-1.857],[14.4295,-1.8915],[14.3815,-1.9255],[14.317,-1.938],[14.2645,-1.966],[14.2695,-2.033],[14.2535,-2.1265],[14.2255,-2.1905],[14.1585,-2.2285],[14.194,-2.286],[14.253,-2.3375],[14.157,-2.3915],[14.1495,-2.4345],[14.114,-2.4885],[14.063,-2.475],[14.001,-2.4985],[13.968,-2.471],[13.9315,-2.49],[13.866,-2.469],[13.869,-2.414],[13.928,-2.363],[13.891,-2.3305],[13.8465,-2.256],[13.8095,-2.1445],[13.758,-2.0915],[13.727,-2.151],[13.727,-2.184],[13.5855,-2.328],[13.552,-2.3695],[13.501,-2.401],[13.487,-2.4355],[13.4085,-2.4175],[13.3875,-2.4285],[13.186,-2.359],[13.153,-2.3745],[13.0415,-2.328],[13.011,-2.2955],[13.0065,-2.2405],[12.944,-2.195],[12.901,-2.143],[12.9005,-2.0745],[12.8715,-2.0485],[12.8455,-1.9545],[12.8185,-1.9085],[12.7475,-1.8895],[12.7165,-1.852],[12.65,-1.8225],[12.585,-1.827],[12.5185,-1.877],[12.507,-1.9215],[12.45,-1.9195],[12.448,-2.0245],[12.479,-2.082],[12.517,-2.095],[12.484,-2.164],[12.496,-2.221],[12.4635,-2.3135],[12.478,-2.327],[12.091,-2.407],[12.0345,-2.4065],[11.98,-2.344],[11.9415,-2.3355],[11.8015,-2.372],[11.7635,-2.4025],[11.6885,-2.394],[11.677,-2.354],[11.618,-2.3325],[11.593,-2.3745],[11.602,-2.4455],[11.5935,-2.504],[11.6295,-2.5505],[11.647,-2.627],[11.612,-2.716],[11.546,-2.794],[11.549,-2.8655],[11.628,-2.8205],[11.6545,-2.827],[11.7135,-2.9185],[11.7485,-2.946],[11.8055,-3.018],[11.766,-3.047],[11.732,-3.038],[11.701,-3.089],[11.699,-3.173],[11.801,-3.2145],[11.871,-3.276],[11.954,-3.2885],[11.9635,-3.3515],[11.9155,-3.386],[11.8395,-3.556],[11.8525,-3.5895],[11.926,-3.637],[11.8685,-3.71],[11.74,-3.6865],[11.6835,-3.6945],[11.6525,-3.636],[11.5805,-3.5315],[11.5515,-3.5125],[11.483,-3.514],[11.431,-3.591],[11.348,-3.604],[11.223,-3.698],[11.1845,-3.8165],[11.1395,-3.9235],[11.005,-4.101],[11.0905,-4.158],[11.18,-4.2295],[11.219,-4.3125],[11.254,-4.3545],[11.3905,-4.465],[11.584,-4.634],[11.5845,-4.707],[11.6545,-4.894],[11.715,-4.966],[11.8475,-5.149],[12.016,-5.041],[12.0885,-4.9595],[12.166,-4.896],[12.2085,-4.8035],[12.312,-4.8035],[12.3715,-4.7335],[12.399,-4.666],[12.391,-4.611],[12.4465,-4.602],[12.487,-4.565],[12.536,-4.588],[12.5635,-4.5635],[12.638,-4.5635],[12.71,-4.4775],[12.765,-4.507],[12.781,-4.4875],[12.7585,-4.4175],[12.816,-4.4375],[12.853,-4.43],[12.9385,-4.5015],[13.0075,-4.59],[13.1025,-4.684]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/92/Flag_of_the_Republic_of_the_Congo.svg","name:en":"Congo-Brazzaville","wikidata":"Q971","ISO3166-1:alpha2":"CG","ISO3166-1:alpha3":"COG","ISO3166-1:numeric":"178"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[43.0255,-11.737],[43.059,-11.872],[43.1275,-11.971],[43.2045,-12.029],[43.283,-12.056],[43.3915,-12.126],[43.4665,-12.138],[43.422,-12.24],[43.4205,-12.316],[43.4405,-12.452],[43.4955,-12.545],[43.599,-12.608],[43.669,-12.621],[43.745,-12.618],[43.8325,-12.589],[43.913,-12.586],[43.975,-12.563],[44.0335,-12.513],[44.0785,-12.414],[44.077,-12.33],[44.1615,-12.385],[44.2665,-12.432],[44.37,-12.537],[44.45,-12.575],[44.563,-12.579],[44.6215,-12.558],[44.68,-12.514],[44.7205,-12.448],[44.738,-12.388],[44.7435,-12.234],[44.6905,-12.048],[44.6415,-11.955],[44.578,-11.899],[44.5305,-11.878],[44.4435,-11.869],[44.368,-11.89],[44.26,-11.969],[44.1465,-11.969],[44.0595,-12.017],[44.0115,-12.083],[43.9955,-12.139],[43.997,-12.199],[43.9335,-12.155],[43.8015,-12.082],[43.661,-12.049],[43.706,-11.972],[43.721,-11.872],[43.7025,-11.806],[43.659,-11.74],[43.645,-11.674],[43.607,-11.589],[43.6205,-11.435],[43.606,-11.341],[43.55,-11.246],[43.4905,-11.199],[43.4395,-11.179],[43.353,-11.165],[43.227,-11.194],[43.1455,-11.245],[43.1035,-11.295],[43.0755,-11.358],[43.06,-11.456],[43.066,-11.498],[43.056,-11.626],[43.0255,-11.737]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/94/Flag_of_the_Comoros.svg","name:en":"Comoros","wikidata":"Q970","ISO3166-1:alpha2":"KM","ISO3166-1:alpha3":"COM","ISO3166-1:numeric":"174"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[30.5435,-2.413],[30.4715,-2.367],[30.459,-2.3185],[30.4085,-2.31],[30.3735,-2.3525],[30.2925,-2.3735],[30.232,-2.3505],[30.185,-2.427],[30.126,-2.437],[30.061,-2.39],[30.0465,-2.361],[29.9595,-2.3275],[29.944,-2.373],[29.9675,-2.446],[29.9205,-2.5565],[29.9355,-2.642],[29.918,-2.7025],[29.887,-2.7495],[29.8115,-2.771],[29.7695,-2.767],[29.7455,-2.807],[29.708,-2.8195],[29.6585,-2.7875],[29.543,-2.8295],[29.487,-2.8025],[29.4385,-2.7975],[29.3845,-2.821],[29.334,-2.747],[29.3505,-2.7005],[29.328,-2.653],[29.264,-2.6185],[29.2225,-2.632],[29.1495,-2.5915],[29.0625,-2.6015],[29.055,-2.7125],[29.0405,-2.7435],[29.001,-2.7855],[29.006,-2.8165],[29.0515,-2.821],[29.094,-2.882],[29.0965,-2.9205],[29.158,-2.9505],[29.203,-3.0225],[29.2545,-3.0525],[29.2475,-3.1255],[29.2225,-3.198],[29.238,-3.279],[29.2135,-3.295],[29.245,-3.5155],[29.2495,-3.7165],[29.2255,-3.843],[29.244,-3.928],[29.313,-3.9855],[29.3825,-4.117],[29.419,-4.2495],[29.436,-4.449],[29.6595,-4.448],[29.7075,-4.462],[29.7685,-4.4565],[29.765,-4.4275],[29.8155,-4.364],[29.8665,-4.381],[29.8935,-4.3535],[29.9615,-4.3255],[30.006,-4.28],[30.04,-4.2765],[30.078,-4.168],[30.1575,-4.115],[30.215,-4.0465],[30.2135,-3.9905],[30.256,-3.884],[30.308,-3.8455],[30.331,-3.7845],[30.41,-3.7665],[30.388,-3.713],[30.4215,-3.6415],[30.4555,-3.607],[30.451,-3.5605],[30.501,-3.517],[30.618,-3.4665],[30.6775,-3.398],[30.635,-3.3595],[30.6665,-3.3205],[30.826,-3.264],[30.8135,-3.2235],[30.846,-3.206],[30.836,-3.094],[30.816,-3.0395],[30.8375,-2.976],[30.7475,-2.9975],[30.704,-2.9715],[30.668,-2.9935],[30.647,-2.954],[30.5765,-2.8945],[30.5065,-2.9535],[30.4495,-2.913],[30.415,-2.843],[30.439,-2.802],[30.4405,-2.745],[30.4595,-2.691],[30.42,-2.6625],[30.485,-2.556],[30.5435,-2.413]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/5/50/Flag_of_Burundi.svg","name:en":"Burundi","wikidata":"Q967","ISO3166-1:alpha2":"BI","ISO3166-1:alpha3":"BDI","ISO3166-1:numeric":"108"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[72.246,-53.0205],[72.2675,-53.104],[72.3295,-53.173],[72.4245,-53.2215],[72.5885,-53.25],[72.7395,-53.2325],[72.8695,-53.176],[72.9315,-53.1205],[72.982,-53.1195],[73.034,-53.1585],[73.048,-53.2435],[73.0795,-53.2845],[73.194,-53.3525],[73.2925,-53.376],[73.4945,-53.3945],[73.61,-53.391],[73.728,-53.3725],[73.8805,-53.3135],[73.97,-53.3005],[74.0895,-53.26],[74.149,-53.219],[74.202,-53.1325],[74.197,-53.065],[74.1615,-53.009],[74.062,-52.943],[73.918,-52.909],[73.873,-52.8175],[73.8225,-52.7755],[73.7265,-52.7275],[73.5775,-52.703],[73.451,-52.716],[73.334,-52.762],[73.247,-52.764],[73.147,-52.785],[73.041,-52.8315],[72.9485,-52.9075],[72.894,-52.9185],[72.8185,-52.8745],[72.637,-52.824],[72.5125,-52.825],[72.373,-52.864],[72.263,-52.958],[72.246,-53.0205]]],[[[96.6115,-11.8345],[96.6225,-11.903],[96.658,-11.9665],[96.6305,-12.0345],[96.6125,-12.1285],[96.612,-12.1895],[96.635,-12.2735],[96.724,-12.3725],[96.7695,-12.396],[96.908,-12.4115],[97.0065,-12.384],[97.086,-12.319],[97.1205,-12.257],[97.1315,-12.145],[97.1015,-12.0505],[97.0515,-11.9705],[97.0115,-11.93],[97.035,-11.8315],[97.0165,-11.7445],[96.97,-11.6795],[96.8805,-11.629],[96.7655,-11.6295],[96.6705,-11.6885],[96.6325,-11.7465],[96.6115,-11.8345]]],[[[105.33,-10.5125],[105.3445,-10.586],[105.368,-10.6295],[105.433,-10.688],[105.5035,-10.7135],[105.5765,-10.758],[105.635,-10.771],[105.715,-10.7635],[105.761,-10.746],[105.819,-10.701],[105.8525,-10.649],[105.9095,-10.516],[105.9155,-10.4535],[105.9,-10.3665],[105.869,-10.299],[105.8015,-10.238],[105.7405,-10.2155],[105.6295,-10.218],[105.5705,-10.2415],[105.48,-10.2535],[105.407,-10.3005],[105.357,-10.3805],[105.33,-10.5125]]],[[[112.7,-25.5885],[112.7035,-25.638],[112.7455,-25.7625],[112.754,-25.8365],[112.8725,-26.052],[112.9365,-26.119],[112.9465,-26.2195],[113.0015,-26.303],[113.0695,-26.3735],[113.083,-26.458],[113.1105,-26.5105],[113.163,-26.5685],[113.3715,-26.7575],[113.419,-26.811],[113.588,-27.0305],[113.7645,-27.3215],[113.8885,-27.564],[113.926,-27.6775],[113.8805,-27.8275],[113.8845,-27.8945],[113.904,-27.948],[113.965,-28.186],[114.027,-28.2795],[114.0875,-28.3435],[114.152,-28.3785],[114.1955,-28.428],[114.253,-28.519],[114.3185,-28.58],[114.377,-28.6765],[114.3435,-28.789],[114.371,-28.894],[114.4245,-28.9745],[114.5175,-29.0685],[114.6525,-29.192],[114.676,-29.251],[114.6225,-29.3105],[114.597,-29.4135],[114.637,-29.5165],[114.721,-29.5855],[114.716,-29.6235],[114.6675,-29.6665],[114.632,-29.7305],[114.6255,-29.8085],[114.6455,-29.87],[114.706,-29.944],[114.6905,-30.028],[114.7135,-30.107],[114.712,-30.16],[114.7425,-30.24],[114.742,-30.3175],[114.768,-30.48],[114.7905,-30.561],[114.8515,-30.688],[114.997,-30.945],[115.0565,-30.9955],[115.13,-31.147],[115.1215,-31.1985],[115.1475,-31.3125],[115.2075,-31.38],[115.262,-31.41],[115.2935,-31.5115],[115.369,-31.583],[115.416,-31.667],[115.469,-31.7895],[115.4,-31.8085],[115.3135,-31.854],[115.2435,-31.921],[115.217,-31.9785],[115.2125,-32.056],[115.241,-32.126],[115.3305,-32.2015],[115.4275,-32.227],[115.4025,-32.303],[115.4055,-32.379],[115.425,-32.425],[115.428,-32.4945],[115.378,-32.6155],[115.37,-32.6805],[115.3965,-32.8545],[115.4205,-32.938],[115.449,-33.1125],[115.442,-33.192],[115.409,-33.246],[115.376,-33.337],[115.287,-33.434],[115.1975,-33.3805],[115.11,-33.343],[115.0025,-33.3255],[114.9445,-33.3325],[114.8305,-33.39],[114.78,-33.4545],[114.762,-33.531],[114.7665,-33.596],[114.741,-33.6495],[114.74,-33.749],[114.723,-33.7955],[114.734,-33.9065],[114.7315,-34.0025],[114.7485,-34.0445],[114.7635,-34.168],[114.761,-34.289],[114.806,-34.392],[114.902,-34.488],[115.011,-34.567],[115.0895,-34.6105],[115.2315,-34.625],[115.325,-34.6005],[115.375,-34.572],[115.49,-34.622],[115.6245,-34.725],[115.7265,-34.8185],[115.7885,-34.96],[115.8195,-34.992],[115.926,-35.0505],[115.983,-35.066],[116.027,-35.14],[116.083,-35.183],[116.17,-35.213],[116.237,-35.2165],[116.3345,-35.1935],[116.4465,-35.2335],[116.701,-35.2755],[116.821,-35.2575],[116.927,-35.2645],[117.035,-35.244],[117.1445,-35.2685],[117.278,-35.241],[117.331,-35.2445],[117.5275,-35.3215],[117.586,-35.333],[117.6935,-35.33],[117.7575,-35.3695],[117.831,-35.3895],[117.953,-35.384],[118.0035,-35.369],[118.1345,-35.305],[118.19,-35.2595],[118.3405,-35.1845],[118.392,-35.1485],[118.5165,-35.1435],[118.6105,-35.1155],[118.7,-35.0345],[118.7285,-34.9475],[118.73,-34.897],[118.819,-34.8565],[118.946,-34.757],[119.0035,-34.6895],[119.198,-34.7325],[119.333,-34.7245],[119.523,-34.6485],[119.6425,-34.5815],[119.7255,-34.5625],[119.8155,-34.5005],[119.854,-34.434],[119.862,-34.375],[119.8435,-34.3035],[119.8095,-34.256],[119.959,-34.1785],[120.0535,-34.157],[120.121,-34.164],[120.213,-34.1495],[120.262,-34.2275],[120.3685,-34.2875],[120.488,-34.295],[120.6225,-34.25],[120.6775,-34.2045],[120.7745,-34.2625],[120.86,-34.278],[120.962,-34.264],[121.025,-34.2335],[121.085,-34.173],[121.115,-34.072],[121.187,-34.0785],[121.2535,-34.068],[121.416,-34.175],[121.4455,-34.2735],[121.5065,-34.334],[121.623,-34.3755],[121.677,-34.4475],[121.7445,-34.488],[121.765,-34.554],[121.8475,-34.6365],[121.9105,-34.663],[122.0105,-34.674],[122.115,-34.648],[122.207,-34.5725],[122.306,-34.558],[122.3825,-34.5175],[122.437,-34.453],[122.4545,-34.4025],[122.5515,-34.393],[122.8575,-34.334],[123.132,-34.3675],[123.243,-34.351],[123.286,-34.363],[123.3185,-34.4745],[123.388,-34.539],[123.4775,-34.5735],[123.593,-34.5735],[123.7115,-34.519],[123.777,-34.4485],[123.804,-34.3515],[123.854,-34.3075],[123.9895,-34.2905],[124.0545,-34.2535],[124.117,-34.1875],[124.139,-34.1395],[124.144,-34.0655],[124.232,-34.0495],[124.3295,-33.9875],[124.3925,-33.901],[124.4155,-33.826],[124.404,-33.6975],[124.3585,-33.601],[124.312,-33.561],[124.225,-33.525],[124.2445,-33.4395],[124.3015,-33.325],[124.3245,-33.2495],[124.392,-33.1735],[124.5065,-33.1325],[124.7265,-33.108],[124.834,-33.0865],[125.0105,-33.01],[125.094,-32.9455],[125.2165,-32.892],[125.4025,-32.7965],[125.5275,-32.7695],[125.693,-32.701],[125.8325,-32.6],[125.93,-32.5375],[126.0485,-32.4765],[126.118,-32.474],[126.2435,-32.453],[126.3035,-32.471],[126.535,-32.5045],[126.6765,-32.5135],[126.8095,-32.499],[127.0395,-32.499],[127.1255,-32.4825],[127.3085,-32.47],[127.4315,-32.438],[127.5645,-32.4165],[127.6815,-32.364],[127.794,-32.327],[128.0715,-32.273],[128.428,-32.158],[128.7685,-32.0245],[128.854,-31.973],[129.0985,-31.873],[129.4675,-31.836],[129.5545,-31.823],[129.8735,-31.8065],[129.95,-31.791],[130.1315,-31.787],[130.2665,-31.776],[130.5015,-31.7935],[130.5715,-31.789],[130.781,-31.808],[130.911,-31.7905],[131.0705,-31.7395],[131.184,-31.6905],[131.3955,-31.776],[131.5615,-31.854],[131.6955,-31.933],[131.6985,-32.017],[131.7485,-32.1075],[131.82,-32.1575],[131.8895,-32.1785],[131.9165,-32.2425],[131.964,-32.2925],[132.015,-32.3225],[132.0955,-32.343],[132.153,-32.3425],[132.232,-32.321],[132.291,-32.2885],[132.354,-32.2295],[132.4005,-32.2225],[132.8525,-32.3075],[132.9165,-32.35],[132.984,-32.4885],[132.916,-32.5695],[132.899,-32.6395],[132.9065,-32.697],[132.9395,-32.7585],[133.0285,-32.825],[133.1225,-32.8465],[133.2565,-32.848],[133.372,-32.813],[133.7945,-32.8975],[133.856,-33.026],[133.9305,-33.1325],[134.0265,-33.2255],[134.0885,-33.308],[134.1775,-33.3585],[134.3435,-33.513],[134.307,-33.5345],[134.2405,-33.5375],[134.1545,-33.565],[134.0675,-33.642],[134.042,-33.7035],[134.045,-33.7845],[134.063,-33.826],[134.03,-33.882],[134.002,-33.9735],[134.002,-34.0365],[134.0305,-34.108],[134.0685,-34.1505],[134.1645,-34.2005],[134.218,-34.2095],[134.3055,-34.203],[134.419,-34.1495],[134.481,-34.075],[134.5175,-33.966],[134.612,-33.9255],[134.6875,-33.919],[134.8035,-33.8585],[134.8735,-33.923],[134.8775,-33.983],[134.91,-34.0505],[135.0,-34.1235],[134.964,-34.354],[134.9155,-34.402],[134.8885,-34.4535],[134.81,-34.439],[134.7045,-34.4455],[134.5925,-34.505],[134.544,-34.5705],[134.532,-34.6745],[134.487,-34.735],[134.469,-34.8285],[134.489,-34.894],[134.5245,-34.942],[134.609,-34.996],[134.6555,-35.01],[134.764,-35.0115],[134.827,-34.9935],[134.895,-34.951],[134.98,-34.9815],[135.0865,-34.983],[135.209,-34.929],[135.2895,-34.911],[135.3065,-34.987],[135.435,-35.1435],[135.555,-35.2025],[136.0245,-35.6875],[136.3005,-35.9695],[136.3935,-36.0825],[136.449,-36.1225],[136.4715,-36.1745],[136.5305,-36.237],[136.6365,-36.2815],[136.693,-36.3245],[136.7675,-36.352],[136.864,-36.357],[137.0195,-36.306],[136.9955,-36.3625],[136.997,-36.4395],[137.03,-36.506],[137.139,-36.5815],[137.23,-36.5985],[137.3655,-36.571],[137.4435,-36.52],[137.486,-36.4765],[137.522,-36.3835],[137.5175,-36.329],[137.5905,-36.327],[137.696,-36.2895],[137.763,-36.2275],[137.7945,-36.138],[137.847,-36.0705],[138.032,-36.1055],[138.127,-36.093],[138.2455,-36.024],[138.3995,-35.964],[138.4905,-35.899],[138.6855,-35.7955],[138.883,-35.7955],[139.054,-35.9085],[139.2195,-36.0515],[139.3195,-36.157],[139.4325,-36.3095],[139.4825,-36.394],[139.573,-36.588],[139.4915,-36.765],[139.437,-36.792],[139.3755,-36.851],[139.3505,-36.903],[139.3465,-36.9815],[139.3625,-37.0325],[139.4225,-37.104],[139.4755,-37.1345],[139.4795,-37.2005],[139.5065,-37.2695],[139.6755,-37.5075],[139.7985,-37.6145],[139.8685,-37.6895],[140.0165,-37.777],[140.1005,-37.9085],[140.1355,-37.987],[140.22,-38.0705],[140.3255,-38.126],[140.3955,-38.178],[140.572,-38.2505],[140.6725,-38.2635],[140.9155,-38.2535],[141.0065,-38.2935],[141.1105,-38.3595],[141.116,-38.4215],[141.152,-38.488],[141.2315,-38.5525],[141.312,-38.5825],[141.5065,-38.631],[141.574,-38.6315],[141.7295,-38.6055],[141.8235,-38.571],[141.95,-38.622],[142.068,-38.618],[142.1385,-38.593],[142.247,-38.5985],[142.3495,-38.5815],[142.444,-38.605],[142.605,-38.713],[142.721,-38.775],[142.796,-38.8035],[142.956,-38.8325],[143.007,-38.883],[143.0865,-38.9335],[143.231,-38.972],[143.294,-38.9715],[143.3615,-39.0215],[143.454,-39.0535],[143.5135,-39.0585],[143.635,-39.047],[143.699,-39.022],[143.888,-38.889],[144.005,-38.8455],[144.059,-38.804],[144.2075,-38.6535],[144.417,-38.55],[144.499,-38.492],[144.536,-38.49],[144.6445,-38.564],[144.7245,-38.6565],[144.781,-38.6845],[144.882,-38.703],[144.964,-38.699],[145.05,-38.7255],[145.208,-38.7335],[145.35,-38.768],[145.461,-38.846],[145.569,-38.8795],[145.641,-38.8805],[145.666,-38.957],[145.705,-39.0195],[145.786,-39.081],[145.8645,-39.106],[145.968,-39.108],[145.9935,-39.1865],[146.0395,-39.2465],[146.1535,-39.327],[146.254,-39.4085],[146.3315,-39.5075],[146.3925,-39.5385],[146.434,-39.629],[146.5125,-39.69],[146.6325,-39.7215],[146.7465,-39.709],[146.834,-39.666],[146.889,-39.606],[146.956,-39.6755],[147.025,-39.7095],[146.996,-39.7535],[146.9815,-39.8425],[147.0095,-39.9145],[147.0735,-39.976],[147.202,-40.02],[147.319,-40.0125],[147.423,-39.964],[147.47,-40.014],[147.46,-40.146],[147.539,-40.3725],[147.6005,-40.444],[147.773,-40.584],[147.58,-40.5845],[147.4725,-40.625],[147.423,-40.667],[147.2905,-40.6325],[147.186,-40.641],[147.107,-40.6715],[147.0275,-40.744],[146.9515,-40.743],[146.8625,-40.764],[146.7595,-40.8365],[146.624,-40.867],[146.5195,-40.918],[146.334,-40.954],[146.27,-40.9505],[146.1,-40.889],[145.96,-40.846],[145.896,-40.7895],[145.758,-40.745],[145.6795,-40.6775],[145.6185,-40.6525],[145.531,-40.64],[145.4805,-40.5865],[145.21,-40.3345],[145.1795,-40.287],[145.071,-40.2115],[144.982,-40.192],[144.8905,-40.188],[144.786,-40.197],[144.714,-40.1755],[144.6035,-40.1745],[144.5185,-40.2],[144.43,-40.2465],[144.407,-40.163],[144.3545,-40.1045],[144.386,-40.027],[144.398,-39.917],[144.423,-39.855],[144.4215,-39.768],[144.369,-39.6865],[144.354,-39.603],[144.324,-39.557],[144.148,-39.412],[144.0175,-39.361],[143.8565,-39.362],[143.7705,-39.3725],[143.665,-39.4255],[143.63,-39.462],[143.567,-39.6095],[143.5545,-39.6715],[143.5925,-39.817],[143.57,-39.9175],[143.6015,-40.0225],[143.599,-40.0965],[143.6255,-40.1765],[143.677,-40.25],[143.775,-40.33],[143.858,-40.359],[143.9305,-40.3655],[144.005,-40.433],[144.0775,-40.462],[144.1035,-40.5605],[144.197,-40.641],[144.2805,-40.669],[144.3685,-40.6745],[144.4105,-40.7135],[144.423,-40.7775],[144.3585,-40.8725],[144.3395,-41.003],[144.353,-41.074],[144.3995,-41.146],[144.4075,-41.2365],[144.4795,-41.393],[144.4795,-41.4395],[144.5125,-41.52],[144.6305,-41.6535],[144.6465,-41.74],[144.6835,-41.821],[144.777,-41.895],[144.8705,-41.9875],[144.9635,-42.062],[144.909,-42.132],[144.896,-42.1825],[144.9025,-42.3105],[144.927,-42.4025],[144.9545,-42.446],[144.9635,-42.56],[145.002,-42.679],[145.0435,-42.744],[145.105,-42.7915],[145.141,-42.8785],[145.153,-42.943],[145.2205,-43.026],[145.25,-43.088],[145.3025,-43.1375],[145.4195,-43.1855],[145.501,-43.265],[145.578,-43.417],[145.6575,-43.4765],[145.676,-43.511],[145.754,-43.5785],[145.7725,-43.6435],[145.8095,-43.692],[145.8965,-43.747],[146.136,-43.847],[146.2075,-43.903],[146.314,-43.938],[146.387,-43.9425],[146.4885,-43.9245],[146.605,-43.852],[146.6975,-43.848],[146.704,-43.906],[146.7445,-43.9735],[146.8545,-44.0415],[146.979,-44.061],[147.0805,-44.048],[147.203,-44.002],[147.2585,-43.9565],[147.2985,-43.8815],[147.301,-43.83],[147.2685,-43.752],[147.423,-43.712],[148.136,-43.422],[148.219,-43.371],[148.2645,-43.313],[148.3265,-43.155],[148.431,-42.7065],[148.597,-42.415],[148.6155,-42.3465],[148.6245,-42.084],[148.574,-41.996],[148.5895,-41.943],[148.5645,-41.796],[148.5665,-41.7025],[148.5875,-41.5975],[148.554,-41.48],[148.6035,-41.411],[148.6335,-41.269],[148.6025,-41.1925],[148.556,-41.1325],[148.601,-41.0775],[148.621,-40.985],[148.5805,-40.8555],[148.4755,-40.723],[148.518,-40.675],[148.585,-40.6305],[148.689,-40.582],[148.742,-40.5235],[148.7655,-40.4365],[148.7495,-40.3665],[148.7045,-40.2945],[148.6575,-40.2465],[148.657,-40.1915],[148.6305,-40.1275],[148.5785,-40.0745],[148.6245,-39.979],[148.613,-39.889],[148.571,-39.8255],[148.472,-39.762],[148.381,-39.7355],[148.2905,-39.7335],[148.26,-39.7065],[148.2695,-39.6315],[148.2345,-39.5475],[148.186,-39.499],[148.0835,-39.4505],[147.993,-39.4365],[147.9205,-39.442],[147.832,-39.4735],[147.746,-39.4305],[147.6355,-39.403],[147.6145,-39.3555],[147.5505,-39.291],[147.436,-39.246],[147.282,-39.235],[147.274,-39.128],[147.221,-39.058],[147.162,-39.02],[147.0705,-38.994],[146.955,-38.999],[146.9625,-38.95],[146.94,-38.867],[147.014,-38.827],[147.2455,-38.6195],[147.653,-38.2965],[147.852,-38.1625],[148.027,-38.087],[148.2605,-38.022],[148.4605,-38.0025],[148.657,-38.008],[148.792,-38.0195],[148.9595,-37.9815],[149.149,-37.98],[149.257,-38.006],[149.323,-38.006],[149.42,-37.979],[149.546,-37.971],[149.615,-37.9485],[149.813,-37.8545],[149.906,-37.7705],[150.0005,-37.7595],[150.11,-37.7005],[150.209,-37.583],[150.2295,-37.5085],[150.2225,-37.41],[150.2895,-37.327],[150.2985,-37.2255],[150.2475,-37.0885],[150.1985,-37.0135],[150.191,-36.9065],[150.2425,-36.727],[150.308,-36.6085],[150.313,-36.5175],[150.3325,-36.441],[150.404,-36.4005],[150.467,-36.314],[150.471,-36.197],[150.434,-36.1295],[150.3915,-36.0915],[150.41,-35.977],[150.4585,-35.92],[150.482,-35.84],[150.5665,-35.699],[150.643,-35.618],[150.6655,-35.513],[150.71,-35.462],[150.735,-35.398],[150.8185,-35.374],[150.9015,-35.3315],[150.9625,-35.2775],[150.9905,-35.228],[151.051,-35.1655],[151.0915,-35.037],[151.0845,-34.9595],[151.036,-34.882],[151.103,-34.7165],[151.146,-34.633],[151.188,-34.471],[151.174,-34.3975],[151.195,-34.349],[151.2975,-34.28],[151.4195,-34.153],[151.4645,-34.093],[151.498,-34.022],[151.546,-33.835],[151.564,-33.706],[151.6595,-33.578],[151.721,-33.448],[151.792,-33.3745],[151.8545,-33.2615],[151.876,-33.195],[151.9535,-33.0765],[152.017,-33.0075],[152.065,-32.9915],[152.173,-32.9875],[152.337,-32.9165],[152.385,-32.881],[152.4485,-32.8015],[152.508,-32.763],[152.566,-32.674],[152.6415,-32.658],[152.736,-32.5945],[152.777,-32.527],[152.789,-32.475],[152.7765,-32.3965],[152.785,-32.305],[152.8065,-32.2115],[152.778,-32.1195],[152.8175,-32.0515],[152.909,-31.996],[152.9735,-31.917],[152.989,-31.855],[153.0765,-31.692],[153.084,-31.633],[153.15,-31.561],[153.1675,-31.5155],[153.17,-31.4315],[153.2065,-31.351],[153.213,-31.227],[153.251,-31.1885],[153.2935,-31.0975],[153.335,-30.931],[153.2955,-30.8105],[153.2325,-30.7295],[153.2655,-30.551],[153.374,-30.3855],[153.447,-30.3345],[153.4865,-30.2745],[153.499,-30.183],[153.478,-30.119],[153.549,-30.0805],[153.6095,-30.002],[153.6235,-29.932],[153.6075,-29.8565],[153.5415,-29.7645],[153.5615,-29.703],[153.5725,-29.607],[153.5965,-29.5095],[153.6015,-29.333],[153.66,-29.2785],[153.6945,-29.1875],[153.68,-29.094],[153.7895,-28.9765],[153.828,-28.8995],[153.8335,-28.791],[153.8615,-28.677],[153.8655,-28.6165],[153.8355,-28.5275],[153.7855,-28.466],[153.807,-28.3735],[153.8125,-28.247],[153.8015,-28.154],[153.7665,-28.0805],[153.7,-28.0115],[153.6575,-27.985],[153.653,-27.8875],[153.7,-27.6305],[153.7635,-27.4945],[153.78,-27.4115],[153.772,-27.346],[153.701,-27.044],[153.714,-26.9785],[153.696,-26.899],[153.6555,-26.8415],[153.564,-26.7875],[153.475,-26.7765],[153.3625,-26.696],[153.36,-26.6455],[153.321,-26.5035],[153.341,-26.415],[153.3305,-26.3135],[153.2975,-26.258],[153.3405,-26.127],[153.404,-25.9955],[153.408,-25.887],[153.383,-25.83],[153.3105,-25.76],[153.3,-25.687],[153.3545,-25.5365],[153.4135,-25.404],[153.567,-25.0775],[153.579,-25.0275],[153.567,-24.923],[153.544,-24.8675],[153.4815,-24.8015],[153.4915,-24.6905],[153.4615,-24.5715],[153.3685,-24.484],[153.3205,-24.464],[153.2385,-24.456],[153.167,-24.4725],[153.1095,-24.5065],[152.4755,-24.5475],[152.3805,-24.5275],[152.286,-24.4615],[152.2185,-24.3725],[152.15,-24.1735],[151.9675,-23.8795],[151.9175,-23.8235],[151.8435,-23.785],[151.7615,-23.761],[151.862,-23.727],[151.9585,-23.7925],[152.02,-23.8625],[152.0875,-23.896],[152.125,-23.9475],[152.183,-23.9895],[152.213,-24.037],[152.2625,-24.08],[152.3565,-24.115],[152.4385,-24.1165],[152.4915,-24.104],[152.4965,-24.159],[152.531,-24.2315],[152.607,-24.2935],[152.7005,-24.3185],[152.7825,-24.3095],[152.8505,-24.2785],[152.903,-24.229],[152.9415,-24.1295],[152.9315,-24.05],[152.8635,-23.956],[152.7855,-23.916],[152.7275,-23.9065],[152.6495,-23.916],[152.6335,-23.8175],[152.572,-23.737],[152.4885,-23.674],[152.4405,-23.607],[152.398,-23.5755],[152.373,-23.5165],[152.308,-23.45],[152.2425,-23.3175],[152.186,-23.2565],[152.116,-23.101],[152.053,-23.0245],[151.9795,-22.9865],[151.925,-22.977],[151.8475,-22.984],[151.741,-23.043],[151.6985,-23.055],[151.5475,-23.146],[151.4855,-23.2445],[151.479,-23.3255],[151.5105,-23.4075],[151.4755,-23.446],[151.3815,-23.321],[151.2965,-23.102],[151.212,-22.7025],[151.1515,-22.5575],[151.121,-22.5185],[150.965,-22.3715],[150.9315,-22.2865],[150.8955,-22.0905],[150.916,-21.9815],[150.916,-21.9245],[150.882,-21.8405],[150.8205,-21.7765],[150.6045,-21.626],[150.555,-21.58],[150.5095,-21.3935],[150.471,-21.335],[150.395,-21.2555],[150.426,-21.2165],[150.471,-21.1045],[150.4725,-21.0355],[150.4555,-20.983],[150.4085,-20.92],[150.3675,-20.8905],[150.283,-20.864],[150.1795,-20.754],[150.069,-20.7025],[149.959,-20.7105],[149.8725,-20.763],[149.7975,-20.645],[149.7535,-20.602],[149.6705,-20.565],[149.5375,-20.5365],[149.3575,-20.455],[149.395,-20.2895],[149.3895,-20.196],[149.322,-20.096],[149.109,-19.9115],[149.0395,-19.8715],[148.912,-19.837],[148.6765,-19.8165],[148.571,-19.787],[148.5695,-19.673],[148.523,-19.595],[148.4815,-19.56],[148.3995,-19.526],[148.3215,-19.5245],[148.245,-19.5515],[148.1775,-19.6145],[148.1525,-19.667],[148.046,-19.6595],[148.0085,-19.5985],[147.9575,-19.5535],[147.895,-19.5205],[147.819,-19.508],[147.761,-19.472],[147.672,-19.3415],[147.6435,-19.268],[147.604,-19.2105],[147.5475,-19.154],[147.4975,-19.125],[147.2105,-19.033],[147.163,-19.0005],[147.045,-18.9665],[146.982,-18.837],[147.084,-18.845],[147.145,-18.828],[147.2505,-18.7525],[147.3245,-18.717],[147.3865,-18.6485],[147.413,-18.568],[147.41,-18.5055],[147.3435,-18.339],[147.315,-18.2905],[147.26,-18.24],[147.1705,-18.207],[147.1855,-18.122],[147.1785,-18.077],[147.1325,-17.995],[147.082,-17.9545],[146.998,-17.8625],[146.963,-17.802],[146.8755,-17.7025],[146.8325,-17.6355],[146.756,-17.585],[146.6705,-17.4765],[146.5845,-17.426],[146.512,-17.4165],[146.4415,-17.4315],[146.3155,-17.5035],[146.2945,-17.471],[146.282,-17.401],[146.3785,-17.383],[146.463,-17.3205],[146.4955,-17.2675],[146.5135,-17.173],[146.485,-17.0725],[146.4995,-17.001],[146.541,-16.948],[146.5635,-16.875],[146.546,-16.771],[146.4955,-16.703],[146.4115,-16.6245],[146.307,-16.58],[146.2125,-16.4155],[146.198,-16.35],[146.1505,-16.2785],[146.0885,-16.2365],[145.964,-16.1995],[145.941,-16.0635],[145.914,-16.008],[145.869,-15.9595],[145.8475,-15.894],[145.8125,-15.846],[145.8255,-15.7515],[145.846,-15.719],[145.867,-15.635],[145.855,-15.562],[145.807,-15.4855],[145.7515,-15.438],[145.7565,-15.359],[145.8,-15.314],[145.8265,-15.2605],[145.8455,-15.168],[145.891,-15.116],[145.92,-15.049],[145.9415,-14.895],[145.9405,-14.8275],[145.921,-14.7215],[145.8925,-14.6295],[145.773,-14.4315],[145.669,-14.3185],[145.511,-14.2105],[145.2985,-14.1095],[145.2065,-14.083],[145.1465,-14.0525],[145.054,-14.0305],[144.993,-14.0015],[144.979,-13.944],[144.9115,-13.856],[144.828,-13.814],[144.789,-13.773],[144.713,-13.732],[144.581,-13.7165],[144.5045,-13.741],[144.4205,-13.6145],[144.346,-13.553],[144.3105,-13.4695],[144.2365,-13.3355],[144.199,-13.298],[144.1775,-13.1765],[144.184,-13.071],[144.1555,-12.9825],[144.1165,-12.9195],[144.0595,-12.875],[144.06,-12.8185],[144.0305,-12.695],[143.994,-12.623],[144.005,-12.5425],[144.0685,-12.42],[144.1315,-12.329],[144.153,-12.1925],[144.187,-12.063],[144.216,-11.9895],[144.2735,-11.9205],[144.3135,-11.7655],[144.3015,-11.6665],[144.2725,-11.611],[144.297,-11.5405],[144.298,-11.4845],[144.261,-11.354],[144.282,-11.2595],[144.2775,-11.187],[144.2575,-11.12],[144.191,-11.039],[144.127,-11.008],[144.0595,-10.9965],[143.9705,-11.008],[143.909,-11.044],[143.853,-11.1195],[143.7905,-11.116],[143.707,-11.1425],[143.639,-11.203],[143.5885,-11.3275],[143.51,-11.375],[143.4625,-11.2815],[143.4725,-11.0935],[143.604,-11.096],[143.654,-11.078],[143.708,-11.0375],[143.7445,-10.9855],[143.8025,-10.9415],[143.8475,-10.8665],[143.8575,-10.793],[143.849,-10.742],[143.8745,-10.656],[143.869,-10.592],[143.8365,-10.523],[143.7665,-10.4615],[143.699,-10.439],[143.66,-10.38],[143.698,-10.286],[143.736,-10.269],[143.779,-10.2985],[143.882,-10.321],[143.956,-10.35],[144.028,-10.352],[144.083,-10.3405],[144.1815,-10.2735],[144.2245,-10.1865],[144.3265,-10.0775],[144.35,-10.0265],[144.404,-9.984],[144.45,-9.902],[144.4545,-9.8085],[144.4005,-9.6755],[144.3025,-9.5765],[144.256,-9.5495],[144.251,-9.4985],[143.801,-9.365],[143.501,-9.3985],[143.3345,-9.5485],[143.346,-9.501],[143.3025,-9.46],[143.238,-9.495],[143.2485,-9.5485],[143.0845,-9.5485],[143.001,-9.665],[142.3845,-9.6985],[142.001,-9.765],[141.9455,-9.7995],[141.9075,-9.8475],[141.8795,-9.923],[141.858,-10.0225],[141.849,-10.174],[141.834,-10.255],[141.837,-10.311],[141.7245,-10.5175],[141.7065,-10.5765],[141.707,-10.635],[141.7305,-10.7035],[141.812,-10.8815],[141.8,-10.942],[141.819,-11.0665],[141.861,-11.1465],[141.9155,-11.1905],[141.9095,-11.345],[141.861,-11.463],[141.8465,-11.53],[141.807,-11.6155],[141.719,-11.66],[141.672,-11.7185],[141.6555,-11.761],[141.6505,-11.8355],[141.664,-11.8865],[141.627,-11.954],[141.569,-12.0885],[141.521,-12.1585],[141.464,-12.3435],[141.391,-12.492],[141.379,-12.538],[141.39,-12.923],[141.375,-13.004],[141.442,-13.2445],[141.4135,-13.344],[141.3595,-13.426],[141.3075,-13.588],[141.287,-13.7335],[141.2625,-13.8455],[141.2625,-13.9345],[141.2925,-14.034],[141.378,-14.1495],[141.3865,-14.2345],[141.3535,-14.316],[141.3205,-14.4595],[141.321,-14.514],[141.3475,-14.621],[141.3595,-14.7535],[141.393,-14.918],[141.432,-15.012],[141.3685,-15.141],[141.3675,-15.2255],[141.342,-15.2715],[141.3285,-15.3405],[141.2795,-15.444],[141.227,-15.6335],[141.2115,-15.7915],[141.173,-15.865],[141.166,-15.9265],[141.2,-16.059],[141.15,-16.133],[141.124,-16.2325],[141.068,-16.325],[141.0595,-16.4335],[141.015,-16.5645],[140.9925,-16.6055],[140.904,-16.6795],[140.867,-16.783],[140.8015,-16.836],[140.7215,-16.9865],[140.708,-17.0505],[140.7145,-17.117],[140.6885,-17.2385],[140.6095,-17.2775],[140.5,-17.15],[140.4835,-17.1665],[140.5915,-17.293],[140.525,-17.369],[140.4555,-17.3905],[140.397,-17.4335],[140.3135,-17.473],[140.194,-17.463],[140.09,-17.479],[140.0055,-17.4325],[139.917,-17.369],[139.7665,-17.322],[139.807,-17.282],[139.841,-17.216],[139.8575,-17.1085],[140.012,-16.829],[140.068,-16.771],[140.094,-16.719],[140.108,-16.643],[140.0885,-16.5585],[139.998,-16.3945],[139.93,-16.308],[139.893,-16.276],[139.809,-16.2425],[139.765,-16.239],[139.7,-16.2115],[139.631,-16.202],[139.358,-16.0555],[139.283,-16.03],[139.17,-16.0455],[139.0835,-16.111],[139.0515,-16.1725],[139.0425,-16.228],[139.035,-16.438],[138.982,-16.504],[138.913,-16.543],[138.8505,-16.626],[138.6915,-16.5675],[138.634,-16.5585],[138.5485,-16.5715],[138.4905,-16.543],[138.397,-16.521],[138.321,-16.482],[138.2415,-16.4755],[138.092,-16.3275],[138.0335,-16.2885],[137.9555,-16.19],[137.8975,-16.0895],[137.8275,-16.04],[137.7285,-16.0185],[137.649,-15.9845],[137.525,-15.9545],[137.461,-15.9305],[137.419,-15.875],[137.3245,-15.8205],[137.302,-15.584],[137.282,-15.526],[137.2415,-15.473],[137.085,-15.3405],[136.9735,-15.2885],[136.887,-15.286],[136.836,-15.3015],[136.613,-15.2935],[136.3495,-15.218],[136.32,-15.1865],[136.2865,-15.0625],[136.246,-15.012],[136.173,-14.97],[136.091,-14.907],[135.9775,-14.8835],[135.9755,-14.8345],[135.9465,-14.757],[135.972,-14.7125],[135.9885,-14.6105],[136.073,-14.5575],[136.115,-14.499],[136.136,-14.4265],[136.345,-14.4465],[136.4095,-14.43],[136.477,-14.448],[136.5545,-14.4955],[136.696,-14.525],[136.728,-14.5855],[136.7785,-14.6325],[136.8425,-14.66],[136.924,-14.664],[136.9935,-14.6405],[137.053,-14.592],[137.096,-14.4995],[137.144,-14.4315],[137.189,-14.2945],[137.191,-14.157],[137.138,-13.8315],[137.1385,-13.791],[137.177,-13.6265],[137.1665,-13.556],[137.1175,-13.478],[136.897,-13.01],[136.931,-12.933],[136.929,-12.7765],[136.949,-12.701],[137.0085,-12.6695],[137.065,-12.603],[137.085,-12.5445],[137.161,-12.4655],[137.1845,-12.382],[137.1785,-12.2965],[137.085,-11.9895],[137.0355,-11.583],[136.9715,-11.032],[136.96,-10.952],[136.9305,-10.8885],[136.855,-10.822],[136.7335,-10.796],[136.6655,-10.808],[136.5945,-10.852],[136.555,-10.903],[136.498,-11.049],[136.4615,-11.087],[136.3845,-11.2235],[136.3205,-11.2915],[136.049,-11.3505],[135.9975,-11.3755],[135.912,-11.441],[135.8615,-11.458],[135.793,-11.5125],[135.7585,-11.5735],[135.6735,-11.666],[135.649,-11.7305],[135.564,-11.7435],[135.5135,-11.7385],[135.4885,-11.6325],[135.4145,-11.533],[135.293,-11.433],[135.237,-11.412],[135.1775,-11.408],[135.1055,-11.4265],[135.031,-11.485],[134.955,-11.5955],[134.9385,-11.644],[134.9375,-11.7165],[134.7815,-11.7395],[134.6795,-11.7095],[134.6115,-11.7185],[134.536,-11.76],[134.459,-11.8485],[134.364,-11.7465],[134.3045,-11.7015],[134.12,-11.656],[134.022,-11.562],[133.8885,-11.5195],[133.818,-11.5155],[133.6965,-11.544],[133.6975,-11.484],[133.649,-11.3665],[133.6,-11.311],[133.517,-11.2685],[133.4055,-11.272],[133.311,-11.303],[133.2665,-11.3275],[133.2195,-11.3765],[133.1255,-11.269],[133.206,-11.157],[133.223,-11.075],[133.217,-11.015],[133.246,-10.9405],[133.233,-10.828],[133.187,-10.76],[133.1245,-10.719],[133.0235,-10.702],[132.9595,-10.7145],[132.8775,-10.769],[132.8425,-10.764],[132.576,-10.763],[132.4825,-10.7885],[132.434,-10.8195],[132.382,-10.8325],[132.233,-10.9025],[132.066,-10.9215],[131.9435,-10.9205],[131.8245,-10.957],[131.2885,-10.9855],[131.2165,-10.992],[131.159,-11.0115],[131.1055,-11.0505],[131.0095,-11.0805],[130.9465,-11.0645],[130.882,-11.069],[130.8285,-11.0895],[130.77,-11.138],[130.696,-11.0855],[130.609,-11.0595],[130.4415,-10.915],[130.368,-10.8905],[130.3075,-10.8885],[130.2355,-10.91],[130.144,-10.991],[130.119,-11.049],[130.067,-11.2275],[130.0435,-11.2725],[129.9685,-11.3755],[129.9415,-11.4635],[129.8715,-11.6285],[129.827,-11.697],[129.816,-11.81],[129.836,-11.8815],[129.8705,-11.935],[130.0925,-12.5855],[130.108,-12.6805],[130.0575,-12.7035],[130.0045,-12.751],[129.9645,-12.8085],[129.93,-12.886],[129.8875,-12.909],[129.8155,-12.993],[129.785,-13.104],[129.7915,-13.187],[129.738,-13.2905],[129.6615,-13.3665],[129.626,-13.4175],[129.6005,-13.501],[129.603,-13.553],[129.569,-13.6005],[129.5495,-13.661],[129.4725,-13.6365],[129.401,-13.6405],[129.3075,-13.6895],[129.2545,-13.7655],[129.1945,-13.8205],[129.1625,-13.8855],[129.1585,-13.972],[129.204,-14.0675],[129.244,-14.1035],[129.2045,-14.176],[129.1625,-14.2805],[129.147,-14.36],[129.0815,-14.449],[128.993,-14.4285],[128.938,-14.435],[128.9025,-14.406],[128.8225,-14.374],[128.7745,-14.3715],[128.6765,-14.401],[128.6205,-14.45],[128.5885,-14.5075],[128.5335,-14.4195],[128.4845,-14.386],[128.374,-14.363],[128.2915,-14.3845],[128.2355,-14.3425],[128.1375,-14.316],[128.05,-14.333],[128.0035,-14.2465],[127.9415,-14.1865],[127.878,-14.102],[127.7045,-13.9405],[127.6555,-13.912],[127.6095,-13.834],[127.556,-13.7785],[127.48,-13.742],[127.41,-13.6515],[127.3295,-13.6095],[127.2495,-13.603],[127.1565,-13.632],[127.074,-13.544],[127.005,-13.496],[126.935,-13.479],[126.826,-13.4975],[126.765,-13.5295],[126.399,-13.548],[126.3165,-13.542],[126.2785,-13.4495],[126.188,-13.3805],[126.115,-13.366],[126.092,-13.3175],[126.0395,-13.2625],[125.973,-13.2315],[125.858,-13.2335],[125.778,-13.279],[125.746,-13.317],[125.718,-13.3835],[125.657,-13.407],[125.5945,-13.4635],[125.558,-13.5545],[125.56,-13.619],[125.5935,-13.6955],[125.467,-13.789],[125.425,-13.863],[125.311,-13.858],[125.2345,-13.893],[125.103,-13.997],[125.065,-14.0755],[125.0305,-14.0985],[124.976,-14.1645],[124.8525,-14.2205],[124.7955,-14.2315],[124.7065,-14.2905],[124.651,-14.3775],[124.632,-14.4805],[124.651,-14.558],[124.551,-14.7235],[124.441,-14.803],[124.23,-14.867],[124.165,-14.9185],[124.1405,-14.956],[124.078,-14.991],[124.0125,-15.0875],[123.969,-15.112],[123.916,-15.1665],[123.8865,-15.232],[123.8895,-15.3425],[123.811,-15.421],[123.8,-15.404],[123.819,-15.3275],[123.811,-15.264],[123.752,-15.172],[123.6865,-15.1325],[123.5475,-15.096],[123.487,-15.096],[123.4085,-15.12],[123.3605,-15.1545],[123.312,-15.2275],[123.2165,-15.23],[123.1325,-15.208],[123.081,-15.207],[123.002,-15.2305],[122.919,-15.3065],[122.8895,-15.3745],[122.884,-15.4805],[122.8985,-15.566],[122.936,-15.648],[123.018,-15.7355],[123.1235,-15.792],[123.2335,-15.8025],[123.18,-15.8425],[123.056,-15.912],[123.0015,-15.966],[122.966,-16.0725],[122.9145,-16.129],[122.765,-16.251],[122.6785,-16.388],[122.5755,-16.483],[122.5305,-16.565],[122.4545,-16.6],[122.408,-16.643],[122.356,-16.7275],[122.2985,-16.6775],[122.2265,-16.6455],[122.138,-16.6315],[122.004,-16.6535],[121.952,-16.681],[121.892,-16.749],[121.8665,-16.8345],[121.872,-16.8935],[121.9065,-16.966],[122.018,-17.062],[122.006,-17.1325],[121.955,-17.239],[121.934,-17.327],[121.929,-17.472],[121.9355,-17.582],[121.976,-17.6885],[121.977,-17.824],[121.99,-17.8685],[121.974,-17.91],[121.942,-18.161],[121.875,-18.232],[121.7795,-18.2445],[121.6825,-18.2845],[121.542,-18.431],[121.4965,-18.524],[121.428,-18.5745],[121.382,-18.6635],[121.3815,-18.7455],[121.4005,-18.7975],[121.3545,-18.8685],[121.3045,-19.0045],[121.117,-19.229],[121.076,-19.271],[120.9335,-19.3885],[120.8315,-19.451],[120.598,-19.5525],[120.4185,-19.6135],[120.3205,-19.6255],[120.211,-19.686],[120.058,-19.687],[119.9085,-19.7145],[119.7975,-19.755],[119.71,-19.7605],[119.5855,-19.8185],[119.402,-19.7785],[119.338,-19.7395],[119.27,-19.7235],[119.2985,-19.6795],[119.32,-19.592],[119.309,-19.517],[119.2725,-19.4545],[119.179,-19.389],[119.0585,-19.3765],[118.9755,-19.4045],[118.9145,-19.4575],[118.885,-19.509],[118.872,-19.576],[118.8915,-19.667],[118.791,-19.693],[118.701,-19.7715],[118.6665,-19.8535],[118.611,-19.9155],[118.584,-20.002],[118.5905,-20.0675],[118.4665,-20.084],[118.308,-20.114],[118.2495,-20.135],[118.1455,-20.129],[118.0515,-20.1685],[118.0135,-20.2045],[117.919,-20.252],[117.8535,-20.271],[117.777,-20.3175],[117.6895,-20.3915],[117.5195,-20.479],[117.4025,-20.501],[117.252,-20.292],[117.2,-20.2555],[117.1015,-20.228],[117.0265,-20.225],[116.9225,-20.167],[116.865,-20.152],[116.771,-20.16],[116.495,-20.272],[115.6895,-20.2095],[115.5675,-20.151],[115.474,-20.081],[115.4025,-20.066],[115.298,-20.086],[115.247,-20.1185],[115.1875,-20.1855],[115.1645,-20.2435],[115.1625,-20.3135],[115.1865,-20.382],[115.2445,-20.4455],[115.2295,-20.578],[115.151,-20.661],[115.107,-20.765],[115.091,-20.885],[115.067,-20.932],[114.868,-21.124],[114.64,-21.3495],[114.462,-21.4005],[114.315,-21.4335],[114.236,-21.4745],[114.1465,-21.561],[114.0815,-21.579],[114.0285,-21.612],[113.891,-21.6755],[113.844,-21.7045],[113.764,-21.781],[113.718,-21.863],[113.681,-22.012],[113.6165,-22.1885],[113.5675,-22.26],[113.5035,-22.3845],[113.474,-22.4255],[113.408,-22.5965],[113.406,-22.688],[113.437,-22.8085],[113.4655,-22.869],[113.5545,-22.9575],[113.515,-23.0825],[113.558,-23.336],[113.5515,-23.3975],[113.5045,-23.4265],[113.4445,-23.4905],[113.379,-23.6185],[113.317,-23.712],[113.2645,-23.8305],[113.2455,-23.924],[113.204,-24.0325],[113.203,-24.12],[113.1745,-24.1955],[113.185,-24.3155],[113.181,-24.422],[112.9915,-24.6205],[112.9285,-24.737],[112.909,-24.825],[112.902,-24.9475],[112.867,-25.0605],[112.871,-25.1385],[112.8485,-25.2405],[112.7875,-25.361],[112.715,-25.4705],[112.7,-25.5885]]],[[[113.347,-28.2875],[113.3635,-28.3765],[113.441,-28.536],[113.488,-28.8025],[113.531,-28.886],[113.6865,-29.072],[113.812,-29.1615],[113.891,-29.188],[114.003,-29.1895],[114.0695,-29.167],[114.1585,-29.0905],[114.2245,-28.9685],[114.264,-28.85],[114.265,-28.755],[114.234,-28.6905],[114.087,-28.527],[114.024,-28.38],[113.988,-28.33],[113.8855,-28.2645],[113.7035,-28.096],[113.6495,-28.0745],[113.5575,-28.0675],[113.494,-28.0825],[113.416,-28.1305],[113.3775,-28.18],[113.347,-28.2875]]],[[[118.6745,-17.605],[118.6855,-17.675],[118.721,-17.7425],[118.763,-17.7905],[118.838,-17.8405],[118.95,-17.8615],[119.0285,-17.842],[119.1295,-17.7635],[119.172,-17.6835],[119.1865,-17.63],[119.183,-17.523],[119.291,-17.5865],[119.3775,-17.594],[119.439,-17.5795],[119.4925,-17.55],[119.5635,-17.4645],[119.585,-17.4105],[119.5915,-17.305],[119.558,-17.1805],[119.5115,-17.115],[119.455,-17.0725],[119.3585,-17.044],[119.2845,-17.051],[119.2385,-17.07],[119.1745,-17.12],[119.128,-17.196],[119.105,-17.281],[119.105,-17.3545],[119.0515,-17.3175],[118.949,-17.2945],[118.829,-17.3305],[118.76,-17.3965],[118.6885,-17.531],[118.6745,-17.605]]],[[[121.5105,-14.146],[121.5295,-14.2375],[121.559,-14.2855],[121.639,-14.3555],[121.739,-14.4],[121.811,-14.413],[121.897,-14.403],[122.0415,-14.332],[122.125,-14.2625],[122.1795,-14.155],[122.183,-14.0595],[122.153,-13.972],[122.134,-13.8785],[122.2085,-13.824],[122.244,-13.7675],[122.26,-13.7055],[122.256,-13.641],[122.2275,-13.5725],[122.181,-13.5065],[122.1295,-13.4625],[122.0325,-13.426],[121.9565,-13.428],[121.8965,-13.449],[121.8195,-13.5165],[121.783,-13.581],[121.7705,-13.694],[121.7035,-13.7345],[121.651,-13.808],[121.617,-13.9],[121.537,-14.012],[121.5105,-14.146]]],[[[122.723,-12.2385],[122.7365,-12.314],[122.7705,-12.372],[122.8445,-12.432],[122.924,-12.475],[122.9845,-12.494],[123.1825,-12.494],[123.243,-12.47],[123.3155,-12.4005],[123.3365,-12.357],[123.361,-12.254],[123.3365,-12.137],[123.304,-12.079],[123.2325,-12.0165],[123.092,-11.9755],[123.0155,-11.9785],[122.9175,-12.028],[122.845,-12.053],[122.7865,-12.0935],[122.7335,-12.1765],[122.723,-12.2385]]],[[[123.33,-12.538],[123.3435,-12.611],[123.391,-12.6845],[123.4315,-12.7165],[123.5045,-12.744],[123.571,-12.747],[123.6535,-12.7255],[123.7075,-12.693],[123.769,-12.6115],[123.786,-12.5375],[123.7825,-12.4915],[123.7445,-12.408],[123.653,-12.341],[123.5535,-12.323],[123.462,-12.34],[123.4025,-12.3765],[123.352,-12.442],[123.33,-12.538]]],[[[123.3315,-14.109],[123.355,-14.2045],[123.427,-14.284],[123.4915,-14.3135],[123.608,-14.314],[123.678,-14.2795],[123.748,-14.188],[123.7625,-14.116],[123.733,-14.006],[123.681,-13.946],[123.576,-13.9015],[123.494,-13.906],[123.428,-13.934],[123.366,-13.9945],[123.3315,-14.109]]],[[[141.362,-9.8285],[141.3735,-9.8615],[141.4325,-9.8795],[141.4875,-9.8275],[141.4585,-9.7745],[141.3955,-9.7775],[141.362,-9.8285]]],[[[141.481,-9.533],[141.515,-9.587],[141.5065,-9.6215],[141.5475,-9.6685],[141.5995,-9.6575],[141.6235,-9.6275],[141.6175,-9.5745],[141.656,-9.521],[141.6445,-9.467],[141.5575,-9.448],[141.5025,-9.4885],[141.481,-9.533]]],[[[142.0595,-9.261],[142.091,-9.315],[142.163,-9.34],[142.2705,-9.3475],[142.333,-9.3165],[142.346,-9.266],[142.275,-9.23],[142.2365,-9.1915],[142.1435,-9.196],[142.0595,-9.261]]],[[[142.127,-9.5455],[142.1555,-9.5915],[142.2035,-9.592],[142.2515,-9.615],[142.3475,-9.6265],[142.3895,-9.568],[142.356,-9.5195],[142.259,-9.492],[142.1875,-9.485],[142.152,-9.498],[142.127,-9.5455]]],[[[142.4955,-9.366],[142.472,-9.4055],[142.483,-9.4535],[142.517,-9.485],[142.5855,-9.46],[142.647,-9.4785],[142.773,-9.4855],[142.8185,-9.4585],[142.851,-9.3915],[142.8435,-9.349],[142.8065,-9.3225],[142.5925,-9.3555],[142.559,-9.3745],[142.4955,-9.366]]],[[[143.7835,-9.174],[143.801,-9.211],[143.846,-9.222],[143.931,-9.1745],[143.934,-9.12],[143.9005,-9.091],[143.8615,-9.091],[143.7965,-9.139],[143.7835,-9.174]]],[[[144.074,-9.358],[144.103,-9.406],[144.1635,-9.4135],[144.202,-9.457],[144.274,-9.4535],[144.296,-9.4155],[144.2775,-9.3605],[144.236,-9.3335],[144.1895,-9.34],[144.132,-9.3055],[144.084,-9.3265],[144.074,-9.358]]],[[[147.593,-16.5235],[147.608,-16.603],[147.644,-16.6635],[147.702,-16.7155],[147.799,-16.7495],[147.8725,-16.7455],[147.9325,-16.725],[147.9985,-16.73],[148.086,-16.708],[148.191,-16.649],[148.2575,-16.5795],[148.2925,-16.509],[148.302,-16.455],[148.294,-16.3845],[148.246,-16.298],[148.204,-16.2585],[148.1475,-16.23],[148.065,-16.209],[147.9805,-16.209],[147.8615,-16.1815],[147.804,-16.188],[147.7005,-16.2455],[147.6375,-16.3335],[147.6235,-16.423],[147.593,-16.5235]]],[[[148.121,-17.574],[148.139,-17.6575],[148.1345,-17.7115],[148.159,-17.801],[148.1985,-17.853],[148.234,-17.9315],[148.33,-18.0255],[148.3745,-18.0545],[148.455,-18.0805],[148.5325,-18.0845],[148.5905,-18.0705],[148.6935,-18.0005],[148.7415,-17.894],[148.7395,-17.8165],[148.7835,-17.754],[148.802,-17.693],[148.8045,-17.607],[148.789,-17.5385],[148.753,-17.46],[148.6815,-17.3775],[148.6205,-17.3465],[148.5665,-17.336],[148.4675,-17.3525],[148.4115,-17.3875],[148.3295,-17.372],[148.2395,-17.3925],[148.183,-17.431],[148.1335,-17.5055],[148.121,-17.574]]],[[[148.917,-16.9755],[148.945,-17.0995],[148.9915,-17.1635],[149.0405,-17.1975],[149.1265,-17.2245],[149.2235,-17.2165],[149.3185,-17.158],[149.4035,-17.0275],[149.4215,-16.919],[149.4065,-16.855],[149.3645,-16.7895],[149.2835,-16.7345],[149.174,-16.7205],[149.0835,-16.753],[148.9765,-16.8335],[148.928,-16.9095],[148.917,-16.9755]]],[[[149.1,-19.7385],[149.111,-19.8045],[149.162,-19.884],[149.3025,-19.977],[149.4225,-20.032],[149.5105,-20.0865],[149.576,-20.098],[149.6675,-20.082],[149.7285,-20.047],[149.7665,-20.008],[149.8685,-19.9325],[149.912,-19.8785],[149.9445,-19.8085],[149.9725,-19.6695],[149.9645,-19.5885],[149.905,-19.489],[149.858,-19.4455],[149.757,-19.387],[149.698,-19.3395],[149.598,-19.3125],[149.515,-19.3255],[149.4615,-19.353],[149.386,-19.356],[149.337,-19.3725],[149.2685,-19.4245],[149.226,-19.505],[149.1625,-19.5645],[149.105,-19.679],[149.1,-19.7385]]],[[[149.4085,-15.722],[149.4195,-15.79],[149.4795,-15.8775],[149.547,-15.917],[149.662,-15.9255],[149.725,-15.903],[149.797,-15.837],[149.829,-15.7565],[149.816,-15.65],[149.773,-15.5845],[149.6695,-15.526],[149.5515,-15.5305],[149.4745,-15.575],[149.4295,-15.634],[149.4085,-15.722]]],[[[149.6945,-16.9695],[149.6985,-17.0055],[149.7405,-17.0965],[149.7885,-17.14],[149.871,-17.1725],[149.935,-17.1735],[150.0875,-17.1275],[150.146,-17.093],[150.2085,-17.006],[150.221,-16.95],[150.2165,-16.8795],[150.1835,-16.8085],[150.1035,-16.7425],[150.016,-16.721],[149.94,-16.732],[149.7975,-16.7905],[149.7285,-16.855],[149.6945,-16.9695]]],[[[149.752,-16.294],[149.773,-16.3885],[149.8225,-16.456],[149.873,-16.489],[149.988,-16.5085],[150.0665,-16.4845],[150.0635,-16.576],[150.0985,-16.6565],[150.2005,-16.764],[150.2965,-16.8085],[150.346,-16.8125],[150.421,-16.797],[150.516,-16.724],[150.5545,-16.622],[150.553,-16.5695],[150.5315,-16.5055],[150.4675,-16.3975],[150.4315,-16.3595],[150.361,-16.322],[150.308,-16.3125],[150.2245,-16.324],[150.1795,-16.3135],[150.231,-16.216],[150.2445,-16.135],[150.2265,-16.056],[150.165,-15.972],[150.1085,-15.9335],[150.017,-15.908],[149.9595,-15.9105],[149.8625,-15.944],[149.813,-15.985],[149.767,-16.0715],[149.761,-16.1345],[149.776,-16.1955],[149.752,-16.294]]],[[[150.5925,-17.4295],[150.6115,-17.5135],[150.642,-17.5605],[150.619,-17.622],[150.616,-17.6865],[150.648,-17.7725],[150.6845,-17.8135],[150.753,-17.853],[150.868,-17.8615],[150.967,-17.816],[151.0145,-17.762],[151.0435,-17.6515],[151.143,-17.647],[151.167,-17.748],[151.22,-17.8105],[151.2625,-17.8365],[151.3335,-17.856],[151.458,-17.845],[151.575,-17.79],[151.6645,-17.7715],[151.7595,-17.729],[151.902,-17.623],[151.9825,-17.593],[152.0495,-17.5865],[152.174,-17.53],[152.2495,-17.4395],[152.276,-17.367],[152.319,-17.311],[152.358,-17.209],[152.365,-17.1315],[152.3505,-17.0695],[152.2745,-16.9665],[152.2265,-16.9355],[152.1385,-16.91],[152.0585,-16.9145],[151.9245,-16.9035],[151.7855,-16.9195],[151.699,-16.9655],[151.612,-17.0355],[151.5605,-17.0965],[151.4905,-17.15],[151.3825,-17.208],[151.321,-17.264],[151.287,-17.3375],[151.1995,-17.248],[151.1395,-17.221],[151.0505,-17.2135],[150.953,-17.249],[150.9195,-17.2505],[150.8265,-17.224],[150.711,-17.2465],[150.647,-17.293],[150.6015,-17.3705],[150.5925,-17.4295]]],[[[151.0225,-21.8115],[151.0275,-21.854],[151.0615,-21.9285],[151.0975,-21.9665],[151.184,-22.012],[151.2585,-22.0235],[151.356,-22.003],[151.405,-21.973],[151.463,-21.8985],[151.4775,-21.782],[151.432,-21.686],[151.377,-21.6385],[151.2945,-21.6085],[151.1775,-21.6165],[151.099,-21.657],[151.046,-21.72],[151.0225,-21.8115]]],[[[151.4175,-21.332],[151.4275,-21.3875],[151.4765,-21.4865],[151.569,-21.5685],[151.6525,-21.5915],[151.7185,-21.6245],[151.7885,-21.635],[151.851,-21.6265],[151.9695,-21.594],[151.987,-21.68],[151.97,-21.7915],[151.9985,-21.892],[152.054,-21.971],[152.046,-22.026],[152.072,-22.1205],[152.1195,-22.1765],[152.2085,-22.2595],[152.3305,-22.348],[152.3415,-22.449],[152.3755,-22.505],[152.4235,-22.5455],[152.53,-22.593],[152.6445,-22.5965],[152.8035,-22.548],[152.866,-22.5115],[152.932,-22.429],[152.969,-22.3185],[152.9795,-22.2575],[152.9835,-22.1335],[152.967,-22.066],[152.9215,-22.0005],[152.9075,-21.889],[152.854,-21.794],[152.8405,-21.745],[152.763,-21.6155],[152.7935,-21.47],[152.7795,-21.4],[152.7465,-21.346],[152.8025,-21.291],[152.84,-21.227],[152.8645,-21.1095],[152.8425,-20.9815],[152.8215,-20.9375],[152.771,-20.882],[152.7215,-20.8515],[152.6175,-20.8205],[152.3905,-20.7775],[152.222,-20.7265],[152.1595,-20.723],[152.034,-20.738],[151.935,-20.78],[151.8735,-20.847],[151.849,-20.9185],[151.7655,-20.8725],[151.687,-20.861],[151.6315,-20.868],[151.5635,-20.898],[151.484,-20.989],[151.457,-21.0875],[151.4675,-21.161],[151.4265,-21.269],[151.4175,-21.332]]],[[[151.9485,-19.222],[151.9765,-19.321],[152.0635,-19.43],[152.1035,-19.4595],[152.1905,-19.497],[152.2815,-19.5015],[152.357,-19.4835],[152.4965,-19.4065],[152.553,-19.3405],[152.5955,-19.2675],[152.619,-19.1535],[152.61,-19.074],[152.584,-18.955],[152.5505,-18.894],[152.454,-18.7865],[152.3735,-18.741],[152.2945,-18.7275],[152.174,-18.742],[152.097,-18.784],[152.0475,-18.8445],[152.029,-18.894],[152.03,-18.984],[151.987,-19.0595],[151.9485,-19.222]]],[[[153.298,-21.8555],[153.3315,-21.977],[153.3735,-22.037],[153.437,-22.088],[153.502,-22.1155],[153.5885,-22.1255],[153.711,-22.101],[153.798,-22.0485],[153.9105,-21.926],[153.957,-21.861],[153.9975,-21.753],[153.999,-21.667],[153.9815,-21.6045],[153.926,-21.5185],[153.8205,-21.4605],[153.731,-21.457],[153.6215,-21.507],[153.5755,-21.563],[153.55,-21.649],[153.4835,-21.65],[153.4055,-21.677],[153.328,-21.7505],[153.298,-21.8555]]],[[[154.133,-21.012],[154.139,-21.0625],[154.1745,-21.1355],[154.2415,-21.1945],[154.3255,-21.2245],[154.3915,-21.227],[154.4945,-21.1965],[154.5545,-21.1465],[154.5895,-21.097],[154.6125,-21.0195],[154.617,-20.9345],[154.6055,-20.8665],[154.5805,-20.8165],[154.4985,-20.745],[154.4275,-20.7235],[154.3695,-20.723],[154.2905,-20.748],[154.2285,-20.798],[154.147,-20.9405],[154.133,-21.012]]],[[[154.94,-22.179],[154.9595,-22.263],[155.0205,-22.336],[155.09,-22.3785],[155.182,-22.4085],[155.2785,-22.417],[155.3585,-22.402],[155.4695,-22.3945],[155.5545,-22.3685],[155.6495,-22.305],[155.6905,-22.2305],[155.692,-22.1285],[155.639,-22.0375],[155.5735,-21.992],[155.4855,-21.965],[155.429,-21.965],[155.278,-21.997],[155.181,-21.975],[155.099,-21.984],[155.0035,-22.036],[154.959,-22.096],[154.94,-22.179]]],[[[155.3145,-23.2525],[155.338,-23.3445],[155.4055,-23.418],[155.4745,-23.4495],[155.5665,-23.458],[155.6425,-23.442],[155.726,-23.3865],[155.7655,-23.3265],[155.7815,-23.2525],[155.7635,-23.169],[155.717,-23.1035],[155.6745,-23.0715],[155.603,-23.045],[155.4835,-23.052],[155.4255,-23.0755],[155.369,-23.1185],[155.3345,-23.1685],[155.3145,-23.2525]]],[[[155.492,-21.278],[155.5115,-21.3605],[155.557,-21.422],[155.595,-21.4495],[155.6935,-21.48],[155.824,-21.4595],[155.91,-21.421],[155.979,-21.3555],[156.007,-21.2915],[156.0075,-21.2035],[155.9525,-21.0375],[155.909,-20.969],[155.8125,-20.909],[155.7205,-20.898],[155.6445,-20.9165],[155.5875,-20.9525],[155.5395,-21.0155],[155.524,-21.0605],[155.527,-21.165],[155.492,-21.278]]],[[[155.627,-17.3505],[155.655,-17.4995],[155.6875,-17.5605],[155.76,-17.619],[155.81,-17.6365],[155.9005,-17.638],[156.005,-17.5885],[156.055,-17.526],[156.0815,-17.4635],[156.086,-17.3435],[156.059,-17.279],[156.02,-17.226],[155.9515,-17.168],[155.8875,-17.1465],[155.8105,-17.1465],[155.741,-17.169],[155.694,-17.2015],[155.647,-17.2645],[155.627,-17.3505]]],[[[158.3265,-55.124],[158.3425,-55.182],[158.407,-55.2505],[158.489,-55.292],[158.615,-55.3195],[158.7635,-55.3165],[158.8595,-55.293],[158.964,-55.2405],[159.0155,-55.1885],[159.04,-55.111],[159.0145,-55.0395],[158.9465,-54.9775],[159.102,-54.923],[159.1845,-54.8385],[159.1965,-54.7565],[159.2515,-54.6485],[159.2915,-54.5245],[159.293,-54.4645],[159.3405,-54.3575],[159.3095,-54.2745],[159.25,-54.2215],[159.1215,-54.17],[158.9975,-54.156],[158.835,-54.1795],[158.7155,-54.24],[158.6505,-54.3445],[158.557,-54.41],[158.51,-54.4835],[158.4305,-54.7465],[158.4385,-54.8295],[158.5325,-54.9315],[158.3875,-55.0075],[158.3455,-55.0575],[158.3265,-55.124]]],[[[158.7875,-29.9425],[158.8175,-30.0455],[158.872,-30.105],[158.933,-30.1395],[159.0305,-30.1735],[159.139,-30.1815],[159.22,-30.159],[159.3135,-30.086],[159.3495,-30.0135],[159.3505,-29.9085],[159.31,-29.831],[159.194,-29.7385],[159.121,-29.7135],[159.0475,-29.7105],[158.9165,-29.7535],[158.8445,-29.8065],[158.8085,-29.858],[158.7875,-29.9425]]],[[[158.801,-31.513],[158.814,-31.583],[158.8665,-31.698],[158.9605,-31.7765],[159.004,-31.792],[159.032,-31.8585],[159.0685,-31.9],[159.1445,-31.9515],[159.229,-31.9835],[159.293,-31.988],[159.4085,-31.9555],[159.4615,-31.9155],[159.505,-31.846],[159.515,-31.7825],[159.482,-31.6855],[159.4115,-31.6065],[159.359,-31.5755],[159.3555,-31.5195],[159.3255,-31.453],[159.2535,-31.3605],[159.2155,-31.329],[159.131,-31.2925],[159.0665,-31.2855],[158.9655,-31.307],[158.851,-31.3915],[158.8085,-31.4685],[158.801,-31.513]]],[[[158.818,-29.46],[158.828,-29.5225],[158.8665,-29.5905],[158.9425,-29.65],[159.058,-29.684],[159.187,-29.6695],[159.2755,-29.625],[159.3465,-29.5435],[159.37,-29.451],[159.3615,-29.3915],[159.309,-29.3045],[159.262,-29.2665],[159.186,-29.233],[159.1155,-29.2235],[159.001,-29.246],[158.9115,-29.2925],[158.8465,-29.361],[158.818,-29.46]]],[[[167.6855,-29.009],[167.688,-29.07],[167.728,-29.195],[167.77,-29.2635],[167.8705,-29.3255],[167.9625,-29.3365],[168.069,-29.3065],[168.1285,-29.2615],[168.1685,-29.2115],[168.2195,-29.0845],[168.22,-28.9825],[168.1575,-28.884],[168.0745,-28.832],[167.9325,-28.794],[167.84,-28.807],[167.7715,-28.843],[167.7145,-28.9075],[167.6855,-29.009]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/b9/Flag_of_Australia.svg","name:en":"Australia","wikidata":"Q408","ISO3166-1:alpha2":"AU","ISO3166-1:alpha3":"AUS","ISO3166-1:numeric":"036"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-71.18,20.9795],[-72.0295,20.0],[-72.0575,19.953],[-72.0315,19.9245],[-71.914,19.7965],[-71.804,19.733],[-71.7735,19.7315],[-71.7455,19.634],[-71.743,19.5845],[-71.7135,19.552],[-71.6795,19.434],[-71.712,19.3715],[-71.778,19.3345],[-71.7405,19.277],[-71.691,19.239],[-71.639,19.2315],[-71.631,19.1835],[-71.6525,19.139],[-71.723,19.0535],[-71.771,19.0315],[-71.8355,18.97],[-71.783,18.9485],[-71.768,18.907],[-71.725,18.8755],[-71.722,18.804],[-71.738,18.722],[-71.804,18.6855],[-71.807,18.6355],[-71.8445,18.629],[-71.9665,18.6565],[-71.9815,18.612],[-71.881,18.504],[-71.9045,18.457],[-71.844,18.429],[-71.83,18.399],[-71.696,18.3405],[-71.768,18.2205],[-71.7835,18.17],[-71.745,18.137],[-71.744,18.053],[-71.8295,17.954],[-71.9395,17.841],[-71.897,17.5945],[-71.8375,17.3895],[-71.7935,17.33],[-71.7125,17.281],[-71.658,17.2705],[-71.5375,17.2955],[-70.1125,18.023],[-68.7725,17.9375],[-68.683,17.9185],[-68.55,17.9135],[-68.4905,17.926],[-68.405,17.9875],[-68.382,18.0235],[-68.133,18.51],[-68.118,18.549],[-68.11,18.644],[-68.12,18.6995],[-68.5255,19.9025],[-68.589,20.009],[-68.597,20.0515],[-69.341,20.7815],[-69.3875,20.835],[-69.556,20.9345],[-69.814,21.0675],[-70.4545,21.2855],[-70.5565,21.2925],[-70.635,21.26],[-70.695,21.2015],[-70.8275,21.185],[-70.979,21.149],[-71.0835,21.038],[-71.18,20.9795]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9f/Flag_of_the_Dominican_Republic.svg","name:en":"Dominican Republic","wikidata":"Q786","ISO3166-1:alpha2":"DO","ISO3166-1:alpha3":"DOM","ISO3166-1:numeric":"214"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-61.68,15.6445],[-61.687,15.526],[-61.672,15.449],[-61.635,15.3525],[-61.598,15.283],[-61.574,15.1625],[-61.539,15.093],[-61.45,15.027],[-61.349,15.0075],[-61.159,15.079],[-61.084,15.1445],[-61.044,15.2375],[-61.0345,15.315],[-61.0365,15.495],[-61.0435,15.541],[-61.0835,15.63],[-61.1385,15.7015],[-61.3235,15.734],[-61.4425,15.787],[-61.68,15.6445]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/c4/Flag_of_Dominica.svg","name:en":"Dominica","wikidata":"Q784","ISO3166-1:alpha2":"DM","ISO3166-1:alpha3":"DMA","ISO3166-1:numeric":"212"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-65.123,32.275],[-65.099,32.1895],[-65.062,32.1345],[-64.9665,32.0685],[-64.8865,32.0485],[-64.8195,32.047],[-64.7235,32.0685],[-64.517,32.1825],[-64.458,32.2325],[-64.418,32.3055],[-64.4135,32.396],[-64.4655,32.498],[-64.5575,32.5655],[-64.6305,32.588],[-64.7295,32.586],[-64.8515,32.5295],[-64.8995,32.5225],[-65.029,32.4635],[-65.0835,32.4125],[-65.113,32.3515],[-65.123,32.275]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/bf/Flag_of_Bermuda.svg","name:en":"Bermuda","wikidata":"Q23635","ISO3166-1:alpha2":"BM","ISO3166-1:alpha3":"BMU","ISO3166-1:numeric":"060"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[5.4175,-1.416],[5.4285,-1.506],[5.4665,-1.585],[5.516,-1.6315],[5.57,-1.66],[5.634,-1.673],[5.6995,-1.665],[5.789,-1.6095],[5.8395,-1.529],[5.8575,-1.4075],[5.826,-1.2975],[5.7735,-1.2425],[5.6945,-1.2085],[5.635,-1.202],[5.5655,-1.213],[5.47,-1.275],[5.4345,-1.33],[5.4175,-1.416]]],[[[8.8315,3.9605],[8.7495,3.986],[8.692,3.988],[8.6225,3.969],[8.528,3.894],[8.434,3.764],[8.407,3.662],[8.3245,3.614],[8.2545,3.517],[8.2245,3.433],[8.215,3.373],[8.225,3.291],[8.255,3.203],[8.29,3.148],[8.382,3.083],[8.6415,3.013],[8.698,3.011],[8.759,3.027],[8.841,3.091],[8.9195,3.191],[8.9685,3.304],[9.04,3.448],[9.099,3.525],[9.1275,3.593],[9.1385,3.705],[9.1255,3.771],[9.047,3.856],[8.9835,3.906],[8.8315,3.9605]]],[[[11.36,2.172],[11.0,2.171],[10.656,2.174],[10.19,2.175],[10.167,2.152],[10.035,2.163],[9.906,2.2075],[9.848,2.2455],[9.8375,2.325],[9.762,2.3905],[9.621,2.45],[9.592,2.4005],[9.576,2.3015],[9.5935,2.207],[9.5645,2.0895],[9.5935,1.9775],[9.547,1.893],[9.4375,1.7695],[9.4145,1.712],[9.405,1.6315],[9.3325,1.554],[9.2845,1.4885],[9.262,1.422],[9.22,1.368],[9.1645,1.2685],[9.142,1.1585],[9.1675,1.0755],[9.12,1.0045],[9.103,0.9175],[9.116,0.814],[9.1495,0.7535],[9.355,0.8465],[9.519,0.963],[9.5475,1.0225],[9.62,1.0295],[9.668,1.062],[9.749,1.063],[9.798,1.0],[9.8795,0.9885],[9.895,0.953],[9.958,0.929],[9.9935,0.9385],[9.992,1.0025],[10.7185,1.0025],[11.3535,1.002],[11.3495,1.4715],[11.3465,1.8315],[11.355,2.1595],[11.36,2.172]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/31/Flag_of_Equatorial_Guinea.svg","name:en":"Equatorial Guinea","wikidata":"Q983","ISO3166-1:alpha2":"GQ","ISO3166-1:alpha3":"GNQ","ISO3166-1:numeric":"226"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[1.673,6.04],[1.8815,6.084],[2.13,6.127],[2.353,6.149],[2.426,6.142],[2.5125,6.159],[2.629,6.164],[2.738,6.178],[2.7065,6.3775],[2.706,6.52],[2.748,6.568],[2.7295,6.637],[2.784,6.699],[2.7845,6.764],[2.7345,6.785],[2.7415,6.9275],[2.7125,6.9515],[2.729,7.017],[2.7615,7.0435],[2.7405,7.105],[2.773,7.133],[2.7575,7.2515],[2.745,7.2815],[2.745,7.4245],[2.794,7.4295],[2.7925,7.4975],[2.735,7.55],[2.7165,7.6365],[2.729,7.7555],[2.7255,7.8025],[2.6785,7.8745],[2.6995,7.9325],[2.733,8.0815],[2.754,8.2125],[2.7205,8.25],[2.696,8.3545],[2.7195,8.3875],[2.7085,8.4225],[2.7495,8.4485],[2.7555,8.654],[2.739,8.683],[2.749,8.7405],[2.731,8.787],[2.7595,8.8445],[2.7905,8.9895],[2.783,9.0695],[2.8795,9.0645],[2.953,9.0925],[2.9725,9.075],[3.0885,9.102],[3.122,9.1925],[3.123,9.2325],[3.158,9.284],[3.1555,9.3605],[3.133,9.441],[3.1615,9.4975],[3.1885,9.5115],[3.252,9.6065],[3.267,9.659],[3.314,9.6595],[3.361,9.708],[3.325,9.761],[3.332,9.8055],[3.3625,9.835],[3.4625,9.8705],[3.515,9.8605],[3.5635,9.901],[3.598,9.957],[3.617,10.084],[3.659,10.109],[3.6795,10.177],[3.608,10.2115],[3.5765,10.2725],[3.604,10.344],[3.602,10.4125],[3.6835,10.4615],[3.785,10.4075],[3.8055,10.4505],[3.8055,10.514],[3.845,10.5945],[3.835,10.696],[3.78,10.736],[3.7455,10.817],[3.7695,10.924],[3.751,11.013],[3.725,11.0275],[3.7225,11.1285],[3.6935,11.129],[3.4765,11.438],[3.525,11.575],[3.5765,11.6685],[3.6095,11.6935],[3.5515,11.7285],[3.5615,11.7785],[3.482,11.86],[3.448,11.8585],[3.3735,11.889],[3.323,11.8845],[3.2795,11.942],[3.2205,12.0615],[3.126,12.156],[3.0745,12.1815],[3.0145,12.266],[2.9665,12.2865],[2.8695,12.3895],[2.8415,12.4055],[2.7225,12.3525],[2.6945,12.283],[2.662,12.3065],[2.5925,12.2995],[2.5475,12.274],[2.471,12.273],[2.4015,12.258],[2.3875,12.2165],[2.4035,12.1035],[2.464,11.9855],[2.4065,11.9525],[2.409,11.9025],[2.3805,11.8575],[2.372,11.798],[2.2985,11.716],[2.3145,11.6795],[2.184,11.594],[2.0195,11.4275],[1.982,11.42],[1.8725,11.446],[1.7735,11.4195],[1.6015,11.3975],[1.5835,11.447],[1.4745,11.471],[1.3955,11.453],[1.392,11.4115],[1.326,11.3525],[1.347,11.3065],[1.294,11.2985],[1.284,11.266],[1.1925,11.2635],[1.0745,11.132],[1.101,11.068],[1.0275,11.0525],[1.013,11.0875],[0.912,10.996],[0.8885,10.92],[0.8795,10.7995],[0.8095,10.728],[0.8005,10.681],[0.8075,10.607],[0.7855,10.5245],[0.7765,10.3765],[1.098,10.15],[1.153,10.121],[1.355,9.9955],[1.3635,9.826],[1.3685,9.5965],[1.3395,9.546],[1.3705,9.4815],[1.393,9.479],[1.407,9.3445],[1.4315,9.3015],[1.5105,9.211],[1.57,9.166],[1.6045,9.1045],[1.6265,9.0075],[1.617,8.9595],[1.628,8.881],[1.6245,8.548],[1.661,8.497],[1.631,8.452],[1.613,8.369],[1.6345,8.358],[1.638,7.8465],[1.6425,7.62],[1.656,7.5325],[1.6445,7.443],[1.6425,6.9955],[1.559,6.997],[1.584,6.91],[1.6065,6.9045],[1.5945,6.7995],[1.6235,6.7375],[1.58,6.6915],[1.6075,6.665],[1.61,6.6135],[1.703,6.532],[1.745,6.4735],[1.7965,6.3205],[1.7765,6.2855],[1.63,6.2355],[1.673,6.04]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/0a/Flag_of_Benin.svg","name:en":"Benin","wikidata":"Q962","ISO3166-1:alpha2":"BJ","ISO3166-1:alpha3":"BEN","ISO3166-1:numeric":"204"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-64.64,18.1065],[-64.534,18.1215],[-64.458,18.1555],[-64.324,18.24],[-64.2595,18.3065],[-64.2095,18.33],[-64.144,18.3935],[-64.11,18.4875],[-64.1165,18.5555],[-64.0735,18.6225],[-64.0595,18.6905],[-64.0815,18.789],[-64.1355,18.862],[-64.177,18.8985],[-64.289,18.9455],[-64.389,18.95],[-64.4655,18.9405],[-64.537,18.908],[-64.587,18.86],[-64.6145,18.81],[-64.6275,18.7475],[-64.6195,18.6875],[-64.6945,18.6585],[-64.847,18.6525],[-64.956,18.6115],[-64.897,18.4895],[-64.872,18.4085],[-64.799,18.408],[-64.756,18.377],[-64.6395,18.364],[-64.6605,18.29],[-64.64,18.1065]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/42/Flag_of_the_British_Virgin_Islands.svg","name:en":"British Virgin Islands","wikidata":"Q25305","ISO3166-1:alpha2":"VG","ISO3166-1:alpha3":"VGB","ISO3166-1:numeric":"092"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[24.0,19.5],[23.4995,19.772],[22.831,20.129],[22.268,20.4255],[21.6615,20.741],[21.2735,20.941],[20.7355,21.216],[20.2605,21.4555],[19.6715,21.7505],[19.186,21.99],[18.63,22.262],[18.1465,22.494],[17.819,22.6505],[17.7885,22.661],[16.0,23.4515],[14.9985,23.001],[15.074,22.6135],[15.1945,21.999],[15.2025,21.496],[15.2845,21.4455],[15.627,20.9555],[15.5685,20.9105],[15.554,20.8525],[15.576,20.7665],[15.6755,20.6965],[15.9965,20.353],[15.754,19.9325],[15.6665,19.264],[15.6025,18.782],[15.573,18.2625],[15.5435,17.729],[15.522,17.333],[15.5055,16.898],[15.2585,16.6395],[14.9565,16.3255],[14.9135,16.2765],[14.6105,15.956],[14.385,15.7315],[14.276,15.588],[13.97,15.1565],[13.8695,15.043],[13.7895,14.863],[13.81,14.7215],[13.7455,14.6985],[13.6775,14.6365],[13.696,14.551],[13.641,14.5135],[13.572,14.5055],[13.4935,14.4745],[13.4735,14.443],[13.4855,14.3585],[13.6335,13.708],[14.0835,13.0835],[14.4665,13.0835],[14.535,12.946],[14.5605,12.9205],[14.565,12.8365],[14.547,12.7925],[14.5945,12.746],[14.669,12.7195],[14.7095,12.7265],[14.7615,12.6775],[14.772,12.635],[14.823,12.64],[14.8545,12.576],[14.848,12.518],[14.9085,12.3805],[14.8935,12.3075],[14.9095,12.1915],[14.8855,12.165],[14.956,12.0995],[14.9935,12.088],[15.038,12.104],[15.0605,12.06],[15.051,12.0145],[15.085,12.002],[15.0395,11.9105],[15.0495,11.8585],[15.089,11.855],[15.122,11.7885],[15.0635,11.712],[15.102,11.5845],[15.1445,11.5625],[15.058,11.4145],[15.0735,11.3265],[15.0485,11.2805],[15.068,11.2015],[15.095,11.168],[15.092,11.0335],[15.046,11.004],[15.079,10.958],[15.095,10.876],[15.0675,10.8235],[15.096,10.748],[15.138,10.6865],[15.161,10.626],[15.1425,10.592],[15.1555,10.529],[15.216,10.498],[15.2795,10.4055],[15.304,10.312],[15.3455,10.298],[15.4405,10.1975],[15.502,10.099],[15.617,10.0455],[15.6885,9.993],[15.5235,9.952],[15.414,9.9335],[15.3645,9.959],[15.248,9.9895],[15.1485,9.9945],[15.06,9.9455],[15.033,9.9655],[14.958,9.983],[14.8025,9.935],[14.4635,10.002],[14.2065,10.002],[14.1735,9.904],[14.131,9.82],[14.0225,9.728],[13.9765,9.638],[14.04,9.602],[14.0925,9.5505],[14.1045,9.518],[14.15,9.5025],[14.204,9.4465],[14.2685,9.358],[14.3045,9.3715],[14.339,9.31],[14.373,9.294],[14.3475,9.2085],[14.407,9.148],[14.464,9.115],[14.4905,9.058],[14.5665,9.014],[14.745,8.8795],[14.844,8.812],[14.9,8.8135],[14.9225,8.7785],[14.989,8.7285],[14.9825,8.689],[15.06,8.681],[15.109,8.6595],[15.151,8.606],[15.154,8.572],[15.2,8.5125],[15.395,8.0935],[15.394,8.0465],[15.452,7.8855],[15.5065,7.792],[15.5875,7.774],[15.5855,7.668],[15.567,7.5945],[15.4935,7.525],[15.5465,7.511],[15.728,7.519],[15.743,7.4785],[15.8095,7.441],[15.975,7.4835],[16.039,7.534],[16.0565,7.5775],[16.1635,7.5945],[16.1855,7.6145],[16.2475,7.612],[16.296,7.6545],[16.398,7.683],[16.4235,7.7155],[16.407,7.7705],[16.432,7.81],[16.479,7.7895],[16.506,7.8455],[16.577,7.874],[16.5895,7.774],[16.6615,7.742],[16.66,7.672],[16.6845,7.6395],[16.73,7.639],[16.776,7.607],[16.809,7.5375],[16.86,7.545],[16.9015,7.6035],[16.9525,7.645],[17.0355,7.639],[17.106,7.695],[17.1525,7.67],[17.1675,7.7185],[17.208,7.7495],[17.258,7.753],[17.2765,7.8105],[17.36,7.856],[17.4725,7.9],[17.5105,7.8725],[17.535,7.925],[17.606,7.9295],[17.6845,7.983],[17.9215,7.9585],[18.032,8.0095],[18.192,8.018],[18.6015,8.0465],[18.637,8.091],[18.63,8.1465],[18.6735,8.212],[18.7865,8.2545],[18.8335,8.29],[18.8495,8.3455],[18.919,8.387],[18.9295,8.4375],[19.039,8.5375],[19.0465,8.5935],[19.1065,8.664],[19.1005,8.7005],[19.0335,8.7315],[18.907,8.8505],[18.8615,8.878],[18.9115,8.9235],[18.978,8.9405],[19.0725,9.015],[19.147,9.0095],[19.1775,9.027],[19.2635,9.016],[19.51,9.0185],[19.5715,9.0295],[19.684,9.0135],[19.7865,9.048],[19.8785,9.0525],[20.0165,9.093],[20.062,9.1345],[20.147,9.1115],[20.207,9.1395],[20.2535,9.115],[20.3715,9.1085],[20.434,9.137],[20.488,9.2095],[20.498,9.277],[20.538,9.3185],[20.6035,9.298],[20.668,9.2985],[20.678,9.3595],[20.738,9.3705],[20.7745,9.4055],[20.831,9.4285],[20.826,9.458],[20.896,9.5215],[20.9565,9.6055],[20.986,9.612],[21.015,9.7385],[21.103,9.7725],[21.1155,9.822],[21.1885,9.8805],[21.225,9.9425],[21.2765,9.9805],[21.342,9.9585],[21.432,10.038],[21.4735,10.148],[21.5355,10.212],[21.6145,10.2135],[21.667,10.236],[21.688,10.2845],[21.7155,10.2905],[21.7245,10.366],[21.748,10.4065],[21.7015,10.5145],[21.7165,10.6355],[21.811,10.677],[21.8615,10.669],[21.9075,10.714],[22.0085,10.7515],[22.015,10.808],[22.0475,10.8305],[22.113,10.8325],[22.176,10.814],[22.202,10.8705],[22.2505,10.912],[22.271,10.9035],[22.323,10.9415],[22.415,10.963],[22.466,11.0015],[22.529,10.9765],[22.6005,10.9855],[22.653,10.966],[22.7675,10.955],[22.7855,10.931],[22.878,10.9205],[22.9195,11.0665],[22.9755,11.216],[22.972,11.2775],[22.9485,11.316],[22.931,11.416],[22.791,11.4015],[22.7755,11.462],[22.642,11.516],[22.5615,11.6215],[22.5535,11.6725],[22.573,11.799],[22.6145,12.0045],[22.641,12.071],[22.5375,12.058],[22.478,12.03],[22.5015,12.177],[22.4365,12.3545],[22.433,12.4035],[22.3865,12.4545],[22.409,12.487],[22.467,12.6215],[22.335,12.6705],[22.2235,12.747],[22.166,12.672],[22.0745,12.64],[21.977,12.6385],[21.9015,12.6775],[21.8565,12.741],[21.858,12.772],[21.8145,12.8065],[21.847,12.838],[21.91,12.99],[21.941,13.049],[22.0295,13.143],[22.0755,13.151],[22.1595,13.1905],[22.183,13.231],[22.2695,13.321],[22.2885,13.3915],[22.2395,13.454],[22.2265,13.567],[22.1635,13.6235],[22.134,13.6695],[22.1405,13.723],[22.0845,13.779],[22.234,13.966],[22.3445,14.0135],[22.3965,14.052],[22.4345,14.0515],[22.477,14.101],[22.5525,14.121],[22.567,14.164],[22.5555,14.232],[22.4785,14.2445],[22.444,14.272],[22.436,14.315],[22.4695,14.351],[22.4475,14.384],[22.4345,14.496],[22.3845,14.5195],[22.4035,14.592],[22.47,14.6295],[22.7025,14.6915],[22.6775,14.766],[22.667,14.8635],[22.7095,14.8955],[22.76,14.908],[22.7515,14.97],[22.8125,15.0345],[22.882,15.0885],[22.9405,15.116],[22.935,15.169],[22.9675,15.1825],[23.004,15.2405],[22.985,15.2595],[23.003,15.322],[22.988,15.415],[22.9305,15.462],[22.9185,15.4945],[22.937,15.5645],[22.9875,15.5835],[23.0755,15.6675],[23.1105,15.715],[23.207,15.7185],[23.3375,15.694],[23.397,15.6975],[23.552,15.7685],[23.6635,15.7745],[23.8115,15.7515],[23.9995,15.6975],[23.999,16.1995],[24.0,16.733],[23.999,17.0995],[23.999,17.6995],[23.9995,18.033],[23.999,18.5325],[23.999,19.066],[24.0,19.5]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/4b/Flag_of_Chad.svg","name:en":"Chad","wikidata":"Q657","ISO3166-1:alpha2":"TD","ISO3166-1:alpha3":"TCD","ISO3166-1:numeric":"148"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[35.944,4.619],[35.9645,4.5275],[36.0475,4.4465],[36.234,4.449],[36.5475,4.442],[36.6455,4.4515],[36.681,4.439],[36.8445,4.4475],[36.988,4.3895],[37.0315,4.3795],[37.09,4.341],[37.137,4.293],[37.5015,4.0565],[37.7075,3.9105],[37.9025,3.7835],[37.994,3.7295],[38.13,3.606],[38.1915,3.62],[38.4485,3.602],[38.551,3.642],[38.58,3.604],[38.6655,3.593],[38.7145,3.5725],[38.9065,3.5125],[39.0215,3.51],[39.0875,3.539],[39.191,3.4775],[39.4295,3.451],[39.498,3.4625],[39.515,3.407],[39.554,3.3975],[39.588,3.492],[39.606,3.503],[39.7585,3.659],[39.787,3.702],[39.8695,3.8745],[40.172,4.0275],[40.376,4.1065],[40.652,4.225],[40.7175,4.245],[40.759,4.279],[40.844,4.2465],[40.8825,4.213],[40.904,4.1545],[40.965,4.132],[41.092,4.0135],[41.1055,3.9855],[41.1695,3.9425],[41.271,3.958],[41.33,3.9395],[41.3915,3.963],[41.427,3.9455],[41.4795,3.952],[41.5505,3.9815],[41.567,3.9665],[41.6315,3.9825],[41.6745,3.96],[41.7235,3.987],[41.8445,3.949],[41.907,3.9825],[41.943,4.0165],[41.9465,4.0555],[42.0005,4.0935],[42.0875,4.179],[42.194,4.179],[42.37,4.1895],[42.587,4.216],[42.669,4.2495],[42.7355,4.2645],[42.825,4.267],[42.8975,4.318],[42.9695,4.403],[43.0075,4.468],[43.026,4.5415],[43.0795,4.602],[43.232,4.695],[43.4345,4.7945],[43.552,4.8355],[43.809,4.902],[44.0315,4.9435],[44.154,4.9505],[44.202,4.9425],[44.385,4.941],[44.549,4.926],[44.625,4.933],[44.978,4.9235],[44.9985,4.946],[45.411,5.5365],[45.845,5.9565],[46.511,6.5205],[46.873,6.9075],[47.3375,7.3825],[47.557,7.561],[47.9825,8.0],[46.993,8.0015],[46.2255,8.2635],[45.6265,8.4625],[45.2675,8.5795],[44.69,8.7725],[43.9965,9.0],[43.643,9.357],[43.5155,9.3815],[43.439,9.447],[43.4055,9.545],[43.33,9.6015],[43.298,9.606],[43.257,9.843],[43.15,9.899],[43.086,9.908],[43.036,10.034],[42.8875,10.1895],[42.833,10.278],[42.792,10.4035],[42.747,10.512],[42.7085,10.578],[42.719,10.6475],[42.766,10.7215],[42.93,10.947],[42.9615,10.9845],[42.8675,10.9695],[42.7905,10.9885],[42.783,11.0335],[42.7525,11.0795],[42.688,11.057],[42.629,11.0955],[42.6045,11.07],[42.5065,11.04],[42.4255,10.983],[42.368,10.998],[42.268,10.9715],[42.11,10.9705],[42.0685,10.925],[41.946,10.9155],[41.9175,10.939],[41.7945,10.9795],[41.803,11.006],[41.8075,11.3185],[41.7715,11.494],[41.804,11.572],[41.8075,11.6555],[41.836,11.733],[41.895,11.756],[41.9,11.793],[41.955,11.812],[42.095,12.0085],[42.1605,12.1175],[42.2575,12.255],[42.317,12.3045],[42.337,12.372],[42.404,12.4685],[42.2785,12.6355],[42.2195,12.7625],[42.0575,12.801],[42.03,12.868],[41.9665,12.9235],[41.8905,13.0745],[41.8105,13.1665],[41.738,13.2365],[41.7215,13.2735],[41.6685,13.3235],[41.6425,13.385],[41.503,13.4455],[41.449,13.4885],[41.403,13.501],[41.309,13.5795],[41.2505,13.6105],[41.172,13.728],[41.1155,13.8275],[40.995,14.0165],[40.9435,14.0805],[40.8105,14.172],[40.5725,14.2695],[40.4515,14.307],[40.365,14.3665],[40.2595,14.411],[40.213,14.387],[40.1475,14.5395],[40.0905,14.548],[40.037,14.5045],[40.0325,14.4785],[39.9305,14.415],[39.8385,14.4905],[39.821,14.4835],[39.765,14.5485],[39.713,14.5555],[39.6435,14.605],[39.5865,14.609],[39.5095,14.552],[39.4895,14.505],[39.4475,14.5055],[39.3705,14.537],[39.36,14.4835],[39.234,14.4515],[39.2635,14.49],[39.241,14.563],[39.2055,14.5655],[39.1575,14.6085],[39.154,14.653],[39.0995,14.6355],[39.0295,14.637],[38.9785,14.545],[38.936,14.54],[38.9005,14.505],[38.7945,14.4665],[38.6895,14.4645],[38.647,14.4425],[38.596,14.442],[38.525,14.4165],[38.4555,14.4135],[38.4295,14.453],[38.319,14.557],[38.271,14.617],[38.2655,14.6705],[38.2325,14.692],[38.1435,14.6755],[38.0915,14.7165],[38.0565,14.7155],[38.0165,14.746],[37.9125,14.894],[37.5275,14.1845],[37.4675,14.2155],[37.4715,14.251],[37.406,14.29],[37.404,14.3345],[37.373,14.3835],[37.312,14.4475],[37.2095,14.44],[37.1355,14.4095],[37.1015,14.336],[37.092,14.2715],[37.014,14.2515],[36.965,14.295],[36.853,14.322],[36.744,14.3225],[36.6955,14.3015],[36.6335,14.3135],[36.5605,14.2575],[36.5285,14.212],[36.4465,13.957],[36.487,13.8395],[36.4075,13.652],[36.3975,13.568],[36.2485,13.368],[36.1555,13.0245],[36.1695,12.984],[36.133,12.9235],[36.1655,12.8755],[36.1405,12.704],[36.081,12.7235],[36.0065,12.724],[35.6995,12.666],[35.6995,12.622],[35.649,12.594],[35.438,12.2505],[35.437,12.21],[35.386,12.17],[35.3465,12.0835],[35.347,12.0385],[35.271,11.9755],[35.269,11.9385],[35.227,11.8955],[35.1345,11.864],[35.081,11.801],[35.0585,11.74],[35.064,11.6545],[35.096,11.583],[35.0875,11.536],[35.0045,11.349],[34.9405,11.249],[35.0075,11.1985],[35.0055,11.1745],[34.9335,10.9565],[34.9785,10.9155],[34.9755,10.8645],[34.8685,10.786],[34.8525,10.7265],[34.798,10.7195],[34.733,10.7695],[34.674,10.8345],[34.5945,10.888],[34.4395,10.7845],[34.357,10.6385],[34.3015,10.5715],[34.293,10.522],[34.348,10.2465],[34.3215,10.164],[34.323,10.117],[34.2315,10.0305],[34.207,9.905],[34.14,9.758],[34.086,9.553],[34.1065,9.5],[34.1455,9.033],[34.1455,8.6075],[34.1005,8.556],[34.045,8.53],[34.0215,8.4885],[33.971,8.502],[33.9005,8.4835],[33.876,8.4555],[33.8765,8.412],[33.809,8.402],[33.7675,8.3675],[33.689,8.3875],[33.6755,8.446],[33.6195,8.4715],[33.561,8.473],[33.423,8.453],[33.3975,8.4265],[33.309,8.466],[33.214,8.4275],[33.187,8.383],[33.2045,8.3315],[33.173,8.301],[33.171,8.2025],[33.193,8.137],[33.1185,8.107],[33.0845,8.0735],[33.078,8.024],[33.0395,8.009],[33.038,7.9675],[32.998,7.9455],[33.0065,7.8565],[33.071,7.7915],[33.1785,7.789],[33.2505,7.778],[33.323,7.7075],[33.437,7.7525],[33.5195,7.728],[33.5815,7.689],[33.6285,7.695],[33.724,7.6565],[33.7855,7.587],[33.866,7.559],[33.8995,7.5125],[34.004,7.4185],[34.0365,7.3555],[34.04,7.272],[34.024,7.2435],[34.074,7.218],[34.105,7.17],[34.19,7.1315],[34.1945,7.0405],[34.2705,7.0025],[34.311,6.9505],[34.372,6.913],[34.4605,6.9195],[34.5305,6.852],[34.5435,6.816],[34.53,6.755],[34.589,6.7285],[34.6245,6.743],[34.7045,6.6915],[34.7185,6.653],[34.765,6.6035],[34.8515,6.6095],[34.9275,6.556],[35.009,6.475],[35.022,6.435],[34.9915,6.3935],[35.0005,6.35],[34.95,6.2465],[34.9735,6.203],[34.964,6.1365],[35.0,6.0805],[35.007,6.021],[34.993,5.945],[35.0065,5.89],[35.13,5.6875],[35.126,5.6245],[35.306,5.5035],[35.3095,5.464],[35.2895,5.378],[35.321,5.336],[35.4115,5.3645],[35.505,5.4235],[35.5675,5.412],[35.628,5.383],[35.7205,5.388],[35.7705,5.351],[35.84,5.336],[35.8635,5.301],[35.828,5.261],[35.866,5.184],[35.8185,5.1005],[35.818,4.774],[35.949,4.631],[35.944,4.619]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/7/71/Flag_of_Ethiopia.svg","name:en":"Ethiopia","wikidata":"Q115","ISO3166-1:alpha2":"ET","ISO3166-1:alpha3":"ETH","ISO3166-1:numeric":"231"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[43.298,12.7925],[43.151,12.7205],[42.9815,12.6495],[42.9195,12.613],[42.8895,12.617],[42.8595,12.5495],[42.8255,12.541],[42.7975,12.477],[42.825,12.434],[42.764,12.4115],[42.752,12.385],[42.688,12.3625],[42.567,12.476],[42.464,12.524],[42.404,12.4685],[42.337,12.372],[42.317,12.3045],[42.2575,12.255],[42.1605,12.1175],[42.095,12.0085],[41.955,11.812],[41.9,11.793],[41.895,11.756],[41.836,11.733],[41.8075,11.6555],[41.804,11.572],[41.7715,11.494],[41.8075,11.3185],[41.803,11.006],[41.7945,10.9795],[41.9175,10.939],[41.946,10.9155],[42.0685,10.925],[42.11,10.9705],[42.268,10.9715],[42.368,10.998],[42.4255,10.983],[42.5065,11.04],[42.6045,11.07],[42.629,11.0955],[42.688,11.057],[42.7525,11.0795],[42.783,11.0335],[42.7905,10.9885],[42.8675,10.9695],[42.9615,10.9845],[42.967,10.997],[43.228,11.412],[43.3445,11.6225],[43.4255,11.7115],[43.41,11.783],[43.47,11.8055],[43.5495,11.885],[43.6045,12.002],[43.617,12.0545],[43.621,12.1565],[43.5995,12.2885],[43.6535,12.3865],[43.6565,12.453],[43.6365,12.518],[43.5355,12.5525],[43.4305,12.5525],[43.3205,12.5955],[43.29,12.633],[43.273,12.687],[43.298,12.7925]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/34/Flag_of_Djibouti.svg","name:en":"Djibouti","wikidata":"Q977","ISO3166-1:alpha2":"DJ","ISO3166-1:alpha3":"DJI","ISO3166-1:numeric":"262"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[8.5905,37.143],[8.418,37.121],[8.2525,37.153],[7.741,37.176],[7.596,37.2415],[7.413,37.286],[7.223,37.296],[7.122,37.285],[6.756,37.179],[6.615,37.263],[6.5325,37.2845],[6.3765,37.289],[6.2575,37.2595],[6.191,37.2315],[6.0795,37.161],[5.9935,37.061],[5.6455,37.0185],[5.5435,36.9875],[5.173,36.9805],[5.096,37.0145],[4.8825,37.0815],[4.7915,37.097],[4.352,37.1175],[4.186,37.1155],[3.8705,37.1265],[3.678,37.083],[3.288,37.02],[3.0205,37.0215],[2.926,37.0165],[2.803,36.993],[2.71,36.941],[2.3925,36.846],[2.3015,36.846],[1.921,36.7865],[1.7835,36.7875],[1.6415,36.756],[1.478,36.7435],[1.3775,36.7555],[1.2755,36.7465],[1.021,36.69],[0.845,36.634],[0.6915,36.5475],[0.5405,36.507],[0.1985,36.3565],[0.053,36.269],[-0.013,36.2125],[-0.369,36.1125],[-0.4365,36.1065],[-0.579,36.0695],[-0.8205,35.9665],[-0.9525,35.9685],[-1.171,35.9285],[-1.2815,35.8905],[-1.349,35.837],[-1.662,35.4635],[-1.8355,35.3635],[-1.98,35.322],[-2.2065,35.337],[-2.211,35.0585],[-2.1705,35.0095],[-2.1305,34.997],[-2.035,34.9245],[-1.973,34.9355],[-1.9745,34.8875],[-1.8935,34.8415],[-1.8885,34.8065],[-1.7395,34.7435],[-1.771,34.7235],[-1.839,34.628],[-1.7415,34.508],[-1.687,34.4905],[-1.782,34.3915],[-1.7055,34.307],[-1.712,34.2615],[-1.692,34.194],[-1.646,34.1025],[-1.6985,33.8695],[-1.672,33.806],[-1.6765,33.759],[-1.721,33.7405],[-1.7325,33.701],[-1.6465,33.676],[-1.5995,33.6155],[-1.588,33.529],[-1.62,33.49],[-1.6215,33.448],[-1.6635,33.378],[-1.6705,33.284],[-1.6065,33.213],[-1.576,33.149],[-1.462,33.042],[-1.486,32.9755],[-1.544,32.958],[-1.399,32.7625],[-1.2715,32.6955],[-1.0005,32.5195],[-1.063,32.453],[-1.1285,32.41],[-1.188,32.407],[-1.2485,32.3205],[-1.235,32.2895],[-1.241,32.2055],[-1.183,32.1635],[-1.154,32.11],[-1.2215,32.08],[-1.41,32.0875],[-1.509,32.104],[-1.5765,32.092],[-1.749,32.121],[-1.9035,32.1645],[-1.9685,32.1575],[-2.015,32.182],[-2.1325,32.1465],[-2.18,32.142],[-2.2775,32.1685],[-2.5425,32.145],[-2.6,32.113],[-2.8735,32.1115],[-2.931,32.035],[-2.8415,31.8805],[-2.844,31.832],[-2.8205,31.7935],[-3.252,31.7135],[-3.6645,31.6335],[-3.661,31.378],[-3.7645,31.334],[-3.759,31.2635],[-3.7905,31.236],[-3.7595,31.176],[-3.778,31.124],[-3.681,31.165],[-3.674,31.097],[-3.606,31.0765],[-3.5365,31.0135],[-3.5565,30.932],[-3.6515,30.8425],[-3.6295,30.7445],[-3.6445,30.6905],[-3.768,30.626],[-3.817,30.5905],[-3.8865,30.6105],[-4.001,30.593],[-4.1485,30.585],[-4.3295,30.5215],[-4.427,30.4395],[-4.488,30.372],[-4.6075,30.2825],[-4.9365,30.1405],[-5.124,30.003],[-5.2395,29.933],[-5.289,29.881],[-5.3235,29.815],[-5.3175,29.789],[-5.445,29.6335],[-5.5655,29.4765],[-5.651,29.5045],[-5.686,29.541],[-5.7505,29.53],[-5.7275,29.591],[-5.8135,29.6075],[-5.8765,29.5905],[-5.9365,29.5935],[-6.07,29.562],[-6.1655,29.5825],[-6.2475,29.5655],[-6.2895,29.5705],[-6.468,29.56],[-6.5275,29.5215],[-6.6185,29.53],[-6.721,29.5055],[-6.777,29.462],[-6.834,29.468],[-6.9085,29.4955],[-7.0225,29.4935],[-7.15,29.5225],[-7.257,29.474],[-7.345,29.392],[-7.4885,29.36],[-7.6135,29.3655],[-7.6345,29.301],[-7.773,29.255],[-7.822,29.211],[-7.8735,29.1935],[-7.958,29.1215],[-8.04,29.08],[-8.202,28.9845],[-8.3515,28.8855],[-8.458,28.792],[-8.5735,28.7475],[-8.6685,28.667],[-8.669,28.241],[-8.668,27.6665],[-8.668,27.315],[-8.2315,27.057],[-7.5785,26.67],[-7.266,26.483],[-6.833,26.2235],[-6.434,25.9805],[-6.0345,25.736],[-5.3905,25.344],[-4.8335,25.0],[-4.4805,24.7715],[-4.0945,24.5215],[-3.602,24.203],[-2.987,23.805],[-2.5945,23.5505],[-2.054,23.201],[-1.668,22.951],[-1.304,22.7155],[-0.923,22.469],[-0.52,22.208],[-0.061,21.911],[0.505,21.5445],[0.9095,21.2825],[1.1665,21.1165],[1.192,21.0035],[1.1915,20.924],[1.164,20.7905],[1.1785,20.7265],[1.3165,20.74],[1.353,20.677],[1.5035,20.6225],[1.591,20.6005],[1.6425,20.56],[1.675,20.4795],[1.668,20.4065],[1.775,20.337],[1.798,20.298],[1.884,20.2945],[1.8975,20.243],[1.947,20.26],[2.0025,20.2425],[2.037,20.2695],[2.084,20.244],[2.1335,20.2445],[2.192,20.28],[2.194,20.3155],[2.2735,20.299],[2.3125,20.2695],[2.318,20.218],[2.3565,20.1905],[2.4015,20.1175],[2.3975,20.061],[2.4745,20.098],[2.525,20.089],[2.562,20.033],[2.666,20.052],[2.701,20.087],[2.723,20.006],[2.8235,19.9645],[2.857,19.973],[2.977,19.953],[3.0765,19.9055],[3.145,19.8585],[3.2375,19.842],[3.2595,19.8175],[3.23,19.711],[3.2505,19.6495],[3.2325,19.6055],[3.265,19.5305],[3.248,19.498],[3.263,19.439],[3.208,19.431],[3.1785,19.359],[3.2005,19.277],[3.1225,19.185],[3.1245,19.1255],[3.1635,19.1145],[3.276,19.0335],[3.2945,19.003],[3.3575,18.968],[3.8105,19.0585],[4.2665,19.144],[4.336,19.1495],[4.8495,19.2535],[5.179,19.3205],[5.8105,19.447],[5.9875,19.599],[6.1275,19.7125],[6.437,19.9755],[6.4695,20.0085],[6.999,20.455],[7.4595,20.8425],[7.994,21.167],[8.0135,21.1835],[8.4345,21.4395],[8.997,21.7785],[9.051,21.8],[9.351,21.976],[9.756,22.211],[10.2385,22.4965],[10.6715,22.7455],[11.0015,22.9335],[11.2925,23.116],[11.729,23.364],[11.9975,23.517],[11.846,23.806],[11.6045,24.2645],[11.4225,24.2005],[11.1385,24.391],[11.0775,24.411],[10.9815,24.491],[10.9495,24.5325],[10.8965,24.556],[10.821,24.5675],[10.7665,24.5105],[10.706,24.573],[10.6335,24.5665],[10.542,24.534],[10.3565,24.537],[10.3025,24.599],[10.2165,24.6505],[10.153,24.784],[10.106,24.846],[10.0975,24.881],[10.038,24.9655],[10.032,25.3595],[9.751,25.725],[9.5375,26.0025],[9.399,26.1955],[9.456,26.2535],[9.5125,26.385],[9.8635,26.52],[9.9135,26.647],[9.902,26.743],[9.9255,26.862],[9.8625,26.9425],[9.818,27.1495],[9.798,27.1745],[9.7825,27.2565],[9.7945,27.395],[9.8135,27.463],[9.863,27.5045],[9.8885,27.609],[9.9425,27.7325],[9.943,27.836],[9.962,27.886],[9.833,28.286],[9.9025,28.759],[9.8715,29.0275],[9.78,29.425],[9.5385,29.901],[9.415,30.0425],[9.3915,30.1465],[9.4155,30.1875],[9.559,30.229],[9.474,30.559],[9.3595,31.0],[9.187,31.676],[9.0985,31.9995],[9.0655,32.0875],[8.8005,32.236],[8.357,32.5025],[8.3225,32.8235],[8.247,32.9245],[8.116,33.05],[8.1175,33.1],[7.9015,33.1855],[7.832,33.188],[7.786,33.2905],[7.749,33.3275],[7.7365,33.4245],[7.634,33.572],[7.565,33.727],[7.562,33.7775],[7.5255,33.7985],[7.547,33.837],[7.522,33.905],[7.5605,34.0145],[7.5305,34.061],[7.614,34.1135],[7.6515,34.201],[7.723,34.1705],[7.7965,34.209],[7.845,34.329],[7.8565,34.4055],[7.9285,34.4185],[7.959,34.4485],[8.011,34.458],[8.043,34.4935],[8.1155,34.5125],[8.1615,34.569],[8.206,34.5775],[8.244,34.6205],[8.25,34.664],[8.2995,34.7415],[8.253,34.9155],[8.3075,34.947],[8.3155,35.009],[8.3615,35.103],[8.4,35.128],[8.4545,35.22],[8.3125,35.3125],[8.3145,35.3775],[8.3535,35.463],[8.36,35.5255],[8.356,35.67],[8.2645,35.7305],[8.2715,35.9075],[8.291,35.957],[8.2975,36.0415],[8.346,36.097],[8.3095,36.1615],[8.355,36.2335],[8.3395,36.267],[8.372,36.298],[8.4045,36.4235],[8.176,36.4595],[8.1615,36.4985],[8.286,36.538],[8.326,36.574],[8.418,36.6225],[8.447,36.6235],[8.4875,36.6975],[8.4595,36.7515],[8.484,36.7795],[8.5725,36.773],[8.6695,36.8175],[8.6295,36.8605],[8.642,36.941],[8.5905,37.143]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/7/77/Flag_of_Algeria.svg","name:en":"Algeria","wikidata":"Q262","ISO3166-1:alpha2":"DZ","ISO3166-1:alpha3":"DZA","ISO3166-1:numeric":"012"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[1.726,42.5025],[1.7505,42.564],[1.7135,42.615],[1.6005,42.626],[1.5495,42.656],[1.479,42.6515],[1.442,42.6035],[1.425,42.558],[1.4445,42.4415],[1.5525,42.4335],[1.597,42.4675],[1.726,42.5025]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/19/Flag_of_Andorra.svg","name:en":"Andorra","wikidata":"Q228","ISO3166-1:alpha2":"AD","ISO3166-1:alpha3":"AND","ISO3166-1:numeric":"020"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[13.2105,45.453],[13.2555,45.3355],[13.2855,45.1795],[13.2885,45.1155],[13.352,44.964],[13.48,44.805],[13.701,44.5985],[14.128,44.3425],[14.402,44.1865],[14.646,43.992],[14.7825,43.916],[14.8555,43.831],[15.0625,43.6595],[15.2685,43.5375],[15.4375,43.4495],[15.7835,43.339],[15.856,43.3025],[15.92,43.2335],[15.879,43.2145],[15.7675,43.235],[15.666,43.2235],[15.6175,43.256],[15.5165,43.2885],[15.3815,43.2845],[15.299,43.2545],[15.225,43.1955],[15.188,43.12],[15.205,43.017],[15.2425,42.969],[15.3255,42.917],[15.3895,42.898],[15.497,42.8935],[15.578,42.8435],[15.748,42.8065],[15.8125,42.805],[15.9215,42.7605],[16.0035,42.753],[16.1245,42.7765],[16.194,42.816],[16.2335,42.8145],[16.2225,42.716],[16.2785,42.592],[16.1945,42.5875],[16.0855,42.548],[16.0125,42.4795],[15.988,42.4255],[15.9905,42.3395],[16.0675,42.244],[16.1385,42.209],[16.268,42.1825],[16.347,42.1765],[16.433,42.19],[16.5015,42.2185],[16.575,42.2815],[16.61,42.345],[16.6045,42.4355],[16.513,42.5495],[16.5985,42.565],[16.795,42.5225],[16.917,42.5225],[17.185,42.5665],[17.2835,42.5715],[17.398,42.552],[17.4845,42.521],[17.5745,42.514],[17.8665,42.4545],[18.0895,42.388],[18.2035,42.333],[18.272,42.279],[18.4195,42.2095],[18.54,42.39],[18.524,42.4205],[18.434,42.484],[18.438,42.5555],[18.3645,42.6155],[18.25,42.6035],[18.194,42.6555],[18.111,42.6865],[18.0415,42.749],[17.9095,42.8105],[17.844,42.9025],[17.786,42.892],[17.6785,42.9205],[17.642,42.884],[17.5485,42.9235],[17.7105,42.973],[17.639,43.089],[17.45,43.1775],[17.428,43.2175],[17.3425,43.2595],[17.252,43.4005],[17.288,43.44],[17.224,43.498],[17.155,43.4925],[17.0825,43.543],[17.008,43.576],[16.9335,43.636],[16.894,43.6935],[16.8075,43.758],[16.7245,43.796],[16.717,43.8515],[16.667,43.875],[16.5735,43.9475],[16.505,44.026],[16.4365,44.0305],[16.43,44.0835],[16.3095,44.1445],[16.2125,44.217],[16.189,44.3095],[16.218,44.346],[16.14,44.392],[16.123,44.5105],[16.019,44.563],[16.0555,44.611],[15.894,44.7495],[15.835,44.714],[15.7885,44.7455],[15.7285,44.8255],[15.76,44.8695],[15.738,44.9355],[15.783,44.9715],[15.741,45.062],[15.7895,45.1175],[15.7645,45.1665],[15.827,45.2195],[15.9445,45.2135],[15.978,45.2305],[16.086,45.132],[16.109,45.0925],[16.174,45.0705],[16.194,45.031],[16.292,44.9985],[16.3545,45.0035],[16.394,45.1125],[16.4785,45.1615],[16.4915,45.208],[16.603,45.2305],[16.7,45.197],[16.731,45.2075],[16.8435,45.194],[16.936,45.2755],[16.9825,45.23],[17.183,45.1465],[17.2455,45.146],[17.2705,45.188],[17.3425,45.1425],[17.5135,45.1085],[17.6015,45.1065],[17.66,45.1335],[17.84,45.046],[17.899,45.0585],[17.939,45.111],[18.002,45.1515],[18.1115,45.0825],[18.172,45.077],[18.2215,45.097],[18.253,45.1395],[18.326,45.1015],[18.406,45.11],[18.479,45.0615],[18.5805,45.082],[18.713,45.0385],[18.728,44.999],[18.794,44.995],[18.793,44.9345],[18.768,44.9025],[18.856,44.853],[19.019,44.855],[18.989,44.906],[19.143,44.941],[19.0925,44.995],[19.106,45.079],[19.077,45.1135],[19.142,45.13],[19.187,45.166],[19.295,45.173],[19.418,45.1665],[19.4475,45.196],[19.4205,45.2335],[19.26,45.243],[19.1045,45.299],[19.093,45.335],[18.9715,45.377],[19.0235,45.403],[18.987,45.455],[18.997,45.491],[19.0825,45.4885],[19.096,45.5205],[18.984,45.537],[18.9085,45.5675],[18.936,45.6385],[18.9285,45.691],[18.9795,45.7395],[18.9585,45.7675],[18.894,45.7515],[18.8735,45.7845],[18.9185,45.819],[18.8855,45.859],[18.89,45.922],[18.807,45.903],[18.791,45.878],[18.705,45.918],[18.628,45.8735],[18.5555,45.7945],[18.4105,45.739],[18.244,45.761],[18.191,45.788],[18.082,45.7645],[18.0015,45.7945],[17.833,45.792],[17.746,45.828],[17.6725,45.835],[17.6145,45.9095],[17.5655,45.9375],[17.4455,45.9505],[17.3955,45.9305],[17.3745,45.982],[17.313,45.9665],[17.1595,46.1695],[17.006,46.223],[16.973,46.225],[16.887,46.28],[16.88,46.334],[16.801,46.3855],[16.7075,46.403],[16.6645,46.459],[16.597,46.476],[16.5385,46.476],[16.4715,46.5165],[16.3655,46.5465],[16.2415,46.4985],[16.3015,46.3785],[16.189,46.378],[16.148,46.405],[16.0505,46.382],[16.0775,46.348],[16.0015,46.3075],[15.8635,46.2675],[15.7915,46.2585],[15.7855,46.2165],[15.6745,46.227],[15.6075,46.167],[15.6325,46.0835],[15.715,46.058],[15.709,45.931],[15.683,45.8635],[15.629,45.833],[15.5385,45.8475],[15.3,45.7545],[15.2595,45.726],[15.311,45.684],[15.3545,45.7145],[15.39,45.6375],[15.3065,45.6325],[15.301,45.5375],[15.3855,45.4865],[15.329,45.4525],[15.277,45.466],[15.222,45.4255],[15.1665,45.422],[15.0535,45.4945],[14.9795,45.4995],[14.8165,45.4605],[14.8035,45.4955],[14.7205,45.534],[14.698,45.568],[14.5955,45.628],[14.507,45.5945],[14.5005,45.5495],[14.4375,45.511],[14.328,45.472],[14.2455,45.5035],[14.143,45.475],[14.0705,45.4855],[13.9145,45.4535],[13.887,45.426],[13.8145,45.434],[13.7655,45.467],[13.6755,45.4425],[13.601,45.468],[13.467,45.5895],[13.312,45.546],[13.2105,45.453]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/1b/Flag_of_Croatia.svg","name:en":"Croatia","wikidata":"Q224","ISO3166-1:alpha2":"HR","ISO3166-1:alpha3":"HRV","ISO3166-1:numeric":"191"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[20.5945,41.877],[20.5765,41.917],[20.6265,41.961],[20.5945,42.043],[20.5545,42.0825],[20.568,42.121],[20.524,42.2105],[20.4565,42.2725],[20.327,42.3275],[20.2575,42.319],[20.2275,42.4195],[20.165,42.5065],[20.0765,42.556],[20.0175,42.5435],[20.0035,42.5095],[19.9435,42.5175],[19.8315,42.466],[19.7665,42.5015],[19.7435,42.545],[19.7755,42.591],[19.723,42.661],[19.662,42.628],[19.61,42.5755],[19.616,42.5435],[19.563,42.5015],[19.468,42.3895],[19.414,42.351],[19.349,42.2405],[19.281,42.1805],[19.4025,42.1035],[19.3705,42.037],[19.377,41.974],[19.347,41.9135],[19.373,41.8445],[19.2645,41.7495],[19.3105,41.5835],[19.3105,41.5175],[19.2675,41.35],[19.3095,41.1485],[19.257,40.892],[19.1625,40.679],[19.135,40.574],[19.1245,40.4175],[19.2045,40.339],[19.284,40.205],[19.671,39.9875],[19.809,39.9195],[19.8635,39.873],[19.937,39.8395],[19.9735,39.7965],[19.964,39.722],[20.088,39.6825],[20.1345,39.6545],[20.22,39.6465],[20.2315,39.685],[20.322,39.735],[20.295,39.7555],[20.3045,39.8165],[20.39,39.788],[20.4105,39.8445],[20.319,39.974],[20.395,39.998],[20.411,40.0515],[20.4495,40.074],[20.55,40.064],[20.677,40.1025],[20.693,40.154],[20.6785,40.1895],[20.7215,40.216],[20.713,40.283],[20.7895,40.362],[20.787,40.429],[20.8425,40.48],[20.969,40.4885],[20.968,40.5185],[21.043,40.558],[21.0575,40.668],[20.96,40.772],[20.985,40.795],[20.9775,40.8555],[20.9485,40.9225],[20.848,40.9375],[20.8015,40.898],[20.7315,40.911],[20.675,41.08],[20.596,41.092],[20.596,41.133],[20.516,41.2305],[20.498,41.322],[20.5515,41.377],[20.557,41.417],[20.5135,41.4375],[20.469,41.4975],[20.4705,41.559],[20.5545,41.5835],[20.517,41.663],[20.5205,41.7515],[20.573,41.788],[20.5585,41.8675],[20.5945,41.877]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/3/36/Flag_of_Albania.svg","name:en":"Albania","wikidata":"Q222","ISO3166-1:alpha2":"AL","ISO3166-1:alpha3":"ALB","ISO3166-1:numeric":"008"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[19.226,43.528],[19.273,43.5965],[19.3575,43.606],[19.481,43.5715],[19.532,43.668],[19.5185,43.7145],[19.4655,43.7645],[19.395,43.798],[19.294,43.92],[19.2535,43.951],[19.235,44.0085],[19.3105,43.996],[19.3885,43.9605],[19.5265,43.956],[19.5645,43.9995],[19.6185,44.0135],[19.5995,44.0705],[19.512,44.081],[19.491,44.1165],[19.3605,44.1835],[19.328,44.269],[19.2285,44.2645],[19.1325,44.317],[19.103,44.3715],[19.147,44.415],[19.1285,44.52],[19.19,44.547],[19.1835,44.573],[19.303,44.688],[19.318,44.8215],[19.3695,44.8805],[19.3095,44.908],[19.2255,44.8985],[19.175,44.9215],[19.065,44.8615],[19.019,44.855],[18.856,44.853],[18.768,44.9025],[18.793,44.9345],[18.794,44.995],[18.728,44.999],[18.713,45.0385],[18.5805,45.082],[18.479,45.0615],[18.406,45.11],[18.326,45.1015],[18.253,45.1395],[18.2215,45.097],[18.172,45.077],[18.1115,45.0825],[18.002,45.1515],[17.939,45.111],[17.899,45.0585],[17.84,45.046],[17.66,45.1335],[17.6015,45.1065],[17.5135,45.1085],[17.3425,45.1425],[17.2705,45.188],[17.2455,45.146],[17.183,45.1465],[16.9825,45.23],[16.936,45.2755],[16.8435,45.194],[16.731,45.2075],[16.7,45.197],[16.603,45.2305],[16.4915,45.208],[16.4785,45.1615],[16.394,45.1125],[16.3545,45.0035],[16.292,44.9985],[16.194,45.031],[16.174,45.0705],[16.109,45.0925],[16.086,45.132],[15.978,45.2305],[15.9445,45.2135],[15.827,45.2195],[15.7645,45.1665],[15.7895,45.1175],[15.741,45.062],[15.783,44.9715],[15.738,44.9355],[15.76,44.8695],[15.7285,44.8255],[15.7885,44.7455],[15.835,44.714],[15.894,44.7495],[16.0555,44.611],[16.019,44.563],[16.123,44.5105],[16.14,44.392],[16.218,44.346],[16.189,44.3095],[16.2125,44.217],[16.3095,44.1445],[16.43,44.0835],[16.4365,44.0305],[16.505,44.026],[16.5735,43.9475],[16.667,43.875],[16.717,43.8515],[16.7245,43.796],[16.8075,43.758],[16.894,43.6935],[16.9335,43.636],[17.008,43.576],[17.0825,43.543],[17.155,43.4925],[17.224,43.498],[17.288,43.44],[17.252,43.4005],[17.3425,43.2595],[17.428,43.2175],[17.45,43.1775],[17.639,43.089],[17.7105,42.973],[17.5485,42.9235],[17.642,42.884],[17.6785,42.9205],[17.786,42.892],[17.844,42.9025],[17.9095,42.8105],[18.0415,42.749],[18.111,42.6865],[18.194,42.6555],[18.25,42.6035],[18.3645,42.6155],[18.438,42.5555],[18.5,42.588],[18.569,42.656],[18.528,42.724],[18.4735,42.757],[18.458,42.8255],[18.509,42.8865],[18.4825,42.9285],[18.498,42.9955],[18.5435,43.0325],[18.6605,43.0375],[18.6485,43.147],[18.6675,43.204],[18.733,43.281],[18.852,43.324],[18.911,43.3605],[18.96,43.3175],[18.9555,43.2875],[19.009,43.251],[19.0835,43.319],[19.04,43.3655],[19.0045,43.443],[18.961,43.4605],[18.95,43.5035],[18.9885,43.5555],[19.062,43.505],[19.153,43.5365],[19.226,43.528]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/bf/Flag_of_Bosnia_and_Herzegovina.svg","name:en":"Bosnia and Herzegovina","wikidata":"Q225","ISO3166-1:alpha2":"BA","ISO3166-1:alpha3":"BIH","ISO3166-1:numeric":"070"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[33.1665,22.0],[33.413,22.0],[34.08,22.0],[34.215,21.9975],[34.3,22.0055],[34.3535,21.996],[34.475,21.9995],[35.1815,22.0],[35.556,22.0],[36.0995,22.0],[36.485,22.0],[36.6195,22.0055],[36.737,21.999],[37.0905,22.0],[37.1155,22.065],[37.102,22.133],[37.019,22.34],[36.944,22.4315],[36.844,22.4785],[36.797,22.661],[36.7545,22.7365],[36.5545,22.958],[36.5625,23.567],[36.549,23.6335],[36.524,23.677],[36.4665,23.729],[35.9845,24.027],[35.9295,24.214],[35.902,24.2705],[35.835,24.364],[35.788,24.411],[35.533,24.58],[35.41,24.7155],[35.4,24.831],[35.3855,24.8705],[35.0595,25.444],[35.022,25.4885],[34.872,25.6115],[34.782,25.8105],[34.497,26.1935],[34.3245,26.7735],[34.2755,26.8635],[34.2275,26.9225],[34.2165,27.177],[34.253,27.3735],[34.4505,27.611],[34.519,27.7135],[34.477,27.7895],[34.457,27.9005],[34.466,28.025],[34.49,28.0645],[34.536,28.193],[34.545,28.277],[34.5825,28.369],[34.6225,28.432],[34.677,28.579],[34.688,28.6725],[34.7115,28.728],[34.737,28.8415],[34.7335,28.905],[34.7615,28.9525],[34.7625,29.053],[34.816,29.193],[34.8305,29.2695],[34.8845,29.375],[34.921,29.4535],[34.8785,29.5435],[34.8665,29.597],[34.8785,29.6435],[34.8565,29.688],[34.8485,29.759],[34.707,30.1175],[34.6115,30.371],[34.5435,30.413],[34.5575,30.4945],[34.5185,30.5325],[34.519,30.592],[34.497,30.679],[34.4035,30.859],[34.332,31.041],[34.2675,31.22],[34.219,31.3235],[34.069,31.478],[33.971,31.418],[33.887,31.3855],[33.679,31.327],[33.589,31.322],[33.5145,31.359],[33.4105,31.3915],[33.28,31.421],[33.141,31.437],[33.0605,31.427],[32.948,31.3925],[32.835,31.3355],[32.654,31.293],[32.522,31.431],[32.463,31.475],[32.39,31.4995],[32.2395,31.527],[32.113,31.6545],[32.032,31.7025],[31.9485,31.7315],[31.8665,31.7355],[31.77,31.7175],[31.607,31.6595],[31.2705,31.775],[31.1655,31.796],[31.028,31.8005],[30.9605,31.792],[30.499,31.672],[30.373,31.705],[30.2955,31.699],[30.2245,31.6715],[29.976,31.5275],[29.6605,31.317],[29.429,31.2165],[29.301,31.181],[29.046,31.0815],[28.916,31.162],[28.6735,31.242],[28.4365,31.292],[28.0855,31.3005],[28.0635,31.345],[28.0085,31.4015],[27.8915,31.4455],[27.806,31.4415],[27.6055,31.403],[27.544,31.4815],[27.4915,31.5295],[27.3865,31.568],[27.1505,31.5995],[27.0385,31.6485],[26.696,31.7165],[26.295,31.8],[25.9115,31.833],[25.829,31.827],[25.377,31.722],[25.134,31.67],[25.076,31.599],[25.0765,31.551],[24.981,31.5],[24.8625,31.406],[24.8445,31.3625],[24.8635,31.2385],[24.8585,31.155],[24.9035,31.0395],[24.9805,30.9],[25.011,30.782],[24.9455,30.6445],[24.89,30.452],[24.849,30.393],[24.7975,30.348],[24.698,30.2295],[24.65,30.1265],[24.7405,30.0985],[24.8345,29.8765],[24.8125,29.7845],[24.887,29.664],[24.876,29.512],[24.998,29.249],[24.9985,28.8885],[25.0005,28.4295],[25.0025,28.1205],[25.001,27.524],[25.0005,27.0665],[24.999,26.4145],[24.999,25.9845],[24.998,25.513],[24.997,24.7865],[24.9985,24.468],[24.999,23.899],[24.9995,23.5665],[25.001,23.04],[25.0015,22.337],[25.0,22.0],[25.527,22.0],[26.2895,22.0],[26.643,22.0],[27.242,22.0],[27.7535,22.0],[28.316,22.0],[29.024,22.0],[29.5745,22.0],[30.0,22.0],[30.4155,22.0],[31.0,22.0],[31.315,22.0],[31.3385,22.081],[31.3765,22.148],[31.47,22.225],[31.506,22.185],[31.43,22.078],[31.399,22.0],[32.0,22.0],[32.5425,22.0],[33.1665,22.0]]],[[[34.6195,26.308],[34.662,26.1975],[34.745,26.1315],[34.818,26.1045],[34.871,26.1005],[34.952,26.117],[35.001,26.143],[35.057,26.201],[35.086,26.2835],[35.0715,26.373],[35.038,26.4255],[34.9225,26.5015],[34.843,26.515],[34.763,26.5015],[34.667,26.4385],[34.624,26.3545],[34.6195,26.308]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/fe/Flag_of_Egypt.svg","name:en":"Egypt","wikidata":"Q79","ISO3166-1:alpha2":"EG","ISO3166-1:alpha3":"EGY","ISO3166-1:numeric":"818"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[26.358,41.711],[26.277,41.7135],[26.234,41.739],[26.1665,41.7475],[26.086,41.717],[26.0605,41.6885],[26.094,41.627],[26.154,41.6055],[26.1475,41.5545],[26.185,41.52],[26.1555,41.4735],[26.1925,41.447],[26.132,41.355],[26.0115,41.3445],[25.9745,41.318],[25.884,41.3045],[25.846,41.3375],[25.6275,41.3055],[25.575,41.3195],[25.532,41.2805],[25.4755,41.2885],[25.3365,41.2415],[25.239,41.2455],[25.1815,41.3075],[25.0825,41.338],[25.056,41.3655],[24.977,41.376],[24.9005,41.4075],[24.8205,41.4015],[24.804,41.3465],[24.7455,41.3835],[24.7305,41.416],[24.608,41.4275],[24.5255,41.5685],[24.4505,41.522],[24.303,41.538],[24.2605,41.573],[24.198,41.539],[24.077,41.5415],[24.0735,41.47],[23.966,41.4395],[23.933,41.471],[23.89,41.45],[23.8005,41.4375],[23.7675,41.396],[23.674,41.4105],[23.6155,41.3755],[23.5255,41.405],[23.401,41.4005],[23.3405,41.3635],[23.3225,41.4],[23.2325,41.376],[23.2205,41.333],[23.18,41.3185],[23.0765,41.32],[22.9275,41.3385],[22.812,41.344],[22.7645,41.322],[22.748,41.1665],[22.706,41.143],[22.667,41.186],[22.618,41.134],[22.416,41.1195],[22.2145,41.17],[22.1285,41.1235],[22.0675,41.1565],[21.932,41.104],[21.914,41.0505],[21.801,40.9745],[21.783,40.9285],[21.707,40.943],[21.649,40.9015],[21.5665,40.8665],[21.5325,40.9075],[21.417,40.9175],[21.3635,40.8805],[21.252,40.8625],[21.2065,40.884],[21.1565,40.8575],[20.9775,40.8555],[20.985,40.795],[20.96,40.772],[21.0575,40.668],[21.043,40.558],[20.968,40.5185],[20.969,40.4885],[20.8425,40.48],[20.787,40.429],[20.7895,40.362],[20.713,40.283],[20.7215,40.216],[20.6785,40.1895],[20.693,40.154],[20.677,40.1025],[20.55,40.064],[20.4495,40.074],[20.411,40.0515],[20.395,39.998],[20.319,39.974],[20.4105,39.8445],[20.39,39.788],[20.3045,39.8165],[20.295,39.7555],[20.322,39.735],[20.2315,39.685],[20.22,39.6465],[20.1345,39.6545],[20.088,39.6825],[19.964,39.722],[19.9735,39.7965],[19.937,39.8395],[19.8635,39.873],[19.809,39.9195],[19.729,39.8995],[19.673,39.9755],[19.6165,39.998],[19.5235,39.995],[19.4705,39.965],[19.3785,39.97],[19.2775,39.9295],[19.249,39.8785],[19.2615,39.8005],[19.3125,39.756],[19.374,39.7375],[19.408,39.6855],[19.4705,39.649],[19.5485,39.646],[19.622,39.57],[19.7045,39.5145],[19.7105,39.4565],[19.813,39.3405],[19.9265,39.3155],[20.0025,39.286],[19.9925,39.2075],[20.037,39.1355],[20.1915,39.0305],[20.2715,39.014],[20.3675,39.051],[20.394,39.139],[20.445,39.113],[20.5105,39.0475],[20.5705,39.0085],[20.597,38.927],[20.555,38.906],[20.4755,38.8165],[20.429,38.712],[20.4095,38.567],[20.4225,38.5185],[20.407,38.465],[20.32,38.438],[20.279,38.3955],[20.264,38.331],[20.2275,38.279],[20.2075,38.186],[20.227,38.1275],[20.308,38.066],[20.422,38.0295],[20.482,37.9945],[20.5615,37.9785],[20.495,37.8925],[20.5005,37.7775],[20.6185,37.655],[20.732,37.5695],[20.808,37.5435],[20.905,37.5565],[20.965,37.597],[21.064,37.614],[21.114,37.6675],[21.1215,37.7315],[21.1795,37.7155],[21.1755,37.66],[21.214,37.569],[21.2915,37.5325],[21.363,37.5395],[21.464,37.482],[21.4985,37.447],[21.5685,37.33],[21.489,37.2705],[21.443,37.181],[21.4455,37.127],[21.4125,37.074],[21.436,36.986],[21.5285,36.933],[21.5725,36.8105],[21.5665,36.7255],[21.608,36.6635],[21.7475,36.6015],[21.8695,36.5895],[21.9765,36.6165],[22.0175,36.6805],[22.073,36.734],[22.097,36.8085],[22.15,36.792],[22.238,36.6535],[22.2425,36.583],[22.2225,36.52],[22.258,36.433],[22.353,36.3725],[22.424,36.2995],[22.512,36.2885],[22.5755,36.317],[22.626,36.3845],[22.629,36.5085],[22.6165,36.543],[22.6885,36.6435],[22.7205,36.596],[22.812,36.5305],[22.811,36.4255],[22.7665,36.334],[22.7745,36.237],[22.7955,36.153],[22.916,36.0175],[23.018,35.993],[23.107,36.04],[23.201,35.989],[23.153,35.937],[23.15,35.8725],[23.201,35.7805],[23.264,35.735],[23.3445,35.7225],[23.41,35.747],[23.4765,35.7075],[23.3805,35.653],[23.3575,35.6185],[23.356,35.556],[23.4335,35.4895],[23.39,35.3115],[23.4035,35.241],[23.4435,35.189],[23.531,35.141],[23.646,35.121],[23.832,35.1385],[23.94,35.12],[24.0045,35.095],[24.17,35.09],[24.2745,35.073],[24.333,35.0805],[24.4525,35.047],[24.4475,34.998],[24.483,34.9325],[24.5455,34.904],[24.6095,34.903],[24.638,34.854],[24.6905,34.8245],[24.7905,34.8185],[24.85,34.831],[24.9695,34.8215],[25.2235,34.8475],[25.38,34.889],[25.492,34.88],[25.5585,34.887],[25.569,34.8285],[25.598,34.7965],[25.6805,34.765],[25.7985,34.7835],[25.8675,34.8535],[25.8645,34.9085],[25.937,34.9295],[26.0015,34.9135],[26.024,34.862],[26.0935,34.819],[26.136,34.815],[26.2095,34.838],[26.2635,34.8885],[26.2785,34.931],[26.34,34.973],[26.388,35.052],[26.4705,35.24],[26.475,35.282],[26.4505,35.3335],[26.709,35.436],[26.7215,35.3415],[26.752,35.283],[26.79,35.2575],[26.8775,35.238],[26.92,35.2425],[27.0595,35.3155],[27.1065,35.2975],[27.2085,35.3115],[27.3155,35.3985],[27.3615,35.4635],[27.3655,35.513],[27.303,35.636],[27.3425,35.711],[27.3645,35.8205],[27.366,35.902],[27.341,35.961],[27.5495,36.1115],[27.631,36.0355],[27.6005,35.967],[27.6,35.9195],[27.633,35.8425],[27.7055,35.782],[27.7885,35.777],[27.9175,35.8305],[27.999,35.9055],[28.034,35.96],[28.106,35.9525],[28.201,36.01],[28.227,36.113],[28.289,36.205],[28.3705,36.363],[28.355,36.485],[28.2825,36.55],[28.2095,36.5615],[28.002,36.4695],[27.9605,36.4705],[27.931,36.5375],[27.8955,36.6975],[27.814,36.7085],[27.775,36.6935],[27.6415,36.5745],[27.462,36.543],[27.3515,36.586],[27.298,36.6335],[27.247,36.726],[27.351,36.8075],[27.3935,36.905],[27.246,36.9425],[27.1875,36.981],[27.1435,37.065],[27.1595,37.2425],[27.1535,37.312],[27.109,37.4575],[27.054,37.564],[26.9585,37.649],[27.0085,37.6965],[27.0865,37.6995],[27.165,37.724],[27.1605,37.7905],[27.101,37.846],[27.054,37.914],[26.9185,37.965],[26.363,38.0955],[26.2215,38.1675],[26.1945,38.2415],[26.213,38.3835],[26.243,38.446],[26.3155,38.453],[26.3125,38.537],[26.216,38.6515],[26.2225,38.688],[26.2665,38.736],[26.324,38.756],[26.451,38.7725],[26.6185,38.809],[26.6465,38.9095],[26.6995,38.98],[26.7045,39.032],[26.674,39.122],[26.432,39.434],[26.143,39.4055],[25.9815,39.396],[25.9275,39.48],[25.928,39.7145],[25.8925,39.8415],[25.8915,39.8905],[25.732,39.9575],[25.6985,39.992],[25.6225,40.129],[25.643,40.199],[25.6935,40.2335],[26.05,40.3715],[25.955,40.7295],[26.083,40.73],[26.125,40.7425],[26.158,40.809],[26.248,40.8815],[26.302,40.9025],[26.328,40.977],[26.3665,41.018],[26.3105,41.0805],[26.332,41.097],[26.3075,41.172],[26.323,41.2535],[26.4075,41.254],[26.4605,41.282],[26.498,41.3285],[26.5865,41.3225],[26.6355,41.3835],[26.591,41.5285],[26.595,41.61],[26.5295,41.6215],[26.471,41.6695],[26.358,41.711]]],[[[20.869,37.2625],[20.896,37.1905],[20.9855,37.146],[21.056,37.1515],[21.117,37.189],[21.1355,37.279],[21.0905,37.337],[21.0485,37.358],[20.9715,37.3625],[20.9225,37.345],[20.8805,37.3045],[20.869,37.2625]]],[[[23.8625,34.9445],[23.8845,34.876],[23.9215,34.8155],[23.976,34.7575],[24.07,34.7095],[24.1315,34.701],[24.214,34.7305],[24.2525,34.7805],[24.2445,34.8815],[24.2085,34.9345],[24.121,34.9695],[24.0355,35.0315],[23.962,35.0375],[23.883,34.994],[23.8625,34.9445]]],[[[29.3105,36.011],[29.4,35.9475],[29.556,35.916],[29.7295,35.923],[29.7005,36.086],[29.6135,36.149],[29.484,36.1855],[29.3105,36.011]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/5/5c/Flag_of_Greece.svg","name:en":"Greece","wikidata":"Q41","ISO3166-1:alpha2":"GR","ISO3166-1:alpha3":"GRC","ISO3166-1:numeric":"300"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[28.324,41.9815],[28.28,42.0865],[28.1675,42.2165],[28.1,42.254],[28.073,42.3175],[28.1665,42.6625],[28.1765,42.7165],[28.17,42.8105],[28.181,42.901],[28.1635,42.983],[28.288,43.1845],[28.428,43.162],[28.5205,43.1645],[28.6465,43.21],[28.763,43.314],[28.8315,43.4005],[28.8775,43.486],[28.8875,43.5395],[28.8545,43.6335],[28.8555,43.7385],[28.579,43.7385],[28.4465,43.7335],[28.3485,43.752],[28.236,43.7585],[27.9945,43.843],[27.944,43.9845],[27.917,44.0085],[27.843,43.966],[27.71,43.9595],[27.6735,44.03],[27.612,44.012],[27.469,44.0225],[27.3995,44.012],[27.356,44.0585],[27.2915,44.075],[27.229,44.1155],[27.135,44.1405],[27.042,44.1445],[26.9015,44.1325],[26.774,44.0805],[26.601,44.0525],[26.5535,44.058],[26.4345,44.0355],[26.3075,44.027],[26.198,43.9855],[26.106,43.968],[26.06,43.91],[25.9525,43.8595],[25.8525,43.759],[25.7855,43.7135],[25.6805,43.691],[25.5655,43.646],[25.5085,43.647],[25.391,43.6185],[25.3435,43.6305],[25.252,43.683],[25.1895,43.697],[25.115,43.6845],[25.007,43.7245],[24.8015,43.709],[24.746,43.6845],[24.623,43.742],[24.501,43.7625],[24.407,43.7365],[24.3495,43.698],[24.1745,43.682],[24.0865,43.702],[23.967,43.7445],[23.8725,43.753],[23.705,43.806],[23.6255,43.7915],[23.5115,43.838],[23.433,43.8495],[23.268,43.846],[23.1405,43.8055],[23.0465,43.7965],[22.881,43.832],[22.841,43.882],[22.8795,43.981],[23.0035,44.0105],[23.0485,44.0625],[23.001,44.095],[22.922,44.1],[22.7915,44.164],[22.7545,44.194],[22.6745,44.216],[22.6475,44.2045],[22.6105,44.1065],[22.6215,44.0635],[22.535,44.052],[22.5225,44.019],[22.4095,44.004],[22.409,43.9395],[22.357,43.8095],[22.3955,43.7595],[22.408,43.696],[22.492,43.639],[22.4875,43.5685],[22.5335,43.471],[22.5975,43.4355],[22.6605,43.426],[22.6795,43.3945],[22.7665,43.3775],[22.8275,43.329],[22.8485,43.2755],[22.8965,43.227],[23.0055,43.186],[22.983,43.111],[22.919,43.0775],[22.8985,43.036],[22.7855,42.9825],[22.78,42.932],[22.7445,42.886],[22.6815,42.872],[22.6195,42.896],[22.5355,42.882],[22.441,42.806],[22.487,42.749],[22.4675,42.641],[22.438,42.572],[22.5475,42.507],[22.559,42.485],[22.52,42.3975],[22.478,42.3935],[22.4555,42.3335],[22.3605,42.311],[22.434,42.258],[22.528,42.14],[22.6805,42.0635],[22.798,42.0455],[22.867,42.022],[22.874,41.9535],[22.9025,41.876],[22.928,41.862],[22.965,41.778],[23.0085,41.769],[23.0335,41.7225],[22.9515,41.642],[22.973,41.56],[22.958,41.4945],[22.9795,41.4465],[22.952,41.4175],[22.9655,41.3535],[22.9275,41.3385],[23.0765,41.32],[23.18,41.3185],[23.2205,41.333],[23.2325,41.376],[23.3225,41.4],[23.3405,41.3635],[23.401,41.4005],[23.5255,41.405],[23.6155,41.3755],[23.674,41.4105],[23.7675,41.396],[23.8005,41.4375],[23.89,41.45],[23.933,41.471],[23.966,41.4395],[24.0735,41.47],[24.077,41.5415],[24.198,41.539],[24.2605,41.573],[24.303,41.538],[24.4505,41.522],[24.5255,41.5685],[24.608,41.4275],[24.7305,41.416],[24.7455,41.3835],[24.804,41.3465],[24.8205,41.4015],[24.9005,41.4075],[24.977,41.376],[25.056,41.3655],[25.0825,41.338],[25.1815,41.3075],[25.239,41.2455],[25.3365,41.2415],[25.4755,41.2885],[25.532,41.2805],[25.575,41.3195],[25.6275,41.3055],[25.846,41.3375],[25.884,41.3045],[25.9745,41.318],[26.0115,41.3445],[26.132,41.355],[26.1925,41.447],[26.1555,41.4735],[26.185,41.52],[26.1475,41.5545],[26.154,41.6055],[26.094,41.627],[26.0605,41.6885],[26.086,41.717],[26.1665,41.7475],[26.234,41.739],[26.277,41.7135],[26.358,41.711],[26.3295,41.752],[26.369,41.821],[26.5385,41.8235],[26.584,41.902],[26.561,41.9255],[26.641,41.972],[26.755,41.96],[26.787,41.9895],[26.833,41.969],[26.871,41.991],[26.9575,41.997],[27.0145,42.045],[27.022,42.079],[27.107,42.086],[27.1915,42.0605],[27.2215,42.098],[27.3125,42.0865],[27.3765,42.046],[27.393,42.007],[27.447,41.967],[27.5745,41.9375],[27.714,41.977],[27.778,41.966],[27.8685,41.9995],[27.9075,41.975],[28.0405,41.9815],[28.324,41.9815]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9a/Flag_of_Bulgaria.svg","name:en":"Bulgaria","wikidata":"Q219","ISO3166-1:alpha2":"BG","ISO3166-1:alpha3":"BGR","ISO3166-1:numeric":"100"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[43.474,41.123],[43.568,41.145],[43.597,41.1295],[43.6845,41.134],[43.7505,41.1095],[43.8415,41.161],[43.9385,41.176],[43.9635,41.165],[44.076,41.196],[44.162,41.189],[44.186,41.2435],[44.271,41.2125],[44.3445,41.2265],[44.4765,41.182],[44.596,41.1935],[44.616,41.2405],[44.7915,41.2205],[44.807,41.2875],[44.9615,41.256],[45.014,41.2965],[45.093,41.339],[45.165,41.4065],[45.309,41.473],[45.3915,41.4275],[45.4545,41.455],[45.564,41.407],[45.601,41.3735],[45.6485,41.379],[45.7405,41.344],[45.7005,41.298],[45.7415,41.2585],[45.817,41.222],[45.887,41.211],[45.953,41.178],[46.1895,41.192],[46.2915,41.174],[46.369,41.1195],[46.458,41.098],[46.4925,41.0555],[46.55,41.1125],[46.631,41.098],[46.66,41.131],[46.6675,41.219],[46.7,41.2415],[46.697,41.3195],[46.6165,41.3905],[46.5225,41.4115],[46.331,41.5015],[46.2975,41.572],[46.1955,41.63],[46.2075,41.6535],[46.1815,41.7345],[46.216,41.7635],[46.3045,41.7755],[46.3985,41.8445],[46.422,41.908],[46.3995,41.94],[46.3205,41.9295],[46.246,41.979],[46.237,42.016],[46.1615,41.9905],[46.0385,42.02],[45.9875,42.0455],[45.9295,42.032],[45.9215,42.081],[45.8555,42.1135],[45.786,42.102],[45.748,42.146],[45.6475,42.1865],[45.609,42.234],[45.652,42.292],[45.7535,42.3095],[45.7345,42.3785],[45.7745,42.4285],[45.7755,42.4885],[45.7215,42.4755],[45.6875,42.5025],[45.614,42.5055],[45.5715,42.548],[45.4935,42.535],[45.4185,42.5515],[45.3545,42.522],[45.2835,42.606],[45.252,42.62],[45.1585,42.7075],[45.086,42.7115],[45.053,42.6925],[44.98,42.745],[44.8875,42.747],[44.804,42.6145],[44.7665,42.643],[44.753,42.714],[44.68,42.756],[44.5,42.734],[44.394,42.7065],[44.3195,42.723],[44.2495,42.681],[44.225,42.6305],[44.162,42.6065],[44.1155,42.6175],[44.0105,42.5915],[43.9625,42.5475],[43.8365,42.5985],[43.7705,42.589],[43.715,42.6365],[43.759,42.655],[43.804,42.715],[43.779,42.758],[43.6775,42.802],[43.609,42.8135],[43.561,42.8675],[43.185,42.9385],[43.173,42.963],[43.051,43.019],[42.99,43.119],[42.853,43.179],[42.7765,43.189],[42.698,43.172],[42.6665,43.136],[42.617,43.1635],[42.5435,43.1765],[42.4475,43.22],[42.442,43.251],[42.358,43.247],[42.3365,43.2195],[42.253,43.2125],[42.1995,43.228],[42.038,43.188],[41.867,43.244],[41.804,43.202],[41.7455,43.237],[41.6845,43.217],[41.6215,43.222],[41.5435,43.2705],[41.413,43.3245],[41.363,43.3685],[41.288,43.337],[41.221,43.3805],[41.0395,43.3995],[41.0045,43.432],[40.95,43.4195],[40.8935,43.457],[40.662,43.563],[40.5665,43.519],[40.478,43.549],[40.2995,43.57],[40.2615,43.5855],[40.0905,43.5555],[40.0085,43.3855],[39.8845,43.2245],[40.0135,43.171],[40.058,43.08],[40.1675,43.012],[40.297,42.995],[40.4435,42.9295],[40.64,42.89],[40.7395,42.8925],[40.8015,42.8365],[40.89,42.777],[40.934,42.6885],[41.0435,42.62],[41.1125,42.6045],[41.222,42.601],[41.2665,42.4955],[41.2945,42.3545],[41.3815,42.2155],[41.381,42.142],[41.4145,42.0595],[41.4805,41.9695],[41.5075,41.893],[41.487,41.824],[41.4375,41.7945],[41.3435,41.701],[41.2995,41.612],[41.6355,41.4865],[41.747,41.4715],[41.824,41.4315],[41.8815,41.4605],[41.9555,41.5235],[42.043,41.494],[42.085,41.51],[42.203,41.492],[42.2745,41.494],[42.439,41.4415],[42.5195,41.4365],[42.513,41.472],[42.573,41.51],[42.601,41.585],[42.684,41.6],[42.7745,41.5785],[42.8365,41.585],[42.8015,41.497],[42.8995,41.479],[42.967,41.4515],[43.0215,41.3785],[43.109,41.3495],[43.132,41.321],[43.2125,41.2905],[43.1925,41.253],[43.247,41.177],[43.3675,41.2035],[43.4485,41.1765],[43.474,41.123]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/0f/Flag_of_Georgia.svg","name:en":"Georgia","wikidata":"Q230","ISO3166-1:alpha2":"GE","ISO3166-1:alpha3":"GEO","ISO3166-1:numeric":"268"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[50.9195,26.2145],[50.923,26.271],[50.872,26.391],[50.8075,26.4715],[50.8055,26.527],[50.773,26.5975],[50.719,26.649],[50.655,26.6785],[50.5955,26.687],[50.5565,26.621],[50.4885,26.5845],[50.3875,26.53],[50.3765,26.4075],[50.3415,26.3735],[50.3165,26.252],[50.311,26.171],[50.27,26.0795],[50.304,25.879],[50.366,25.819],[50.4165,25.6985],[50.529,25.594],[50.5675,25.576],[50.58,25.586],[50.7345,25.5725],[50.7695,25.547],[50.7985,25.6225],[50.8395,25.6385],[50.868,25.7495],[50.816,25.895],[50.85,26.011],[50.9075,26.077],[50.9195,26.2145]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/2c/Flag_of_Bahrain.svg","name:en":"Bahrain","wikidata":"Q398","ISO3166-1:alpha2":"BH","ISO3166-1:alpha3":"BHR","ISO3166-1:numeric":"048"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[44.7635,39.7145],[44.888,39.7485],[44.9425,39.7265],[45.007,39.7505],[45.061,39.7945],[45.1345,39.7435],[45.187,39.677],[45.172,39.593],[45.243,39.6115],[45.342,39.542],[45.492,39.5115],[45.5905,39.57],[45.6235,39.5635],[45.6945,39.6035],[45.799,39.5715],[45.838,39.4685],[45.804,39.428],[45.7925,39.369],[45.8615,39.3565],[45.9985,39.2915],[45.9895,39.2005],[46.031,39.0925],[46.07,39.078],[46.1015,39.016],[46.1095,38.954],[46.1495,38.8895],[46.1405,38.8445],[46.187,38.843],[46.2825,38.9005],[46.363,38.9165],[46.425,38.8855],[46.458,38.897],[46.534,38.867],[46.5125,38.936],[46.546,39.0035],[46.531,39.0945],[46.44,39.1705],[46.462,39.1995],[46.544,39.1755],[46.5895,39.2355],[46.547,39.26],[46.494,39.336],[46.448,39.3395],[46.39,39.388],[46.3855,39.433],[46.4585,39.4495],[46.5055,39.483],[46.51,39.525],[46.5735,39.541],[46.5665,39.572],[46.489,39.587],[46.434,39.569],[46.4125,39.631],[46.3345,39.636],[46.2495,39.601],[46.1715,39.615],[46.155,39.651],[46.08,39.685],[45.969,39.792],[45.941,39.7875],[45.826,39.826],[45.7805,39.947],[45.701,39.968],[45.611,39.974],[45.6215,40.021],[45.796,40.0255],[45.834,39.99],[45.8805,40.021],[45.912,40.0755],[45.904,40.104],[45.955,40.135],[45.9785,40.1905],[45.9595,40.2755],[45.9305,40.297],[45.7855,40.329],[45.697,40.367],[45.652,40.367],[45.5895,40.4305],[45.512,40.4555],[45.4385,40.52],[45.4595,40.5815],[45.388,40.6185],[45.3635,40.655],[45.43,40.7465],[45.5455,40.7745],[45.608,40.8505],[45.602,40.8825],[45.4765,40.93],[45.454,40.969],[45.3685,41.008],[45.251,41.0135],[45.215,41.0385],[45.0755,41.069],[45.099,41.12],[45.15,41.1135],[45.202,41.138],[45.127,41.1995],[45.0515,41.193],[45.052,41.2395],[45.014,41.2965],[44.9615,41.256],[44.807,41.2875],[44.7915,41.2205],[44.616,41.2405],[44.596,41.1935],[44.4765,41.182],[44.3445,41.2265],[44.271,41.2125],[44.186,41.2435],[44.162,41.189],[44.076,41.196],[43.9635,41.165],[43.9385,41.176],[43.8415,41.161],[43.7505,41.1095],[43.6845,41.134],[43.597,41.1295],[43.568,41.145],[43.474,41.123],[43.447,41.099],[43.4685,41.0305],[43.5975,40.9835],[43.6715,40.9365],[43.6785,40.8445],[43.707,40.82],[43.7485,40.731],[43.6865,40.593],[43.611,40.514],[43.558,40.4945],[43.56,40.459],[43.6055,40.438],[43.62,40.398],[43.591,40.346],[43.6765,40.2605],[43.714,40.1615],[43.6485,40.132],[43.6785,40.096],[43.761,40.084],[43.8965,40.0215],[43.994,40.032],[44.1705,40.0275],[44.2745,40.0495],[44.351,40.0275],[44.4805,39.967],[44.554,39.9005],[44.652,39.7955],[44.711,39.77],[44.7635,39.7145]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/2f/Flag_of_Armenia.svg","name:en":"Armenia","wikidata":"Q399","ISO3166-1:alpha2":"AM","ISO3166-1:alpha3":"ARM","ISO3166-1:numeric":"051"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[3.08,51.551],[2.991,51.5215],[2.917,51.4755],[2.737,51.4045],[2.6145,51.3455],[2.389,51.2685],[2.546,51.0885],[2.574,51.0035],[2.633,50.946],[2.604,50.9165],[2.635,50.813],[2.718,50.8135],[2.7895,50.729],[2.899,50.694],[2.9385,50.745],[3.019,50.7735],[3.1485,50.79],[3.245,50.713],[3.241,50.669],[3.2885,50.526],[3.3905,50.498],[3.6075,50.497],[3.663,50.456],[3.6655,50.347],[3.838,50.3545],[3.9005,50.327],[3.9675,50.35],[4.036,50.3435],[4.1225,50.298],[4.201,50.275],[4.1555,50.163],[4.197,50.135],[4.231,50.0735],[4.136,50.021],[4.1965,49.9555],[4.31,49.9695],[4.4455,49.937],[4.51,49.947],[4.5975,49.9865],[4.6845,49.997],[4.704,50.0965],[4.824,50.161],[4.8755,50.154],[4.8675,50.0965],[4.827,50.05],[4.791,49.958],[4.849,49.948],[4.89,49.909],[4.851,49.8655],[4.856,49.792],[5.0085,49.782],[5.095,49.762],[5.125,49.727],[5.206,49.696],[5.2685,49.6965],[5.3535,49.6305],[5.425,49.5985],[5.449,49.517],[5.482,49.506],[5.5935,49.522],[5.6645,49.553],[5.7005,49.54],[5.8185,49.5465],[5.9095,49.6645],[5.887,49.7095],[5.792,49.787],[5.755,49.7915],[5.736,49.897],[5.775,49.961],[5.832,49.9765],[5.819,50.013],[5.901,50.116],[5.9615,50.1315],[5.9645,50.1715],[6.025,50.183],[6.1195,50.1635],[6.1375,50.13],[6.19,50.1875],[6.1765,50.236],[6.37,50.3125],[6.4005,50.3435],[6.343,50.3805],[6.3775,50.4415],[6.309,50.5015],[6.23,50.497],[6.197,50.5305],[6.235,50.565],[6.2665,50.642],[6.1915,50.64],[6.1145,50.7225],[6.033,50.727],[6.021,50.7545],[5.8865,50.77],[5.8075,50.756],[5.7765,50.782],[5.695,50.755],[5.694,50.8115],[5.654,50.82],[5.6515,50.875],[5.7145,50.9085],[5.756,50.9575],[5.758,51.0335],[5.8225,51.0925],[5.847,51.1415],[5.767,51.1835],[5.658,51.1845],[5.5605,51.2225],[5.558,51.2625],[5.4875,51.2995],[5.4175,51.2625],[5.226,51.2685],[5.242,51.305],[5.1315,51.347],[5.071,51.3935],[5.1045,51.4315],[5.079,51.4715],[4.9285,51.396],[4.83,51.421],[4.8405,51.4785],[4.774,51.505],[4.6665,51.4445],[4.5355,51.423],[4.538,51.4825],[4.4425,51.4685],[4.3915,51.408],[4.242,51.354],[4.1665,51.293],[4.064,51.2475],[4.0115,51.244],[3.8865,51.2],[3.7915,51.214],[3.7955,51.256],[3.591,51.3045],[3.5155,51.287],[3.5275,51.246],[3.4485,51.2415],[3.3945,51.2655],[3.3585,51.315],[3.3855,51.334],[3.295,51.449],[3.08,51.551]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/65/Flag_of_Belgium.svg","name:en":"Belgium","wikidata":"Q31","ISO3166-1:alpha2":"BE","ISO3166-1:alpha3":"BEL","ISO3166-1:numeric":"056"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[9.5505,47.537],[9.7255,47.533],[9.7665,47.589],[9.816,47.5475],[9.959,47.5345],[10.0375,47.489],[10.1055,47.4285],[10.1195,47.3755],[10.182,47.3925],[10.237,47.3735],[10.174,47.27],[10.3305,47.305],[10.4385,47.4135],[10.476,47.433],[10.4315,47.504],[10.4545,47.556],[10.5735,47.534],[10.598,47.5695],[10.751,47.5375],[10.7775,47.514],[10.8905,47.5375],[10.9095,47.4855],[11.006,47.394],[11.1155,47.3955],[11.2055,47.434],[11.291,47.427],[11.442,47.516],[11.5725,47.5145],[11.605,47.5795],[11.781,47.591],[12.013,47.623],[12.14,47.6055],[12.208,47.614],[12.1675,47.6825],[12.183,47.7005],[12.3635,47.684],[12.429,47.6965],[12.5125,47.6255],[12.575,47.6325],[12.6035,47.672],[12.732,47.6795],[12.8075,47.6105],[12.7945,47.557],[12.9085,47.497],[13.001,47.464],[13.0475,47.492],[13.0435,47.5835],[13.0955,47.6285],[13.0785,47.688],[13.046,47.7125],[12.933,47.7095],[12.9395,47.7785],[13.0015,47.8545],[12.8575,48.007],[12.7705,48.066],[12.765,48.129],[12.848,48.168],[12.873,48.2025],[12.9595,48.2105],[13.0215,48.258],[13.1955,48.2955],[13.2615,48.295],[13.4135,48.377],[13.445,48.5285],[13.5085,48.5905],[13.593,48.5695],[13.727,48.513],[13.8075,48.5845],[13.8265,48.6285],[13.801,48.7165],[13.8395,48.7715],[13.769,48.8315],[13.737,48.8795],[13.6715,48.88],[13.58,48.9705],[13.507,48.969],[13.4025,48.987],[13.392,49.0545],[13.289,49.1185],[13.2365,49.1135],[13.0805,49.2475],[13.034,49.264],[13.029,49.3045],[12.95,49.343],[12.803,49.3415],[12.7575,49.395],[12.656,49.435],[12.644,49.5215],[12.574,49.56],[12.528,49.618],[12.5215,49.6865],[12.44,49.706],[12.403,49.762],[12.467,49.7855],[12.5475,49.9205],[12.4785,49.9355],[12.4605,49.995],[12.3675,50.0195],[12.1995,50.1105],[12.201,50.1885],[12.1545,50.2285],[12.1305,50.319],[12.1845,50.322],[12.2015,50.273],[12.294,50.221],[12.3325,50.234],[12.3985,50.3215],[12.4925,50.356],[12.5125,50.3965],[12.6275,50.416],[12.7075,50.408],[12.8215,50.459],[12.935,50.4125],[13.018,50.445],[13.056,50.501],[13.208,50.522],[13.2485,50.592],[13.4125,50.6195],[13.4625,50.602],[13.5445,50.677],[13.6675,50.7315],[13.8575,50.728],[13.907,50.7925],[13.992,50.8195],[14.035,50.805],[14.305,50.884],[14.3885,50.9005],[14.397,50.9365],[14.3105,50.955],[14.2625,50.9855],[14.292,51.0465],[14.454,51.036],[14.599,50.987],[14.5605,50.925],[14.65,50.9315],[14.619,50.858],[14.7995,50.8225],[14.8235,50.8705],[14.8965,50.9405],[14.9795,51.0775],[14.993,51.1625],[15.038,51.244],[15.033,51.2945],[14.9775,51.3415],[14.9465,51.472],[14.737,51.5255],[14.712,51.5615],[14.766,51.6105],[14.7475,51.6755],[14.6565,51.7405],[14.644,51.7965],[14.5905,51.838],[14.693,51.901],[14.721,51.9525],[14.746,52.0815],[14.683,52.1125],[14.716,52.233],[14.6895,52.257],[14.594,52.274],[14.534,52.396],[14.635,52.4975],[14.604,52.529],[14.638,52.5745],[14.596,52.6105],[14.468,52.6595],[14.3505,52.7515],[14.21,52.818],[14.1415,52.824],[14.158,52.8765],[14.1435,52.9615],[14.2355,52.993],[14.338,53.0465],[14.3875,53.1425],[14.3775,53.202],[14.4495,53.2595],[14.3735,53.409],[14.3715,53.4565],[14.3025,53.5535],[14.317,53.618],[14.284,53.6345],[14.267,53.6985],[14.2835,53.7725],[14.2125,53.8675],[14.242,53.9875],[14.168,54.239],[14.0695,54.2775],[14.0785,54.441],[14.0225,54.6075],[13.9975,54.649],[13.9085,54.7195],[13.65,54.839],[13.5455,54.8735],[13.427,54.885],[13.2025,54.867],[13.111,54.845],[12.9715,54.786],[12.749,54.744],[12.322,54.578],[12.2585,54.451],[12.165,54.3855],[11.9515,54.3335],[11.6445,54.331],[11.5385,54.4075],[11.311,54.5295],[11.1415,54.577],[10.9795,54.556],[10.82,54.5475],[10.7545,54.5145],[10.592,54.5205],[10.339,54.593],[10.1695,54.738],[10.0515,54.766],[9.8945,54.842],[9.74,54.8235],[9.6045,54.8545],[9.383,54.839],[9.342,54.8035],[9.25,54.8095],[9.2405,54.85],[9.1555,54.8705],[9.0475,54.872],[8.948,54.9025],[8.6865,54.909],[8.5555,54.921],[8.557,54.993],[8.3955,55.0695],[8.29,55.065],[8.0445,55.099],[7.985,55.0045],[7.9455,54.9115],[7.931,54.7535],[7.946,54.651],[7.9745,54.587],[8.151,54.346],[7.9985,54.387],[7.862,54.394],[7.721,54.376],[7.576,54.303],[7.5355,54.252],[7.5245,54.1675],[7.5505,54.1135],[7.698,53.984],[7.533,53.9605],[7.3665,53.949],[7.29,53.93],[7.1125,53.9195],[6.96,53.885],[6.727,53.8635],[6.592,53.8165],[6.5005,53.8025],[6.3955,53.7615],[6.346,53.7245],[6.4125,53.6045],[6.5515,53.5825],[6.699,53.4935],[6.8825,53.4475],[6.9025,53.3535],[7.0525,53.3065],[7.1915,53.315],[7.2175,53.198],[7.179,53.1385],[7.203,53.1135],[7.213,53.011],[7.1815,52.9415],[7.0715,52.8105],[7.055,52.6445],[6.94,52.638],[6.897,52.6515],[6.742,52.6455],[6.715,52.626],[6.7265,52.563],[6.6975,52.4865],[6.7745,52.4595],[6.8545,52.4595],[6.9415,52.4355],[6.994,52.4655],[7.072,52.352],[7.0265,52.292],[7.0615,52.2345],[6.9815,52.2215],[6.8555,52.1205],[6.7605,52.119],[6.751,52.085],[6.688,52.04],[6.8265,51.9935],[6.8285,51.964],[6.722,51.896],[6.675,51.916],[6.4645,51.855],[6.407,51.829],[6.2795,51.874],[6.1665,51.8405],[6.0555,51.8525],[5.945,51.8235],[6.029,51.726],[6.0365,51.673],[6.1095,51.647],[6.0915,51.606],[6.212,51.5135],[6.2235,51.475],[6.2055,51.3995],[6.2265,51.3605],[6.1695,51.3295],[6.0725,51.2425],[6.0915,51.1345],[5.938,51.035],[5.955,50.9885],[6.0175,50.9835],[6.018,50.9345],[6.0925,50.9175],[6.074,50.8465],[6.019,50.8465],[6.021,50.7545],[6.033,50.727],[6.1145,50.7225],[6.1915,50.64],[6.2665,50.642],[6.235,50.565],[6.197,50.5305],[6.23,50.497],[6.309,50.5015],[6.3775,50.4415],[6.343,50.3805],[6.4005,50.3435],[6.37,50.3125],[6.1765,50.236],[6.19,50.1875],[6.1375,50.13],[6.112,50.0595],[6.1985,49.9485],[6.2615,49.881],[6.364,49.8505],[6.397,49.8225],[6.5165,49.805],[6.506,49.7165],[6.431,49.67],[6.4215,49.622],[6.3745,49.5915],[6.356,49.5295],[6.3675,49.4695],[6.428,49.477],[6.552,49.425],[6.588,49.3835],[6.589,49.322],[6.6615,49.282],[6.7115,49.1885],[6.834,49.1515],[6.9185,49.2225],[7.035,49.1915],[7.067,49.1145],[7.245,49.13],[7.2985,49.1175],[7.3655,49.172],[7.44,49.1835],[7.5285,49.097],[7.57,49.0795],[7.868,49.0335],[7.9315,49.058],[8.07,48.9965],[8.216,48.9755],[8.129,48.8795],[8.106,48.8245],[7.894,48.6655],[7.8415,48.6435],[7.803,48.5905],[7.8045,48.5125],[7.7705,48.4915],[7.737,48.4065],[7.7455,48.3325],[7.6945,48.3025],[7.668,48.2245],[7.577,48.118],[7.5705,48.0315],[7.622,47.9725],[7.5595,47.8825],[7.5315,47.7865],[7.548,47.74],[7.5195,47.6675],[7.589,47.59],[7.6975,47.533],[7.7955,47.5575],[7.8225,47.588],[7.892,47.5875],[7.9165,47.548],[8.099,47.562],[8.1845,47.6045],[8.288,47.6105],[8.325,47.5725],[8.4315,47.5665],[8.467,47.6415],[8.4055,47.674],[8.473,47.764],[8.6115,47.802],[8.6825,47.7835],[8.7235,47.7455],[8.728,47.6925],[8.7925,47.675],[8.824,47.711],[8.899,47.648],[9.0265,47.6865],[9.256,47.659],[9.445,47.595],[9.5145,47.537],[9.5505,47.537]]],[[[7.409,54.1365],[7.409,54.0075],[7.55,54.0275],[7.4485,54.1385],[7.409,54.1365]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/ba/Flag_of_Germany.svg","name:en":"Germany","wikidata":"Q183","ISO3166-1:alpha2":"DE","ISO3166-1:alpha3":"DEU","ISO3166-1:numeric":"276"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[9.5305,47.2705],[9.585,47.2055],[9.573,47.1755],[9.626,47.146],[9.6345,47.101],[9.607,47.061],[9.68,47.062],[9.8735,47.0065],[9.88,46.935],[10.0265,46.896],[10.0595,46.861],[10.123,46.8485],[10.232,46.8665],[10.2415,46.9315],[10.3095,46.95],[10.3555,46.9925],[10.488,46.9385],[10.4695,46.855],[10.5705,46.8425],[10.6625,46.8745],[10.763,46.8205],[10.814,46.775],[11.021,46.7665],[11.072,46.856],[11.187,46.9695],[11.3205,46.9925],[11.3825,46.9705],[11.4425,46.9765],[11.479,47.011],[11.538,46.984],[11.627,47.0135],[11.7645,46.9725],[11.9315,47.037],[12.02,47.047],[12.186,47.092],[12.227,47.082],[12.2045,47.027],[12.126,47.013],[12.1385,46.9565],[12.211,46.8775],[12.2665,46.887],[12.306,46.8335],[12.309,46.785],[12.3575,46.775],[12.384,46.7165],[12.5485,46.659],[12.6905,46.657],[12.9335,46.6095],[13.0905,46.601],[13.193,46.5725],[13.322,46.553],[13.5045,46.5665],[13.714,46.523],[13.7935,46.5055],[13.912,46.521],[14.0195,46.4815],[14.1215,46.4765],[14.1915,46.443],[14.308,46.4305],[14.4295,46.447],[14.447,46.4215],[14.54,46.4115],[14.675,46.4505],[14.759,46.5045],[14.8185,46.5095],[14.844,46.577],[14.8865,46.613],[14.9795,46.6015],[15.016,46.641],[15.1105,46.6595],[15.236,46.6395],[15.414,46.6555],[15.464,46.6145],[15.5435,46.632],[15.5465,46.667],[15.65,46.706],[15.7215,46.696],[15.8625,46.722],[15.95,46.688],[16.0425,46.686],[15.985,46.753],[15.986,46.8275],[16.114,46.869],[16.2465,46.9495],[16.3025,46.9985],[16.4525,47.003],[16.5205,47.0615],[16.4645,47.099],[16.517,47.1495],[16.428,47.185],[16.442,47.2485],[16.4895,47.2805],[16.4455,47.4065],[16.588,47.423],[16.662,47.4555],[16.6525,47.5005],[16.7055,47.523],[16.653,47.622],[16.59,47.6175],[16.5145,47.646],[16.477,47.6905],[16.552,47.7225],[16.548,47.7515],[16.6375,47.756],[16.721,47.7355],[16.749,47.6815],[16.913,47.688],[17.093,47.7085],[17.0705,47.728],[17.072,47.808],[17.01,47.8585],[17.078,47.8775],[17.1125,47.9275],[17.0945,47.971],[17.161,48.0065],[17.0675,48.0315],[17.0775,48.106],[16.976,48.172],[16.895,48.313],[16.843,48.3515],[16.85,48.4495],[16.954,48.5435],[16.94,48.6165],[16.9055,48.714],[16.776,48.712],[16.6745,48.7715],[16.462,48.8045],[16.4095,48.7445],[16.36,48.728],[16.2685,48.7415],[16.093,48.747],[15.9945,48.7795],[15.8275,48.871],[15.7535,48.852],[15.6865,48.857],[15.6195,48.8955],[15.5135,48.914],[15.4665,48.9515],[15.367,48.982],[15.291,48.9845],[15.269,48.9585],[15.1895,48.943],[15.1585,48.99],[15.0645,48.9995],[15.0215,49.0205],[14.976,48.971],[14.993,48.904],[14.973,48.8745],[14.956,48.758],[14.8255,48.784],[14.7945,48.73],[14.741,48.7015],[14.706,48.591],[14.6635,48.582],[14.607,48.6285],[14.391,48.5935],[14.342,48.5545],[14.1955,48.5925],[14.054,48.604],[14.053,48.6525],[14.0035,48.7085],[13.9555,48.715],[13.8395,48.7715],[13.801,48.7165],[13.8265,48.6285],[13.8075,48.5845],[13.727,48.513],[13.593,48.5695],[13.5085,48.5905],[13.445,48.5285],[13.4135,48.377],[13.2615,48.295],[13.1955,48.2955],[13.0215,48.258],[12.9595,48.2105],[12.873,48.2025],[12.848,48.168],[12.765,48.129],[12.7705,48.066],[12.8575,48.007],[13.0015,47.8545],[12.9395,47.7785],[12.933,47.7095],[13.046,47.7125],[13.0785,47.688],[13.0955,47.6285],[13.0435,47.5835],[13.0475,47.492],[13.001,47.464],[12.9085,47.497],[12.7945,47.557],[12.8075,47.6105],[12.732,47.6795],[12.6035,47.672],[12.575,47.6325],[12.5125,47.6255],[12.429,47.6965],[12.3635,47.684],[12.183,47.7005],[12.1675,47.6825],[12.208,47.614],[12.14,47.6055],[12.013,47.623],[11.781,47.591],[11.605,47.5795],[11.5725,47.5145],[11.442,47.516],[11.291,47.427],[11.2055,47.434],[11.1155,47.3955],[11.006,47.394],[10.9095,47.4855],[10.8905,47.5375],[10.7775,47.514],[10.751,47.5375],[10.598,47.5695],[10.5735,47.534],[10.4545,47.556],[10.4315,47.504],[10.476,47.433],[10.4385,47.4135],[10.3305,47.305],[10.174,47.27],[10.237,47.3735],[10.182,47.3925],[10.1195,47.3755],[10.1055,47.4285],[10.0375,47.489],[9.959,47.5345],[9.816,47.5475],[9.7665,47.589],[9.7255,47.533],[9.5505,47.537],[9.593,47.466],[9.6545,47.4545],[9.652,47.4085],[9.5835,47.3125],[9.5305,47.2705]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/41/Flag_of_Austria.svg","name:en":"Austria","wikidata":"Q40","ISO3166-1:alpha2":"AT","ISO3166-1:alpha3":"AUT","ISO3166-1:numeric":"040"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[14.8235,50.8705],[14.7995,50.8225],[14.619,50.858],[14.65,50.9315],[14.5605,50.925],[14.599,50.987],[14.454,51.036],[14.292,51.0465],[14.2625,50.9855],[14.3105,50.955],[14.397,50.9365],[14.3885,50.9005],[14.305,50.884],[14.035,50.805],[13.992,50.8195],[13.907,50.7925],[13.8575,50.728],[13.6675,50.7315],[13.5445,50.677],[13.4625,50.602],[13.4125,50.6195],[13.2485,50.592],[13.208,50.522],[13.056,50.501],[13.018,50.445],[12.935,50.4125],[12.8215,50.459],[12.7075,50.408],[12.6275,50.416],[12.5125,50.3965],[12.4925,50.356],[12.3985,50.3215],[12.3325,50.234],[12.294,50.221],[12.2015,50.273],[12.1845,50.322],[12.1305,50.319],[12.1545,50.2285],[12.201,50.1885],[12.1995,50.1105],[12.3675,50.0195],[12.4605,49.995],[12.4785,49.9355],[12.5475,49.9205],[12.467,49.7855],[12.403,49.762],[12.44,49.706],[12.5215,49.6865],[12.528,49.618],[12.574,49.56],[12.644,49.5215],[12.656,49.435],[12.7575,49.395],[12.803,49.3415],[12.95,49.343],[13.029,49.3045],[13.034,49.264],[13.0805,49.2475],[13.2365,49.1135],[13.289,49.1185],[13.392,49.0545],[13.4025,48.987],[13.507,48.969],[13.58,48.9705],[13.6715,48.88],[13.737,48.8795],[13.769,48.8315],[13.8395,48.7715],[13.9555,48.715],[14.0035,48.7085],[14.053,48.6525],[14.054,48.604],[14.1955,48.5925],[14.342,48.5545],[14.391,48.5935],[14.607,48.6285],[14.6635,48.582],[14.706,48.591],[14.741,48.7015],[14.7945,48.73],[14.8255,48.784],[14.956,48.758],[14.973,48.8745],[14.993,48.904],[14.976,48.971],[15.0215,49.0205],[15.0645,48.9995],[15.1585,48.99],[15.1895,48.943],[15.269,48.9585],[15.291,48.9845],[15.367,48.982],[15.4665,48.9515],[15.5135,48.914],[15.6195,48.8955],[15.6865,48.857],[15.7535,48.852],[15.8275,48.871],[15.9945,48.7795],[16.093,48.747],[16.2685,48.7415],[16.36,48.728],[16.4095,48.7445],[16.462,48.8045],[16.6745,48.7715],[16.776,48.712],[16.9055,48.714],[16.94,48.6165],[17.043,48.7635],[17.089,48.786],[17.115,48.8335],[17.1925,48.8745],[17.242,48.8685],[17.3965,48.813],[17.477,48.8415],[17.52,48.813],[17.633,48.855],[17.704,48.861],[17.7815,48.9255],[17.8855,48.9275],[17.9245,49.02],[18.0245,49.021],[18.082,49.0465],[18.116,49.092],[18.1065,49.134],[18.184,49.287],[18.297,49.3045],[18.379,49.3305],[18.492,49.435],[18.548,49.468],[18.5455,49.5005],[18.7105,49.5025],[18.7545,49.4885],[18.851,49.517],[18.8045,49.679],[18.719,49.684],[18.636,49.715],[18.5695,49.8345],[18.604,49.857],[18.431,49.938],[18.278,49.9635],[18.2065,49.998],[18.117,49.994],[18.103,50.0225],[17.954,50.005],[17.8685,49.9725],[17.7775,50.02],[17.75,50.0775],[17.6765,50.103],[17.5925,50.16],[17.7585,50.2065],[17.689,50.302],[17.6105,50.266],[17.3425,50.281],[17.29,50.3175],[17.1105,50.405],[16.9835,50.42],[16.908,50.4495],[16.8605,50.411],[16.908,50.391],[16.9405,50.32],[17.02,50.2785],[16.999,50.216],[16.898,50.222],[16.81,50.1895],[16.7835,50.1455],[16.706,50.0965],[16.641,50.112],[16.5605,50.1645],[16.5485,50.23],[16.4895,50.264],[16.361,50.3795],[16.2675,50.3795],[16.199,50.442],[16.3605,50.501],[16.445,50.5795],[16.343,50.6615],[16.235,50.6715],[16.188,50.6275],[16.1035,50.6635],[16.029,50.604],[15.9885,50.685],[15.8635,50.68],[15.816,50.7555],[15.7055,50.7375],[15.579,50.779],[15.5245,50.777],[15.439,50.809],[15.392,50.776],[15.353,50.8505],[15.277,50.891],[15.292,50.9535],[15.2295,50.9965],[15.105,50.9915],[15.0165,51.022],[15.0175,50.967],[14.9895,50.9215],[15.002,50.869],[14.8235,50.8705]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/cb/Flag_of_the_Czech_Republic.svg","name:en":"Czechia","wikidata":"Q213","ISO3166-1:alpha2":"CZ","ISO3166-1:alpha3":"CZE","ISO3166-1:numeric":"203"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[26.44,59.9385],[26.1535,59.9],[26.0215,59.815],[25.5785,59.8265],[24.4815,59.7035],[23.9535,59.5765],[23.5215,59.4815],[23.1915,59.4835],[23.125,59.464],[22.7335,59.2915],[22.496,59.2885],[22.3085,59.245],[21.85,59.0565],[21.6515,58.9185],[21.6965,58.8315],[21.6065,58.6885],[21.514,58.6475],[21.453,58.5985],[21.4215,58.5365],[21.3825,58.3015],[21.4035,58.2565],[21.6135,57.895],[21.7165,57.7865],[21.843,57.763],[21.916,57.7495],[22.1435,57.779],[22.5835,57.9275],[22.7075,57.941],[22.999,57.702],[23.181,57.5865],[23.406,57.594],[23.5825,57.6695],[23.6485,57.783],[23.601,57.899],[24.2095,57.899],[24.261,57.917],[24.357,57.8745],[24.46,57.88],[24.4625,57.925],[24.585,57.962],[24.6285,57.942],[24.742,57.982],[24.8325,57.972],[25.0205,58.018],[25.106,58.078],[25.2165,58.074],[25.3035,58.0345],[25.467,58.005],[25.486,57.975],[25.7035,57.9035],[25.7725,57.9125],[25.8205,57.865],[26.0585,57.8365],[26.027,57.775],[26.136,57.751],[26.2055,57.715],[26.275,57.5975],[26.4015,57.572],[26.4695,57.5755],[26.5,57.5245],[26.6145,57.5295],[26.676,57.5665],[26.782,57.5725],[26.9455,57.603],[27.0315,57.6045],[27.1175,57.562],[27.2255,57.5545],[27.3515,57.518],[27.3305,57.5705],[27.405,57.6125],[27.3765,57.668],[27.4475,57.717],[27.5215,57.716],[27.5055,57.7665],[27.5415,57.823],[27.6155,57.839],[27.741,57.8275],[27.813,57.86],[27.6565,57.9555],[27.6215,58.005],[27.602,58.1175],[27.4915,58.2245],[27.487,58.3035],[27.553,58.366],[27.357,58.7875],[27.731,58.973],[27.745,59.027],[27.792,59.07],[27.8085,59.1295],[27.865,59.161],[27.9015,59.2385],[27.954,59.2705],[28.1295,59.291],[28.21,59.3705],[28.191,59.4005],[28.0425,59.4715],[27.857,59.582],[26.915,59.6315],[26.44,59.9385]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/8f/Flag_of_Estonia.svg","name:en":"Estonia","wikidata":"Q191","ISO3166-1:alpha2":"EE","ISO3166-1:alpha3":"EST","ISO3166-1:numeric":"233"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[24.1445,65.3955],[24.1545,65.2925],[24.084,65.08],[23.8685,64.733],[23.836,64.6655],[23.206,64.5045],[23.0625,64.4455],[23.002,64.388],[22.961,64.22],[22.5965,64.1375],[22.397,64.072],[22.213,63.952],[22.12,63.8475],[21.8845,63.701],[21.66,63.6725],[21.509,63.667],[21.376,63.633],[20.9385,63.5195],[20.6965,63.483],[20.401,63.332],[20.276,63.2435],[20.166,63.165],[20.4185,62.7245],[20.665,62.366],[20.8115,61.987],[20.903,61.646],[20.7715,61.127],[20.4375,60.902],[20.025,60.7275],[19.6355,60.6945],[19.22,60.6115],[19.1965,60.517],[19.161,60.375],[19.083,60.1915],[19.6585,59.7915],[19.9405,59.595],[19.9945,59.591],[20.2845,59.466],[20.384,59.4575],[20.761,59.5325],[21.4345,59.4785],[21.5335,59.4765],[22.3965,59.513],[22.6345,59.608],[22.8575,59.6355],[23.352,59.657],[24.206,59.7835],[24.4885,59.817],[24.7855,59.892],[24.93,59.9215],[25.1695,59.9435],[25.5825,59.928],[26.0175,59.977],[26.075,60.014],[26.2945,60.0465],[26.492,60.1535],[26.611,60.162],[26.7655,60.2005],[27.294,60.2005],[27.455,60.2235],[27.725,60.3915],[27.686,60.4335],[27.747,60.451],[27.7735,60.5335],[27.8735,60.6045],[28.1355,60.741],[28.5245,60.957],[28.658,60.951],[28.714,61.0445],[28.819,61.1215],[28.957,61.1515],[28.9855,61.1735],[29.2335,61.2685],[29.3345,61.355],[29.503,61.4615],[29.7405,61.5735],[29.8185,61.6555],[30.0385,61.765],[30.0705,61.8175],[30.1555,61.858],[30.305,61.964],[30.423,62.0225],[30.602,62.1415],[30.6565,62.2085],[30.7205,62.209],[31.1385,62.442],[31.222,62.4985],[31.3455,62.6405],[31.439,62.7855],[31.5865,62.9085],[31.463,63.0245],[31.2655,63.115],[31.24,63.218],[31.1485,63.2615],[30.979,63.308],[30.9345,63.3555],[30.85,63.3685],[30.7875,63.4055],[30.484,63.4665],[30.3845,63.5455],[30.244,63.6075],[29.972,63.757],[30.2605,63.822],[30.321,63.9095],[30.447,63.983],[30.528,64.049],[30.5535,64.132],[30.4665,64.2045],[30.4825,64.2625],[30.21,64.3505],[30.11,64.365],[30.045,64.402],[30.0585,64.451],[29.987,64.534],[29.9895,64.5875],[30.136,64.649],[30.0415,64.741],[30.043,64.793],[29.7395,64.79],[29.645,64.8665],[29.5995,64.995],[29.627,65.0605],[29.7325,65.0915],[29.897,65.105],[29.8195,65.1445],[29.8935,65.193],[29.764,65.229],[29.635,65.2315],[29.602,65.26],[29.7465,65.3475],[29.733,65.4725],[29.864,65.5605],[29.7225,65.637],[30.017,65.6965],[30.1385,65.6685],[30.068,65.895],[29.9975,65.979],[29.924,66.126],[29.7095,66.268],[29.5245,66.4905],[29.3505,66.644],[29.1185,66.8015],[29.061,66.8525],[29.033,66.9255],[29.0735,66.996],[29.5155,67.281],[29.527,67.311],[29.717,67.394],[29.9305,67.523],[30.0155,67.673],[29.6595,67.803],[29.327,68.0745],[28.646,68.1965],[28.434,68.5395],[28.707,68.7325],[28.8015,68.8695],[28.661,68.8865],[28.468,68.8855],[28.4955,68.93],[28.9295,69.052],[28.8055,69.111],[28.8315,69.2245],[29.2195,69.3975],[29.3365,69.4785],[29.1705,69.639],[29.134,69.6955],[28.404,69.8185],[28.3455,69.881],[28.1605,69.921],[27.9845,70.014],[27.9595,70.092],[27.5745,70.067],[27.5235,70.023],[27.437,70.0205],[27.3055,69.958],[27.0315,69.911],[26.986,69.935],[26.7325,69.9465],[26.676,69.9645],[26.4665,69.94],[26.3605,69.845],[26.136,69.7385],[26.007,69.723],[25.8925,69.6655],[25.976,69.61],[25.876,69.529],[25.793,69.421],[25.8465,69.394],[25.742,69.319],[25.694,69.1955],[25.742,69.145],[25.7205,69.109],[25.7775,69.0195],[25.627,68.8925],[25.4815,68.905],[25.2675,68.851],[25.157,68.8],[25.0765,68.622],[24.917,68.605],[24.6085,68.682],[24.3025,68.7175],[24.0755,68.78],[23.9835,68.827],[23.7755,68.819],[23.6735,68.7055],[23.4405,68.692],[23.1675,68.6285],[23.046,68.6895],[22.801,68.6875],[22.5355,68.7445],[22.3745,68.7165],[22.341,68.827],[22.192,68.919],[22.176,68.9565],[21.7235,69.2145],[21.627,69.2765],[21.279,69.312],[21.096,69.261],[20.9875,69.192],[21.1085,69.104],[21.0575,69.0365],[20.7175,69.12],[20.5485,69.06],[20.775,69.0325],[20.9135,68.9605],[20.844,68.9365],[20.997,68.8965],[21.234,68.814],[21.3195,68.7595],[21.3895,68.765],[21.43,68.6915],[21.565,68.6755],[21.7015,68.6305],[21.7015,68.5965],[21.89,68.5845],[22.018,68.496],[22.153,68.47],[22.351,68.4805],[22.466,68.4415],[22.804,68.393],[22.918,68.3335],[23.0705,68.2995],[23.153,68.231],[23.1415,68.1545],[23.2785,68.1575],[23.3965,68.044],[23.531,68.0065],[23.663,67.942],[23.641,67.915],[23.51,67.88],[23.493,67.664],[23.559,67.6195],[23.545,67.583],[23.408,67.5015],[23.4105,67.4675],[23.5365,67.46],[23.7635,67.426],[23.718,67.385],[23.775,67.3395],[23.731,67.2875],[23.5835,67.2695],[23.596,67.207],[23.557,67.166],[23.6535,67.104],[23.674,67.065],[23.8565,66.956],[23.864,66.922],[23.9945,66.8235],[23.978,66.784],[23.8795,66.762],[23.908,66.7215],[23.8685,66.657],[23.8605,66.5595],[23.65,66.454],[23.689,66.3875],[23.646,66.3005],[23.7335,66.206],[23.916,66.162],[23.9365,66.0795],[24.0375,66.009],[24.042,65.9635],[24.153,65.8625],[24.132,65.7715],[24.172,65.7255],[24.1775,65.6605],[24.132,65.5155],[24.1445,65.3955]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/bc/Flag_of_Finland.svg","name:en":"Finland","wikidata":"Q33","ISO3166-1:alpha2":"FI","ISO3166-1:alpha3":"FIN","ISO3166-1:numeric":"246"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[102.621,11.3895],[102.5795,11.296],[102.5755,11.24],[102.6245,10.653],[102.684,9.9175],[102.697,9.8545],[102.7305,9.7985],[102.939,9.549],[103.003,9.497],[103.118,9.4755],[103.7785,9.949],[103.86,10.0045],[103.935,10.154],[103.901,10.2615],[103.8265,10.291],[103.8005,10.3675],[103.838,10.402],[103.914,10.3905],[103.9265,10.4305],[103.9715,10.48],[104.011,10.4805],[104.0885,10.4205],[104.1105,10.3835],[104.1245,10.232],[104.2275,10.2715],[104.439,10.423],[104.5505,10.4555],[104.588,10.5275],[104.6945,10.537],[104.753,10.518],[104.869,10.522],[104.897,10.547],[104.957,10.638],[105.0985,10.721],[105.0655,10.7805],[105.0295,10.8925],[105.083,10.9565],[105.1075,10.9185],[105.1575,10.9225],[105.2385,10.893],[105.265,10.897],[105.344,10.8665],[105.4335,10.9725],[105.4955,10.9485],[105.5365,10.952],[105.6675,10.9875],[105.73,11.0255],[105.7795,11.0315],[105.807,10.9735],[105.8645,10.8995],[105.8485,10.864],[105.9,10.8445],[105.9725,10.8935],[106.0725,10.811],[106.1655,10.8115],[106.1865,10.842],[106.14,10.915],[106.154,10.983],[106.206,10.978],[106.188,11.0505],[106.154,11.102],[106.1215,11.0885],[106.023,11.1405],[106.014,11.1905],[105.9415,11.2055],[105.8755,11.2875],[105.885,11.361],[105.874,11.4055],[105.8855,11.5325],[105.8625,11.5655],[105.8095,11.5965],[105.8525,11.662],[105.884,11.677],[105.9535,11.6405],[106.016,11.7285],[106.024,11.7745],[106.069,11.776],[106.1155,11.743],[106.19,11.754],[106.2495,11.7285],[106.3125,11.674],[106.3685,11.697],[106.4405,11.669],[106.4535,11.6905],[106.418,11.77],[106.465,11.8725],[106.412,11.9735],[106.4555,11.989],[106.496,11.969],[106.724,11.9755],[106.7915,12.0815],[106.927,12.0635],[106.99,12.085],[107.054,12.1425],[107.1005,12.2065],[107.14,12.2335],[107.1555,12.278],[107.2305,12.296],[107.268,12.3245],[107.363,12.3195],[107.387,12.271],[107.434,12.246],[107.447,12.291],[107.544,12.351],[107.5435,12.3995],[107.58,12.4955],[107.5895,12.5595],[107.5695,12.642],[107.582,12.6795],[107.559,12.716],[107.562,12.7925],[107.492,12.8975],[107.4845,12.9445],[107.5045,12.976],[107.496,13.028],[107.548,13.17],[107.6275,13.3665],[107.617,13.5265],[107.5745,13.6205],[107.5705,13.6625],[107.536,13.7405],[107.4515,13.7945],[107.4555,13.98],[107.3865,13.9895],[107.3655,14.013],[107.367,14.0835],[107.3385,14.128],[107.3775,14.1795],[107.4095,14.2645],[107.391,14.3265],[107.4465,14.403],[107.488,14.406],[107.532,14.5465],[107.5225,14.588],[107.5595,14.623],[107.5565,14.686],[107.469,14.6215],[107.4375,14.524],[107.329,14.5915],[107.2875,14.5795],[107.2535,14.5225],[107.2085,14.4885],[107.165,14.416],[107.0835,14.395],[107.0775,14.4265],[107.0155,14.397],[106.967,14.314],[106.895,14.3335],[106.838,14.294],[106.7175,14.422],[106.6395,14.4485],[106.612,14.4975],[106.5705,14.521],[106.546,14.59],[106.5235,14.5915],[106.438,14.5235],[106.4355,14.4815],[106.4045,14.45],[106.3295,14.439],[106.264,14.4785],[106.2415,14.4645],[106.2375,14.3985],[106.1875,14.3515],[106.0955,14.373],[106.023,14.312],[106.027,14.246],[106.0515,14.2025],[106.1075,14.188],[106.1215,14.1095],[106.1875,14.063],[106.168,14.0195],[106.1,13.979],[106.1055,13.9095],[105.996,13.9305],[105.911,13.9305],[105.7925,14.0235],[105.7885,14.0775],[105.699,14.094],[105.5565,14.1605],[105.4435,14.1085],[105.3615,14.1065],[105.3245,14.159],[105.282,14.171],[105.247,14.26],[105.206,14.3125],[105.2065,14.3435],[105.151,14.2835],[105.154,14.2545],[105.1025,14.213],[105.05,14.215],[105.026,14.238],[105.0005,14.305],[105.0025,14.362],[104.8795,14.412],[104.8335,14.4025],[104.806,14.4375],[104.7525,14.4055],[104.6985,14.4275],[104.641,14.423],[104.5645,14.354],[104.5,14.3765],[104.4765,14.361],[104.307,14.383],[104.2775,14.408],[104.217,14.3675],[104.1715,14.359],[104.108,14.3785],[104.0935,14.3535],[104.029,14.34],[104.0095,14.356],[103.9,14.338],[103.837,14.371],[103.78,14.3615],[103.7005,14.392],[103.707,14.433],[103.6555,14.4395],[103.642,14.4145],[103.578,14.4335],[103.497,14.4105],[103.4675,14.3645],[103.435,14.391],[103.402,14.358],[103.2665,14.3495],[103.219,14.3235],[103.1885,14.3345],[103.079,14.294],[103.022,14.2285],[102.952,14.207],[102.941,14.1525],[102.9005,14.0835],[102.9085,14.021],[102.869,14.005],[102.783,13.933],[102.7665,13.8565],[102.6885,13.752],[102.5805,13.7005],[102.549,13.6595],[102.5715,13.635],[102.57,13.586],[102.5375,13.567],[102.439,13.56],[102.3665,13.578],[102.334,13.5405],[102.363,13.506],[102.3625,13.4245],[102.345,13.347],[102.3495,13.2775],[102.386,13.218],[102.399,13.1565],[102.494,13.014],[102.488,12.944],[102.508,12.8975],[102.5325,12.7675],[102.5005,12.7385],[102.511,12.67],[102.567,12.658],[102.6435,12.612],[102.6775,12.543],[102.7655,12.457],[102.7875,12.4155],[102.726,12.3645],[102.7175,12.2225],[102.705,12.18],[102.734,12.111],[102.769,12.0755],[102.785,11.9765],[102.815,11.9335],[102.8195,11.8925],[102.8665,11.8065],[102.9115,11.7455],[102.914,11.6545],[102.621,11.3895]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/83/Flag_of_Cambodia.svg","name:en":"Cambodia","wikidata":"Q424","ISO3166-1:alpha2":"KH","ISO3166-1:alpha3":"KHM","ISO3166-1:numeric":"116"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[89.14,21.4265],[89.2645,21.4835],[89.585,21.5995],[89.824,21.7035],[89.9065,21.7525],[89.946,21.793],[89.9785,21.866],[90.0585,21.838],[90.083,21.815],[90.1655,21.788],[90.2345,21.8015],[90.267,21.824],[90.392,21.7825],[90.5315,21.812],[90.607,21.8155],[90.689,21.853],[90.773,21.83],[90.8595,21.8385],[90.9125,21.8835],[90.9495,21.943],[91.051,21.9545],[91.109,21.972],[91.176,22.016],[91.2725,22.113],[91.273,22.314],[91.3205,22.358],[91.3825,22.3645],[91.4805,22.31],[91.645,22.3505],[91.6615,22.3305],[91.652,22.23],[91.6895,22.1725],[91.719,22.0605],[91.7105,21.7775],[91.7155,21.4965],[91.7465,21.4495],[91.836,21.3755],[91.909,21.284],[91.906,21.161],[91.9355,21.0905],[92.03,20.9705],[92.13,20.7375],[92.0945,20.627],[92.1105,20.5505],[92.1875,20.434],[92.2565,20.391],[92.338,20.3755],[92.3985,20.385],[92.4245,20.4815],[92.4285,20.565],[92.363,20.5895],[92.343,20.649],[92.3715,20.7025],[92.34,20.819],[92.272,20.947],[92.2535,21.021],[92.2585,21.0775],[92.176,21.16],[92.218,21.2355],[92.1975,21.328],[92.2585,21.363],[92.27,21.4305],[92.3245,21.4195],[92.3425,21.4665],[92.381,21.4795],[92.425,21.433],[92.4275,21.381],[92.475,21.3545],[92.5175,21.3885],[92.564,21.372],[92.5945,21.2495],[92.674,21.2835],[92.643,21.408],[92.618,21.4695],[92.5985,21.66],[92.5995,21.7945],[92.6215,21.8755],[92.601,21.982],[92.5665,22.1415],[92.599,22.137],[92.591,22.255],[92.543,22.491],[92.5165,22.7225],[92.479,22.7535],[92.4545,22.82],[92.4645,22.8545],[92.4195,22.911],[92.378,22.9295],[92.374,22.971],[92.3925,23.0565],[92.361,23.0985],[92.354,23.236],[92.402,23.2365],[92.381,23.352],[92.3535,23.39],[92.3165,23.4865],[92.306,23.583],[92.273,23.6435],[92.291,23.681],[92.279,23.7265],[92.205,23.705],[92.141,23.7325],[92.068,23.648],[92.0005,23.673],[91.978,23.735],[91.9295,23.683],[91.9495,23.617],[91.966,23.484],[91.8535,23.4065],[91.813,23.349],[91.7625,23.3095],[91.8085,23.135],[91.834,23.094],[91.7835,23.037],[91.7215,22.989],[91.627,22.956],[91.5775,22.9675],[91.544,23.0],[91.5515,23.0385],[91.4975,23.147],[91.503,23.1935],[91.449,23.261],[91.418,23.2685],[91.384,23.193],[91.3835,23.1555],[91.412,23.077],[91.3705,23.0715],[91.3255,23.1585],[91.325,23.2385],[91.2915,23.319],[91.251,23.4765],[91.202,23.523],[91.1605,23.639],[91.2065,23.65],[91.21,23.6875],[91.1575,23.69],[91.1695,23.7485],[91.21,23.747],[91.2535,23.8345],[91.231,23.8815],[91.272,23.9605],[91.3225,23.993],[91.361,23.984],[91.398,24.05],[91.376,24.1055],[91.474,24.099],[91.586,24.0715],[91.6435,24.1135],[91.6455,24.1705],[91.7255,24.144],[91.762,24.1545],[91.75,24.241],[91.8235,24.2085],[91.9115,24.144],[91.9475,24.2645],[91.923,24.3335],[91.996,24.3875],[92.091,24.371],[92.169,24.4355],[92.1545,24.4795],[92.17,24.5305],[92.2145,24.503],[92.26,24.683],[92.2975,24.7345],[92.27,24.832],[92.244,24.8425],[92.249,24.909],[92.317,24.895],[92.424,24.853],[92.499,24.904],[92.4845,24.9325],[92.4205,24.967],[92.428,25.0315],[92.347,25.05],[92.224,25.0995],[92.193,25.14],[92.0345,25.1885],[91.9825,25.1705],[91.915,25.181],[91.791,25.1655],[91.7575,25.174],[91.6945,25.134],[91.636,25.127],[91.5755,25.172],[91.548,25.1495],[91.44,25.151],[91.328,25.1765],[91.269,25.2045],[91.1795,25.1955],[91.082,25.198],[90.816,25.151],[90.776,25.176],[90.741,25.1585],[90.5235,25.1745],[90.4385,25.147],[90.3835,25.154],[90.289,25.1955],[90.1105,25.2245],[89.904,25.3105],[89.838,25.296],[89.8145,25.374],[89.861,25.5155],[89.8825,25.6215],[89.8355,25.7155],[89.8265,25.81],[89.833,25.8705],[89.8875,25.945],[89.8255,25.9455],[89.85,25.99],[89.8215,26.01],[89.7655,26.1285],[89.6875,26.1815],[89.6185,26.1795],[89.601,26.1295],[89.6295,26.1165],[89.6435,26.063],[89.589,26.039],[89.5865,25.9805],[89.54,25.97],[89.5165,26.0095],[89.4635,25.998],[89.4275,26.013],[89.3405,26.0155],[89.254,26.064],[89.2285,26.123],[89.155,26.139],[89.148,26.209],[89.125,26.264],[89.1355,26.3095],[89.105,26.3265],[89.09,26.392],[89.0375,26.4],[88.9575,26.4575],[88.911,26.3705],[88.9825,26.309],[89.04,26.281],[89.0455,26.241],[88.9535,26.242],[88.9185,26.288],[88.8755,26.2865],[88.8385,26.2325],[88.803,26.3055],[88.6675,26.272],[88.702,26.336],[88.65,26.4295],[88.5605,26.461],[88.448,26.5355],[88.397,26.626],[88.35,26.5105],[88.4155,26.4695],[88.4845,26.459],[88.524,26.36],[88.434,26.335],[88.3495,26.2825],[88.3475,26.221],[88.325,26.2045],[88.1775,26.148],[88.1585,26.095],[88.1855,26.0635],[88.1775,26.0215],[88.1415,26.0145],[88.111,25.934],[88.0855,25.9145],[88.102,25.8285],[88.172,25.787],[88.2365,25.81],[88.357,25.7215],[88.402,25.673],[88.454,25.6645],[88.45,25.6045],[88.548,25.5175],[88.603,25.516],[88.6465,25.478],[88.7105,25.4815],[88.7595,25.5265],[88.8035,25.5245],[88.838,25.3695],[88.9055,25.338],[88.9155,25.312],[89.0095,25.2985],[88.952,25.247],[88.949,25.181],[88.875,25.179],[88.8315,25.206],[88.7995,25.171],[88.7155,25.207],[88.6205,25.2055],[88.559,25.192],[88.477,25.213],[88.444,25.198],[88.463,25.0795],[88.438,25.009],[88.3975,24.969],[88.396,24.9375],[88.3425,24.8705],[88.264,24.8855],[88.2295,24.958],[88.1695,24.9515],[88.152,24.9065],[88.165,24.8615],[88.109,24.8125],[88.063,24.7255],[88.008,24.668],[88.0755,24.6335],[88.1065,24.573],[88.111,24.524],[88.226,24.469],[88.3655,24.412],[88.498,24.321],[88.577,24.3165],[88.652,24.294],[88.7065,24.303],[88.7395,24.2445],[88.744,24.1875],[88.7005,24.153],[88.699,24.0845],[88.7455,24.0325],[88.723,23.997],[88.737,23.919],[88.6695,23.868],[88.587,23.873],[88.59,23.7995],[88.5595,23.712],[88.5905,23.639],[88.637,23.605],[88.6515,23.556],[88.753,23.4795],[88.7575,23.3845],[88.703,23.307],[88.734,23.2435],[88.8095,23.255],[88.85,23.2305],[88.912,23.234],[88.9415,23.2065],[88.916,23.13],[88.8685,23.101],[88.884,23.0405],[88.855,22.9585],[88.8905,22.9275],[88.9105,22.88],[88.95,22.876],[88.963,22.819],[88.9115,22.7575],[88.96,22.685],[88.931,22.652],[88.9425,22.558],[88.9595,22.552],[89.0005,22.4315],[88.985,22.3255],[88.996,22.2855],[89.033,22.2585],[89.0705,22.197],[89.07,22.1505],[89.04,22.1025],[89.0825,22.003],[89.073,21.929],[89.0275,21.9195],[89.0425,21.867],[89.0285,21.791],[89.14,21.6085],[89.14,21.4265]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/f9/Flag_of_Bangladesh.svg","name:en":"Bangladesh","wikidata":"Q902","ISO3166-1:alpha2":"BD","ISO3166-1:alpha3":"BGD","ISO3166-1:numeric":"050"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[137.2235,8.389],[137.2285,8.343],[137.2615,8.271],[137.343,8.156],[137.415,8.11],[137.466,8.098],[137.5495,8.106],[137.611,8.132],[137.691,8.218],[137.715,8.295],[137.696,8.402],[137.7425,8.451],[137.7735,8.52],[137.7725,8.614],[137.7325,8.692],[137.686,8.733],[137.5735,8.765],[137.492,8.747],[137.427,8.703],[137.382,8.64],[137.365,8.579],[137.3055,8.549],[137.2495,8.486],[137.2235,8.389]]],[[[137.852,9.453],[137.8695,9.367],[137.9295,9.287],[138.037,9.243],[138.151,9.262],[138.232,9.329],[138.322,9.383],[138.368,9.44],[138.3915,9.5],[138.4005,9.576],[138.3575,9.701],[138.2765,9.797],[138.2,9.832],[138.0825,9.825],[138.018,9.788],[137.977,9.743],[137.873,9.567],[137.852,9.453]]],[[[139.3705,10.042],[139.3825,9.974],[139.4235,9.897],[139.435,9.783],[139.4955,9.684],[139.547,9.624],[139.6535,9.581],[139.732,9.588],[139.801,9.623],[139.8715,9.715],[139.976,9.742],[140.05,9.79],[140.089,9.847],[140.109,9.905],[140.111,9.981],[140.065,10.077],[140.026,10.112],[139.9555,10.143],[139.8935,10.214],[139.8115,10.268],[139.7285,10.29],[139.6725,10.288],[139.5005,10.229],[139.4265,10.179],[139.399,10.143],[139.3705,10.042]]],[[[140.1345,8.158],[140.1575,8.062],[140.23,7.985],[140.3615,7.921],[140.439,7.914],[140.4905,7.926],[140.5525,7.963],[140.6015,8.028],[140.6205,8.106],[140.616,8.156],[140.5835,8.229],[140.5505,8.27],[140.485,8.32],[140.412,8.347],[140.3205,8.356],[140.256,8.339],[140.205,8.307],[140.1475,8.226],[140.1345,8.158]]],[[[140.3055,9.759],[140.3235,9.675],[140.3605,9.62],[140.443,9.567],[140.507,9.556],[140.6035,9.575],[140.6525,9.606],[140.707,9.669],[140.7335,9.763],[140.708,9.866],[140.6495,9.932],[140.5625,9.969],[140.4735,9.965],[140.3955,9.929],[140.352,9.887],[140.3185,9.829],[140.3055,9.759]]],[[[142.8285,6.698],[142.836,6.644],[142.875,6.571],[142.9205,6.531],[143.035,6.487],[143.125,6.488],[143.1895,6.515],[143.229,6.548],[143.27,6.616],[143.276,6.73],[143.254,6.784],[143.197,6.846],[143.0885,6.892],[143.01,6.899],[142.9515,6.884],[142.87,6.821],[142.8415,6.77],[142.8285,6.698]]],[[[143.6185,7.355],[143.6275,7.293],[143.683,7.196],[143.768,7.137],[143.862,7.125],[143.9805,7.156],[144.061,7.21],[144.103,7.279],[144.117,7.351],[144.1135,7.405],[144.09,7.476],[144.0165,7.553],[143.932,7.581],[143.816,7.575],[143.729,7.546],[143.6595,7.481],[143.626,7.413],[143.6185,7.355]]],[[[144.2335,7.247],[144.256,7.156],[144.316,7.083],[144.368,7.054],[144.466,7.039],[144.5295,7.05],[144.6105,7.102],[144.648,7.157],[144.666,7.231],[144.6595,7.291],[144.6185,7.376],[144.5555,7.433],[144.497,7.456],[144.4115,7.458],[144.3075,7.406],[144.256,7.34],[144.2335,7.247]]],[[[144.302,8.608],[144.313,8.54],[144.3585,8.449],[144.4125,8.404],[144.494,8.378],[144.5525,8.38],[144.617,8.403],[144.7035,8.49],[144.728,8.565],[144.7275,8.617],[144.699,8.695],[144.6085,8.779],[144.5405,8.804],[144.4645,8.803],[144.3665,8.753],[144.3275,8.703],[144.302,8.608]]],[[[145.165,9.214],[145.183,9.13],[145.22,9.075],[145.3025,9.0215],[145.366,9.0105],[145.463,9.03],[145.512,9.061],[145.5665,9.124],[145.593,9.218],[145.5675,9.321],[145.509,9.3875],[145.44,9.4205],[145.351,9.4245],[145.255,9.3845],[145.211,9.342],[145.178,9.284],[145.165,9.214]]],[[[145.65,7.684],[145.683,7.575],[145.7505,7.512],[145.8555,7.485],[145.946,7.507],[145.9425,7.431],[145.988,7.302],[146.063,7.229],[146.1275,7.206],[146.205,7.207],[146.2625,7.228],[146.31,7.264],[146.3855,7.252],[146.4595,7.267],[146.5115,7.298],[146.5745,7.389],[146.585,7.467],[146.5755,7.519],[146.544,7.58],[146.4675,7.669],[146.3755,7.717],[146.309,7.721],[146.227,7.709],[146.1695,7.716],[146.087,7.698],[146.071,7.784],[146.029,7.846],[145.9355,7.9],[145.841,7.903],[145.7325,7.848],[145.681,7.793],[145.65,7.684]]],[[[146.526,8.087],[146.5295,8.047],[146.5625,7.97],[146.603,7.927],[146.6895,7.887],[146.7515,7.884],[146.8285,7.908],[146.875,7.943],[146.9265,8.032],[146.9265,8.138],[146.898,8.199],[146.8295,8.261],[146.7285,8.286],[146.665,8.275],[146.581,8.221],[146.5455,8.169],[146.526,8.087]]],[[[146.8225,7.378],[146.838,7.298],[146.8865,7.229],[146.9905,7.177],[147.09,7.184],[147.181,7.239],[147.228,7.308],[147.242,7.37],[147.2295,7.454],[147.177,7.531],[147.107,7.573],[146.994,7.583],[146.943,7.567],[146.888,7.529],[146.8325,7.438],[146.8225,7.378]]],[[[147.443,8.105],[147.4505,8.051],[147.479,7.99],[147.5485,7.928],[147.626,7.904],[147.688,7.907],[147.7455,7.928],[147.8205,7.999],[147.848,8.073],[147.8455,8.147],[147.822,8.208],[147.7615,8.272],[147.6825,8.304],[147.626,8.306],[147.5485,8.282],[147.5125,8.257],[147.4605,8.187],[147.443,8.105]]],[[[148.967,7.372],[148.9775,7.308],[149.011,7.245],[149.08,7.178],[149.128,7.156],[149.2095,7.148],[149.3105,7.184],[149.3845,7.268],[149.4035,7.336],[149.5015,7.348],[149.5955,7.418],[149.629,7.489],[149.6355,7.643],[149.616,7.727],[149.546,7.808],[149.4735,7.838],[149.3885,7.838],[149.3385,7.821],[149.2655,7.76],[149.2055,7.66],[149.1915,7.572],[149.098,7.559],[149.032,7.518],[148.9735,7.42],[148.967,7.372]]],[[[149.095,6.677],[149.1175,6.584],[149.1495,6.538],[149.198,6.5],[149.2625,6.477],[149.3665,6.485],[149.434,6.524],[149.473,6.57],[149.508,6.67],[149.5055,6.738],[149.4775,6.808],[149.4065,6.875],[149.342,6.898],[149.264,6.898],[149.1755,6.859],[149.118,6.79],[149.095,6.677]]],[[[149.479,8.584],[149.507,8.474],[149.5825,8.397],[149.665,8.37],[149.7265,8.372],[149.814,8.41],[149.868,8.472],[149.9045,8.586],[149.898,8.658],[149.8715,8.715],[149.8025,8.778],[149.738,8.801],[149.68,8.803],[149.6065,8.781],[149.521,8.707],[149.4855,8.636],[149.479,8.584]]],[[[149.8615,8.947],[149.889,8.843],[149.9715,8.766],[150.0615,8.744],[150.095,8.696],[150.178,8.628],[150.1835,8.52],[150.203,8.479],[150.274,8.41],[150.366,8.374],[150.4585,8.37],[150.5095,8.386],[150.568,8.427],[150.6025,8.474],[150.626,8.568],[150.594,8.677],[150.543,8.732],[150.525,8.836],[150.4835,8.897],[150.394,8.974],[150.372,9.058],[150.3135,9.139],[150.261,9.172],[150.1745,9.189],[150.0735,9.179],[150.022,9.158],[149.937,9.102],[149.883,9.035],[149.8615,8.947]]],[[[151.2385,7.387],[151.255,7.307],[151.337,7.165],[151.41,7.112],[151.4775,7.096],[151.548,7.042],[151.6135,7.024],[151.691,7.026],[151.7185,6.983],[151.774,6.937],[151.8255,6.848],[151.8775,6.81],[151.9765,6.788],[152.06,6.807],[152.108,6.838],[152.1665,6.908],[152.197,6.965],[152.207,7.049],[152.183,7.128],[152.228,7.224],[152.2315,7.284],[152.2015,7.408],[152.1975,7.476],[152.1685,7.592],[152.1215,7.699],[152.097,7.733],[152.0145,7.807],[151.951,7.844],[151.817,7.88],[151.7335,7.88],[151.635,7.854],[151.572,7.825],[151.502,7.743],[151.48,7.664],[151.4335,7.596],[151.3635,7.571],[151.275,7.501],[151.246,7.439],[151.2385,7.387]]],[[[151.4835,8.547],[151.4895,8.489],[151.564,8.322],[151.6275,8.263],[151.726,8.23],[151.8295,8.246],[151.9015,8.288],[151.9965,8.376],[152.0825,8.36],[152.17,8.381],[152.2135,8.41],[152.2815,8.412],[152.36,8.443],[152.4215,8.506],[152.476,8.54],[152.534,8.624],[152.542,8.738],[152.5055,8.842],[152.468,8.897],[152.384,8.959],[152.2805,8.981],[152.1885,8.974],[152.099,8.948],[152.048,8.916],[151.9985,8.852],[151.9795,8.792],[151.931,8.774],[151.865,8.798],[151.714,8.807],[151.6625,8.795],[151.5855,8.748],[151.5385,8.702],[151.499,8.635],[151.4835,8.547]]],[[[152.3685,6.993],[152.3855,6.915],[152.4195,6.859],[152.4815,6.809],[152.501,6.751],[152.547,6.687],[152.5865,6.658],[152.693,6.632],[152.773,6.646],[152.8655,6.714],[152.924,6.801],[152.9465,6.898],[152.9335,6.964],[152.879,7.044],[152.824,7.08],[152.748,7.101],[152.717,7.139],[152.654,7.182],[152.593,7.198],[152.5,7.186],[152.41,7.119],[152.3745,7.045],[152.3685,6.993]]],[[[152.911,5.925],[152.94,5.821],[153.0115,5.745],[153.055,5.717],[153.13,5.694],[153.175,5.694],[153.257,5.721],[153.301,5.756],[153.3365,5.808],[153.3555,5.9],[153.349,5.972],[153.3265,6.028],[153.27,6.089],[153.216,6.117],[153.141,6.13],[153.0275,6.108],[152.9735,6.071],[152.9285,6.007],[152.911,5.925]]],[[[153.2535,5.454],[153.2865,5.344],[153.364,5.237],[153.457,5.188],[153.4985,5.141],[153.598,5.089],[153.6455,5.083],[153.756,5.107],[153.8465,5.158],[153.8935,5.202],[153.928,5.262],[153.941,5.34],[153.9945,5.401],[154.0155,5.45],[154.021,5.538],[154.0075,5.588],[153.9515,5.664],[153.877,5.717],[153.8255,5.735],[153.7295,5.733],[153.645,5.787],[153.546,5.794],[153.4535,5.752],[153.4005,5.686],[153.3325,5.633],[153.278,5.557],[153.2535,5.454]]],[[[154.04,8.101],[154.057,8.017],[154.1095,7.944],[154.19,7.891],[154.2605,7.864],[154.336,7.863],[154.4085,7.89],[154.446,7.919],[154.5045,8.01],[154.5165,8.07],[154.5115,8.16],[154.4925,8.213],[154.412,8.308],[154.357,8.337],[154.2835,8.348],[154.177,8.321],[154.1115,8.275],[154.055,8.177],[154.04,8.101]]],[[[154.5785,1.104],[154.5805,1.0],[154.6025,0.933],[154.656,0.869],[154.7135,0.838],[154.821,0.831],[154.916,0.872],[154.97,0.927],[155.006,1.017],[155.01,1.089],[154.9805,1.187],[154.9185,1.256],[154.8015,1.302],[154.744,1.3],[154.6785,1.276],[154.64,1.247],[154.5935,1.178],[154.5785,1.104]]],[[[154.72,3.824],[154.741,3.735],[154.7835,3.678],[154.8235,3.649],[154.9065,3.624],[155.0315,3.639],[155.0855,3.668],[155.145,3.731],[155.173,3.806],[155.175,3.858],[155.134,3.973],[155.069,4.036],[154.966,4.071],[154.848,4.053],[154.79,4.015],[154.75,3.964],[154.728,3.904],[154.72,3.824]]],[[[154.945,7.555],[154.95,7.509],[154.9795,7.442],[155.0335,7.388],[155.0825,7.301],[155.1825,7.239],[155.348,7.207],[155.462,7.23],[155.5135,7.261],[155.5595,7.314],[155.5965,7.382],[155.616,7.474],[155.607,7.532],[155.6115,7.628],[155.5705,7.719],[155.504,7.785],[155.405,7.819],[155.2845,7.801],[155.1815,7.826],[155.091,7.816],[155.0345,7.786],[154.994,7.747],[154.9525,7.655],[154.945,7.555]]],[[[156.949,5.789],[156.9525,5.751],[156.9875,5.67],[157.0215,5.633],[157.122,5.587],[157.221,5.59],[157.2795,5.575],[157.387,5.586],[157.479,5.637],[157.521,5.689],[157.5465,5.773],[157.542,5.837],[157.5125,5.914],[157.4405,5.998],[157.3275,6.051],[157.233,6.046],[157.1425,5.991],[157.08,5.978],[156.999,5.922],[156.9585,5.851],[156.949,5.789]]],[[[157.5665,7.084],[157.5885,6.992],[157.622,6.943],[157.721,6.866],[157.717,6.792],[157.7315,6.688],[157.7635,6.612],[157.844,6.544],[157.9115,6.525],[157.9785,6.528],[158.1125,6.587],[158.273,6.564],[158.3235,6.571],[158.411,6.608],[158.5155,6.715],[158.548,6.765],[158.5675,6.841],[158.564,6.897],[158.4935,7.089],[158.444,7.157],[158.3375,7.238],[158.2765,7.254],[158.183,7.242],[158.1345,7.216],[158.082,7.159],[158.024,7.115],[157.9725,7.202],[157.9075,7.25],[157.7925,7.284],[157.728,7.281],[157.641,7.24],[157.6,7.195],[157.5665,7.084]]],[[[159.547,6.665],[159.563,6.585],[159.61,6.518],[159.714,6.466],[159.7745,6.464],[159.8585,6.491],[159.9325,6.565],[159.9605,6.633],[159.9695,6.693],[159.9515,6.777],[159.8805,6.86],[159.803,6.891],[159.732,6.894],[159.6325,6.856],[159.582,6.802],[159.5605,6.757],[159.547,6.665]]],[[[160.489,6.222],[160.5075,6.136],[160.552,6.066],[160.6405,6.008],[160.7425,6.001],[160.843,6.05],[160.9025,6.142],[160.917,6.214],[160.9,6.3],[160.8685,6.35],[160.79,6.409],[160.6995,6.431],[160.6275,6.42],[160.5535,6.375],[160.501,6.29],[160.489,6.222]]],[[[162.698,5.302],[162.7045,5.248],[162.766,5.138],[162.826,5.095],[162.898,5.071],[162.9975,5.059],[163.1035,5.086],[163.191,5.168],[163.219,5.224],[163.236,5.3],[163.2255,5.392],[163.1985,5.46],[163.159,5.512],[163.073,5.561],[162.9705,5.568],[162.9015,5.552],[162.832,5.514],[162.7545,5.438],[162.709,5.364],[162.698,5.302]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/e/e4/Flag_of_the_Federated_States_of_Micronesia.svg","name:en":"Federated States of Micronesia","wikidata":"Q702","ISO3166-1:alpha2":"FM","ISO3166-1:alpha3":"FSM","ISO3166-1:numeric":"583"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-109.6795,-27.2],[-109.649,-27.302],[-109.576,-27.37],[-109.504,-27.397],[-109.376,-27.392],[-109.1165,-27.291],[-109.0305,-27.205],[-109.003,-27.103],[-109.0375,-26.997],[-109.0875,-26.943],[-109.1335,-26.915],[-109.2755,-26.87],[-109.37,-26.855],[-109.4625,-26.869],[-109.5175,-26.895],[-109.597,-26.975],[-109.654,-27.086],[-109.6795,-27.2]]],[[[-105.5885,-26.4715],[-105.5635,-26.564],[-105.5085,-26.6265],[-105.436,-26.6645],[-105.367,-26.6755],[-105.258,-26.653],[-105.2025,-26.6165],[-105.1585,-26.56],[-105.141,-26.5125],[-105.14,-26.436],[-105.177,-26.3555],[-105.221,-26.314],[-105.282,-26.283],[-105.347,-26.2695],[-105.4575,-26.287],[-105.505,-26.3135],[-105.565,-26.381],[-105.5885,-26.4715]]],[[[-81.0785,-33.751],[-81.0395,-33.879],[-80.9695,-33.953],[-80.9245,-33.982],[-80.802,-34.015],[-80.71,-34.008],[-80.645,-33.984],[-80.563,-33.92],[-80.528,-33.859],[-80.515,-33.795],[-80.521,-33.719],[-80.555,-33.639],[-80.6285,-33.564],[-80.7585,-33.523],[-80.8445,-33.526],[-80.951,-33.564],[-80.9925,-33.593],[-81.0595,-33.675],[-81.0785,-33.751]]],[[[-80.3375,-26.296],[-80.3105,-26.392],[-80.253,-26.453],[-80.1855,-26.491],[-80.1245,-26.509],[-80.0395,-26.509],[-79.932,-26.548],[-79.851,-26.546],[-79.7355,-26.505],[-79.6775,-26.449],[-79.6515,-26.397],[-79.6455,-26.315],[-79.6605,-26.267],[-79.705,-26.205],[-79.781,-26.157],[-79.84,-26.14],[-79.939,-26.14],[-79.9845,-26.111],[-80.068,-26.088],[-80.177,-26.099],[-80.254,-26.137],[-80.297,-26.179],[-80.33,-26.244],[-80.3375,-26.296]]],[[[-79.1955,-33.698],[-79.18,-33.77],[-79.097,-33.867],[-79.025,-33.901],[-78.92,-33.915],[-78.7905,-33.882],[-78.681,-33.863],[-78.5855,-33.802],[-78.5325,-33.703],[-78.532,-33.643],[-78.5595,-33.572],[-78.642,-33.483],[-78.74,-33.435],[-78.824,-33.41],[-78.9235,-33.41],[-79.0475,-33.464],[-79.141,-33.556],[-79.171,-33.602],[-79.1955,-33.698]]],[[[-70.591,-18.35],[-70.583,-18.405],[-70.5445,-18.4755],[-70.561,-18.639],[-70.5535,-18.705],[-70.569,-18.825],[-70.5265,-18.99],[-70.5275,-19.038],[-70.49,-19.17],[-70.4955,-19.33],[-70.483,-19.38],[-70.4275,-19.507],[-70.451,-19.583],[-70.448,-19.641],[-70.425,-19.7],[-70.375,-19.757],[-70.376,-19.849],[-70.344,-20.017],[-70.3485,-20.079],[-70.375,-20.189],[-70.3685,-20.262],[-70.3955,-20.342],[-70.3865,-20.437],[-70.4135,-20.528],[-70.4065,-20.67],[-70.4235,-20.82],[-70.413,-20.874],[-70.3725,-20.941],[-70.392,-21.029],[-70.3765,-21.099],[-70.301,-21.274],[-70.311,-21.374],[-70.2915,-21.442],[-70.2995,-21.496],[-70.3365,-21.543],[-70.362,-21.618],[-70.3715,-21.794],[-70.398,-21.851],[-70.4,-21.943],[-70.4265,-22.049],[-70.462,-22.265],[-70.499,-22.555],[-70.5055,-22.675],[-70.5205,-22.711],[-70.531,-22.826],[-70.605,-22.843],[-70.701,-22.911],[-70.7735,-22.995],[-70.7935,-23.053],[-70.796,-23.139],[-70.819,-23.221],[-70.8285,-23.393],[-70.846,-23.495],[-70.8415,-23.557],[-70.814,-23.622],[-70.76,-23.677],[-70.6995,-23.709],[-70.7435,-23.847],[-70.731,-24.069],[-70.74,-24.179],[-70.7765,-24.367],[-70.7725,-24.411],[-70.796,-24.511],[-70.789,-24.613],[-70.8005,-24.725],[-70.7665,-24.836],[-70.739,-24.972],[-70.714,-25.023],[-70.728,-25.091],[-70.7115,-25.181],[-70.6695,-25.246],[-70.725,-25.327],[-70.803,-25.383],[-70.8645,-25.486],[-70.8725,-25.558],[-70.9145,-25.655],[-70.954,-25.718],[-70.963,-25.842],[-70.9435,-25.91],[-70.8775,-26.02],[-70.9105,-26.085],[-70.9195,-26.171],[-70.893,-26.249],[-70.914,-26.341],[-70.9305,-26.565],[-70.9805,-26.686],[-71.0395,-26.8],[-71.0575,-26.866],[-71.049,-26.937],[-71.1055,-26.978],[-71.179,-27.088],[-71.1935,-27.128],[-71.2025,-27.268],[-71.1865,-27.326],[-71.188,-27.404],[-71.1505,-27.486],[-71.2215,-27.542],[-71.2485,-27.585],[-71.276,-27.677],[-71.3325,-27.812],[-71.3715,-27.946],[-71.375,-28.0],[-71.4035,-28.063],[-71.411,-28.127],[-71.3945,-28.199],[-71.425,-28.313],[-71.4855,-28.395],[-71.4975,-28.447],[-71.5405,-28.536],[-71.541,-28.616],[-71.572,-28.659],[-71.6485,-28.711],[-71.7265,-28.824],[-71.7455,-28.881],[-71.7865,-28.927],[-71.816,-28.992],[-71.8095,-29.1],[-71.758,-29.179],[-71.7775,-29.257],[-71.7645,-29.353],[-71.7215,-29.4165],[-71.757,-29.463],[-71.778,-29.523],[-71.7635,-29.639],[-71.7285,-29.705],[-71.692,-29.741],[-71.5715,-29.789],[-71.555,-29.84],[-71.6055,-29.886],[-71.6385,-29.947],[-71.644,-30.039],[-71.7535,-30.071],[-71.8335,-30.144],[-71.8745,-30.216],[-71.91,-30.324],[-71.929,-30.5],[-71.9485,-30.586],[-71.9465,-30.734],[-71.9125,-30.954],[-71.895,-31.006],[-71.9015,-31.156],[-71.8725,-31.272],[-71.8445,-31.444],[-71.809,-31.536],[-71.814,-31.62],[-71.78,-31.724],[-71.794,-31.842],[-71.7625,-31.953],[-71.7615,-32.057],[-71.7755,-32.217],[-71.752,-32.297],[-71.7085,-32.364],[-71.688,-32.424],[-71.7135,-32.53],[-71.7035,-32.597],[-71.77,-32.722],[-71.785,-32.804],[-71.779,-32.854],[-71.922,-32.966],[-71.979,-33.061],[-71.9785,-33.141],[-71.946,-33.213],[-71.9245,-33.305],[-71.949,-33.415],[-71.9405,-33.479],[-71.868,-33.577],[-71.9815,-33.649],[-72.015,-33.695],[-72.068,-33.834],[-72.212,-34.025],[-72.2435,-34.088],[-72.2495,-34.146],[-72.224,-34.277],[-72.2795,-34.366],[-72.2905,-34.416],[-72.2885,-34.61],[-72.304,-34.657],[-72.3695,-34.747],[-72.4205,-34.864],[-72.432,-34.997],[-72.514,-35.047],[-72.5915,-35.117],[-72.644,-35.22],[-72.7305,-35.328],[-72.743,-35.38],[-72.7945,-35.419],[-72.8425,-35.48],[-72.8735,-35.554],[-72.878,-35.636],[-72.8395,-35.72],[-72.903,-35.793],[-72.976,-35.849],[-73.0135,-35.901],[-73.0535,-36.039],[-73.07,-36.187],[-73.0635,-36.245],[-73.1275,-36.368],[-73.1895,-36.423],[-73.3075,-36.484],[-73.3635,-36.565],[-73.3815,-36.617],[-73.4525,-36.71],[-73.4695,-36.768],[-73.545,-36.76],[-73.627,-36.772],[-73.7225,-36.822],[-73.759,-36.861],[-73.7895,-36.931],[-73.805,-37.038],[-73.86,-37.095],[-73.902,-37.189],[-73.9325,-37.305],[-73.9355,-37.373],[-73.914,-37.447],[-73.8835,-37.488],[-73.919,-37.553],[-73.9325,-37.625],[-73.895,-37.783],[-73.779,-37.942],[-73.709,-38.086],[-73.705,-38.127],[-73.748,-38.182],[-73.8335,-38.137],[-73.906,-38.119],[-74.015,-38.121],[-74.1265,-38.166],[-74.1785,-38.215],[-74.215,-38.311],[-74.1985,-38.419],[-74.135,-38.54],[-74.046,-38.613],[-73.981,-38.637],[-73.859,-38.643],[-73.7585,-38.611],[-73.715,-38.754],[-73.6575,-38.854],[-73.5695,-39.04],[-73.4875,-39.272],[-73.489,-39.328],[-73.543,-39.514],[-73.6175,-39.58],[-73.651,-39.631],[-73.671,-39.725],[-73.691,-39.747],[-73.842,-39.811],[-73.901,-39.863],[-73.9615,-39.963],[-73.9655,-40.033],[-73.944,-40.092],[-73.9755,-40.145],[-74.0125,-40.281],[-74.0395,-40.461],[-74.0245,-40.527],[-74.087,-40.612],[-74.15,-40.846],[-74.1905,-40.907],[-74.2095,-41.001],[-74.1745,-41.201],[-74.1255,-41.283],[-74.109,-41.3395],[-74.1205,-41.413],[-74.317,-41.7265],[-74.336,-41.7685],[-74.477,-42.2375],[-74.701,-43.177],[-75.033,-43.413],[-75.091,-43.4725],[-75.1325,-43.561],[-75.145,-43.632],[-75.1275,-43.884],[-75.0865,-44.4645],[-75.3465,-44.625],[-75.4495,-44.7185],[-75.4845,-44.796],[-75.4845,-44.84],[-75.437,-44.9695],[-75.245,-45.606],[-75.855,-46.5295],[-75.8955,-46.631],[-75.919,-46.742],[-75.913,-46.86],[-75.825,-46.9925],[-75.7145,-47.0845],[-75.7085,-47.6705],[-75.9665,-48.017],[-75.9985,-48.1005],[-76.0335,-48.7885],[-76.047,-49.126],[-75.976,-49.496],[-75.82,-50.1125],[-75.8375,-50.3635],[-75.8345,-50.6685],[-75.7925,-50.87],[-75.772,-50.9175],[-75.587,-51.2015],[-75.6845,-51.5535],[-75.677,-51.642],[-75.471,-52.0925],[-75.432,-52.4125],[-75.421,-52.45],[-75.3495,-52.5305],[-75.269,-52.5705],[-75.0465,-52.6475],[-75.0745,-52.731],[-75.0715,-52.84],[-75.0335,-52.9305],[-74.599,-53.418],[-73.7695,-54.16],[-73.4035,-54.704],[-73.3575,-54.751],[-73.255,-54.8035],[-73.152,-54.8255],[-72.209,-54.9145],[-71.183,-55.3525],[-71.0295,-55.389],[-70.671,-55.4195],[-70.315,-55.5435],[-69.9115,-55.6395],[-69.7305,-55.8375],[-69.639,-55.9],[-69.494,-55.9395],[-69.411,-55.9445],[-68.2195,-55.9275],[-68.0615,-56.0235],[-67.9775,-56.049],[-67.7405,-56.1],[-67.3805,-56.1685],[-67.176,-56.1725],[-66.9165,-56.134],[-66.7555,-56.0815],[-66.5505,-55.9645],[-66.4835,-55.91],[-66.4505,-55.8365],[-66.429,-55.6235],[-66.1205,-55.315],[-66.0775,-55.2395],[-66.0785,-55.1835],[-66.4165,-55.1215],[-66.671,-55.119],[-66.7915,-55.0135],[-66.8525,-54.988],[-66.958,-54.9715],[-67.032,-54.9765],[-67.1325,-54.9275],[-67.273,-54.905],[-67.477,-54.9235],[-67.5725,-54.8945],[-67.705,-54.9055],[-67.9505,-54.8735],[-68.253,-54.8855],[-68.4115,-54.8825],[-68.6095,-54.9135],[-68.5955,-54.8085],[-68.6075,-54.5555],[-68.608,-54.1885],[-68.6065,-53.48],[-68.6065,-52.9755],[-68.607,-52.659],[-68.4325,-52.3975],[-68.4185,-52.3325],[-68.5735,-52.325],[-68.586,-52.3065],[-68.7095,-52.2855],[-68.838,-52.278],[-68.987,-52.2035],[-69.19,-52.1505],[-69.4865,-52.1515],[-69.9955,-52.0005],[-70.667,-52.0],[-71.0645,-52.0],[-71.9225,-52.0],[-72.0265,-51.9555],[-71.9385,-51.9085],[-71.949,-51.8735],[-72.121,-51.7445],[-72.2,-51.713],[-72.299,-51.6975],[-72.2875,-51.6325],[-72.3385,-51.584],[-72.441,-51.584],[-72.391,-51.515],[-72.3245,-51.476],[-72.337,-51.4215],[-72.308,-51.3775],[-72.3575,-51.318],[-72.274,-51.286],[-72.2585,-51.244],[-72.347,-51.2025],[-72.4015,-51.1355],[-72.374,-51.023],[-72.2655,-51.035],[-72.267,-50.965],[-72.246,-50.9],[-72.2605,-50.836],[-72.349,-50.7545],[-72.286,-50.66],[-72.4105,-50.6375],[-72.4955,-50.602],[-72.5835,-50.6585],[-72.697,-50.645],[-72.7325,-50.6155],[-72.893,-50.67],[-72.957,-50.741],[-73.094,-50.773],[-73.1965,-50.7415],[-73.153,-50.658],[-73.1935,-50.6155],[-73.2875,-50.59],[-73.3645,-50.518],[-73.3575,-50.429],[-73.3975,-50.3705],[-73.3615,-50.3015],[-73.4525,-50.2415],[-73.4615,-50.185],[-73.522,-50.1535],[-73.436,-50.011],[-73.477,-49.97],[-73.5585,-49.947],[-73.5105,-49.8795],[-73.4905,-49.8165],[-73.4385,-49.758],[-73.504,-49.7095],[-73.506,-49.666],[-73.4605,-49.6245],[-73.5355,-49.564],[-73.5445,-49.5045],[-73.4635,-49.4825],[-73.489,-49.4345],[-73.4275,-49.3935],[-73.432,-49.314],[-73.4965,-49.2685],[-73.473,-49.2045],[-73.149,-49.284],[-73.1395,-49.178],[-73.0785,-49.1405],[-73.042,-49.0775],[-73.001,-49.0595],[-72.923,-48.9345],[-72.85,-48.965],[-72.7945,-48.9645],[-72.747,-48.908],[-72.6965,-48.8965],[-72.534,-48.8005],[-72.542,-48.631],[-72.586,-48.4875],[-72.5025,-48.5175],[-72.44,-48.514],[-72.3735,-48.4495],[-72.4055,-48.417],[-72.277,-48.3635],[-72.2345,-48.316],[-72.3155,-48.2355],[-72.2985,-48.16],[-72.361,-48.0745],[-72.414,-48.079],[-72.427,-47.966],[-72.503,-47.9585],[-72.523,-47.902],[-72.475,-47.865],[-72.467,-47.8135],[-72.504,-47.7635],[-72.4345,-47.7345],[-72.4205,-47.661],[-72.3455,-47.6325],[-72.291,-47.512],[-72.31,-47.479],[-72.266,-47.4155],[-72.1985,-47.416],[-72.127,-47.328],[-72.046,-47.3405],[-71.997,-47.295],[-72.0155,-47.25],[-71.9735,-47.2095],[-71.879,-47.2295],[-71.8905,-47.1865],[-71.8505,-47.162],[-71.881,-47.107],[-71.9495,-47.087],[-71.88,-47.011],[-71.9525,-46.959],[-71.9705,-46.904],[-71.931,-46.8685],[-71.9485,-46.81],[-71.839,-46.799],[-71.6485,-46.689],[-71.6685,-46.613],[-71.669,-46.528],[-71.757,-46.346],[-71.724,-46.2845],[-71.751,-46.229],[-71.7995,-46.1915],[-71.8645,-46.1895],[-71.889,-46.1275],[-71.762,-46.112],[-71.676,-46.049],[-71.6465,-45.983],[-71.6145,-45.9625],[-71.656,-45.886],[-71.769,-45.8465],[-71.741,-45.807],[-71.798,-45.711],[-71.7955,-45.6645],[-71.727,-45.577],[-71.746,-45.5415],[-71.6815,-45.514],[-71.5605,-45.5235],[-71.477,-45.497],[-71.532,-45.397],[-71.3845,-45.3495],[-71.333,-45.319],[-71.331,-45.2505],[-71.4185,-45.1755],[-71.4705,-45.1485],[-71.511,-45.061],[-71.5565,-45.0325],[-71.5605,-44.9785],[-71.6845,-44.9695],[-71.812,-44.921],[-71.933,-44.9425],[-71.979,-44.9035],[-72.05,-44.882],[-72.069,-44.851],[-72.0065,-44.7835],[-71.9135,-44.777],[-71.8565,-44.802],[-71.7835,-44.751],[-71.6755,-44.7865],[-71.494,-44.737],[-71.396,-44.79],[-71.2765,-44.8095],[-71.207,-44.75],[-71.198,-44.689],[-71.2355,-44.641],[-71.1865,-44.593],[-71.1215,-44.597],[-71.092,-44.533],[-71.137,-44.4695],[-71.24,-44.4175],[-71.332,-44.429],[-71.3645,-44.3895],[-71.4755,-44.391],[-71.5725,-44.409],[-71.6545,-44.4095],[-71.695,-44.384],[-71.8075,-44.4205],[-71.8405,-44.35],[-71.791,-44.3145],[-71.811,-44.254],[-71.8075,-44.1875],[-71.8515,-44.1295],[-71.752,-44.094],[-71.682,-43.9745],[-71.649,-43.9455],[-71.6655,-43.902],[-71.759,-43.8445],[-71.7515,-43.7855],[-71.703,-43.7395],[-71.6105,-43.701],[-71.581,-43.6515],[-71.608,-43.6285],[-71.69,-43.6265],[-71.716,-43.5775],[-71.7765,-43.5385],[-71.871,-43.553],[-71.8485,-43.4835],[-71.889,-43.45],[-71.8965,-43.32],[-71.8425,-43.335],[-71.7915,-43.298],[-71.7315,-43.3075],[-71.757,-43.228],[-71.73,-43.201],[-71.7605,-43.1645],[-71.8875,-43.1265],[-71.924,-43.101],[-71.9445,-43.046],[-72.0365,-43.0135],[-72.076,-42.949],[-72.143,-42.898],[-72.165,-42.799],[-72.129,-42.7325],[-72.1795,-42.698],[-72.096,-42.642],[-72.1035,-42.6005],[-72.028,-42.515],[-72.04,-42.4595],[-72.023,-42.4175],[-72.133,-42.384],[-72.137,-42.328],[-72.168,-42.2605],[-72.1585,-42.1935],[-72.173,-42.1405],[-72.0925,-42.154],[-72.049,-42.116],[-71.9705,-42.145],[-71.927,-42.19],[-71.73,-42.122],[-71.7935,-41.9625],[-71.775,-41.9075],[-71.7895,-41.831],[-71.7645,-41.817],[-71.784,-41.735],[-71.886,-41.605],[-71.837,-41.566],[-71.851,-41.515],[-71.8345,-41.4335],[-71.911,-41.358],[-71.8755,-41.2965],[-71.8575,-41.212],[-71.888,-41.161],[-71.841,-41.15],[-71.8515,-41.0985],[-71.8195,-41.0605],[-71.9085,-40.973],[-71.855,-40.9445],[-71.8685,-40.892],[-71.9275,-40.8335],[-71.923,-40.783],[-71.9595,-40.7585],[-71.9495,-40.719],[-71.866,-40.658],[-71.8375,-40.61],[-71.87,-40.5725],[-71.8415,-40.452],[-71.8035,-40.406],[-71.7085,-40.4225],[-71.6715,-40.311],[-71.736,-40.3055],[-71.828,-40.208],[-71.7995,-40.136],[-71.814,-40.0805],[-71.7,-40.117],[-71.6665,-40.0745],[-71.6895,-40.0365],[-71.5925,-39.901],[-71.6465,-39.853],[-71.691,-39.8425],[-71.6805,-39.769],[-71.7125,-39.7245],[-71.684,-39.692],[-71.6985,-39.588],[-71.618,-39.5985],[-71.61,-39.628],[-71.518,-39.6255],[-71.461,-39.583],[-71.5345,-39.5305],[-71.473,-39.4935],[-71.4465,-39.3965],[-71.4015,-39.352],[-71.3885,-39.2655],[-71.4075,-39.096],[-71.441,-38.9775],[-71.4255,-38.9215],[-71.2675,-38.8515],[-71.2605,-38.815],[-71.2065,-38.8175],[-71.1075,-38.772],[-71.0275,-38.7585],[-70.925,-38.763],[-70.892,-38.721],[-70.904,-38.667],[-70.829,-38.5995],[-70.8405,-38.5415],[-70.911,-38.5035],[-70.976,-38.442],[-70.985,-38.361],[-71.0195,-38.218],[-70.997,-38.17],[-71.0435,-38.124],[-70.9865,-38.1045],[-71.053,-38.0455],[-71.051,-37.9925],[-71.1145,-37.953],[-71.108,-37.8925],[-71.1705,-37.78],[-71.156,-37.7575],[-71.212,-37.689],[-71.194,-37.6305],[-71.1265,-37.5825],[-71.1195,-37.4865],[-71.15,-37.4025],[-71.199,-37.3795],[-71.2155,-37.2725],[-71.114,-37.205],[-71.136,-37.1645],[-71.0925,-37.1145],[-71.1705,-36.9965],[-71.1065,-36.9715],[-71.1445,-36.929],[-71.122,-36.864],[-71.1325,-36.8155],[-71.1115,-36.7285],[-71.013,-36.6975],[-71.0405,-36.6495],[-71.0555,-36.5665],[-71.0385,-36.4775],[-70.956,-36.5045],[-70.894,-36.4715],[-70.89,-36.4035],[-70.7875,-36.429],[-70.713,-36.427],[-70.6795,-36.3895],[-70.7125,-36.3395],[-70.6845,-36.3045],[-70.705,-36.2725],[-70.6395,-36.243],[-70.5835,-36.147],[-70.5345,-36.1415],[-70.4905,-36.179],[-70.421,-36.156],[-70.4105,-36.056],[-70.3715,-36.0435],[-70.3905,-35.951],[-70.425,-35.9135],[-70.421,-35.874],[-70.3155,-35.819],[-70.3795,-35.787],[-70.3695,-35.7375],[-70.418,-35.63],[-70.3865,-35.604],[-70.4135,-35.529],[-70.382,-35.5125],[-70.4465,-35.464],[-70.4525,-35.3925],[-70.4185,-35.3545],[-70.439,-35.316],[-70.4965,-35.323],[-70.583,-35.28],[-70.5425,-35.2025],[-70.4705,-35.203],[-70.388,-35.171],[-70.362,-35.1365],[-70.3755,-35.046],[-70.3345,-34.9915],[-70.3195,-34.9315],[-70.257,-34.8205],[-70.309,-34.768],[-70.2145,-34.681],[-70.223,-34.64],[-70.1035,-34.482],[-70.015,-34.413],[-70.0145,-34.3385],[-70.031,-34.288],[-69.967,-34.251],[-69.9315,-34.2815],[-69.795,-34.243],[-69.7915,-34.2005],[-69.869,-34.1405],[-69.8395,-34.007],[-69.892,-33.925],[-69.8555,-33.8925],[-69.899,-33.8475],[-69.904,-33.7715],[-69.865,-33.715],[-69.8845,-33.6845],[-69.8655,-33.583],[-69.872,-33.5395],[-69.835,-33.515],[-69.82,-33.4325],[-69.7705,-33.361],[-69.7995,-33.2885],[-69.9175,-33.267],[-70.003,-33.323],[-70.039,-33.27],[-70.0275,-33.2325],[-70.0645,-33.205],[-70.066,-33.104],[-70.081,-33.029],[-70.0215,-33.008],[-70.0015,-32.946],[-70.001,-32.8845],[-70.0445,-32.87],[-70.0545,-32.832],[-70.108,-32.8005],[-70.1705,-32.6255],[-70.123,-32.5355],[-70.149,-32.466],[-70.2365,-32.429],[-70.2225,-32.325],[-70.319,-32.2735],[-70.301,-32.207],[-70.305,-32.1425],[-70.3415,-32.1095],[-70.322,-32.0505],[-70.2485,-32.024],[-70.2085,-31.978],[-70.272,-31.8905],[-70.392,-31.8795],[-70.455,-31.8485],[-70.4675,-31.7005],[-70.513,-31.6895],[-70.567,-31.583],[-70.553,-31.51],[-70.5695,-31.4735],[-70.53,-31.3755],[-70.545,-31.3065],[-70.517,-31.234],[-70.5235,-31.19],[-70.4985,-31.125],[-70.432,-31.102],[-70.408,-31.1665],[-70.319,-31.043],[-70.2985,-30.9625],[-70.3215,-30.9245],[-70.278,-30.81],[-70.247,-30.635],[-70.1795,-30.5115],[-70.195,-30.4915],[-70.117,-30.431],[-70.144,-30.372],[-70.1035,-30.3565],[-70.0705,-30.391],[-69.955,-30.3855],[-69.9035,-30.3435],[-69.8855,-30.2185],[-69.8355,-30.219],[-69.8095,-30.1455],[-69.905,-30.1065],[-69.961,-30.0685],[-69.912,-30.028],[-69.926,-30.0005],[-69.8985,-29.958],[-69.896,-29.8795],[-69.8775,-29.8615],[-69.9135,-29.807],[-69.8795,-29.7335],[-69.942,-29.646],[-69.9315,-29.5845],[-69.9555,-29.535],[-69.948,-29.491],[-69.9815,-29.452],[-69.967,-29.4145],[-70.0215,-29.3835],[-70.0205,-29.3305],[-69.9855,-29.277],[-69.946,-29.263],[-69.9335,-29.189],[-69.883,-29.144],[-69.787,-29.13],[-69.787,-29.0285],[-69.7535,-28.957],[-69.7665,-28.924],[-69.693,-28.771],[-69.7295,-28.736],[-69.7265,-28.6705],[-69.6955,-28.599],[-69.6645,-28.5815],[-69.6645,-28.482],[-69.642,-28.442],[-69.65,-28.396],[-69.5325,-28.3345],[-69.457,-28.1835],[-69.384,-28.213],[-69.3795,-28.1815],[-69.3275,-28.1555],[-69.299,-28.0695],[-69.264,-28.0465],[-69.2675,-28.0105],[-69.2105,-27.9645],[-69.182,-27.972],[-69.134,-27.909],[-69.089,-27.7855],[-69.0935,-27.7175],[-69.0455,-27.699],[-69.053,-27.617],[-68.9765,-27.5605],[-68.943,-27.515],[-68.9635,-27.4685],[-68.9365,-27.4445],[-68.8685,-27.317],[-68.8245,-27.294],[-68.8685,-27.2605],[-68.841,-27.1545],[-68.8085,-27.1465],[-68.778,-27.099],[-68.6685,-27.104],[-68.6185,-27.17],[-68.573,-27.175],[-68.5565,-27.1145],[-68.4965,-27.135],[-68.4325,-27.0655],[-68.3475,-27.0335],[-68.2985,-27.039],[-68.315,-26.974],[-68.281,-26.9035],[-68.3655,-26.801],[-68.5875,-26.493],[-68.5575,-26.287],[-68.381,-26.178],[-68.479,-25.708],[-68.5415,-25.6385],[-68.525,-25.567],[-68.573,-25.4935],[-68.5865,-25.4275],[-68.5225,-25.3745],[-68.5435,-25.3025],[-68.511,-25.181],[-68.4595,-25.126],[-68.4095,-25.1455],[-68.3435,-25.1105],[-68.3795,-25.0415],[-68.407,-25.0285],[-68.432,-24.9055],[-68.4865,-24.8955],[-68.531,-24.8585],[-68.568,-24.7975],[-68.5445,-24.7245],[-68.5155,-24.703],[-68.475,-24.6215],[-68.431,-24.5775],[-68.387,-24.484],[-68.309,-24.492],[-68.2965,-24.455],[-68.2455,-24.396],[-67.961,-24.285],[-67.3225,-24.0345],[-67.112,-23.3805],[-66.9905,-23.0005],[-67.1805,-22.814],[-67.5675,-22.8985],[-67.7985,-22.881],[-67.8815,-22.834],[-67.8675,-22.745],[-67.89,-22.719],[-67.8675,-22.6795],[-67.874,-22.64],[-67.8385,-22.5885],[-67.8455,-22.531],[-67.893,-22.4995],[-67.903,-22.4035],[-67.9335,-22.391],[-67.9385,-22.2945],[-67.9215,-22.2755],[-67.933,-22.2015],[-67.957,-22.1515],[-67.939,-22.108],[-67.971,-22.0545],[-68.0715,-21.979],[-68.063,-21.8525],[-68.0655,-21.7675],[-68.1175,-21.6785],[-68.1805,-21.6045],[-68.179,-21.3025],[-68.295,-21.0975],[-68.4125,-20.9345],[-68.493,-20.946],[-68.553,-20.8765],[-68.541,-20.7965],[-68.5535,-20.7285],[-68.526,-20.6965],[-68.4505,-20.6475],[-68.535,-20.5695],[-68.5735,-20.575],[-68.6135,-20.5365],[-68.6665,-20.5165],[-68.7385,-20.457],[-68.7415,-20.3685],[-68.672,-20.355],[-68.6605,-20.3195],[-68.7135,-20.23],[-68.705,-20.1335],[-68.7735,-20.1295],[-68.7625,-20.0785],[-68.64,-20.049],[-68.5665,-20.05],[-68.5215,-19.9245],[-68.5425,-19.8895],[-68.5285,-19.8455],[-68.5995,-19.828],[-68.6205,-19.7895],[-68.69,-19.75],[-68.6825,-19.718],[-68.625,-19.702],[-68.5985,-19.641],[-68.557,-19.5965],[-68.441,-19.4405],[-68.405,-19.416],[-68.4515,-19.368],[-68.5425,-19.297],[-68.62,-19.2765],[-68.6285,-19.251],[-68.806,-19.0835],[-68.8895,-19.0435],[-68.9505,-18.9365],[-68.92,-18.885],[-68.9255,-18.843],[-68.977,-18.738],[-68.988,-18.674],[-69.0325,-18.629],[-69.0045,-18.476],[-69.0475,-18.4265],[-69.053,-18.347],[-69.075,-18.2925],[-69.064,-18.2325],[-69.146,-18.163],[-69.057,-18.0615],[-69.121,-18.005],[-69.281,-17.9695],[-69.3085,-17.896],[-69.3075,-17.8055],[-69.337,-17.7315],[-69.468,-17.605],[-69.4685,-17.4985],[-69.5525,-17.5755],[-69.6665,-17.6605],[-69.7965,-17.646],[-69.826,-17.706],[-69.801,-17.762],[-69.799,-17.8655],[-69.75,-17.9475],[-69.7545,-17.9895],[-69.816,-18.1165],[-69.8605,-18.17],[-69.966,-18.262],[-70.0505,-18.269],[-70.1495,-18.3195],[-70.302,-18.309],[-70.3765,-18.35],[-70.591,-18.35]]],[[[-69.105,-56.447],[-69.086,-56.569],[-68.999,-56.657],[-68.8775,-56.706],[-68.705,-56.725],[-68.563,-56.708],[-68.405,-56.641],[-68.3405,-56.563],[-68.338,-56.487],[-68.3995,-56.375],[-68.5295,-56.286],[-68.661,-56.253],[-68.8665,-56.26],[-68.967,-56.291],[-69.0825,-56.379],[-69.105,-56.447]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/7/78/Flag_of_Chile.svg","name:en":"Chile","wikidata":"Q298","ISO3166-1:alpha2":"CL","ISO3166-1:alpha3":"CHL","ISO3166-1:numeric":"152"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-53.181,-33.869],[-53.0905,-33.801],[-52.642,-33.4455],[-52.585,-33.3965],[-52.46,-33.2535],[-52.405,-33.1735],[-52.296,-32.975],[-52.2265,-32.796],[-52.197,-32.6685],[-52.138,-32.5105],[-52.061,-32.385],[-51.938,-32.335],[-51.8585,-32.252],[-51.82,-32.178],[-51.742,-32.1055],[-51.6605,-32.0535],[-51.3975,-31.915],[-51.188,-31.7765],[-51.1015,-31.707],[-50.77,-31.4015],[-50.6045,-31.2415],[-50.5085,-31.1045],[-50.376,-30.927],[-50.281,-30.7885],[-50.1735,-30.643],[-50.1075,-30.5275],[-50.0405,-30.367],[-49.962,-30.1525],[-49.8965,-30.007],[-49.8255,-29.8655],[-49.7405,-29.714],[-49.6305,-29.5575],[-49.464,-29.342],[-49.3245,-29.185],[-49.158,-29.0285],[-49.027,-28.933],[-48.9155,-28.863],[-48.777,-28.791],[-48.686,-28.76],[-48.6155,-28.6895],[-48.407,-28.4325],[-48.39,-28.3965],[-48.2115,-27.856],[-48.1585,-27.5845],[-48.138,-27.5],[-48.111,-27.282],[-48.134,-27.1645],[-48.329,-26.7805],[-48.349,-26.751],[-48.28,-26.2305],[-47.9805,-25.6805],[-47.9,-25.5235],[-47.854,-25.47],[-47.5855,-25.2985],[-47.172,-25.038],[-47.089,-24.982],[-46.571,-24.654],[-46.187,-24.535],[-46.0065,-24.471],[-45.707,-24.348],[-45.583,-24.301],[-45.335,-24.197],[-45.135,-24.12],[-44.4775,-23.6785],[-44.207,-23.49],[-44.0775,-23.405],[-43.9245,-23.3765],[-43.6785,-23.3435],[-43.196,-23.267],[-42.816,-23.2445],[-42.4165,-23.225],[-41.9905,-23.206],[-41.915,-23.1855],[-41.859,-23.1545],[-41.65,-22.917],[-41.5965,-22.8365],[-41.568,-22.7555],[-41.5085,-22.5265],[-41.482,-22.5035],[-41.181,-22.331],[-40.9455,-22.204],[-40.856,-22.148],[-40.785,-22.0465],[-40.7705,-21.9855],[-40.7695,-21.878],[-40.8145,-21.6765],[-40.6945,-21.5065],[-40.6315,-21.4365],[-40.1885,-20.7915],[-40.1615,-20.739],[-40.0495,-20.4215],[-39.991,-20.2655],[-39.9585,-20.1155],[-39.8995,-19.988],[-39.841,-19.885],[-39.799,-19.855],[-39.7305,-19.8385],[-39.6715,-19.802],[-39.6315,-19.757],[-39.536,-19.5515],[-39.499,-19.4485],[-39.4825,-19.375],[-39.4765,-19.2835],[-39.494,-19.2015],[-39.54,-18.8365],[-39.534,-18.6945],[-39.519,-18.6335],[-39.5215,-18.5545],[-39.461,-18.3935],[-39.4675,-18.3035],[-39.3875,-18.1825],[-39.353,-18.109],[-39.289,-18.141],[-38.962,-18.163],[-38.6705,-18.1685],[-38.593,-18.136],[-38.5365,-18.097],[-38.4915,-18.0045],[-38.4935,-17.9095],[-38.532,-17.8005],[-38.5845,-17.6835],[-38.7285,-17.3185],[-38.877,-16.944],[-38.9285,-16.7845],[-38.896,-16.7205],[-38.8725,-16.5375],[-38.8215,-16.3815],[-38.8015,-16.2485],[-38.7605,-16.153],[-38.716,-16.004],[-38.647,-15.8835],[-38.6435,-15.8305],[-38.6645,-15.7475],[-38.7155,-15.675],[-38.744,-15.601],[-38.7395,-15.425],[-38.77,-15.341],[-38.8015,-15.185],[-38.793,-14.96],[-38.8215,-14.8515],[-38.82,-14.748],[-38.8535,-14.655],[-38.85,-14.611],[-38.774,-14.2845],[-38.7845,-14.195],[-38.752,-14.09],[-38.7055,-13.7955],[-38.6765,-13.6585],[-38.637,-13.3985],[-38.6115,-13.2655],[-38.502,-13.206],[-38.388,-13.183],[-38.333,-13.147],[-38.2645,-13.1265],[-38.2215,-13.097],[-38.0995,-12.9795],[-38.004,-12.8675],[-37.8965,-12.7585],[-37.831,-12.675],[-37.7785,-12.5835],[-37.7095,-12.4885],[-37.675,-12.4255],[-37.602,-12.342],[-37.426,-12.041],[-37.378,-11.9335],[-37.301,-11.7845],[-37.282,-11.7185],[-37.2315,-11.6205],[-37.167,-11.544],[-37.1295,-11.477],[-37.1135,-11.4125],[-37.0785,-11.363],[-36.995,-11.296],[-36.9275,-11.153],[-36.7875,-10.9515],[-36.7,-10.861],[-36.5675,-10.788],[-36.4975,-10.7415],[-36.3625,-10.7045],[-36.2365,-10.6215],[-36.187,-10.544],[-36.131,-10.4875],[-36.0615,-10.3745],[-35.964,-10.313],[-35.857,-10.126],[-35.7545,-10.016],[-35.7165,-9.965],[-35.6965,-9.9005],[-35.6635,-9.8685],[-35.5585,-9.8125],[-35.4935,-9.7195],[-35.3255,-9.528],[-35.2945,-9.4795],[-35.226,-9.422],[-35.0255,-9.1375],[-34.9505,-8.9615],[-34.8805,-8.763],[-34.815,-8.6245],[-34.779,-8.468],[-34.7415,-8.374],[-34.7415,-8.304],[-34.7055,-8.182],[-34.651,-8.0355],[-34.635,-7.915],[-34.644,-7.808],[-34.634,-7.7455],[-34.604,-7.2705],[-34.618,-7.207],[-34.5995,-7.1115],[-34.619,-7.003],[-34.623,-6.903],[-34.716,-6.746],[-34.742,-6.611],[-34.764,-6.562],[-34.7735,-6.421],[-34.813,-6.284],[-34.837,-6.2405],[-34.85,-6.1705],[-34.9,-6.082],[-34.919,-5.9325],[-34.954,-5.857],[-34.996,-5.72],[-34.9985,-5.6485],[-35.0255,-5.5845],[-35.0385,-5.5105],[-35.0675,-5.458],[-35.089,-5.379],[-35.139,-5.278],[-35.155,-5.173],[-35.204,-5.085],[-35.337,-4.9925],[-35.5145,-4.931],[-35.5645,-4.9075],[-35.6745,-4.892],[-35.7635,-4.8665],[-35.8405,-4.859],[-35.9365,-4.8335],[-36.0595,-4.8415],[-36.1895,-4.885],[-36.2915,-4.853],[-36.3755,-4.86],[-36.5045,-4.8475],[-36.623,-4.858],[-36.681,-4.8405],[-36.8115,-4.7515],[-36.917,-4.7135],[-37.0785,-4.7135],[-37.1355,-4.598],[-37.1855,-4.5385],[-37.254,-4.49],[-37.346,-4.4685],[-37.4305,-4.428],[-37.512,-4.4155],[-37.566,-4.364],[-37.5915,-4.3015],[-37.665,-4.221],[-37.7795,-4.1805],[-37.902,-4.0725],[-37.9575,-4.016],[-38.035,-3.9095],[-38.1645,-3.7665],[-38.214,-3.741],[-38.3125,-3.577],[-38.3875,-3.5145],[-38.4485,-3.4885],[-38.5555,-3.4845],[-38.628,-3.4465],[-38.6925,-3.3785],[-38.7955,-3.3305],[-38.817,-3.2865],[-38.8625,-3.238],[-38.981,-3.189],[-39.033,-3.1575],[-39.069,-3.112],[-39.152,-3.0445],[-39.256,-2.991],[-39.3705,-2.954],[-39.528,-2.84],[-39.641,-2.796],[-39.817,-2.6885],[-39.8905,-2.6535],[-39.9815,-2.6305],[-40.107,-2.62],[-40.178,-2.6005],[-40.386,-2.601],[-40.464,-2.578],[-40.5435,-2.578],[-40.6185,-2.6025],[-40.6635,-2.6385],[-40.7735,-2.636],[-40.8245,-2.6465],[-40.956,-2.643],[-41.032,-2.676],[-41.1825,-2.681],[-41.2915,-2.672],[-41.3485,-2.68],[-41.5085,-2.685],[-41.641,-2.5955],[-41.689,-2.5765],[-41.739,-2.5345],[-41.827,-2.508],[-42.0005,-2.477],[-42.244,-2.4275],[-42.782,-2.3305],[-42.8125,-2.31],[-43.028,-2.214],[-43.1995,-2.1565],[-43.265,-2.1465],[-44.778,-1.1145],[-44.834,-1.088],[-45.944,-0.7595],[-46.1515,-0.698],[-47.248,-0.4025],[-47.291,-0.3945],[-47.607,-0.272],[-48.2555,-0.0125],[-48.597,0.4645],[-49.336,1.3205],[-49.771,1.8315],[-50.2875,2.3025],[-50.7865,3.006],[-50.8135,3.1485],[-50.8215,3.2495],[-50.855,3.4555],[-50.8485,3.5415],[-50.8475,3.8605],[-50.869,4.011],[-50.9425,4.2015],[-51.03,4.3425],[-51.1145,4.423],[-51.212,4.489],[-51.3065,4.542],[-51.4,4.6215],[-51.4945,4.6745],[-51.5695,4.585],[-51.637,4.5085],[-51.6455,4.395],[-51.6285,4.2685],[-51.6145,4.2355],[-51.6335,4.176],[-51.6445,4.083],[-51.6585,4.053],[-51.778,3.974],[-51.7975,3.889],[-51.8705,3.807],[-51.927,3.768],[-51.9215,3.724],[-51.971,3.707],[-51.9885,3.63],[-52.087,3.4885],[-52.161,3.3525],[-52.2365,3.2395],[-52.2925,3.2275],[-52.3,3.175],[-52.349,3.1355],[-52.326,3.079],[-52.3955,2.931],[-52.478,2.7805],[-52.4755,2.7635],[-52.533,2.65],[-52.5275,2.581],[-52.5605,2.551],[-52.5515,2.5205],[-52.6165,2.4755],[-52.6605,2.374],[-52.8425,2.2915],[-52.9045,2.189],[-52.9565,2.173],[-53.052,2.19],[-53.105,2.2225],[-53.2225,2.201],[-53.273,2.222],[-53.2255,2.2625],[-53.344,2.351],[-53.371,2.313],[-53.432,2.2925],[-53.4615,2.253],[-53.659,2.2795],[-53.723,2.349],[-53.768,2.3755],[-53.81,2.34],[-53.883,2.3085],[-53.892,2.277],[-53.9375,2.283],[-53.9395,2.2215],[-53.987,2.2115],[-54.015,2.183],[-54.081,2.1745],[-54.1065,2.121],[-54.1395,2.118],[-54.204,2.1625],[-54.2675,2.1435],[-54.363,2.18],[-54.398,2.2035],[-54.478,2.2155],[-54.5365,2.325],[-54.601,2.3375],[-54.642,2.322],[-54.7,2.406],[-54.6965,2.4625],[-54.7605,2.4635],[-54.828,2.4215],[-54.87,2.431],[-54.87,2.468],[-54.9125,2.485],[-54.954,2.5835],[-55.0035,2.591],[-55.103,2.5255],[-55.1235,2.5675],[-55.173,2.5595],[-55.2345,2.5035],[-55.32,2.5155],[-55.356,2.4755],[-55.3455,2.448],[-55.3855,2.4185],[-55.4295,2.439],[-55.4995,2.443],[-55.5705,2.4235],[-55.6985,2.4215],[-55.747,2.4105],[-55.7665,2.455],[-55.83,2.459],[-55.9345,2.5335],[-55.978,2.5275],[-55.9895,2.427],[-56.0365,2.374],[-56.0505,2.335],[-56.094,2.321],[-56.1255,2.278],[-56.1205,2.2505],[-56.043,2.228],[-56.0565,2.1895],[-56.003,2.1675],[-55.967,2.0885],[-55.909,2.0475],[-55.9365,1.9865],[-55.904,1.888],[-55.9565,1.845],[-55.999,1.8315],[-56.0365,1.85],[-56.0985,1.8465],[-56.1525,1.8905],[-56.2345,1.8985],[-56.244,1.878],[-56.335,1.937],[-56.412,1.9285],[-56.469,1.949],[-56.58,1.906],[-56.6215,1.946],[-56.651,1.917],[-56.721,1.926],[-56.774,1.869],[-56.8935,1.8995],[-56.9195,1.9305],[-57.0005,1.9075],[-57.071,1.9685],[-57.071,1.9965],[-57.12,2.01],[-57.2555,1.9505],[-57.277,1.983],[-57.3455,1.9805],[-57.3675,1.9235],[-57.4335,1.906],[-57.432,1.8585],[-57.451,1.8065],[-57.4975,1.767],[-57.553,1.6925],[-57.6295,1.6985],[-57.6505,1.6825],[-57.705,1.731],[-57.7925,1.7265],[-57.8,1.685],[-57.895,1.6745],[-57.927,1.645],[-57.981,1.6595],[-57.9785,1.573],[-58.0055,1.517],[-58.061,1.5255],[-58.1295,1.499],[-58.1605,1.56],[-58.317,1.5685],[-58.3935,1.52],[-58.3855,1.47],[-58.5085,1.463],[-58.505,1.403],[-58.47,1.371],[-58.471,1.3195],[-58.496,1.268],[-58.5885,1.27],[-58.6285,1.2885],[-58.71,1.2835],[-58.7395,1.2],[-58.821,1.171],[-58.8545,1.1835],[-58.904,1.251],[-58.918,1.317],[-59.048,1.323],[-59.253,1.389],[-59.339,1.519],[-59.378,1.521],[-59.431,1.567],[-59.447,1.62],[-59.483,1.627],[-59.493,1.674],[-59.566,1.736],[-59.617,1.716],[-59.632,1.741],[-59.69,1.757],[-59.678,1.807],[-59.691,1.854],[-59.746,1.852],[-59.745,1.929],[-59.73,2.0305],[-59.7425,2.068],[-59.723,2.0985],[-59.7405,2.1795],[-59.72,2.237],[-59.741,2.293],[-59.7805,2.2855],[-59.905,2.3755],[-59.8935,2.4645],[-59.93,2.5655],[-59.978,2.642],[-59.991,2.683],[-59.9935,2.7825],[-59.984,2.9295],[-59.9475,3.003],[-59.9555,3.082],[-59.9015,3.1605],[-59.9125,3.195],[-59.8745,3.229],[-59.8815,3.259],[-59.805,3.357],[-59.84,3.4435],[-59.802,3.493],[-59.859,3.571],[-59.8505,3.6045],[-59.7655,3.626],[-59.7425,3.66],[-59.6685,3.703],[-59.6655,3.7815],[-59.5955,3.7955],[-59.5775,3.832],[-59.593,3.8855],[-59.523,3.932],[-59.5265,3.969],[-59.5865,3.9755],[-59.602,4.03],[-59.6425,4.0675],[-59.6195,4.133],[-59.685,4.147],[-59.7305,4.181],[-59.732,4.286],[-59.6755,4.3465],[-59.735,4.4235],[-59.805,4.466],[-59.911,4.4765],[-59.971,4.5095],[-60.0015,4.495],[-60.071,4.4935],[-60.161,4.5175],[-60.1235,4.605],[-60.07,4.618],[-60.0755,4.6555],[-60.026,4.7055],[-60.0135,4.843],[-59.9795,5.0155],[-59.9825,5.0825],[-60.094,5.14],[-60.106,5.194],[-60.132,5.225],[-60.183,5.2275],[-60.2195,5.269],[-60.313,5.211],[-60.384,5.222],[-60.434,5.182],[-60.527,5.208],[-60.569,5.196],[-60.614,5.219],[-60.682,5.232],[-60.7375,5.202],[-60.694,5.197],[-60.661,5.164],[-60.644,5.057],[-60.599,5.0],[-60.584,4.956],[-60.659,4.849],[-60.726,4.792],[-60.751,4.756],[-60.806,4.749],[-60.852,4.704],[-60.899,4.717],[-60.964,4.544],[-60.994,4.519],[-61.065,4.524],[-61.1195,4.5105],[-61.1475,4.481],[-61.188,4.521],[-61.269,4.54],[-61.323,4.535],[-61.322,4.504],[-61.278,4.478],[-61.351,4.419],[-61.462,4.437],[-61.513,4.406],[-61.508,4.322],[-61.56,4.252],[-61.631,4.241],[-61.658,4.262],[-61.769,4.249],[-61.802,4.229],[-61.818,4.168],[-61.922,4.1615],[-61.9265,4.1245],[-61.993,4.175],[-62.064,4.159],[-62.148,4.079],[-62.252,4.13],[-62.329,4.135],[-62.389,4.178],[-62.462,4.178],[-62.46,4.143],[-62.552,4.109],[-62.534,4.052],[-62.572,4.015],[-62.609,4.044],[-62.701,4.031],[-62.736,4.04],[-62.768,4.007],[-62.743,3.975],[-62.782,3.935],[-62.788,3.894],[-62.729,3.805],[-62.731,3.708],[-62.748,3.673],[-62.804,3.73],[-62.835,3.739],[-62.886,3.684],[-62.919,3.673],[-62.952,3.612],[-62.984,3.61],[-63.032,3.666],[-63.072,3.686],[-63.06,3.752],[-63.123,3.805],[-63.204,3.812],[-63.233,3.882],[-63.204,3.952],[-63.338,3.957],[-63.393,3.981],[-63.452,3.956],[-63.411,3.912],[-63.452,3.859],[-63.489,3.874],[-63.512,3.848],[-63.593,3.906],[-63.592,3.929],[-63.652,4.002],[-63.685,4.009],[-63.7,3.945],[-63.796,3.933],[-63.85,3.95],[-63.928,3.925],[-63.959,3.888],[-64.035,3.935],[-64.097,4.026],[-64.112,4.092],[-64.171,4.129],[-64.218,4.116],[-64.274,4.143],[-64.335,4.129],[-64.431,4.135],[-64.5,4.113],[-64.592,4.114],[-64.623,4.135],[-64.659,4.22],[-64.695,4.253],[-64.78,4.287],[-64.8195,4.235],[-64.802,4.174],[-64.7225,4.1175],[-64.6335,3.962],[-64.587,3.9325],[-64.5435,3.857],[-64.4775,3.7935],[-64.3675,3.76],[-64.281,3.7095],[-64.2675,3.6685],[-64.201,3.605],[-64.172,3.559],[-64.1755,3.515],[-64.2425,3.4355],[-64.222,3.3875],[-64.2285,3.3155],[-64.198,3.201],[-64.2255,3.1365],[-64.1695,3.072],[-64.124,2.9905],[-64.0715,2.9215],[-64.0405,2.829],[-63.9825,2.715],[-63.9905,2.6365],[-64.057,2.5065],[-64.0305,2.481],[-63.931,2.4555],[-63.8425,2.491],[-63.7725,2.4415],[-63.703,2.4535],[-63.6555,2.4365],[-63.5925,2.4475],[-63.523,2.417],[-63.4385,2.436],[-63.3795,2.4195],[-63.3635,2.376],[-63.384,2.352],[-63.3675,2.2685],[-63.401,2.1505],[-63.511,2.1115],[-63.564,2.134],[-63.6355,2.099],[-63.664,2.065],[-63.7115,2.0465],[-63.741,2.0035],[-63.8355,1.9665],[-63.893,1.9895],[-63.972,1.992],[-64.061,1.925],[-64.067,1.8535],[-64.0545,1.803],[-64.076,1.782],[-64.061,1.7025],[-64.077,1.645],[-64.1315,1.576],[-64.173,1.5735],[-64.1965,1.5215],[-64.2435,1.507],[-64.3135,1.456],[-64.3435,1.382],[-64.41,1.403],[-64.348,1.495],[-64.3945,1.5285],[-64.436,1.47],[-64.4665,1.4735],[-64.537,1.4155],[-64.581,1.3595],[-64.6455,1.3005],[-64.6955,1.284],[-64.721,1.2395],[-64.756,1.228],[-64.8025,1.314],[-64.8555,1.266],[-64.8955,1.251],[-64.9715,1.18],[-65.0105,1.1115],[-65.1055,1.156],[-65.1515,1.109],[-65.1755,1.0155],[-65.1755,0.941],[-65.265,0.9205],[-65.3255,0.936],[-65.356,0.865],[-65.396,0.822],[-65.3965,0.7775],[-65.445,0.689],[-65.556,0.654],[-65.6045,0.715],[-65.502,0.849],[-65.512,0.896],[-65.5575,0.9915],[-65.627,1.0145],[-65.743,1.001],[-65.788,0.965],[-65.888,0.91],[-65.941,0.891],[-65.9435,0.8635],[-66.0145,0.804],[-66.07,0.8125],[-66.077,0.762],[-66.1455,0.7475],[-66.1975,0.7815],[-66.3105,0.745],[-66.598,1.0],[-66.851,1.229],[-67.087,1.167],[-67.0995,1.2585],[-67.135,1.3],[-67.134,1.344],[-67.083,1.373],[-67.0855,1.4635],[-67.128,1.543],[-67.1275,1.64],[-67.155,1.665],[-67.16,1.735],[-67.146,1.762],[-67.154,1.8315],[-67.2285,1.8415],[-67.3085,1.9085],[-67.346,1.974],[-67.351,2.012],[-67.3255,2.0545],[-67.358,2.0965],[-67.351,2.16],[-67.3735,2.217],[-67.4405,2.2155],[-67.449,2.1695],[-67.497,2.161],[-67.551,2.0475],[-67.6215,2.0275],[-67.729,2.029],[-67.762,2.014],[-67.835,1.947],[-67.8365,1.9025],[-67.889,1.8645],[-67.9015,1.8115],[-67.9435,1.843],[-67.9885,1.849],[-68.0335,1.891],[-68.096,1.903],[-68.1495,1.9825],[-68.1845,1.986],[-68.245,1.9195],[-68.2855,1.836],[-68.2375,1.8215],[-68.2445,1.7835],[-68.178,1.7675],[-68.1865,1.73],[-68.735,1.731],[-69.391,1.7295],[-69.4825,1.751],[-69.534,1.7765],[-69.655,1.7175],[-69.7445,1.7295],[-69.809,1.695],[-69.843,1.715],[-69.8425,1.0725],[-69.816,1.063],[-69.746,1.1135],[-69.7015,1.1175],[-69.703,1.075],[-69.61,1.0985],[-69.5735,1.073],[-69.4875,1.079],[-69.3825,1.0735],[-69.321,1.0885],[-69.2585,1.054],[-69.1975,0.998],[-69.207,0.965],[-69.1815,0.9025],[-69.149,0.7675],[-69.19,0.7405],[-69.118,0.6555],[-69.1945,0.65],[-69.213,0.61],[-69.2705,0.602],[-69.298,0.649],[-69.349,0.618],[-69.415,0.688],[-69.483,0.733],[-69.6335,0.6365],[-69.6875,0.664],[-69.8095,0.5765],[-69.9155,0.5795],[-69.935,0.553],[-70.047,0.563],[-70.047,0.26],[-70.043,0.069],[-70.043,-0.19],[-69.888,-0.3415],[-69.8435,-0.3385],[-69.7735,-0.3915],[-69.736,-0.4375],[-69.6675,-0.4655],[-69.6085,-0.5045],[-69.591,-0.561],[-69.6015,-0.5965],[-69.563,-0.6405],[-69.622,-0.733],[-69.574,-0.81],[-69.573,-0.8385],[-69.5265,-0.8675],[-69.5295,-0.9175],[-69.4725,-0.9575],[-69.4425,-1.034],[-69.397,-1.1145],[-69.43,-1.235],[-69.407,-1.29],[-69.3975,-1.365],[-69.436,-1.402],[-69.4325,-1.454],[-69.4565,-1.491],[-69.4505,-1.53],[-69.535,-2.003],[-69.613,-2.44],[-69.714,-3.0025],[-69.836,-3.686],[-69.9335,-4.2195],[-69.948,-4.2315],[-69.952,-4.311],[-70.04,-4.348],[-70.126,-4.2865],[-70.202,-4.3555],[-70.211,-4.3175],[-70.256,-4.31],[-70.284,-4.272],[-70.2875,-4.1655],[-70.3295,-4.1445],[-70.43,-4.131],[-70.467,-4.1765],[-70.523,-4.1375],[-70.5845,-4.1855],[-70.6355,-4.172],[-70.672,-4.1955],[-70.7265,-4.185],[-70.7475,-4.161],[-70.8025,-4.1845],[-70.8365,-4.2555],[-70.878,-4.2935],[-70.9335,-4.3795],[-71.017,-4.383],[-71.038,-4.402],[-71.085,-4.373],[-71.107,-4.401],[-71.145,-4.3815],[-71.2615,-4.3995],[-71.264,-4.4305],[-71.34,-4.443],[-71.3795,-4.425],[-71.422,-4.4685],[-71.537,-4.4635],[-71.566,-4.5045],[-71.6195,-4.528],[-71.6445,-4.5015],[-71.708,-4.511],[-71.784,-4.4835],[-71.887,-4.53],[-71.9865,-4.6135],[-72.059,-4.6495],[-72.102,-4.706],[-72.208,-4.7465],[-72.2295,-4.7755],[-72.31,-4.7745],[-72.3265,-4.8015],[-72.3825,-4.8315],[-72.388,-4.8655],[-72.429,-4.9085],[-72.4855,-4.935],[-72.5205,-4.933],[-72.5995,-4.9875],[-72.607,-5.028],[-72.6595,-5.063],[-72.7085,-5.049],[-72.822,-5.1405],[-72.887,-5.1615],[-72.864,-5.2345],[-72.867,-5.29],[-72.8955,-5.325],[-72.9245,-5.408],[-72.958,-5.4645],[-72.9495,-5.5475],[-72.9735,-5.6135],[-72.959,-5.6565],[-73.0575,-5.7965],[-73.152,-5.868],[-73.1855,-5.95],[-73.1935,-6.0055],[-73.2375,-6.043],[-73.25,-6.133],[-73.221,-6.177],[-73.1865,-6.2625],[-73.1605,-6.2765],[-73.1565,-6.327],[-73.1115,-6.447],[-73.171,-6.518],[-73.1995,-6.5695],[-73.2315,-6.5855],[-73.3525,-6.5935],[-73.392,-6.6415],[-73.521,-6.676],[-73.5615,-6.7215],[-73.6035,-6.732],[-73.7105,-6.84],[-73.724,-6.8875],[-73.7615,-6.94],[-73.762,-7.0625],[-73.7985,-7.113],[-73.7165,-7.2275],[-73.695,-7.299],[-73.7225,-7.341],[-73.8185,-7.338],[-73.8615,-7.388],[-73.9235,-7.362],[-73.9175,-7.5005],[-73.9585,-7.5645],[-73.8895,-7.603],[-73.9,-7.639],[-73.869,-7.674],[-73.8375,-7.6705],[-73.8035,-7.714],[-73.714,-7.743],[-73.6765,-7.8],[-73.678,-7.858],[-73.7355,-7.879],[-73.767,-7.9105],[-73.7455,-7.9495],[-73.706,-7.962],[-73.669,-8.0125],[-73.6405,-8.0065],[-73.585,-8.127],[-73.5955,-8.166],[-73.563,-8.2455],[-73.526,-8.2745],[-73.543,-8.3475],[-73.4415,-8.4255],[-73.408,-8.4305],[-73.373,-8.472],[-73.331,-8.476],[-73.344,-8.6025],[-73.3195,-8.6105],[-73.251,-8.6905],[-73.167,-8.6985],[-73.1145,-8.7855],[-73.112,-8.8195],[-73.037,-8.916],[-73.0015,-8.917],[-72.948,-9.029],[-72.94,-9.093],[-72.9635,-9.144],[-73.0195,-9.1855],[-73.034,-9.234],[-73.064,-9.2275],[-73.156,-9.3565],[-73.189,-9.363],[-73.2005,-9.4115],[-72.717,-9.4125],[-72.6975,-9.436],[-72.6425,-9.4435],[-72.5305,-9.4825],[-72.407,-9.4775],[-72.341,-9.5065],[-72.318,-9.544],[-72.2815,-9.5425],[-72.2885,-9.603],[-72.246,-9.6575],[-72.259,-9.712],[-72.215,-9.779],[-72.1515,-9.7975],[-72.162,-9.831],[-72.1505,-9.9055],[-72.174,-9.93],[-72.1615,-9.9805],[-72.181,-10.0005],[-71.8225,-10.0005],[-71.378,-10.0005],[-71.3425,-9.967],[-71.2975,-9.9925],[-71.192,-9.9405],[-71.1575,-9.8725],[-71.051,-9.816],[-70.9985,-9.818],[-70.974,-9.7605],[-70.9245,-9.7415],[-70.868,-9.665],[-70.799,-9.642],[-70.75,-9.5695],[-70.6735,-9.5295],[-70.5845,-9.443],[-70.5055,-9.422],[-70.4945,-9.4405],[-70.5415,-9.538],[-70.5915,-9.5485],[-70.598,-9.6075],[-70.551,-9.67],[-70.528,-9.726],[-70.5365,-9.766],[-70.6125,-9.8055],[-70.613,-10.162],[-70.6135,-10.608],[-70.614,-10.9965],[-70.5305,-10.9345],[-70.4375,-11.0265],[-70.3765,-11.06],[-70.3085,-11.071],[-70.256,-11.0505],[-70.171,-11.043],[-70.092,-10.9855],[-70.067,-10.9945],[-69.901,-10.92],[-69.7885,-10.9295],[-69.7395,-10.964],[-69.572,-10.9455],[-69.522,-10.936],[-69.479,-10.955],[-69.401,-10.9305],[-69.2915,-10.95],[-69.2325,-10.94],[-69.148,-10.972],[-69.0715,-10.967],[-68.9975,-11.0025],[-68.9685,-10.9875],[-68.9125,-11.0215],[-68.8345,-10.993],[-68.748,-11.009],[-68.7655,-11.0665],[-68.73,-11.0985],[-68.7155,-11.1475],[-68.5905,-11.1155],[-68.4835,-11.0775],[-68.429,-11.036],[-68.2765,-10.99],[-68.236,-10.9605],[-68.196,-10.8605],[-68.1255,-10.7985],[-68.0975,-10.7485],[-68.105,-10.715],[-68.015,-10.649],[-67.977,-10.662],[-67.866,-10.6405],[-67.8275,-10.6515],[-67.73,-10.7135],[-67.7075,-10.71],[-67.6755,-10.605],[-67.612,-10.5635],[-67.579,-10.503],[-67.451,-10.4585],[-67.4135,-10.427],[-67.4195,-10.388],[-67.318,-10.3665],[-67.3165,-10.32],[-67.2625,-10.331],[-67.232,-10.315],[-67.17,-10.3375],[-67.125,-10.2905],[-67.079,-10.2895],[-67.016,-10.2585],[-66.9825,-10.1965],[-66.898,-10.111],[-66.8435,-10.087],[-66.8335,-10.061],[-66.7285,-9.98],[-66.6365,-9.943],[-66.62,-9.8935],[-66.4885,-9.868],[-66.3585,-9.864],[-66.312,-9.831],[-66.284,-9.844],[-66.2375,-9.8135],[-66.212,-9.835],[-66.173,-9.7925],[-66.0385,-9.785],[-65.984,-9.8045],[-65.975,-9.7765],[-65.886,-9.752],[-65.855,-9.7955],[-65.8205,-9.7675],[-65.7845,-9.7875],[-65.727,-9.7585],[-65.6695,-9.7815],[-65.627,-9.838],[-65.5125,-9.7935],[-65.5015,-9.7305],[-65.442,-9.6905],[-65.393,-9.687],[-65.355,-9.7225],[-65.2885,-9.869],[-65.331,-9.929],[-65.32,-10.001],[-65.329,-10.046],[-65.301,-10.098],[-65.306,-10.165],[-65.2885,-10.2145],[-65.324,-10.301],[-65.3905,-10.371],[-65.381,-10.429],[-65.4295,-10.4795],[-65.399,-10.5815],[-65.4055,-10.6395],[-65.354,-10.6615],[-65.343,-10.7675],[-65.363,-10.801],[-65.321,-10.8225],[-65.275,-10.873],[-65.2705,-10.96],[-65.2515,-10.99],[-65.2985,-11.026],[-65.287,-11.094],[-65.353,-11.124],[-65.3585,-11.2685],[-65.339,-11.311],[-65.3085,-11.496],[-65.224,-11.516],[-65.234,-11.605],[-65.22,-11.6635],[-65.2585,-11.697],[-65.221,-11.7415],[-65.1845,-11.721],[-65.099,-11.703],[-65.064,-11.7715],[-65.0725,-11.857],[-65.0275,-11.892],[-65.035,-11.9945],[-64.9805,-12.0175],[-64.944,-11.995],[-64.9175,-12.0265],[-64.832,-12.016],[-64.8035,-12.0865],[-64.7605,-12.0945],[-64.7405,-12.1445],[-64.693,-12.1895],[-64.5605,-12.2365],[-64.509,-12.2285],[-64.4955,-12.2675],[-64.5035,-12.3655],[-64.4555,-12.3865],[-64.428,-12.432],[-64.3625,-12.4605],[-64.2995,-12.4565],[-64.277,-12.4985],[-64.228,-12.4545],[-64.1725,-12.47],[-64.174,-12.503],[-64.0555,-12.4935],[-64.0365,-12.517],[-63.99,-12.503],[-63.9455,-12.528],[-63.901,-12.503],[-63.8765,-12.445],[-63.831,-12.461],[-63.7835,-12.428],[-63.623,-12.4725],[-63.559,-12.504],[-63.507,-12.5645],[-63.436,-12.5665],[-63.3885,-12.6495],[-63.297,-12.6825],[-63.24,-12.6905],[-63.1825,-12.6275],[-63.09,-12.638],[-63.084,-12.7165],[-63.0465,-12.741],[-62.9705,-12.8595],[-62.9215,-12.84],[-62.8745,-12.905],[-62.8045,-12.943],[-62.7965,-12.993],[-62.7005,-13.002],[-62.6615,-12.9685],[-62.631,-12.99],[-62.6145,-13.038],[-62.539,-13.074],[-62.459,-13.077],[-62.394,-13.1335],[-62.2645,-13.147],[-62.2155,-13.1105],[-62.1985,-13.152],[-62.1215,-13.151],[-62.115,-13.256],[-62.017,-13.35],[-61.976,-13.367],[-61.926,-13.4285],[-61.8885,-13.441],[-61.869,-13.526],[-61.7865,-13.5375],[-61.6645,-13.503],[-61.578,-13.5115],[-61.4665,-13.554],[-61.331,-13.5035],[-61.2545,-13.4965],[-61.2345,-13.5255],[-61.149,-13.532],[-61.086,-13.492],[-61.0425,-13.5085],[-61.009,-13.5495],[-60.927,-13.5395],[-60.877,-13.62],[-60.832,-13.627],[-60.771,-13.6795],[-60.687,-13.7005],[-60.654,-13.7355],[-60.6245,-13.719],[-60.569,-13.7685],[-60.5205,-13.77],[-60.453,-13.881],[-60.4505,-13.927],[-60.4185,-13.9375],[-60.4045,-13.9985],[-60.4475,-14.0845],[-60.4845,-14.1145],[-60.4545,-14.3135],[-60.3945,-14.369],[-60.407,-14.4015],[-60.379,-14.4645],[-60.34,-14.51],[-60.323,-14.6105],[-60.2735,-14.621],[-60.245,-15.0975],[-60.575,-15.0975],[-60.239,-15.475],[-60.203,-15.885],[-60.174,-16.2665],[-59.47,-16.279],[-58.785,-16.306],[-58.431,-16.3225],[-58.3665,-16.2745],[-58.3295,-16.272],[-58.3035,-16.31],[-58.308,-16.3715],[-58.344,-16.389],[-58.356,-16.428],[-58.334,-16.478],[-58.343,-16.517],[-58.436,-16.592],[-58.47,-16.703],[-58.476,-16.827],[-58.461,-16.841],[-58.462,-16.958],[-58.431,-16.99],[-58.425,-17.112],[-58.398,-17.104],[-58.396,-17.181],[-58.356,-17.212],[-58.317,-17.268],[-58.276,-17.3],[-58.254,-17.352],[-58.202,-17.357],[-58.151,-17.384],[-58.116,-17.451],[-58.06,-17.45],[-58.043,-17.492],[-57.98,-17.51],[-57.883,-17.449],[-57.746,-17.551],[-57.791,-17.5865],[-57.685,-17.8105],[-57.723,-17.8305],[-57.6,-18.046],[-57.574,-18.131],[-57.505,-18.2005],[-57.557,-18.24],[-57.766,-18.899],[-57.719,-18.899],[-57.71,-19.0345],[-57.784,-19.033],[-57.9875,-19.46],[-58.131,-19.758],[-57.858,-19.9705],[-57.905,-20.043],[-57.961,-20.0245],[-57.9795,-20.057],[-58.0215,-20.0585],[-58.055,-20.109],[-58.1695,-20.167],[-58.128,-20.183],[-58.166,-20.231],[-58.1435,-20.272],[-58.0915,-20.26],[-58.1025,-20.3225],[-58.075,-20.3865],[-58.022,-20.4005],[-57.9965,-20.448],[-58.016,-20.527],[-57.995,-20.5615],[-58.0135,-20.6055],[-57.9705,-20.6425],[-57.988,-20.6845],[-57.9515,-20.702],[-57.9155,-20.6685],[-57.87,-20.7255],[-57.935,-20.7455],[-57.856,-20.848],[-57.927,-20.893],[-57.8815,-20.914],[-57.8165,-20.9795],[-57.867,-21.04],[-57.8465,-21.098],[-57.8645,-21.14],[-57.8515,-21.2245],[-57.92,-21.2765],[-57.8525,-21.32],[-57.9095,-21.4065],[-57.9275,-21.4705],[-57.9685,-21.529],[-57.9205,-21.581],[-57.941,-21.6355],[-57.896,-21.7045],[-57.946,-21.741],[-57.9085,-21.773],[-57.93,-21.823],[-57.9165,-21.8765],[-57.974,-22.0155],[-58.009,-22.0395],[-57.93,-22.119],[-57.8005,-22.1505],[-57.733,-22.0995],[-57.6895,-22.0885],[-57.637,-22.106],[-57.5865,-22.145],[-57.5805,-22.1755],[-57.5205,-22.1695],[-57.4835,-22.1925],[-57.389,-22.205],[-57.362,-22.234],[-57.304,-22.224],[-57.237,-22.251],[-57.1785,-22.233],[-57.0605,-22.2305],[-56.946,-22.256],[-56.8835,-22.2475],[-56.8445,-22.3005],[-56.7445,-22.241],[-56.7055,-22.2365],[-56.638,-22.258],[-56.61,-22.223],[-56.5565,-22.195],[-56.517,-22.108],[-56.4715,-22.08],[-56.419,-22.0795],[-56.368,-22.137],[-56.3575,-22.176],[-56.316,-22.218],[-56.243,-22.2355],[-56.2135,-22.2755],[-56.1235,-22.2715],[-55.9695,-22.292],[-55.853,-22.2805],[-55.7895,-22.3845],[-55.749,-22.3835],[-55.735,-22.459],[-55.753,-22.4755],[-55.7235,-22.552],[-55.6255,-22.628],[-55.6135,-22.694],[-55.62,-22.765],[-55.651,-22.7925],[-55.6655,-22.852],[-55.634,-22.992],[-55.596,-23.1195],[-55.542,-23.156],[-55.5235,-23.1985],[-55.542,-23.227],[-55.556,-23.3165],[-55.5045,-23.379],[-55.5445,-23.4485],[-55.5465,-23.5225],[-55.527,-23.5675],[-55.5305,-23.628],[-55.475,-23.6505],[-55.464,-23.712],[-55.43,-23.79],[-55.4465,-23.917],[-55.4195,-23.9575],[-55.336,-23.993],[-55.3175,-23.963],[-55.229,-24.014],[-55.1295,-23.984],[-55.0625,-23.993],[-54.999,-23.9575],[-54.9275,-23.9615],[-54.927,-23.9245],[-54.8595,-23.905],[-54.7935,-23.868],[-54.7055,-23.8645],[-54.6685,-23.8175],[-54.589,-23.839],[-54.515,-23.885],[-54.44,-23.9045],[-54.415,-23.958],[-54.325,-24.021],[-54.282,-24.0735],[-54.3455,-24.147],[-54.3155,-24.258],[-54.277,-24.2965],[-54.2605,-24.3705],[-54.3215,-24.4545],[-54.336,-24.515],[-54.3175,-24.5815],[-54.3245,-24.6605],[-54.3955,-24.803],[-54.4355,-24.9475],[-54.4555,-25.0975],[-54.4275,-25.1505],[-54.499,-25.313],[-54.5835,-25.3955],[-54.6185,-25.4515],[-54.602,-25.4855],[-54.5935,-25.593],[-54.5545,-25.5875],[-54.4255,-25.663],[-54.3745,-25.594],[-54.28,-25.556],[-54.255,-25.596],[-54.1905,-25.5345],[-54.166,-25.543],[-54.1045,-25.4945],[-54.0835,-25.561],[-54.0285,-25.566],[-53.862,-25.659],[-53.8645,-25.7455],[-53.8225,-25.793],[-53.849,-25.835],[-53.825,-25.871],[-53.8425,-25.9325],[-53.772,-26.0315],[-53.7355,-26.042],[-53.742,-26.1155],[-53.711,-26.1305],[-53.6435,-26.2165],[-53.646,-26.2865],[-53.6855,-26.335],[-53.7075,-26.3955],[-53.689,-26.4435],[-53.698,-26.4865],[-53.731,-26.5095],[-53.7225,-26.5815],[-53.742,-26.648],[-53.717,-26.6815],[-53.749,-26.7415],[-53.7145,-26.7535],[-53.682,-26.9165],[-53.726,-26.9585],[-53.718,-26.9845],[-53.7665,-27.044],[-53.7965,-27.0395],[-53.806,-27.1125],[-53.8455,-27.161],[-53.9,-27.173],[-53.959,-27.158],[-54.0055,-27.197],[-54.021,-27.2485],[-54.08,-27.2985],[-54.1585,-27.2935],[-54.192,-27.3075],[-54.2175,-27.386],[-54.3085,-27.423],[-54.3535,-27.4665],[-54.3965,-27.4125],[-54.4645,-27.424],[-54.4495,-27.476],[-54.52,-27.5025],[-54.5715,-27.4545],[-54.614,-27.5315],[-54.689,-27.574],[-54.742,-27.561],[-54.786,-27.576],[-54.814,-27.533],[-54.858,-27.629],[-54.907,-27.6465],[-54.903,-27.721],[-54.9345,-27.769],[-55.043,-27.775],[-55.0325,-27.825],[-55.1255,-27.859],[-55.197,-27.857],[-55.269,-27.931],[-55.31,-27.9215],[-55.3365,-27.9615],[-55.385,-27.985],[-55.3815,-28.0395],[-55.4475,-28.099],[-55.4835,-28.0775],[-55.536,-28.119],[-55.552,-28.1605],[-55.6115,-28.1185],[-55.635,-28.1785],[-55.7,-28.222],[-55.769,-28.2405],[-55.776,-28.271],[-55.67,-28.331],[-55.6915,-28.4175],[-55.739,-28.3765],[-55.8515,-28.355],[-55.9025,-28.412],[-55.881,-28.4695],[-55.986,-28.4975],[-56.022,-28.52],[-56.002,-28.596],[-56.1185,-28.6815],[-56.192,-28.7735],[-56.259,-28.7785],[-56.301,-28.8155],[-56.302,-28.901],[-56.3905,-28.955],[-56.3985,-29.021],[-56.4255,-29.082],[-56.5005,-29.0925],[-56.5915,-29.124],[-56.644,-29.196],[-56.648,-29.2585],[-56.7015,-29.359],[-56.766,-29.3775],[-56.7805,-29.439],[-56.819,-29.488],[-56.899,-29.532],[-56.97,-29.604],[-56.9665,-29.6295],[-57.033,-29.696],[-57.121,-29.765],[-57.242,-29.788],[-57.326,-29.876],[-57.328,-29.972],[-57.3625,-30.013],[-57.414,-30.037],[-57.4805,-30.123],[-57.584,-30.177],[-57.649,-30.194],[-57.5665,-30.2075],[-57.5495,-30.2735],[-57.4185,-30.2775],[-57.3975,-30.3045],[-57.31,-30.259],[-57.291,-30.289],[-57.2035,-30.2855],[-57.167,-30.248],[-57.168,-30.198],[-57.115,-30.1135],[-56.994,-30.086],[-56.906,-30.1075],[-56.8505,-30.089],[-56.781,-30.126],[-56.7845,-30.1505],[-56.6625,-30.1975],[-56.6055,-30.2925],[-56.5375,-30.3355],[-56.49,-30.3985],[-56.3995,-30.447],[-56.384,-30.4975],[-56.1885,-30.6045],[-56.146,-30.706],[-56.062,-30.7745],[-56.023,-30.7855],[-55.9895,-30.8585],[-56.008,-30.8945],[-56.019,-31.0435],[-56.008,-31.0705],[-55.933,-31.087],[-55.8715,-31.071],[-55.8135,-31.0155],[-55.7805,-31.017],[-55.6485,-30.923],[-55.661,-30.8695],[-55.582,-30.834],[-55.5455,-30.8905],[-55.51,-30.902],[-55.4805,-30.9525],[-55.4415,-30.9595],[-55.4375,-31.0045],[-55.3715,-31.0235],[-55.3055,-31.141],[-55.25,-31.206],[-55.2465,-31.2525],[-55.1835,-31.2655],[-55.0745,-31.332],[-55.0025,-31.2695],[-54.9385,-31.354],[-54.858,-31.408],[-54.8365,-31.442],[-54.755,-31.4245],[-54.6705,-31.454],[-54.5865,-31.4565],[-54.5155,-31.5105],[-54.4745,-31.5695],[-54.4565,-31.6515],[-54.081,-31.9295],[-54.0315,-31.896],[-53.9725,-31.9395],[-53.8495,-32.001],[-53.8065,-32.07],[-53.746,-32.0785],[-53.711,-32.1995],[-53.685,-32.2195],[-53.6335,-32.3505],[-53.644,-32.385],[-53.5565,-32.4725],[-53.471,-32.4805],[-53.433,-32.5575],[-53.3715,-32.5695],[-53.2795,-32.6195],[-53.1935,-32.6415],[-53.0755,-32.741],[-53.086,-32.7885],[-53.1385,-32.7895],[-53.185,-32.8505],[-53.2945,-32.8995],[-53.2445,-32.9345],[-53.4445,-33.053],[-53.518,-33.1535],[-53.5215,-33.265],[-53.508,-33.353],[-53.511,-33.4595],[-53.5255,-33.5265],[-53.5325,-33.689],[-53.4395,-33.6935],[-53.4305,-33.739],[-53.3715,-33.743],[-53.181,-33.869]]],[[[-34.018,-3.85],[-34.0065,-3.918],[-33.959,-3.992],[-33.892,-4.0365],[-33.8165,-4.051],[-33.7295,-4.0315],[-33.6665,-3.984],[-33.6275,-3.9185],[-33.615,-3.85],[-33.6325,-3.7685],[-33.687,-3.6955],[-33.75,-3.66],[-33.8165,-3.649],[-33.8935,-3.664],[-33.96,-3.709],[-34.0005,-3.7665],[-34.018,-3.85]]],[[[-32.6405,-3.797],[-32.6365,-3.8885],[-32.5935,-3.9695],[-32.519,-4.0235],[-32.429,-4.04],[-32.3405,-4.016],[-32.271,-3.956],[-32.2345,-3.872],[-32.238,-3.7805],[-32.2815,-3.6995],[-32.3555,-3.6455],[-32.4455,-3.6285],[-32.5345,-3.6525],[-32.604,-3.7125],[-32.6405,-3.797]]],[[[-29.5585,-20.502],[-29.5335,-20.5985],[-29.4925,-20.653],[-29.407,-20.7115],[-29.3295,-20.728],[-29.2,-20.7035],[-29.15,-20.669],[-29.0975,-20.5925],[-29.0825,-20.527],[-29.099,-20.437],[-29.175,-20.346],[-29.249,-20.301],[-29.3175,-20.2845],[-29.4325,-20.305],[-29.508,-20.362],[-29.5485,-20.436],[-29.5585,-20.502]]],[[[-29.5475,0.9255],[-29.541,0.869],[-29.503,0.794],[-29.4355,0.7395],[-29.3635,0.719],[-29.2945,0.725],[-29.249,0.7435],[-29.172,0.8195],[-29.145,0.926],[-29.163,1.003],[-29.2215,1.0775],[-29.2925,1.114],[-29.359,1.1205],[-29.4315,1.102],[-29.4895,1.0615],[-29.5475,0.9255]]],[[[-29.064,-20.466],[-29.0385,-20.5795],[-28.965,-20.662],[-28.8835,-20.6935],[-28.804,-20.694],[-28.7375,-20.671],[-28.6565,-20.595],[-28.629,-20.4995],[-28.6385,-20.4165],[-28.66,-20.371],[-28.741,-20.295],[-28.8105,-20.2705],[-28.881,-20.269],[-28.985,-20.3125],[-29.0445,-20.385],[-29.064,-20.466]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/05/Flag_of_Brazil.svg","name:en":"Brazil","wikidata":"Q155","ISO3166-1:alpha2":"BR","ISO3166-1:alpha3":"BRA","ISO3166-1:numeric":"076"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-81.6315,19.384],[-81.622,19.314],[-81.5735,19.1675],[-81.5105,19.1],[-81.4515,19.072],[-81.3905,19.062],[-81.227,19.0675],[-81.1565,19.093],[-81.0955,19.0935],[-81.0145,19.1165],[-80.962,19.148],[-80.913,19.2],[-80.8805,19.2715],[-80.8755,19.3655],[-80.8945,19.428],[-80.967,19.512],[-81.04,19.5465],[-81.176,19.552],[-81.3635,19.5965],[-81.449,19.589],[-81.5615,19.5305],[-81.602,19.4805],[-81.6315,19.384]]],[[[-80.3225,19.656],[-80.31,19.592],[-80.2795,19.5385],[-80.196,19.4755],[-80.1525,19.462],[-80.0655,19.4585],[-79.9545,19.491],[-79.896,19.482],[-79.804,19.4935],[-79.6425,19.5505],[-79.571,19.6065],[-79.523,19.683],[-79.511,19.7425],[-79.521,19.813],[-79.574,19.895],[-79.61,19.922],[-79.7,19.9545],[-79.81,19.948],[-79.9125,19.905],[-80.0165,19.9105],[-80.1555,19.8755],[-80.217,19.84],[-80.2765,19.787],[-80.312,19.724],[-80.3225,19.656]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/0f/Flag_of_the_Cayman_Islands.svg","name:en":"Cayman Islands","wikidata":"Q5785","ISO3166-1:alpha2":"KY","ISO3166-1:alpha3":"CYM","ISO3166-1:numeric":"136"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-178.3875,-14.257],[-178.3725,-14.3375],[-178.3445,-14.394],[-178.301,-14.4465],[-178.166,-14.5275],[-178.094,-14.5565],[-178.043,-14.563],[-177.953,-14.5435],[-177.842,-14.464],[-177.8035,-14.3925],[-177.799,-14.2975],[-177.8195,-14.2415],[-177.883,-14.171],[-178.058,-14.069],[-178.1515,-14.0415],[-178.2625,-14.058],[-178.3265,-14.1025],[-178.3795,-14.195],[-178.3875,-14.257]]],[[[-176.4555,-13.293],[-176.4435,-13.374],[-176.397,-13.482],[-176.3405,-13.549],[-176.257,-13.587],[-176.141,-13.5875],[-176.049,-13.551],[-176.0005,-13.5025],[-175.9235,-13.3305],[-175.92,-13.271],[-175.961,-13.1565],[-176.0335,-13.0605],[-176.128,-12.9955],[-176.247,-12.987],[-176.3245,-13.021],[-176.39,-13.098],[-176.444,-13.2235],[-176.4555,-13.293]]],[[[-154.936,-21.8145],[-154.919,-21.892],[-154.8755,-21.953],[-154.7765,-22.0095],[-154.7215,-22.022],[-154.6345,-22.0145],[-154.5765,-21.988],[-154.5215,-21.937],[-154.4815,-21.847],[-154.483,-21.761],[-154.502,-21.712],[-154.5455,-21.6565],[-154.6435,-21.603],[-154.714,-21.596],[-154.79,-21.614],[-154.8805,-21.6795],[-154.919,-21.7355],[-154.936,-21.8145]]],[[[-154.935,-16.521],[-154.924,-16.634],[-154.8585,-16.735],[-154.753,-16.7865],[-154.6335,-16.7895],[-154.5335,-16.762],[-154.4545,-16.69],[-154.4195,-16.6235],[-154.41,-16.542],[-154.428,-16.471],[-154.47,-16.395],[-154.5295,-16.337],[-154.5945,-16.3015],[-154.672,-16.281],[-154.744,-16.2875],[-154.8545,-16.3495],[-154.915,-16.433],[-154.935,-16.521]]],[[[-154.7515,-15.816],[-154.7395,-15.889],[-154.6965,-15.9595],[-154.616,-16.014],[-154.5255,-16.033],[-154.432,-16.0135],[-154.3675,-15.969],[-154.33,-15.9215],[-154.3045,-15.861],[-154.305,-15.761],[-154.3405,-15.689],[-154.411,-15.624],[-154.4825,-15.5995],[-154.591,-15.607],[-154.6615,-15.644],[-154.7295,-15.7265],[-154.7515,-15.816]]],[[[-154.201,-16.804],[-154.1915,-16.8695],[-154.166,-16.92],[-154.1085,-16.992],[-154.0635,-17.025],[-153.959,-17.0515],[-153.8565,-17.032],[-153.794,-16.999],[-153.7305,-16.9195],[-153.712,-16.859],[-153.7125,-16.7935],[-153.7535,-16.6885],[-153.826,-16.609],[-153.9105,-16.574],[-154.019,-16.579],[-154.0785,-16.6045],[-154.1375,-16.658],[-154.191,-16.7455],[-154.201,-16.804]]],[[[-153.0385,-22.645],[-153.0295,-22.7085],[-152.995,-22.774],[-152.955,-22.8125],[-152.8845,-22.852],[-152.7815,-22.8645],[-152.695,-22.839],[-152.6105,-22.765],[-152.574,-22.6575],[-152.581,-22.594],[-152.6185,-22.52],[-152.6655,-22.476],[-152.7675,-22.4375],[-152.828,-22.436],[-152.9135,-22.4595],[-152.999,-22.5305],[-153.0335,-22.6035],[-153.0385,-22.645]]],[[[-152.5045,-16.4505],[-152.498,-16.508],[-152.463,-16.581],[-152.4275,-16.6175],[-152.3535,-16.662],[-152.261,-16.686],[-152.2055,-16.684],[-152.1285,-16.655],[-152.066,-16.596],[-152.0355,-16.5305],[-152.0225,-16.427],[-152.041,-16.352],[-152.109,-16.267],[-152.1765,-16.228],[-152.226,-16.216],[-152.3035,-16.22],[-152.3705,-16.24],[-152.434,-16.282],[-152.489,-16.37],[-152.5045,-16.4505]]],[[[-152.0475,-16.247],[-152.0205,-16.3615],[-151.988,-16.419],[-151.9955,-16.581],[-151.968,-16.6515],[-151.926,-16.7],[-151.8145,-16.7515],[-151.7505,-16.7575],[-151.712,-16.801],[-151.6955,-16.944],[-151.68,-16.9915],[-151.6255,-17.068],[-151.525,-17.1235],[-151.4635,-17.133],[-151.38,-17.1235],[-151.318,-17.099],[-151.2065,-17.027],[-151.1495,-16.9505],[-151.0755,-17.0025],[-150.9675,-17.0215],[-150.8845,-17.0015],[-150.802,-16.9345],[-150.7425,-16.8165],[-150.7385,-16.753],[-150.754,-16.6945],[-150.809,-16.582],[-150.8645,-16.5265],[-150.918,-16.497],[-151.0195,-16.483],[-151.1215,-16.508],[-151.206,-16.5795],[-151.2315,-16.505],[-151.3095,-16.4135],[-151.374,-16.375],[-151.428,-16.3605],[-151.5275,-16.3535],[-151.5815,-16.3065],[-151.5745,-16.2625],[-151.5865,-16.1875],[-151.6225,-16.126],[-151.718,-16.054],[-151.779,-16.0345],[-151.885,-16.0365],[-151.944,-16.0625],[-152.0255,-16.153],[-152.0475,-16.247]]],[[[-151.5925,-22.453],[-151.574,-22.537],[-151.52,-22.6435],[-151.4715,-22.6875],[-151.396,-22.7195],[-151.301,-22.7215],[-151.2225,-22.692],[-151.166,-22.644],[-151.111,-22.534],[-151.112,-22.415],[-151.1595,-22.325],[-151.232,-22.27],[-151.282,-22.2455],[-151.3655,-22.2305],[-151.466,-22.2525],[-151.548,-22.3185],[-151.5765,-22.367],[-151.5925,-22.453]]],[[[-150.861,-17.66],[-150.845,-17.7415],[-150.814,-17.792],[-150.738,-17.8515],[-150.6805,-17.8745],[-150.596,-17.879],[-150.5335,-17.861],[-150.468,-17.8185],[-150.423,-17.7605],[-150.4,-17.666],[-150.4145,-17.585],[-150.4835,-17.489],[-150.5285,-17.4575],[-150.615,-17.433],[-150.672,-17.436],[-150.7425,-17.462],[-150.7955,-17.506],[-150.852,-17.6045],[-150.861,-17.66]]],[[[-150.1295,-17.4905],[-150.1135,-17.5765],[-150.078,-17.6475],[-149.9865,-17.7385],[-149.8875,-17.787],[-149.781,-17.791],[-149.7205,-17.888],[-149.649,-17.932],[-149.536,-17.9705],[-149.429,-17.9795],[-149.328,-18.048],[-149.2395,-18.073],[-149.148,-18.0805],[-149.091,-18.0695],[-149.002,-18.0185],[-148.9405,-17.9325],[-148.915,-17.809],[-148.929,-17.718],[-148.961,-17.6595],[-149.0245,-17.591],[-149.098,-17.553],[-149.1175,-17.4975],[-149.1845,-17.408],[-149.244,-17.366],[-149.3635,-17.3165],[-149.462,-17.296],[-149.531,-17.2965],[-149.623,-17.3325],[-149.698,-17.2865],[-149.785,-17.273],[-149.935,-17.2865],[-150.0,-17.303],[-150.0755,-17.355],[-150.107,-17.399],[-150.1295,-17.4905]]],[[[-149.805,-17.018],[-149.7955,-17.083],[-149.7535,-17.1555],[-149.6875,-17.207],[-149.6225,-17.2365],[-149.5365,-17.25],[-149.464,-17.2345],[-149.3855,-17.1795],[-149.3495,-17.1215],[-149.3275,-17.031],[-149.331,-16.957],[-149.3525,-16.898],[-149.435,-16.8165],[-149.5105,-16.7895],[-149.628,-16.79],[-149.7045,-16.8255],[-149.746,-16.864],[-149.794,-16.9565],[-149.805,-17.018]]],[[[-149.748,-23.368],[-149.739,-23.427],[-149.702,-23.499],[-149.652,-23.5525],[-149.558,-23.598],[-149.5015,-23.6035],[-149.4,-23.588],[-149.2795,-23.5405],[-149.214,-23.482],[-149.185,-23.4245],[-149.182,-23.321],[-149.2025,-23.2715],[-149.264,-23.194],[-149.3575,-23.145],[-149.45,-23.127],[-149.5675,-23.1475],[-149.6385,-23.19],[-149.714,-23.262],[-149.748,-23.368]]],[[[-148.924,-14.8775],[-148.914,-14.945],[-148.8715,-15.0245],[-148.803,-15.077],[-148.6855,-15.111],[-148.6115,-15.1055],[-148.497,-15.055],[-148.466,-15.1575],[-148.4305,-15.2175],[-148.357,-15.289],[-148.294,-15.318],[-148.241,-15.327],[-148.163,-15.3165],[-148.0815,-15.2825],[-147.9785,-15.366],[-147.871,-15.4015],[-147.8245,-15.4275],[-147.7415,-15.4465],[-147.664,-15.44],[-147.5715,-15.498],[-147.4845,-15.5175],[-147.283,-15.522],[-147.135,-15.4685],[-147.065,-15.423],[-147.0145,-15.5025],[-147.0525,-15.5425],[-147.088,-15.615],[-147.0955,-15.701],[-147.0625,-15.8025],[-147.017,-15.8645],[-146.959,-15.9165],[-146.8705,-15.9675],[-146.77,-16.012],[-146.5835,-16.054],[-146.6055,-16.1415],[-146.5915,-16.221],[-146.5435,-16.3015],[-146.497,-16.347],[-146.4115,-16.3855],[-146.269,-16.38],[-146.196,-16.347],[-146.15,-16.303],[-146.1075,-16.209],[-146.021,-16.2385],[-145.9465,-16.3945],[-145.802,-16.5605],[-145.6265,-16.71],[-145.5655,-16.7385],[-145.527,-16.853],[-145.4345,-16.9445],[-145.2765,-17.0115],[-145.2275,-17.018],[-145.1155,-17.011],[-144.993,-17.0815],[-144.906,-17.104],[-144.8185,-17.155],[-144.707,-17.1925],[-144.6205,-17.197],[-144.5645,-17.2875],[-144.457,-17.3575],[-144.3665,-17.3785],[-144.3065,-17.3745],[-144.2365,-17.3495],[-144.188,-17.313],[-144.1505,-17.2605],[-144.109,-17.1655],[-144.0935,-17.0985],[-144.1,-17.021],[-144.1215,-16.9675],[-143.9865,-16.93],[-143.923,-16.884],[-143.8735,-16.8025],[-143.76,-16.858],[-143.5395,-16.9475],[-143.518,-17.0435],[-143.4575,-17.146],[-143.3925,-17.207],[-143.3125,-17.2555],[-143.2855,-17.302],[-143.2245,-17.357],[-143.1585,-17.394],[-143.0605,-17.413],[-142.9455,-17.3855],[-142.8745,-17.3305],[-142.8435,-17.283],[-142.822,-17.2015],[-142.8285,-17.134],[-142.8555,-17.0675],[-142.8515,-16.959],[-142.7055,-16.9255],[-142.6585,-16.899],[-142.606,-16.8445],[-142.569,-16.746],[-142.5795,-16.653],[-142.653,-16.517],[-142.738,-16.4535],[-142.8035,-16.4315],[-142.802,-16.3585],[-142.823,-16.294],[-142.8605,-16.2425],[-142.9545,-16.173],[-143.1145,-16.0895],[-143.211,-16.0775],[-143.3085,-16.0985],[-143.361,-16.1295],[-143.4145,-16.192],[-143.4355,-16.2465],[-143.4355,-16.33],[-143.405,-16.41],[-143.4625,-16.4045],[-143.5425,-16.416],[-143.6565,-16.3645],[-143.722,-16.296],[-143.7815,-16.2645],[-143.9105,-16.236],[-144.0365,-16.254],[-144.1155,-16.305],[-144.2075,-16.2145],[-144.3195,-16.154],[-144.3725,-16.1405],[-144.457,-16.1425],[-144.568,-16.196],[-144.5845,-16.103],[-144.669,-15.9605],[-144.5785,-15.9585],[-144.4685,-15.9035],[-144.4195,-15.839],[-144.4015,-15.779],[-144.406,-15.7025],[-144.446,-15.6215],[-144.4785,-15.5865],[-144.557,-15.5365],[-144.615,-15.5215],[-144.728,-15.5355],[-144.786,-15.5715],[-144.8335,-15.6315],[-144.859,-15.712],[-144.858,-15.8415],[-144.9265,-15.6865],[-144.966,-15.639],[-145.046,-15.593],[-145.125,-15.575],[-145.2435,-15.571],[-145.2295,-15.507],[-145.2435,-15.422],[-145.304,-15.336],[-145.3875,-15.2925],[-145.5435,-15.2555],[-145.607,-15.261],[-145.6895,-15.2995],[-145.755,-15.3715],[-145.7865,-15.44],[-145.798,-15.5285],[-145.772,-15.649],[-145.739,-15.7],[-145.667,-15.7705],[-145.5815,-15.817],[-145.466,-15.8255],[-145.4575,-15.9255],[-145.521,-15.8745],[-145.564,-15.857],[-145.6845,-15.852],[-145.737,-15.7635],[-145.782,-15.715],[-145.932,-15.6225],[-146.03,-15.599],[-146.0155,-15.4935],[-145.9915,-15.427],[-145.98,-15.3305],[-145.987,-15.2845],[-146.0215,-15.2165],[-146.072,-15.17],[-146.146,-15.1385],[-146.2565,-15.1135],[-146.393,-15.0985],[-146.461,-15.1105],[-146.5745,-15.045],[-146.7585,-15.0015],[-146.834,-14.9975],[-146.9315,-15.0355],[-147.0485,-15.151],[-147.0825,-15.0965],[-147.176,-15.0345],[-147.255,-15.0235],[-147.3725,-14.931],[-147.4335,-14.861],[-147.519,-14.7955],[-147.65,-14.744],[-147.845,-14.716],[-147.9265,-14.731],[-147.9745,-14.757],[-148.034,-14.7295],[-148.124,-14.705],[-148.265,-14.72],[-148.3185,-14.746],[-148.424,-14.835],[-148.4555,-14.7655],[-148.5145,-14.7075],[-148.63,-14.6635],[-148.7015,-14.6555],[-148.7665,-14.666],[-148.8395,-14.7055],[-148.9085,-14.798],[-148.924,-14.8775]],[[-145.4135,-16.013],[-145.2825,-16.128],[-145.218,-16.1615],[-145.1895,-16.2615],[-145.105,-16.3775],[-145.0605,-16.4135],[-144.9645,-16.4645],[-144.9055,-16.481],[-144.8285,-16.484],[-144.7745,-16.472],[-144.6965,-16.428],[-144.6675,-16.431],[-144.647,-16.4915],[-144.603,-16.5585],[-144.537,-16.6225],[-144.454,-16.675],[-144.4675,-16.7115],[-144.5785,-16.6685],[-144.652,-16.606],[-144.7455,-16.5745],[-144.8225,-16.573],[-144.8975,-16.588],[-144.9865,-16.586],[-145.0665,-16.537],[-145.1605,-16.509],[-145.1525,-16.4515],[-145.168,-16.3735],[-145.2435,-16.266],[-145.3115,-16.2115],[-145.361,-16.144],[-145.4135,-16.013]],[[-143.18,-16.6095],[-143.082,-16.613],[-143.0845,-16.7455],[-143.1785,-16.725],[-143.18,-16.6095]]],[[[-148.491,-15.844],[-148.4845,-15.898],[-148.4565,-15.96],[-148.374,-16.0375],[-148.3165,-16.0635],[-148.2275,-16.0725],[-148.1285,-16.04],[-148.068,-15.991],[-148.0385,-15.9475],[-148.0145,-15.876],[-148.016,-15.8075],[-148.042,-15.7425],[-148.1235,-15.6555],[-148.1865,-15.6185],[-148.2555,-15.6055],[-148.3085,-15.6095],[-148.3835,-15.639],[-148.428,-15.6755],[-148.4715,-15.7465],[-148.491,-15.844]]],[[[-148.285,-17.877],[-148.273,-17.942],[-148.2085,-18.0355],[-148.1325,-18.076],[-148.025,-18.0805],[-147.975,-18.065],[-147.9125,-18.0225],[-147.8815,-17.9835],[-147.851,-17.8945],[-147.8545,-17.83],[-147.894,-17.748],[-147.9645,-17.691],[-148.025,-17.6705],[-148.098,-17.668],[-148.1835,-17.699],[-148.227,-17.7335],[-148.2715,-17.8015],[-148.285,-17.877]]],[[[-147.919,-23.8985],[-147.8995,-23.9835],[-147.8665,-24.031],[-147.811,-24.0735],[-147.7305,-24.1025],[-147.679,-24.107],[-147.586,-24.094],[-147.5115,-24.064],[-147.4435,-24.0195],[-147.3855,-23.942],[-147.3675,-23.8355],[-147.3875,-23.7555],[-147.4325,-23.696],[-147.4945,-23.655],[-147.5475,-23.6385],[-147.6265,-23.6335],[-147.762,-23.6655],[-147.867,-23.7285],[-147.9065,-23.7915],[-147.919,-23.8985]]],[[[-146.61,-14.552],[-146.605,-14.602],[-146.5565,-14.6965],[-146.5055,-14.738],[-146.4245,-14.766],[-146.3145,-14.754],[-146.2545,-14.721],[-146.195,-14.7065],[-146.114,-14.656],[-146.0565,-14.6675],[-145.958,-14.6585],[-145.8785,-14.6375],[-145.744,-14.563],[-145.662,-14.477],[-145.6385,-14.427],[-145.6285,-14.3645],[-145.645,-14.2855],[-145.6825,-14.219],[-145.7485,-14.159],[-145.8385,-14.129],[-145.9225,-14.1345],[-146.0155,-14.1655],[-146.1585,-14.2445],[-146.27,-14.225],[-146.37,-14.24],[-146.488,-14.2975],[-146.5565,-14.3805],[-146.5965,-14.483],[-146.61,-14.552]]],[[[-145.816,-17.3505],[-145.7945,-17.444],[-145.745,-17.5215],[-145.6485,-17.585],[-145.6045,-17.6375],[-145.559,-17.668],[-145.4575,-17.697],[-145.346,-17.6915],[-145.2685,-17.6545],[-145.224,-17.613],[-145.1855,-17.5335],[-145.1885,-17.4275],[-145.234,-17.3435],[-145.3595,-17.2055],[-145.4395,-17.1515],[-145.5375,-17.127],[-145.6285,-17.128],[-145.7365,-17.182],[-145.795,-17.2605],[-145.816,-17.3505]]],[[[-145.4695,-14.693],[-145.4455,-14.792],[-145.3755,-14.871],[-145.3165,-14.9025],[-145.21,-14.911],[-145.1465,-14.8895],[-145.0695,-14.829],[-144.9735,-14.7045],[-144.8375,-14.642],[-144.7065,-14.5455],[-144.6635,-14.481],[-144.649,-14.3895],[-144.668,-14.318],[-144.7215,-14.246],[-144.787,-14.2055],[-144.9135,-14.188],[-145.0555,-14.232],[-145.1795,-14.316],[-145.2135,-14.357],[-145.329,-14.413],[-145.388,-14.474],[-145.4335,-14.55],[-145.4695,-14.693]]],[[[-145.2135,-19.867],[-145.1975,-19.9455],[-145.163,-20.0],[-145.072,-20.0775],[-144.971,-20.1145],[-144.896,-20.109],[-144.809,-20.07],[-144.766,-20.0275],[-144.736,-19.972],[-144.725,-19.865],[-144.752,-19.7595],[-144.792,-19.703],[-144.88,-19.6485],[-144.939,-19.6355],[-145.034,-19.644],[-145.108,-19.6835],[-145.174,-19.751],[-145.208,-19.8235],[-145.2135,-19.867]]],[[[-144.7705,-14.96],[-144.7585,-15.028],[-144.7125,-15.099],[-144.6575,-15.138],[-144.56,-15.16],[-144.493,-15.152],[-144.4085,-15.1105],[-144.341,-15.028],[-144.3245,-14.935],[-144.3415,-14.8665],[-144.4165,-14.78],[-144.465,-14.756],[-144.5385,-14.7425],[-144.6455,-14.7665],[-144.708,-14.8125],[-144.759,-14.893],[-144.7705,-14.96]]],[[[-144.6065,-27.596],[-144.588,-27.6895],[-144.542,-27.759],[-144.423,-27.8345],[-144.3295,-27.8525],[-144.2315,-27.835],[-144.1605,-27.7985],[-144.1025,-27.732],[-144.0765,-27.6305],[-144.082,-27.5625],[-144.112,-27.4875],[-144.17,-27.4235],[-144.2885,-27.3715],[-144.4255,-27.3765],[-144.5095,-27.415],[-144.587,-27.5015],[-144.6065,-27.596]]],[[[-143.77,-20.4405],[-143.7405,-20.5435],[-143.6905,-20.5985],[-143.5745,-20.6555],[-143.5015,-20.6575],[-143.4795,-20.7165],[-143.4205,-20.7855],[-143.315,-20.828],[-143.2305,-20.823],[-143.1285,-20.898],[-143.0545,-20.9145],[-142.9595,-20.898],[-142.866,-20.822],[-142.8365,-20.75],[-142.8335,-20.698],[-142.8715,-20.586],[-142.929,-20.5285],[-142.989,-20.4995],[-143.1025,-20.4945],[-143.1495,-20.4455],[-143.2165,-20.4115],[-143.312,-20.404],[-143.3435,-20.3205],[-143.3875,-20.271],[-143.466,-20.2225],[-143.5765,-20.2145],[-143.6755,-20.2625],[-143.736,-20.3285],[-143.77,-20.4405]]],[[[-143.7365,-27.8855],[-143.7225,-27.9635],[-143.6485,-28.0525],[-143.559,-28.09],[-143.4425,-28.095],[-143.3625,-28.0645],[-143.293,-27.9985],[-143.2675,-27.939],[-143.2585,-27.8695],[-143.2725,-27.8095],[-143.313,-27.748],[-143.354,-27.7155],[-143.4355,-27.6815],[-143.5205,-27.675],[-143.5745,-27.685],[-143.646,-27.72],[-143.705,-27.7865],[-143.7365,-27.8855]]],[[[-143.6895,-17.4455],[-143.678,-17.5155],[-143.6305,-17.6055],[-143.5895,-17.645],[-143.479,-17.689],[-143.401,-17.6845],[-143.312,-17.646],[-143.2615,-17.6045],[-143.229,-17.5575],[-143.209,-17.4905],[-143.219,-17.4],[-143.2485,-17.3455],[-143.297,-17.2975],[-143.409,-17.25],[-143.5265,-17.2505],[-143.591,-17.2765],[-143.667,-17.358],[-143.6895,-17.4455]]],[[[-143.2985,-17.865],[-143.288,-17.9255],[-143.251,-17.993],[-143.192,-18.0465],[-143.1035,-18.0785],[-143.0565,-18.0805],[-142.9745,-18.059],[-142.9285,-18.0305],[-142.88,-17.9745],[-142.852,-17.8685],[-142.8775,-17.755],[-142.9185,-17.6955],[-142.9905,-17.6485],[-143.0755,-17.6335],[-143.1545,-17.65],[-143.236,-17.7045],[-143.29,-17.797],[-143.2985,-17.865]]],[[[-142.8805,-17.553],[-142.873,-17.634],[-142.8155,-17.7425],[-142.718,-17.812],[-142.5965,-17.837],[-142.5125,-17.8245],[-142.4335,-17.785],[-142.3585,-17.6995],[-142.3385,-17.635],[-142.3525,-17.524],[-142.4005,-17.455],[-142.361,-17.392],[-142.347,-17.312],[-142.359,-17.2505],[-142.4255,-17.1565],[-142.5225,-17.1085],[-142.598,-17.101],[-142.6815,-17.1235],[-142.733,-17.1585],[-142.784,-17.233],[-142.7975,-17.3095],[-142.784,-17.3755],[-142.8365,-17.423],[-142.8635,-17.469],[-142.8805,-17.553]]],[[[-142.7395,-16.164],[-142.698,-16.3055],[-142.658,-16.3725],[-142.617,-16.4085],[-142.508,-16.447],[-142.413,-16.439],[-142.327,-16.3975],[-142.283,-16.353],[-142.1835,-16.195],[-142.1135,-16.0275],[-141.9685,-15.8725],[-141.921,-15.7785],[-141.925,-15.6735],[-141.9765,-15.5905],[-142.049,-15.5445],[-142.112,-15.5305],[-142.2015,-15.5395],[-142.294,-15.5845],[-142.398,-15.6785],[-142.4515,-15.753],[-142.523,-15.797],[-142.64,-15.914],[-142.727,-16.0905],[-142.7395,-16.164]]],[[[-142.605,-18.0455],[-142.5875,-18.129],[-142.509,-18.2305],[-142.393,-18.302],[-142.3615,-18.4155],[-142.3035,-18.4805],[-142.2125,-18.519],[-142.143,-18.5195],[-142.0665,-18.492],[-141.9875,-18.4355],[-141.9275,-18.3685],[-141.902,-18.292],[-141.919,-18.18],[-141.981,-18.077],[-141.9775,-18.0115],[-142.0035,-17.884],[-142.074,-17.795],[-142.146,-17.7615],[-142.2685,-17.7635],[-142.3595,-17.8075],[-142.445,-17.818],[-142.533,-17.8685],[-142.5885,-17.957],[-142.605,-18.0455]]],[[[-142.1415,-16.8295],[-142.1195,-16.9235],[-142.07,-16.989],[-142.0085,-17.027],[-141.8985,-17.0465],[-141.827,-17.03],[-141.7435,-16.967],[-141.71,-16.9055],[-141.7005,-16.837],[-141.7205,-16.757],[-141.7525,-16.706],[-141.8065,-16.657],[-141.92,-16.6235],[-142.03,-16.65],[-142.0785,-16.684],[-142.1285,-16.7585],[-142.1415,-16.8295]]],[[[-142.077,-18.7225],[-142.0685,-18.783],[-142.038,-18.849],[-141.9625,-18.9465],[-141.8885,-18.994],[-141.7765,-19.007],[-141.707,-18.989],[-141.6265,-18.938],[-141.583,-18.8825],[-141.545,-18.7655],[-141.5575,-18.6875],[-141.586,-18.6355],[-141.677,-18.553],[-141.766,-18.516],[-141.8565,-18.505],[-141.9175,-18.5135],[-142.007,-18.562],[-142.0445,-18.606],[-142.077,-18.7225]]],[[[-141.7375,-17.377],[-141.6995,-17.4945],[-141.6345,-17.5635],[-141.5655,-17.5945],[-141.4715,-17.5975],[-141.367,-17.556],[-141.3265,-17.5205],[-141.2795,-17.425],[-141.2825,-17.334],[-141.3055,-17.2785],[-141.3875,-17.192],[-141.468,-17.163],[-141.57,-17.1685],[-141.64,-17.1995],[-141.6815,-17.2345],[-141.7285,-17.3135],[-141.7375,-17.377]]],[[[-141.643,-14.105],[-141.6085,-14.211],[-141.552,-14.269],[-141.509,-14.293],[-141.424,-14.3115],[-141.3325,-14.377],[-141.275,-14.393],[-141.1845,-14.4],[-141.1125,-14.3885],[-141.016,-14.323],[-140.973,-14.239],[-140.968,-14.1745],[-140.988,-14.1035],[-141.046,-14.029],[-141.1165,-13.9785],[-141.217,-13.948],[-141.2855,-13.95],[-141.3355,-13.9145],[-141.4395,-13.8905],[-141.5045,-13.9025],[-141.575,-13.944],[-141.611,-13.9855],[-141.6375,-14.049],[-141.643,-14.105]]],[[[-141.4695,-19.1895],[-141.459,-19.2585],[-141.4345,-19.3125],[-141.3865,-19.37],[-141.3225,-19.4085],[-141.258,-19.423],[-141.1615,-19.4105],[-141.074,-19.353],[-141.0305,-19.2835],[-141.018,-19.2225],[-141.0305,-19.138],[-141.0855,-19.052],[-141.189,-18.988],[-141.2735,-18.98],[-141.336,-18.995],[-141.409,-19.043],[-141.4575,-19.1215],[-141.4695,-19.1895]]],[[[-141.2795,-18.1165],[-141.2605,-18.211],[-141.2275,-18.271],[-141.182,-18.3235],[-141.0895,-18.398],[-141.0685,-18.4315],[-140.962,-18.5455],[-140.8765,-18.593],[-140.792,-18.618],[-140.676,-18.631],[-140.5715,-18.61],[-140.527,-18.581],[-140.4755,-18.5155],[-140.455,-18.4225],[-140.476,-18.3395],[-140.5455,-18.249],[-140.6065,-18.2065],[-140.625,-18.1295],[-140.6745,-18.0565],[-140.6405,-18.0335],[-140.504,-17.8985],[-140.445,-17.7805],[-140.44,-17.6975],[-140.478,-17.6045],[-140.5295,-17.554],[-140.6095,-17.5155],[-140.696,-17.506],[-140.7785,-17.524],[-140.9235,-17.6145],[-140.965,-17.6495],[-141.048,-17.7675],[-141.081,-17.8715],[-141.1425,-17.889],[-141.231,-17.959],[-141.272,-18.0495],[-141.2795,-18.1165]]],[[[-141.1095,-15.822],[-141.098,-15.8915],[-141.048,-15.971],[-140.98,-16.018],[-140.864,-16.042],[-140.785,-16.027],[-140.6885,-15.9675],[-140.6295,-15.862],[-140.6245,-15.7865],[-140.654,-15.7025],[-140.7305,-15.63],[-140.8175,-15.6025],[-140.8855,-15.606],[-140.9755,-15.634],[-141.039,-15.6715],[-141.0995,-15.7635],[-141.1095,-15.822]]],[[[-140.9285,-19.125],[-140.9145,-19.2015],[-140.8635,-19.2795],[-140.796,-19.3295],[-140.709,-19.3565],[-140.654,-19.356],[-140.5775,-19.3325],[-140.5315,-19.3015],[-140.4745,-19.23],[-140.4525,-19.161],[-140.4575,-19.0815],[-140.4795,-19.029],[-140.544,-18.9605],[-140.587,-18.938],[-140.677,-18.9175],[-140.769,-18.922],[-140.809,-18.9365],[-140.877,-18.988],[-140.9115,-19.0435],[-140.9285,-19.125]]],[[[-140.9255,-8.0145],[-140.907,-8.1145],[-140.875,-8.1695],[-140.7855,-8.234],[-140.676,-8.2495],[-140.589,-8.219],[-140.545,-8.182],[-140.495,-8.1145],[-140.418,-8.06],[-140.345,-8.0615],[-140.2635,-8.0295],[-140.1985,-7.957],[-140.1765,-7.887],[-140.18,-7.8175],[-140.2225,-7.7315],[-140.2825,-7.683],[-140.332,-7.6645],[-140.4025,-7.6605],[-140.5045,-7.704],[-140.584,-7.6985],[-140.638,-7.713],[-140.7125,-7.761],[-140.831,-7.815],[-140.902,-7.9095],[-140.9255,-8.0145]]],[[[-140.893,-21.684],[-140.8825,-21.7495],[-140.8455,-21.8185],[-140.755,-21.889],[-140.6535,-21.925],[-140.5825,-21.9255],[-140.481,-21.8935],[-140.4215,-21.85],[-140.375,-21.7785],[-140.362,-21.705],[-140.3705,-21.652],[-140.4435,-21.5115],[-140.488,-21.4675],[-140.5625,-21.4325],[-140.631,-21.424],[-140.7375,-21.4465],[-140.7835,-21.477],[-140.871,-21.5945],[-140.893,-21.684]]],[[[-140.8225,-8.676],[-140.8075,-8.7525],[-140.776,-8.8055],[-140.706,-8.8595],[-140.6635,-8.874],[-140.5545,-8.8725],[-140.4995,-8.849],[-140.4535,-8.8105],[-140.4505,-8.871],[-140.405,-9.027],[-140.3685,-9.076],[-140.303,-9.131],[-140.209,-9.176],[-140.2845,-9.2445],[-140.329,-9.32],[-140.3345,-9.418],[-140.3125,-9.4905],[-140.234,-9.5915],[-140.192,-9.6265],[-140.124,-9.658],[-140.0615,-9.668],[-139.972,-9.651],[-139.9135,-9.6125],[-139.8725,-9.5655],[-139.8395,-9.493],[-139.819,-9.3895],[-139.8205,-9.3295],[-139.8395,-9.272],[-139.9075,-9.196],[-140.0265,-9.1385],[-139.9195,-9.1045],[-139.8605,-9.058],[-139.8155,-8.973],[-139.775,-9.0565],[-139.7215,-9.117],[-139.6105,-9.1575],[-139.4585,-9.1405],[-139.366,-9.1005],[-139.2985,-9.008],[-139.2825,-8.9365],[-139.2985,-8.8375],[-139.339,-8.766],[-139.411,-8.704],[-139.463,-8.68],[-139.546,-8.6645],[-139.6135,-8.67],[-139.6905,-8.697],[-139.7435,-8.742],[-139.7935,-8.8195],[-139.848,-8.6755],[-139.908,-8.6225],[-139.9765,-8.596],[-140.087,-8.5975],[-140.149,-8.5815],[-140.2685,-8.592],[-140.3385,-8.6185],[-140.4035,-8.672],[-140.434,-8.5715],[-140.517,-8.4965],[-140.601,-8.474],[-140.6645,-8.478],[-140.717,-8.4985],[-140.7865,-8.562],[-140.8095,-8.605],[-140.8225,-8.676]]],[[[-140.645,-19.634],[-140.6255,-19.7245],[-140.5915,-19.7785],[-140.5085,-19.84],[-140.4335,-19.861],[-140.349,-19.856],[-140.2945,-19.836],[-140.2225,-19.7775],[-140.178,-19.691],[-140.172,-19.6335],[-140.192,-19.553],[-140.263,-19.465],[-140.319,-19.429],[-140.4175,-19.4085],[-140.529,-19.4385],[-140.5995,-19.504],[-140.6315,-19.564],[-140.645,-19.634]]],[[[-140.377,-15.985],[-140.3475,-16.096],[-140.319,-16.134],[-140.2505,-16.1845],[-140.16,-16.209],[-140.099,-16.207],[-140.0105,-16.177],[-139.956,-16.136],[-139.913,-16.082],[-139.8855,-15.9965],[-139.9,-15.8975],[-139.975,-15.805],[-140.0695,-15.768],[-140.1515,-15.765],[-140.211,-15.7765],[-140.317,-15.8375],[-140.3665,-15.919],[-140.377,-15.985]]],[[[-139.4675,-19.3555],[-139.4345,-19.4625],[-139.396,-19.5055],[-139.316,-19.551],[-139.256,-19.566],[-139.18,-19.567],[-139.101,-19.538],[-139.02,-19.4565],[-138.991,-19.38],[-138.947,-19.433],[-138.8765,-19.4735],[-138.8305,-19.542],[-138.761,-19.588],[-138.704,-19.603],[-138.5965,-19.5915],[-138.532,-19.554],[-138.4975,-19.5175],[-138.4665,-19.4535],[-138.4595,-19.386],[-138.4715,-19.328],[-138.512,-19.2595],[-138.5635,-19.217],[-138.6025,-19.1465],[-138.6735,-19.0935],[-138.7245,-19.077],[-138.837,-19.078],[-138.942,-19.125],[-139.0285,-19.2185],[-139.0935,-19.16],[-139.154,-19.135],[-139.2465,-19.13],[-139.3095,-19.1495],[-139.412,-19.217],[-139.4485,-19.27],[-139.4675,-19.3555]]],[[[-139.4275,-18.557],[-139.4195,-18.6145],[-139.364,-18.7035],[-139.2965,-18.746],[-139.2245,-18.7615],[-139.1635,-18.7565],[-139.054,-18.7055],[-139.069,-18.793],[-139.06,-18.841],[-139.027,-18.9035],[-138.973,-18.9525],[-138.9275,-18.9745],[-138.8425,-18.9885],[-138.7285,-18.972],[-138.6555,-18.932],[-138.6105,-18.883],[-138.579,-18.7995],[-138.5825,-18.7235],[-138.6005,-18.677],[-138.6445,-18.6205],[-138.7385,-18.5695],[-138.8335,-18.562],[-138.889,-18.572],[-138.998,-18.628],[-139.0015,-18.506],[-139.041,-18.431],[-139.125,-18.3705],[-139.19,-18.3545],[-139.2575,-18.3585],[-139.3495,-18.4005],[-139.3995,-18.4565],[-139.4275,-18.557]]],[[[-139.366,-9.781],[-139.3515,-9.857],[-139.324,-9.908],[-139.3315,-10.0275],[-139.312,-10.091],[-139.2775,-10.1485],[-139.211,-10.204],[-139.1365,-10.2265],[-139.037,-10.212],[-138.962,-10.1585],[-138.903,-10.197],[-138.836,-10.221],[-138.7625,-10.222],[-138.7115,-10.206],[-138.6465,-10.1585],[-138.612,-10.1055],[-138.5945,-10.0205],[-138.6055,-9.958],[-138.6385,-9.8765],[-138.6095,-9.8185],[-138.5955,-9.749],[-138.6085,-9.674],[-138.669,-9.5895],[-138.7495,-9.548],[-138.7175,-9.453],[-138.7305,-9.367],[-138.759,-9.3155],[-138.8385,-9.251],[-138.919,-9.232],[-139.0215,-9.2555],[-139.0715,-9.2885],[-139.13,-9.3795],[-139.138,-9.4455],[-139.1205,-9.52],[-139.257,-9.5875],[-139.3435,-9.682],[-139.366,-9.781]]],[[[-139.3595,-20.7805],[-139.346,-20.857],[-139.279,-20.949],[-139.174,-20.9945],[-139.0805,-20.988],[-138.9875,-20.934],[-138.9485,-20.882],[-138.926,-20.82],[-138.925,-20.7375],[-138.974,-20.64],[-139.042,-20.5895],[-139.099,-20.5715],[-139.165,-20.569],[-139.257,-20.6],[-139.3345,-20.682],[-139.3595,-20.7805]]],[[[-139.249,-21.883],[-139.2265,-21.9735],[-139.1405,-22.06],[-139.0835,-22.082],[-139.01,-22.0925],[-138.9775,-22.1335],[-138.9985,-22.214],[-138.993,-22.27],[-138.933,-22.394],[-138.9,-22.431],[-138.833,-22.4705],[-138.77,-22.483],[-138.6845,-22.4705],[-138.563,-22.406],[-138.5335,-22.372],[-138.4995,-22.285],[-138.496,-22.2205],[-138.513,-22.156],[-138.5435,-22.1085],[-138.6175,-22.038],[-138.6745,-22.009],[-138.6065,-21.945],[-138.5765,-21.876],[-138.5795,-21.777],[-138.6215,-21.6995],[-138.699,-21.6355],[-138.853,-21.5815],[-138.9445,-21.582],[-139.0205,-21.6115],[-139.0885,-21.6715],[-139.183,-21.7335],[-139.2275,-21.7915],[-139.249,-21.883]]],[[[-139.055,-14.813],[-139.0485,-14.8655],[-139.004,-14.949],[-138.953,-14.992],[-138.864,-15.0335],[-138.7615,-15.039],[-138.6595,-14.994],[-138.615,-14.943],[-138.5825,-14.843],[-138.598,-14.752],[-138.638,-14.689],[-138.711,-14.6255],[-138.822,-14.596],[-138.942,-14.6305],[-139.028,-14.7165],[-139.055,-14.813]]],[[[-138.895,-10.521],[-138.873,-10.6125],[-138.815,-10.687],[-138.7145,-10.7465],[-138.622,-10.7515],[-138.5655,-10.7335],[-138.494,-10.6845],[-138.455,-10.6365],[-138.418,-10.5645],[-138.407,-10.51],[-138.4105,-10.4245],[-138.465,-10.319],[-138.536,-10.2595],[-138.593,-10.2305],[-138.6505,-10.2185],[-138.73,-10.225],[-138.823,-10.2725],[-138.872,-10.3365],[-138.887,-10.38],[-138.895,-10.521]]],[[[-138.7855,-20.8245],[-138.78,-20.883],[-138.7485,-20.9585],[-138.691,-21.018],[-138.6275,-21.061],[-138.529,-21.088],[-138.4505,-21.0775],[-138.3775,-21.0375],[-138.34,-20.9975],[-138.3055,-20.918],[-138.2945,-20.839],[-138.3095,-20.739],[-138.346,-20.6765],[-138.397,-20.632],[-138.5095,-20.5755],[-138.6045,-20.5725],[-138.672,-20.597],[-138.7365,-20.6545],[-138.762,-20.702],[-138.7855,-20.8245]]],[[[-138.6635,-17.3465],[-138.648,-17.432],[-138.61,-17.49],[-138.514,-17.549],[-138.4315,-17.56],[-138.343,-17.5565],[-138.2685,-17.5355],[-138.205,-17.497],[-138.1395,-17.4165],[-138.1235,-17.3665],[-138.123,-17.2995],[-138.149,-17.2295],[-138.2335,-17.151],[-138.3355,-17.126],[-138.441,-17.13],[-138.5195,-17.1515],[-138.6,-17.204],[-138.643,-17.263],[-138.6635,-17.3465]]],[[[-137.359,-23.167],[-137.3365,-23.261],[-137.3005,-23.3125],[-137.208,-23.3715],[-137.1505,-23.383],[-137.0555,-23.37],[-136.9865,-23.329],[-136.9265,-23.2445],[-136.905,-23.176],[-136.9215,-23.0645],[-136.9735,-22.991],[-137.034,-22.95],[-137.1545,-22.933],[-137.225,-22.9555],[-137.294,-23.0055],[-137.335,-23.0635],[-137.359,-23.167]]],[[[-137.28,-18.264],[-137.259,-18.3545],[-137.2105,-18.436],[-137.1295,-18.5125],[-137.025,-18.5585],[-136.9025,-18.555],[-136.848,-18.529],[-136.789,-18.471],[-136.7555,-18.383],[-136.7605,-18.3075],[-136.808,-18.2155],[-136.895,-18.13],[-136.9505,-18.093],[-137.019,-18.066],[-137.1005,-18.0635],[-137.1765,-18.0905],[-137.234,-18.1375],[-137.273,-18.211],[-137.28,-18.264]]],[[[-136.9665,-21.297],[-136.9545,-21.37],[-136.9165,-21.4355],[-136.8635,-21.4825],[-136.7295,-21.5345],[-136.609,-21.554],[-136.5505,-21.6345],[-136.4665,-21.686],[-136.397,-21.7],[-136.291,-21.681],[-136.2165,-21.6275],[-136.18,-21.573],[-136.161,-21.4705],[-136.1845,-21.385],[-136.23,-21.315],[-136.3305,-21.255],[-136.3895,-21.176],[-136.447,-21.142],[-136.568,-21.131],[-136.711,-21.0955],[-136.754,-21.0935],[-136.8425,-21.1145],[-136.916,-21.1695],[-136.9465,-21.216],[-136.9665,-21.297]]],[[[-136.6745,-18.471],[-136.657,-18.553],[-136.5805,-18.6465],[-136.528,-18.6745],[-136.4525,-18.7405],[-136.376,-18.772],[-136.305,-18.7805],[-136.191,-18.7515],[-136.1115,-18.674],[-136.083,-18.565],[-136.098,-18.491],[-136.131,-18.4345],[-136.1815,-18.3855],[-136.2635,-18.327],[-136.372,-18.2745],[-136.46,-18.262],[-136.5735,-18.2945],[-136.633,-18.3475],[-136.661,-18.3985],[-136.6745,-18.471]]],[[[-136.414,-22.0275],[-136.3985,-22.102],[-136.3365,-22.1865],[-136.2565,-22.229],[-136.1385,-22.232],[-136.0665,-22.2],[-136.001,-22.1275],[-135.967,-22.025],[-135.99,-21.905],[-136.0405,-21.8415],[-136.1365,-21.795],[-136.2035,-21.7915],[-136.3135,-21.8345],[-136.3755,-21.898],[-136.403,-21.956],[-136.414,-22.0275]]],[[[-135.8525,-21.4795],[-135.838,-21.5695],[-135.8,-21.661],[-135.7295,-21.731],[-135.6465,-21.7645],[-135.549,-21.774],[-135.4565,-21.754],[-135.3435,-21.701],[-135.2715,-21.6265],[-135.2465,-21.539],[-135.2555,-21.4685],[-135.2785,-21.418],[-135.3625,-21.332],[-135.4805,-21.279],[-135.6265,-21.2755],[-135.7065,-21.2875],[-135.7525,-21.3085],[-135.815,-21.366],[-135.8525,-21.4795]]],[[[-135.328,-23.175],[-135.297,-23.2805],[-135.2495,-23.3335],[-135.031,-23.435],[-134.942,-23.4465],[-134.799,-23.406],[-134.7085,-23.353],[-134.6545,-23.4885],[-134.599,-23.5405],[-134.554,-23.563],[-134.4745,-23.5755],[-134.4005,-23.561],[-134.3195,-23.5135],[-134.2775,-23.4645],[-134.247,-23.383],[-134.2485,-23.3135],[-134.2785,-23.2415],[-134.3185,-23.191],[-134.396,-23.134],[-134.4715,-23.1165],[-134.592,-23.1385],[-134.629,-23.1255],[-134.643,-23.044],[-134.6675,-22.9995],[-134.7215,-22.948],[-134.783,-22.863],[-134.894,-22.81],[-134.9515,-22.802],[-135.0405,-22.818],[-135.13,-22.8855],[-135.17,-22.9425],[-135.291,-23.0605],[-135.3195,-23.1175],[-135.328,-23.175]]],[[[-109.4385,10.3085],[-109.43,10.2495],[-109.4035,10.1915],[-109.367,10.148],[-109.3035,10.104],[-109.2545,10.088],[-109.1715,10.0885],[-109.0825,10.1295],[-109.03,10.1875],[-109.002,10.2585],[-108.997,10.31],[-109.015,10.3875],[-109.0725,10.4625],[-109.1495,10.5055],[-109.2195,10.52],[-109.304,10.505],[-109.3895,10.4415],[-109.4275,10.375],[-109.4385,10.3085]]],[[[-62.847,17.674],[-62.729,17.6825],[-62.6575,17.7235],[-62.6055,17.794],[-62.588,17.853],[-62.588,17.948],[-62.611,18.017],[-62.642,18.059],[-62.7115,18.116],[-62.7645,18.1375],[-62.7675,18.163],[-62.8765,18.1905],[-62.9485,18.181],[-63.2095,18.098],[-63.3605,18.0615],[-63.3275,17.954],[-63.268,17.8965],[-63.139,18.053],[-63.063,18.064],[-62.9495,18.017],[-62.9695,17.9865],[-63.0545,17.806],[-63.0655,17.783],[-63.0195,17.736],[-62.847,17.674]]],[[[-61.1385,15.7015],[-61.036,15.784],[-60.996,15.854],[-60.912,16.093],[-60.814,16.245],[-60.7965,16.293],[-60.8045,16.403],[-60.852,16.482],[-60.9255,16.533],[-60.989,16.549],[-61.071,16.542],[-61.121,16.522],[-61.2105,16.525],[-61.2385,16.581],[-61.309,16.653],[-61.369,16.692],[-61.443,16.713],[-61.508,16.71],[-61.5625,16.692],[-61.8075,16.578],[-61.8585,16.561],[-61.9555,16.48],[-62.0035,16.367],[-62.015,16.238],[-61.975,16.025],[-61.925,15.908],[-61.8325,15.751],[-61.791,15.7],[-61.68,15.6445],[-61.4425,15.787],[-61.3235,15.734],[-61.1385,15.7015]]],[[[-60.753,14.2215],[-60.6905,14.2645],[-60.645,14.326],[-60.6055,14.4245],[-60.6055,14.516],[-60.6235,14.6105],[-60.6865,14.878],[-60.718,14.932],[-60.771,14.978],[-60.844,15.005],[-60.937,15.01],[-61.052,15.062],[-61.159,15.079],[-61.349,15.0075],[-61.399,14.944],[-61.4315,14.862],[-61.435,14.804],[-61.419,14.7275],[-61.3405,14.565],[-61.2955,14.4415],[-61.2575,14.365],[-61.1715,14.285],[-61.097,14.2485],[-61.004,14.2725],[-60.892,14.2435],[-60.753,14.2215]]],[[[-56.4945,47.365],[-56.5065,47.313],[-56.608,47.2615],[-56.659,47.2085],[-56.693,47.13],[-56.692,47.079],[-56.6535,46.9425],[-56.697,46.8295],[-56.6835,46.7675],[-56.64,46.7055],[-56.581,46.654],[-56.5,46.6115],[-56.264,46.5525],[-56.1675,46.5545],[-56.0135,46.5875],[-55.9035,46.646],[-55.9825,46.803],[-56.0995,46.86],[-56.1295,46.931],[-56.105,47.1005],[-56.255,47.3055],[-56.4945,47.365]]],[[[-54.601,2.3375],[-54.5365,2.325],[-54.478,2.2155],[-54.398,2.2035],[-54.363,2.18],[-54.2675,2.1435],[-54.204,2.1625],[-54.1395,2.118],[-54.1065,2.121],[-54.081,2.1745],[-54.015,2.183],[-53.987,2.2115],[-53.9395,2.2215],[-53.9375,2.283],[-53.892,2.277],[-53.883,2.3085],[-53.81,2.34],[-53.768,2.3755],[-53.723,2.349],[-53.659,2.2795],[-53.4615,2.253],[-53.432,2.2925],[-53.371,2.313],[-53.344,2.351],[-53.2255,2.2625],[-53.273,2.222],[-53.2225,2.201],[-53.105,2.2225],[-53.052,2.19],[-52.9565,2.173],[-52.9045,2.189],[-52.8425,2.2915],[-52.6605,2.374],[-52.6165,2.4755],[-52.5515,2.5205],[-52.5605,2.551],[-52.5275,2.581],[-52.533,2.65],[-52.4755,2.7635],[-52.478,2.7805],[-52.3955,2.931],[-52.326,3.079],[-52.349,3.1355],[-52.3,3.175],[-52.2925,3.2275],[-52.2365,3.2395],[-52.161,3.3525],[-52.087,3.4885],[-51.9885,3.63],[-51.971,3.707],[-51.9215,3.724],[-51.927,3.768],[-51.8705,3.807],[-51.7975,3.889],[-51.778,3.974],[-51.6585,4.053],[-51.6445,4.083],[-51.6335,4.176],[-51.6145,4.2355],[-51.6285,4.2685],[-51.6455,4.395],[-51.637,4.5085],[-51.5695,4.585],[-51.602,4.6765],[-51.769,4.9285],[-51.7985,4.964],[-51.864,5.0045],[-52.101,5.094],[-52.2255,5.1955],[-52.441,5.421],[-52.5085,5.468],[-52.857,5.618],[-53.206,5.7545],[-53.507,5.813],[-53.8435,5.978],[-53.967,5.761],[-54.0205,5.6585],[-54.008,5.551],[-54.0485,5.4915],[-54.128,5.4065],[-54.193,5.315],[-54.2965,5.2405],[-54.374,5.109],[-54.4055,5.084],[-54.4375,5.017],[-54.44,4.949],[-54.4865,4.8985],[-54.4735,4.857],[-54.4775,4.748],[-54.433,4.7035],[-54.4335,4.634],[-54.414,4.597],[-54.452,4.509],[-54.4405,4.4195],[-54.386,4.349],[-54.382,4.269],[-54.396,4.2025],[-54.324,4.149],[-54.358,4.0515],[-54.3185,4.015],[-54.2955,3.9475],[-54.2485,3.9055],[-54.2345,3.858],[-54.1995,3.8525],[-54.183,3.7995],[-54.127,3.798],[-54.0785,3.708],[-54.0835,3.6755],[-54.051,3.635],[-54.003,3.645],[-53.98,3.6055],[-54.004,3.563],[-54.009,3.466],[-54.023,3.4105],[-54.048,3.3875],[-54.064,3.3135],[-54.13,3.2845],[-54.174,3.2075],[-54.1935,3.1975],[-54.1945,3.0655],[-54.1715,2.9415],[-54.2075,2.829],[-54.206,2.7765],[-54.263,2.7225],[-54.2805,2.6625],[-54.3175,2.6285],[-54.349,2.5215],[-54.42,2.436],[-54.4735,2.4365],[-54.5045,2.3925],[-54.521,2.337],[-54.572,2.3545],[-54.601,2.3375]]],[[[1.442,42.6035],[1.479,42.6515],[1.5495,42.656],[1.6005,42.626],[1.7135,42.615],[1.7505,42.564],[1.726,42.5025],[1.8045,42.4905],[1.9585,42.424],[1.9645,42.3825],[2.012,42.353],[2.083,42.3635],[2.129,42.4125],[2.2,42.4165],[2.257,42.4385],[2.4145,42.392],[2.481,42.341],[2.542,42.334],[2.5795,42.3585],[2.661,42.367],[2.6795,42.407],[2.8005,42.4195],[2.84,42.459],[2.9185,42.456],[2.9455,42.48],[3.11,42.4355],[3.448,42.4355],[3.4375,42.4965],[3.394,42.588],[3.3105,42.672],[3.3135,42.814],[3.339,42.9795],[3.435,43.0685],[3.509,43.063],[3.599,43.0755],[3.6775,43.109],[3.7845,43.202],[3.8685,43.2255],[3.9965,43.303],[4.127,43.2715],[4.3,43.2565],[4.456,43.1845],[4.644,43.1455],[4.7115,43.147],[4.7925,43.123],[4.9375,43.127],[5.064,43.0375],[5.1535,43.007],[5.3425,42.973],[5.51,42.964],[5.705,42.871],[6.1375,42.787],[6.1835,42.7825],[6.411,42.787],[6.4775,42.7965],[6.615,42.847],[6.7455,42.926],[6.9225,43.095],[6.9735,43.226],[7.2015,43.332],[7.296,43.3815],[7.5,43.5165],[7.4185,43.725],[7.4525,43.742],[7.533,43.537],[7.631,43.5785],[7.6105,43.656],[7.539,43.744],[7.5075,43.842],[7.5115,43.885],[7.5615,43.899],[7.585,43.954],[7.652,43.9735],[7.7185,44.0825],[7.667,44.1335],[7.575,44.153],[7.357,44.1165],[7.2805,44.141],[7.194,44.19],[7.07,44.233],[7.0085,44.235],[6.897,44.3755],[6.9365,44.44],[6.876,44.4825],[6.8545,44.529],[6.9155,44.56],[6.969,44.626],[6.948,44.654],[7.041,44.7195],[7.0,44.789],[7.0065,44.8395],[6.932,44.8635],[6.8645,44.8515],[6.75,44.9075],[6.7635,44.971],[6.7485,45.016],[6.6735,45.02],[6.6275,45.107],[6.6805,45.1405],[6.768,45.16],[6.85,45.1275],[6.9555,45.1805],[6.966,45.208],[7.081,45.2245],[7.136,45.28],[7.1095,45.3185],[7.1595,45.3595],[7.1825,45.408],[7.0485,45.4725],[6.9905,45.531],[6.9955,45.5755],[6.97,45.654],[6.8465,45.6905],[6.808,45.7275],[6.818,45.836],[6.939,45.847],[6.99,45.868],[7.0455,45.9225],[7.0105,45.997],[6.8825,46.095],[6.898,46.122],[6.798,46.136],[6.804,46.2025],[6.8645,46.283],[6.7705,46.3555],[6.821,46.427],[6.682,46.4545],[6.519,46.4565],[6.4255,46.416],[6.335,46.4035],[6.253,46.3605],[6.2195,46.312],[6.2945,46.225],[6.2325,46.206],[6.1365,46.1415],[6.0525,46.1515],[5.995,46.183],[5.979,46.217],[6.1245,46.2515],[6.1025,46.285],[6.17,46.366],[6.0975,46.409],[6.073,46.4655],[6.1565,46.5455],[6.1105,46.5765],[6.283,46.6915],[6.438,46.7615],[6.435,46.8015],[6.4645,46.8905],[6.4325,46.9285],[6.505,46.9655],[6.6335,46.998],[6.7565,47.117],[6.85,47.1565],[6.8805,47.2005],[6.9555,47.244],[6.9405,47.286],[7.0455,47.3265],[7.05,47.3615],[6.924,47.355],[6.9405,47.4335],[7.002,47.454],[6.986,47.4935],[7.139,47.502],[7.2015,47.4925],[7.17,47.443],[7.255,47.4245],[7.3385,47.441],[7.3865,47.4325],[7.511,47.497],[7.5055,47.5445],[7.589,47.59],[7.5195,47.6675],[7.548,47.74],[7.5315,47.7865],[7.5595,47.8825],[7.622,47.9725],[7.5705,48.0315],[7.577,48.118],[7.668,48.2245],[7.6945,48.3025],[7.7455,48.3325],[7.737,48.4065],[7.7705,48.4915],[7.8045,48.5125],[7.803,48.5905],[7.8415,48.6435],[7.894,48.6655],[8.106,48.8245],[8.129,48.8795],[8.216,48.9755],[8.07,48.9965],[7.9315,49.058],[7.868,49.0335],[7.57,49.0795],[7.5285,49.097],[7.44,49.1835],[7.3655,49.172],[7.2985,49.1175],[7.245,49.13],[7.067,49.1145],[7.035,49.1915],[6.9185,49.2225],[6.834,49.1515],[6.7115,49.1885],[6.6615,49.282],[6.589,49.322],[6.588,49.3835],[6.552,49.425],[6.428,49.477],[6.3675,49.4695],[6.257,49.51],[6.196,49.5055],[6.042,49.448],[5.94,49.501],[5.8665,49.5],[5.8185,49.5465],[5.7005,49.54],[5.6645,49.553],[5.5935,49.522],[5.482,49.506],[5.449,49.517],[5.425,49.5985],[5.3535,49.6305],[5.2685,49.6965],[5.206,49.696],[5.125,49.727],[5.095,49.762],[5.0085,49.782],[4.856,49.792],[4.851,49.8655],[4.89,49.909],[4.849,49.948],[4.791,49.958],[4.827,50.05],[4.8675,50.0965],[4.8755,50.154],[4.824,50.161],[4.704,50.0965],[4.6845,49.997],[4.5975,49.9865],[4.51,49.947],[4.4455,49.937],[4.31,49.9695],[4.1965,49.9555],[4.136,50.021],[4.231,50.0735],[4.197,50.135],[4.1555,50.163],[4.201,50.275],[4.1225,50.298],[4.036,50.3435],[3.9675,50.35],[3.9005,50.327],[3.838,50.3545],[3.6655,50.347],[3.663,50.456],[3.6075,50.497],[3.3905,50.498],[3.2885,50.526],[3.241,50.669],[3.245,50.713],[3.1485,50.79],[3.019,50.7735],[2.9385,50.745],[2.899,50.694],[2.7895,50.729],[2.718,50.8135],[2.635,50.813],[2.604,50.9165],[2.633,50.946],[2.574,51.0035],[2.546,51.0885],[2.389,51.2685],[2.3695,51.305],[2.1935,51.281],[2.115,51.2425],[1.969,51.203],[1.8875,51.1995],[1.724,51.0985],[1.5465,51.038],[1.3555,50.949],[1.2815,50.8955],[1.2635,50.8245],[1.242,50.7075],[1.252,50.498],[1.2195,50.4095],[1.219,50.346],[1.1865,50.3015],[1.1645,50.2215],[0.986,50.126],[0.888,50.1195],[0.7835,50.0895],[0.4865,50.046],[0.2995,49.973],[0.0135,49.873],[-0.1055,49.8045],[-0.1665,49.742],[-0.1895,49.6505],[-0.2435,49.5365],[-0.347,49.5545],[-0.6075,49.562],[-0.7045,49.5505],[-0.8595,49.589],[-0.913,49.6465],[-0.9725,49.773],[-1.0425,49.8395],[-1.103,49.871],[-1.2205,49.9065],[-1.4145,49.92],[-1.552,49.896],[-1.6725,49.8875],[-1.7335,49.9085],[-1.8915,49.9325],[-2.0545,49.92],[-2.0505,49.8085],[-2.066,49.681],[-2.139,49.54],[-2.099,49.4595],[-1.994,49.3635],[-1.893,49.3155],[-1.8345,49.25],[-1.8345,49.1825],[-1.8605,49.065],[-1.944,48.9635],[-1.9845,48.9405],[-1.9845,48.8825],[-2.0845,48.871],[-2.243,48.871],[-2.5265,48.927],[-2.5265,49.0585],[-2.5605,49.22],[-2.7785,49.279],[-2.933,49.3035],[-3.008,49.28],[-3.096,49.223],[-3.1575,49.1165],[-3.212,49.1105],[-3.4935,49.1065],[-3.723,49.074],[-4.119,48.954],[-4.643,48.8475],[-4.9055,48.7575],[-5.17,48.6815],[-5.2465,48.667],[-5.3635,48.6055],[-5.4265,48.5315],[-5.451,48.458],[-5.447,48.4085],[-5.319,48.084],[-5.3115,48.0045],[-5.2655,47.9375],[-5.1765,47.8805],[-5.1025,47.858],[-4.479,47.592],[-4.261,47.5455],[-4.1775,47.4925],[-4.038,47.4625],[-3.9115,47.4765],[-3.6675,47.444],[-3.5155,47.222],[-3.4305,47.146],[-3.297,47.0975],[-3.1345,47.0795],[-3.037,47.081],[-2.879,47.108],[-2.6885,47.0335],[-2.67,47.009],[-2.702,46.7045],[-2.6855,46.656],[-2.626,46.586],[-2.557,46.539],[-2.0445,46.3445],[-1.781,46.0845],[-1.701,45.9955],[-1.6615,45.872],[-1.59,45.7955],[-1.558,45.7275],[-1.578,45.6505],[-1.5285,45.541],[-1.467,45.495],[-1.444,45.4495],[-1.448,45.315],[-1.4715,45.1695],[-1.5085,44.8675],[-1.547,44.6745],[-1.562,44.548],[-1.5385,44.4695],[-1.5895,44.172],[-1.656,43.924],[-1.714,43.7375],[-1.72,43.6915],[-1.804,43.595],[-1.772,43.488],[-1.772,43.388],[-1.79,43.3535],[-1.73,43.296],[-1.6695,43.315],[-1.609,43.252],[-1.533,43.2935],[-1.379,43.25],[-1.383,43.19],[-1.4145,43.128],[-1.471,43.079],[-1.441,43.0465],[-1.354,43.0285],[-1.346,43.0905],[-1.2475,43.0425],[-1.111,43.0205],[-1.0065,42.989],[-0.9455,42.9535],[-0.8105,42.9515],[-0.7515,42.967],[-0.718,42.8865],[-0.602,42.8315],[-0.5675,42.781],[-0.5055,42.8275],[-0.4435,42.796],[-0.394,42.799],[-0.308,42.8425],[-0.189,42.787],[-0.156,42.785],[-0.062,42.695],[0.0015,42.686],[0.1845,42.7355],[0.2595,42.7165],[0.2955,42.674],[0.3585,42.7195],[0.4225,42.6905],[0.527,42.7025],[0.675,42.6915],[0.646,42.7825],[0.7085,42.8615],[0.8585,42.8255],[0.9265,42.7895],[0.9605,42.806],[1.109,42.7715],[1.166,42.709],[1.3575,42.7195],[1.442,42.6035]]],[[[9.559,43.193],[9.4815,43.2195],[9.3575,43.225],[9.2715,43.203],[9.141,43.1335],[9.0755,43.0405],[9.053,42.9315],[8.958,42.8925],[8.8705,42.841],[8.56,42.744],[8.4815,42.685],[8.394,42.549],[8.3285,42.5015],[8.283,42.4445],[8.265,42.368],[8.269,42.227],[8.321,41.9555],[8.315,41.864],[8.3365,41.795],[8.4335,41.63],[8.5755,41.4305],[8.7155,41.3145],[8.831,41.261],[9.135,41.318],[9.27,41.292],[9.3165,41.336],[9.45,41.4065],[9.631,41.4335],[9.6495,41.49],[9.6745,41.7045],[9.6795,41.89],[9.79,42.0145],[9.82,42.087],[9.828,42.261],[9.801,42.3815],[9.815,42.435],[9.7825,42.6325],[9.733,42.7035],[9.7645,42.8085],[9.7165,42.8485],[9.6415,42.955],[9.589,43.1755],[9.559,43.193]]],[[[39.414,-21.471],[39.4495,-21.602],[39.482,-21.645],[39.55,-21.6965],[39.6555,-21.726],[39.7575,-21.716],[39.826,-21.6885],[39.881,-21.6505],[39.934,-21.5845],[39.9595,-21.5115],[39.953,-21.4245],[39.907,-21.3435],[39.814,-21.266],[39.731,-21.238],[39.658,-21.236],[39.539,-21.2735],[39.4905,-21.3075],[39.4435,-21.3655],[39.414,-21.471]]],[[[40.112,-22.3525],[40.1215,-22.433],[40.1585,-22.5],[40.241,-22.569],[40.3115,-22.5965],[40.3885,-22.6015],[40.477,-22.5775],[40.534,-22.5365],[40.5785,-22.4865],[40.6085,-22.422],[40.615,-22.3395],[40.585,-22.2505],[40.5425,-22.1955],[40.447,-22.14],[40.339,-22.13],[40.2585,-22.1525],[40.161,-22.2225],[40.124,-22.2865],[40.112,-22.3525]]],[[[42.491,-17.0635],[42.5255,-17.158],[42.574,-17.2095],[42.6475,-17.2515],[42.7015,-17.264],[42.8025,-17.255],[42.8615,-17.2305],[42.9115,-17.188],[42.945,-17.132],[42.959,-17.0705],[42.9515,-17.007],[42.918,-16.94],[42.8625,-16.8895],[42.7635,-16.8515],[42.674,-16.8465],[42.616,-16.8615],[42.554,-16.9015],[42.5105,-16.959],[42.491,-17.0635]]],[[[44.7435,-12.6615],[44.77,-12.7605],[44.747,-12.86],[44.755,-12.938],[44.813,-13.0935],[44.862,-13.1565],[44.9405,-13.217],[44.9935,-13.246],[45.0785,-13.2695],[45.198,-13.2665],[45.281,-13.2355],[45.395,-13.1505],[45.43,-13.091],[45.446,-12.9905],[45.4865,-12.9095],[45.506,-12.8115],[45.4945,-12.7015],[45.4705,-12.6385],[45.435,-12.591],[45.315,-12.48],[45.2035,-12.4105],[45.135,-12.3835],[45.08,-12.379],[44.99,-12.396],[44.9085,-12.4545],[44.838,-12.4845],[44.7935,-12.524],[44.7605,-12.5775],[44.7435,-12.6615]]],[[[47.0815,-11.5955],[47.097,-11.6625],[47.134,-11.7205],[47.214,-11.777],[47.3235,-11.793],[47.3915,-11.7725],[47.4645,-11.7245],[47.5345,-11.6545],[47.57,-11.5945],[47.585,-11.527],[47.5655,-11.4285],[47.5225,-11.37],[47.4195,-11.3175],[47.3335,-11.3185],[47.2675,-11.345],[47.18,-11.4015],[47.128,-11.448],[47.0855,-11.536],[47.0815,-11.5955]]],[[[49.8785,-46.088],[49.8895,-46.153],[49.94,-46.226],[50.0015,-46.2735],[50.1195,-46.3245],[50.096,-46.395],[50.119,-46.4875],[50.149,-46.53],[50.226,-46.5855],[50.2945,-46.6125],[50.3875,-46.6285],[50.5255,-46.616],[50.654,-46.549],[50.705,-46.4765],[50.703,-46.3685],[50.6285,-46.278],[50.536,-46.23],[50.584,-46.1315],[50.684,-46.072],[50.7195,-46.0285],[50.7415,-45.9575],[50.734,-45.905],[50.655,-45.806],[50.5575,-45.7565],[50.462,-45.738],[50.3575,-45.745],[50.211,-45.8035],[50.135,-45.868],[50.029,-45.9],[49.9605,-45.9425],[49.893,-46.0265],[49.8785,-46.088]]],[[[51.352,-46.387],[51.396,-46.5005],[51.5265,-46.615],[51.6605,-46.664],[51.8145,-46.6745],[51.879,-46.667],[51.9895,-46.6315],[52.104,-46.6685],[52.245,-46.68],[52.3865,-46.658],[52.5215,-46.5975],[52.5775,-46.544],[52.6155,-46.465],[52.61,-46.3955],[52.552,-46.302],[52.4135,-46.2185],[52.2605,-46.1845],[52.107,-46.19],[52.0025,-46.217],[51.8885,-46.164],[51.771,-46.143],[51.6135,-46.1595],[51.496,-46.199],[51.392,-46.2725],[51.352,-46.387]]],[[[54.3085,-15.884],[54.3235,-15.9595],[54.3725,-16.0345],[54.457,-16.0875],[54.5535,-16.0965],[54.6155,-16.078],[54.688,-16.021],[54.7185,-15.9725],[54.736,-15.901],[54.7135,-15.7995],[54.6755,-15.749],[54.6075,-15.7035],[54.4985,-15.684],[54.4125,-15.71],[54.3645,-15.747],[54.3295,-15.796],[54.3085,-15.884]]],[[[55.0035,-21.036],[55.019,-21.1495],[55.067,-21.2205],[55.1185,-21.3455],[55.171,-21.4085],[55.222,-21.4495],[55.3585,-21.5205],[55.4805,-21.564],[55.6505,-21.5905],[55.8405,-21.5565],[55.9125,-21.5215],[55.9875,-21.4455],[56.018,-21.3745],[56.0205,-21.286],[56.05,-21.2005],[56.025,-21.069],[55.967,-20.993],[55.9275,-20.9675],[55.858,-20.8295],[55.7625,-20.747],[55.6445,-20.702],[55.476,-20.674],[55.407,-20.674],[55.3325,-20.69],[55.2145,-20.736],[55.147,-20.772],[55.094,-20.8345],[55.075,-20.8845],[55.034,-20.9325],[55.0035,-21.036]]],[[[67.814,-49.953],[67.84,-50.038],[67.8995,-50.095],[67.986,-50.136],[68.0895,-50.1555],[68.1965,-50.151],[68.295,-50.1235],[68.373,-50.076],[68.4205,-50.014],[68.4325,-49.9455],[68.407,-49.878],[68.3475,-49.8205],[68.261,-49.779],[68.104,-49.759],[67.975,-49.783],[67.891,-49.826],[67.835,-49.8855],[67.814,-49.953]]],[[[68.114,-49.516],[68.1615,-49.6215],[68.282,-49.693],[68.432,-49.7145],[68.465,-49.848],[68.5445,-49.939],[68.53,-50.0355],[68.5735,-50.112],[68.6325,-50.157],[68.7425,-50.2035],[68.8755,-50.2185],[69.025,-50.19],[69.123,-50.1305],[69.175,-50.036],[69.1695,-49.977],[69.1295,-49.9125],[69.1965,-49.8975],[69.1915,-49.986],[69.2265,-50.048],[69.354,-50.1265],[69.4625,-50.1475],[69.545,-50.147],[69.6885,-50.1085],[69.7535,-50.0655],[69.8015,-49.9995],[69.8075,-49.9185],[69.936,-49.914],[70.028,-49.932],[70.125,-49.932],[70.369,-49.8765],[70.477,-49.8235],[70.588,-49.6945],[70.6755,-49.666],[70.7725,-49.592],[70.8025,-49.5255],[70.78,-49.425],[70.8175,-49.38],[70.8605,-49.2625],[70.855,-49.167],[70.8085,-49.031],[70.7355,-48.9555],[70.586,-48.8875],[70.445,-48.858],[70.1345,-48.8175],[70.0005,-48.787],[69.874,-48.64],[69.7885,-48.5945],[69.7425,-48.543],[69.672,-48.501],[69.523,-48.4695],[69.4415,-48.4705],[69.221,-48.4955],[69.1035,-48.4545],[69.0965,-48.4095],[69.0385,-48.3285],[68.9455,-48.2765],[68.8155,-48.252],[68.7325,-48.257],[68.6415,-48.2825],[68.5275,-48.367],[68.498,-48.441],[68.413,-48.478],[68.333,-48.5455],[68.302,-48.6155],[68.302,-48.6645],[68.336,-48.734],[68.482,-48.8925],[68.491,-48.9235],[68.4325,-49.0285],[68.4315,-49.1255],[68.46,-49.174],[68.394,-49.225],[68.34,-49.321],[68.2015,-49.374],[68.162,-49.4065],[68.114,-49.516]]],[[[77.249,-38.715],[77.271,-38.805],[77.3175,-38.8665],[77.3725,-38.904],[77.4715,-38.934],[77.5655,-38.938],[77.683,-38.9055],[77.7435,-38.8645],[77.7935,-38.791],[77.8,-38.7],[77.7755,-38.64],[77.7325,-38.588],[77.651,-38.532],[77.5195,-38.5025],[77.4165,-38.516],[77.308,-38.5775],[77.2635,-38.642],[77.249,-38.715]]],[[[77.2605,-37.841],[77.302,-37.9585],[77.3585,-38.015],[77.414,-38.049],[77.5215,-38.0785],[77.648,-38.0685],[77.7735,-38.0],[77.8285,-37.935],[77.8475,-37.8795],[77.837,-37.7735],[77.7705,-37.6685],[77.7075,-37.625],[77.602,-37.595],[77.511,-37.596],[77.369,-37.6455],[77.303,-37.7115],[77.272,-37.7765],[77.2605,-37.841]]],[[[157.985,-19.6495],[157.9945,-19.7075],[158.0495,-19.799],[158.0835,-19.914],[158.1385,-19.994],[158.1925,-20.0465],[158.3025,-20.106],[158.371,-20.1525],[158.4225,-20.172],[158.499,-20.1785],[158.6015,-20.145],[158.641,-20.113],[159.093,-19.5555],[159.1355,-19.4775],[159.185,-19.3605],[159.243,-19.1855],[159.2525,-19.113],[159.2235,-19.0235],[159.1245,-18.905],[159.069,-18.8065],[159.0035,-18.762],[158.9045,-18.743],[158.864,-18.7465],[158.4015,-18.83],[158.3015,-18.8785],[158.1805,-19.0055],[158.154,-19.059],[158.146,-19.148],[158.1085,-19.227],[158.0755,-19.368],[157.9985,-19.555],[157.985,-19.6495]]],[[[158.6325,-21.415],[158.667,-21.522],[158.6995,-21.559],[158.7835,-21.607],[158.8505,-21.6165],[158.965,-21.587],[159.013,-21.551],[159.0605,-21.473],[159.07,-21.4135],[159.056,-21.3435],[159.024,-21.29],[158.963,-21.241],[158.846,-21.2125],[158.7855,-21.2215],[158.691,-21.276],[158.6455,-21.344],[158.6325,-21.415]]],[[[162.6035,-18.1035],[162.6285,-18.4775],[162.653,-18.5675],[162.7035,-18.642],[162.861,-19.1225],[162.893,-19.2705],[162.95,-19.3975],[162.981,-19.5055],[163.0615,-19.632],[163.1505,-19.7285],[163.238,-19.852],[163.352,-19.979],[163.443,-20.0595],[163.4995,-20.132],[163.5325,-20.1925],[163.6065,-20.259],[163.6415,-20.321],[163.6915,-20.378],[163.768,-20.517],[163.8615,-20.66],[163.9545,-20.747],[164.008,-20.785],[164.0965,-20.947],[164.1315,-20.9875],[164.2295,-21.0605],[164.2655,-21.118],[164.31,-21.16],[164.4265,-21.2185],[164.515,-21.249],[164.635,-21.438],[164.6765,-21.482],[164.798,-21.564],[164.9245,-21.6655],[164.973,-21.6945],[165.168,-21.776],[165.2915,-21.8185],[165.3525,-21.897],[165.3985,-21.9325],[165.506,-21.974],[165.615,-22.07],[165.6705,-22.1075],[165.729,-22.1275],[165.7935,-22.1835],[165.8295,-22.2385],[165.9235,-22.2995],[166.0065,-22.415],[166.1885,-22.591],[166.2305,-22.6195],[166.3065,-22.717],[166.4275,-22.782],[166.5395,-22.9045],[166.688,-23.057],[166.7695,-23.111],[166.8475,-23.1755],[166.8955,-23.1985],[166.993,-23.2215],[167.1055,-23.2005],[167.6685,-22.943],[167.7385,-22.895],[167.7855,-22.8315],[167.8105,-22.749],[167.8065,-22.6935],[167.761,-22.541],[167.686,-22.417],[167.586,-22.345],[167.437,-22.2915],[167.2965,-22.216],[167.2255,-22.1505],[167.1605,-22.065],[167.1325,-21.9445],[167.0915,-21.8605],[167.0325,-21.803],[166.773,-21.637],[166.5745,-21.4525],[166.4595,-21.3825],[166.392,-21.3135],[166.2595,-21.2435],[166.1685,-21.1595],[165.892,-20.986],[165.759,-20.8745],[165.6535,-20.7645],[165.4845,-20.6265],[165.464,-20.5575],[165.4235,-20.492],[165.335,-20.428],[165.1955,-20.382],[165.058,-20.3655],[164.96,-20.334],[164.8405,-20.228],[164.724,-20.1325],[164.6865,-20.0785],[164.5555,-19.9355],[164.4925,-19.892],[164.445,-19.8245],[164.386,-19.7665],[164.2935,-19.7215],[164.1835,-19.5775],[163.9835,-19.258],[163.9915,-19.182],[163.9785,-19.1],[163.9525,-19.0545],[163.711,-18.7385],[163.6855,-18.711],[163.463,-18.5115],[163.446,-18.4235],[163.418,-18.337],[163.38,-18.2715],[163.335,-17.978],[163.3195,-17.9245],[163.2695,-17.8565],[163.2195,-17.822],[163.001,-17.7105],[162.898,-17.687],[162.8145,-17.7045],[162.731,-17.7695],[162.7025,-17.8205],[162.6315,-17.993],[162.6035,-18.1035]]],[[[164.139,-18.542],[164.1715,-18.6485],[164.2225,-18.7165],[164.2625,-18.747],[164.37,-18.795],[164.468,-18.802],[164.57,-18.757],[164.6165,-18.7035],[164.644,-18.607],[164.63,-18.5315],[164.5555,-18.377],[164.498,-18.3285],[164.448,-18.308],[164.3645,-18.3015],[164.2665,-18.338],[164.1935,-18.407],[164.156,-18.4635],[164.139,-18.542]]],[[[165.3045,-19.883],[165.3155,-19.945],[165.384,-20.0375],[165.4965,-20.0815],[165.572,-20.079],[165.812,-20.088],[165.899,-20.0735],[165.987,-20.011],[166.0415,-19.909],[166.0565,-19.8025],[166.022,-19.718],[165.9485,-19.6545],[165.6965,-19.5245],[165.5815,-19.502],[165.494,-19.525],[165.4385,-19.5595],[165.379,-19.646],[165.32,-19.799],[165.3045,-19.883]]],[[[165.8965,-20.317],[165.913,-20.4225],[165.988,-20.6355],[166.0315,-20.6905],[166.2465,-20.8735],[166.346,-20.924],[166.408,-20.9355],[166.4685,-20.9295],[166.865,-21.0805],[166.941,-21.181],[167.012,-21.241],[167.14,-21.2865],[167.244,-21.363],[167.2925,-21.3795],[167.428,-21.471],[167.689,-21.737],[167.77,-21.788],[167.8165,-21.7995],[167.9155,-21.852],[168.0475,-21.86],[168.118,-21.8455],[168.2095,-21.8085],[168.266,-21.771],[168.315,-21.703],[168.33,-21.649],[168.3265,-21.5755],[168.349,-21.477],[168.349,-21.4245],[168.326,-21.355],[168.2805,-21.2995],[168.143,-21.201],[168.0235,-21.0105],[167.987,-20.964],[167.908,-20.905],[167.4255,-20.566],[167.299,-20.495],[167.0885,-20.456],[166.8005,-20.296],[166.7125,-20.2185],[166.6675,-20.199],[166.3295,-20.139],[166.247,-20.1035],[166.124,-20.088],[166.054,-20.107],[165.997,-20.143],[165.9285,-20.2135],[165.8965,-20.317]]],[[[168.726,-22.607],[168.738,-22.6735],[168.7815,-22.7445],[168.842,-22.789],[168.9265,-22.8115],[169.016,-22.801],[169.117,-22.7345],[169.167,-22.6455],[169.1685,-22.5355],[169.132,-22.4635],[169.048,-22.3995],[168.974,-22.381],[168.8645,-22.3985],[168.7905,-22.4495],[168.7355,-22.5475],[168.726,-22.607]]],[[[171.135,-22.343],[171.145,-22.404],[171.1795,-22.4665],[171.2655,-22.5295],[171.381,-22.5465],[171.462,-22.523],[171.5475,-22.447],[171.5785,-22.3435],[171.572,-22.295],[171.53,-22.217],[171.4385,-22.154],[171.332,-22.14],[171.263,-22.157],[171.1925,-22.204],[171.152,-22.263],[171.135,-22.343]]],[[[171.8685,-22.389],[171.8795,-22.458],[171.9075,-22.511],[171.9805,-22.573],[172.0725,-22.598],[172.149,-22.5905],[172.2405,-22.5405],[172.2935,-22.4635],[172.303,-22.365],[172.284,-22.3055],[172.2505,-22.2585],[172.172,-22.2055],[172.0995,-22.19],[171.98,-22.2165],[171.903,-22.284],[171.8685,-22.389]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/c/c3/Flag_of_France.svg","name:en":"France","wikidata":"Q142","ISO3166-1:alpha2":"FR","ISO3166-1:alpha3":"FRA","ISO3166-1:numeric":"250"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-0.136,11.1395],[-0.2755,11.175],[-0.2735,11.1235],[-0.336,11.107],[-0.381,11.126],[-0.4275,11.1145],[-0.4335,11.037],[-0.5005,11.0185],[-0.5105,10.993],[-0.5685,10.9925],[-0.5935,10.9235],[-0.6715,10.961],[-0.684,10.9975],[-0.855,10.998],[-0.87,10.9665],[-0.9165,11.002],[-1.0005,11.008],[-1.115,11.004],[-1.115,10.9855],[-1.3825,10.997],[-1.425,11.021],[-1.6155,11.021],[-1.6165,10.985],[-2.1315,10.986],[-2.2245,10.994],[-2.5005,10.99],[-2.6895,11.0045],[-2.8335,11.0065],[-2.841,10.971],[-2.8175,10.9255],[-2.8635,10.8645],[-2.8955,10.764],[-2.9405,10.7105],[-2.91,10.6985],[-2.941,10.6365],[-2.863,10.452],[-2.7775,10.4255],[-2.8315,10.388],[-2.8505,10.319],[-2.832,10.295],[-2.766,10.2655],[-2.761,10.2265],[-2.7965,10.1985],[-2.7905,10.0695],[-2.775,10.01],[-2.743,9.9565],[-2.7625,9.8885],[-2.73,9.8385],[-2.7905,9.7435],[-2.7835,9.6895],[-2.7475,9.634],[-2.772,9.6],[-2.7605,9.555],[-2.687,9.4915],[-2.68,9.3625],[-2.7205,9.333],[-2.664,9.24],[-2.7175,9.2015],[-2.7255,9.17],[-2.773,9.1435],[-2.762,9.0375],[-2.664,9.019],[-2.652,8.9445],[-2.618,8.9215],[-2.623,8.8785],[-2.5845,8.7865],[-2.4955,8.3025],[-2.493,8.2065],[-2.5515,8.1455],[-2.6085,8.152],[-2.626,8.102],[-2.6045,8.0305],[-2.6795,8.0205],[-2.7375,7.9475],[-2.7815,7.952],[-2.791,7.8625],[-2.831,7.82],[-2.922,7.612],[-2.931,7.4945],[-2.97,7.3315],[-2.9755,7.27],[-2.953,7.2375],[-3.024,7.142],[-3.032,7.072],[-3.0875,7.0525],[-3.2305,6.8235],[-3.216,6.7255],[-3.259,6.6165],[-3.2335,6.6015],[-3.236,6.5415],[-3.17,6.283],[-3.1025,6.153],[-3.074,5.985],[-3.02,5.857],[-3.0265,5.709],[-2.954,5.716],[-2.9665,5.6415],[-2.9365,5.6215],[-2.864,5.6525],[-2.7615,5.6],[-2.768,5.5555],[-2.749,5.4375],[-2.724,5.388],[-2.724,5.343],[-2.766,5.317],[-2.7745,5.261],[-2.7275,5.1325],[-2.8075,5.1065],[-2.9485,5.127],[-2.97,5.1035],[-3.0685,5.1345],[-3.1105,5.1185],[-3.1035,5.086],[-3.1485,4.896],[-2.526,4.7705],[-2.409,4.7405],[-2.299,4.6395],[-2.1965,4.5685],[-2.1285,4.5425],[-2.038,4.5415],[-1.9225,4.5645],[-1.8665,4.591],[-1.7965,4.651],[-1.626,4.714],[-1.5585,4.7875],[-1.486,4.8445],[-1.1565,4.922],[-1.0185,5.0015],[-0.8075,5.0125],[-0.7565,5.0225],[-0.682,5.058],[-0.5995,5.132],[-0.4,5.204],[-0.274,5.314],[-0.1435,5.344],[0.0885,5.438],[0.1605,5.4855],[0.1865,5.5175],[0.335,5.581],[0.4385,5.5895],[0.6875,5.567],[0.8315,5.5735],[0.996,5.5995],[1.094,5.664],[1.152,5.736],[1.1775,5.791],[1.1955,5.867],[1.2185,5.8985],[1.2735,5.9265],[1.1995,6.1125],[1.1995,6.169],[1.0835,6.169],[1.054,6.2345],[1.008,6.294],[1.0035,6.3355],[0.893,6.3335],[0.857,6.384],[0.789,6.4085],[0.7495,6.444],[0.7125,6.529],[0.7475,6.563],[0.657,6.6075],[0.6355,6.6415],[0.6485,6.74],[0.5815,6.7615],[0.5675,6.822],[0.532,6.829],[0.535,6.8755],[0.5655,6.923],[0.5265,6.941],[0.5435,6.9885],[0.59,6.999],[0.6115,7.1055],[0.595,7.12],[0.634,7.207],[0.6585,7.3175],[0.644,7.401],[0.5685,7.392],[0.536,7.4275],[0.52,7.514],[0.524,7.594],[0.586,7.622],[0.5905,7.703],[0.6115,7.753],[0.6275,7.8675],[0.5965,7.987],[0.6025,8.022],[0.5845,8.093],[0.6385,8.2605],[0.731,8.2875],[0.729,8.343],[0.6865,8.4115],[0.654,8.42],[0.647,8.491],[0.511,8.564],[0.4715,8.5995],[0.3745,8.754],[0.3795,8.792],[0.441,8.7895],[0.5005,8.8145],[0.5275,8.878],[0.5165,8.9375],[0.494,8.954],[0.457,9.0355],[0.5335,9.2095],[0.506,9.255],[0.5385,9.306],[0.567,9.406],[0.4955,9.446],[0.489,9.487],[0.4485,9.4995],[0.3595,9.499],[0.337,9.452],[0.2655,9.4305],[0.23,9.4625],[0.309,9.502],[0.2475,9.5215],[0.239,9.5715],[0.366,9.576],[0.3565,9.625],[0.303,9.5965],[0.264,9.6635],[0.3175,9.652],[0.351,9.675],[0.3245,9.7225],[0.325,9.772],[0.3575,9.8465],[0.3605,10.0275],[0.4095,10.0205],[0.4175,10.0575],[0.3565,10.091],[0.351,10.1925],[0.3615,10.258],[0.334,10.3365],[0.2645,10.409],[0.1735,10.426],[0.1425,10.5265],[0.061,10.561],[0.0415,10.6015],[-0.059,10.6325],[-0.0785,10.6905],[-0.074,10.7575],[-0.022,10.8185],[-0.0255,10.8805],[-0.005,10.9645],[0.032,10.9805],[0.024,11.0625],[-0.005,11.108],[-0.0545,11.086],[-0.1265,11.106],[-0.136,11.1395]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/19/Flag_of_Ghana.svg","name:en":"Ghana","wikidata":"Q117","ISO3166-1:alpha2":"GH","ISO3166-1:alpha3":"GHA","ISO3166-1:numeric":"288"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-16.8945,12.2375],[-16.837,11.9175],[-16.7855,11.594],[-16.6775,11.2175],[-16.6525,11.1635],[-16.6125,11.119],[-16.302,10.863],[-16.256,10.8395],[-15.798,10.67],[-15.7515,10.659],[-15.5935,10.6515],[-15.562,10.6665],[-15.3415,10.6665],[-15.1015,10.8845],[-15.074,10.892],[-15.002,10.9555],[-14.9575,10.977],[-14.936,11.0265],[-14.8375,11.2025],[-14.7725,11.3645],[-14.69,11.483],[-14.6635,11.505],[-14.5115,11.4965],[-14.4505,11.537],[-14.3195,11.6025],[-14.267,11.677],[-14.135,11.6645],[-14.081,11.6275],[-14.039,11.655],[-13.9885,11.6415],[-13.918,11.68],[-13.872,11.6605],[-13.856,11.705],[-13.772,11.682],[-13.708,11.7075],[-13.7055,11.8325],[-13.7125,11.8805],[-13.6965,12.008],[-13.762,12.03],[-13.8065,12.0885],[-13.868,12.108],[-13.876,12.137],[-13.9495,12.1595],[-13.916,12.2355],[-13.857,12.2425],[-13.851,12.2825],[-13.7645,12.275],[-13.718,12.249],[-13.687,12.308],[-13.6565,12.324],[-13.666,12.3905],[-13.6365,12.433],[-13.6415,12.49],[-13.6715,12.52],[-13.7095,12.608],[-13.708,12.6755],[-14.3235,12.6765],[-14.913,12.6785],[-15.1225,12.686],[-15.184,12.682],[-15.3375,12.6135],[-15.429,12.537],[-15.683,12.425],[-15.89,12.4505],[-15.9535,12.443],[-16.039,12.4725],[-16.1625,12.4495],[-16.203,12.4615],[-16.3755,12.376],[-16.5145,12.3505],[-16.545,12.3605],[-16.609,12.3475],[-16.6895,12.359],[-16.8945,12.2375]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/01/Flag_of_Guinea-Bissau.svg","name:en":"Guinea-Bissau","wikidata":"Q1007","ISO3166-1:alpha2":"GW","ISO3166-1:alpha3":"GNB","ISO3166-1:numeric":"624"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[32.1345,-26.8405],[32.135,-26.527],[32.0775,-26.4055],[32.0745,-26.3055],[32.1055,-26.1615],[32.0875,-26.0085],[32.003,-25.997],[31.975,-25.9525],[31.868,-25.9995],[31.4165,-25.719],[31.316,-25.743],[31.2635,-25.8095],[31.1265,-25.921],[31.113,-25.9825],[31.071,-26.0675],[30.9615,-26.2615],[30.892,-26.321],[30.805,-26.4665],[30.792,-26.569],[30.791,-26.7125],[30.813,-26.8445],[30.8875,-26.8035],[30.9075,-26.86],[30.9735,-26.908],[30.9585,-26.992],[30.985,-27.037],[31.0615,-27.0965],[31.1505,-27.202],[31.4935,-27.315],[31.978,-27.3175],[31.9745,-27.1165],[31.996,-26.924],[32.016,-26.82],[32.0925,-26.805],[32.1345,-26.8405]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/1/1e/Flag_of_Swaziland.svg","name:en":"Eswatini","wikidata":"Q1050","ISO3166-1:alpha2":"SZ","ISO3166-1:alpha3":"SWZ","ISO3166-1:numeric":"748"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[30.796,-8.2765],[30.7595,-8.145],[30.697,-7.9705],[30.6495,-7.878],[30.5095,-7.6795],[30.456,-7.5805],[30.4355,-7.5095],[30.426,-7.428],[30.382,-7.284],[30.3115,-7.137],[30.1885,-6.9625],[30.0375,-6.822],[29.8915,-6.7555],[29.746,-6.6415],[29.704,-6.5865],[29.656,-6.4465],[29.571,-6.338],[29.537,-6.239],[29.533,-6.167],[29.4985,-6.0565],[29.5045,-5.946],[29.5355,-5.894],[29.614,-5.799],[29.632,-5.7485],[29.626,-5.6855],[29.5975,-5.579],[29.5345,-5.448],[29.485,-5.289],[29.4585,-5.1845],[29.4245,-5.1425],[29.3825,-5.052],[29.3515,-4.9515],[29.3285,-4.775],[29.336,-4.652],[29.3715,-4.5695],[29.436,-4.449],[29.419,-4.2495],[29.3825,-4.117],[29.313,-3.9855],[29.244,-3.928],[29.2255,-3.843],[29.2495,-3.7165],[29.245,-3.5155],[29.2135,-3.295],[29.238,-3.279],[29.2225,-3.198],[29.2475,-3.1255],[29.2545,-3.0525],[29.203,-3.0225],[29.158,-2.9505],[29.0965,-2.9205],[29.094,-2.882],[29.0515,-2.821],[29.006,-2.8165],[29.001,-2.7855],[29.0405,-2.7435],[29.004,-2.7045],[28.918,-2.681],[28.891,-2.5575],[28.8625,-2.5325],[28.892,-2.476],[28.8665,-2.4365],[28.909,-2.3725],[28.948,-2.3765],[28.9985,-2.2975],[29.092,-2.2765],[29.1155,-2.256],[29.1735,-2.129],[29.156,-2.0175],[29.129,-1.9415],[29.136,-1.861],[29.156,-1.82],[29.245,-1.698],[29.2685,-1.6295],[29.3105,-1.5995],[29.362,-1.509],[29.4505,-1.506],[29.526,-1.4115],[29.591,-1.3875],[29.608,-1.318],[29.595,-1.2805],[29.607,-1.219],[29.5735,-1.186],[29.591,-1.0535],[29.589,-0.9005],[29.631,-0.8905],[29.641,-0.831],[29.6255,-0.725],[29.6745,-0.5385],[29.7115,-0.22],[29.7325,-0.0805],[29.7185,0.075],[29.7375,0.126],[29.7895,0.1695],[29.82,0.1655],[29.8725,0.388],[29.979,0.5155],[29.973,0.597],[29.9545,0.639],[29.977,0.745],[29.9635,0.7785],[29.989,0.8455],[30.1115,0.895],[30.169,0.905],[30.1765,0.9445],[30.2285,0.9885],[30.235,1.125],[30.29,1.1725],[30.336,1.1505],[30.36,1.2015],[30.391,1.1875],[30.4955,1.206],[30.5195,1.266],[30.5495,1.266],[31.011,1.785],[31.3055,2.1165],[31.3055,2.157],[31.203,2.2215],[31.203,2.2895],[31.131,2.262],[31.077,2.2955],[31.0745,2.3435],[30.9825,2.405],[30.9595,2.395],[30.934,2.335],[30.882,2.341],[30.834,2.427],[30.7415,2.4485],[30.762,2.51],[30.753,2.591],[30.779,2.606],[30.8265,2.729],[30.884,2.814],[30.888,2.8785],[30.8565,2.962],[30.769,3.045],[30.791,3.0635],[30.8025,3.1365],[30.8415,3.243],[30.8875,3.338],[30.937,3.399],[30.942,3.506],[30.8505,3.5005],[30.864,3.5475],[30.8505,3.5825],[30.8045,3.5955],[30.798,3.6555],[30.777,3.681],[30.7275,3.6235],[30.688,3.643],[30.6195,3.6055],[30.5565,3.6275],[30.574,3.671],[30.578,3.754],[30.5485,3.844],[30.47,3.8315],[30.411,3.8655],[30.3465,3.924],[30.277,3.9565],[30.2115,3.94],[30.195,4.024],[30.161,4.049],[30.1635,4.1155],[30.1225,4.112],[30.0595,4.133],[30.028,4.2055],[29.958,4.224],[29.9445,4.248],[29.9655,4.2955],[29.903,4.3475],[29.838,4.3375],[29.8,4.373],[29.797,4.4375],[29.826,4.56],[29.7495,4.5695],[29.62,4.6595],[29.4905,4.6945],[29.473,4.6485],[29.4745,4.5925],[29.4485,4.5665],[29.446,4.52],[29.404,4.473],[29.3695,4.471],[29.347,4.3975],[29.269,4.3975],[29.25,4.352],[29.2215,4.341],[29.138,4.429],[29.08,4.4345],[29.035,4.4915],[28.91,4.476],[28.8095,4.5005],[28.8025,4.5565],[28.7305,4.545],[28.6955,4.5025],[28.668,4.4285],[28.6015,4.4185],[28.584,4.384],[28.5175,4.3795],[28.4645,4.295],[28.3825,4.2855],[28.356,4.353],[28.3015,4.361],[28.2065,4.352],[28.15,4.426],[28.089,4.4345],[28.0375,4.4795],[28.0415,4.531],[28.0175,4.555],[27.9435,4.5735],[27.9225,4.5355],[27.886,4.5425],[27.842,4.5895],[27.7925,4.6065],[27.766,4.69],[27.7825,4.7275],[27.7715,4.7915],[27.707,4.817],[27.6485,4.896],[27.559,4.892],[27.5065,4.9395],[27.512,4.9615],[27.449,5.0195],[27.4415,5.074],[27.2625,5.151],[27.2295,5.153],[27.1355,5.2075],[27.086,5.2085],[27.022,5.1865],[26.9295,5.1375],[26.88,5.0485],[26.862,5.038],[26.747,5.109],[26.6595,5.08],[26.6385,5.0935],[26.571,5.083],[26.515,5.0485],[26.451,5.068],[26.4535,5.0945],[26.386,5.1515],[26.2935,5.1635],[26.244,5.2025],[26.214,5.204],[26.1575,5.2615],[26.093,5.246],[26.0615,5.1995],[25.9805,5.247],[25.9485,5.2045],[25.8265,5.2015],[25.781,5.259],[25.752,5.244],[25.7075,5.301],[25.604,5.339],[25.579,5.3785],[25.5,5.344],[25.4425,5.337],[25.335,5.261],[25.308,5.191],[25.344,5.11],[25.312,5.031],[25.2485,5.026],[25.086,4.9775],[25.0645,4.928],[24.996,4.9585],[24.962,4.9875],[24.9115,4.952],[24.8,4.9265],[24.783,4.8965],[24.6785,4.908],[24.672,4.9675],[24.6305,4.977],[24.625,5.013],[24.5685,5.033],[24.534,5.083],[24.4695,5.1045],[24.432,5.0635],[24.4095,5.102],[24.363,5.0725],[24.393,5.0295],[24.3555,5.006],[24.282,4.9965],[24.2665,4.969],[24.2155,4.954],[24.136,4.895],[24.111,4.9185],[24.0485,4.867],[23.962,4.875],[23.956,4.81],[23.891,4.833],[23.828,4.8325],[23.7665,4.7835],[23.7125,4.7865],[23.676,4.765],[23.5945,4.762],[23.5025,4.6775],[23.4615,4.6785],[23.427,4.6495],[23.429,4.599],[23.3285,4.608],[23.266,4.6665],[23.2305,4.6755],[23.196,4.723],[23.157,4.7395],[23.1105,4.7115],[23.01,4.757],[22.977,4.834],[22.8995,4.815],[22.893,4.75],[22.842,4.6995],[22.816,4.727],[22.782,4.7145],[22.7355,4.6305],[22.731,4.5565],[22.6895,4.4695],[22.62,4.4915],[22.596,4.48],[22.575,4.344],[22.544,4.288],[22.546,4.214],[22.4525,4.1345],[22.3815,4.121],[22.2585,4.115],[22.165,4.155],[22.0885,4.218],[21.9965,4.2455],[21.949,4.2335],[21.859,4.2465],[21.8095,4.287],[21.737,4.312],[21.6485,4.3125],[21.5585,4.253],[21.478,4.2645],[21.429,4.293],[21.387,4.281],[21.3415,4.2935],[21.282,4.345],[21.2265,4.293],[21.116,4.34],[21.0765,4.4],[20.9485,4.446],[20.8415,4.4545],[20.797,4.423],[20.7095,4.433],[20.5805,4.4125],[20.5215,4.4565],[20.4655,4.524],[20.447,4.567],[20.464,4.596],[20.4415,4.646],[20.4075,4.663],[20.3855,4.7335],[20.352,4.7665],[20.254,4.789],[20.173,4.892],[20.1065,4.9025],[20.0075,4.9715],[19.9135,4.9825],[19.863,5.033],[19.8195,5.1075],[19.7215,5.1265],[19.6795,5.1465],[19.613,5.13],[19.5285,5.1495],[19.4805,5.122],[19.437,5.1325],[19.3705,5.0965],[19.362,5.0735],[19.223,4.995],[19.197,4.9415],[19.107,4.941],[19.0195,4.767],[18.9385,4.701],[18.9215,4.6525],[18.8365,4.587],[18.8195,4.5545],[18.806,4.468],[18.786,4.4275],[18.7175,4.369],[18.621,4.3565],[18.603,4.371],[18.545,4.321],[18.6465,4.0615],[18.659,3.986],[18.6475,3.95],[18.6095,3.925],[18.5935,3.818],[18.5785,3.777],[18.6045,3.617],[18.608,3.518],[18.626,3.471],[18.6435,3.3115],[18.633,3.2745],[18.6415,3.2045],[18.62,3.144],[18.539,3.0755],[18.491,2.9495],[18.4445,2.8665],[18.402,2.73],[18.3205,2.581],[18.243,2.5295],[18.2265,2.4845],[18.2245,2.4185],[18.1685,2.3315],[18.1105,2.2805],[18.091,2.218],[18.0945,2.139],[18.072,2.0425],[18.084,1.938],[18.0655,1.875],[18.078,1.729],[18.0705,1.5285],[17.962,1.3195],[17.926,1.1455],[17.845,1.021],[17.8405,0.9245],[17.8775,0.8525],[17.889,0.776],[17.869,0.702],[17.868,0.614],[17.8855,0.571],[17.932,0.534],[17.9685,0.453],[17.954,0.3615],[17.92,0.3145],[17.8215,0.2335],[17.774,0.1225],[17.734,-0.064],[17.6765,-0.168],[17.6635,-0.231],[17.677,-0.3005],[17.7135,-0.356],[17.7165,-0.4145],[17.694,-0.5575],[17.6755,-0.6105],[17.6355,-0.6695],[17.582,-0.6945],[17.5295,-0.7445],[17.344,-0.99],[17.2485,-1.036],[17.1495,-1.0565],[17.0455,-1.109],[16.9535,-1.167],[16.807,-1.3165],[16.74,-1.428],[16.681,-1.562],[16.663,-1.62],[16.576,-1.7865],[16.508,-1.8905],[16.441,-1.96],[16.4065,-1.98],[16.3665,-2.0365],[16.2655,-2.0935],[16.1935,-2.1805],[16.1745,-2.3445],[16.236,-2.602],[16.2355,-2.6545],[16.208,-2.7235],[16.179,-2.904],[16.192,-3.0],[16.1715,-3.118],[16.187,-3.192],[16.1815,-3.2565],[16.2135,-3.287],[16.2015,-3.352],[16.164,-3.423],[16.1245,-3.472],[16.0915,-3.5565],[16.039,-3.627],[15.9995,-3.725],[15.9675,-3.7685],[15.927,-3.8595],[15.906,-3.9335],[15.8865,-3.9545],[15.803,-3.9815],[15.7195,-3.989],[15.5645,-4.0355],[15.517,-4.078],[15.4795,-4.229],[15.404,-4.2855],[15.3285,-4.269],[15.2565,-4.316],[15.1965,-4.325],[15.1755,-4.391],[15.144,-4.4185],[15.1,-4.489],[15.0315,-4.539],[14.9865,-4.603],[14.8985,-4.688],[14.848,-4.807],[14.7535,-4.862],[14.7005,-4.9065],[14.651,-4.922],[14.591,-4.9035],[14.5615,-4.865],[14.472,-4.8505],[14.415,-4.896],[14.3975,-4.8515],[14.407,-4.7035],[14.4195,-4.6515],[14.3905,-4.6335],[14.3595,-4.561],[14.4625,-4.465],[14.4805,-4.432],[14.4255,-4.3975],[14.393,-4.3555],[14.4015,-4.2785],[14.2885,-4.3195],[14.2525,-4.3575],[14.176,-4.398],[14.099,-4.415],[14.07,-4.4045],[13.9445,-4.5155],[13.88,-4.509],[13.8445,-4.4435],[13.7795,-4.424],[13.7235,-4.4555],[13.734,-4.506],[13.7175,-4.6375],[13.7255,-4.6895],[13.6995,-4.745],[13.5775,-4.803],[13.515,-4.7475],[13.495,-4.802],[13.441,-4.863],[13.4285,-4.913],[13.373,-4.8585],[13.3735,-4.8],[13.2815,-4.7655],[13.1855,-4.6665],[13.1405,-4.594],[13.105,-4.6025],[13.1025,-4.684],[13.0515,-4.675],[13.03,-4.7155],[12.9805,-4.7055],[12.923,-4.7475],[12.8965,-4.735],[12.828,-4.782],[12.8155,-4.839],[12.7285,-4.911],[12.72,-4.95],[12.626,-4.9505],[12.6055,-5.0265],[12.518,-5.0465],[12.4695,-5.0825],[12.494,-5.14],[12.528,-5.167],[12.5285,-5.742],[12.2785,-5.742],[12.219,-5.7525],[12.202,-5.774],[12.039,-5.8895],[12.1145,-5.99],[12.3125,-6.006],[12.3895,-6.068],[12.4445,-6.078],[12.625,-6.0195],[12.785,-5.986],[12.856,-5.9245],[12.951,-5.9125],[13.0425,-5.8635],[13.084,-5.871],[13.1135,-5.9035],[13.2225,-5.862],[13.365,-5.902],[13.3775,-5.8725],[13.431,-5.86],[13.5145,-5.8625],[13.572,-5.883],[13.617,-5.873],[13.774,-5.8695],[14.013,-5.839],[14.146,-5.8495],[14.1795,-5.8395],[14.239,-5.881],[14.2775,-5.8605],[14.3105,-5.883],[14.4125,-5.897],[14.5055,-5.8875],[14.596,-5.9045],[14.6995,-5.878],[14.9445,-5.8655],[15.4195,-5.87],[15.68,-5.862],[15.8145,-5.878],[16.153,-5.864],[16.1745,-5.86],[16.4345,-5.866],[16.492,-5.844],[16.5835,-5.878],[16.577,-5.937],[16.6005,-5.9785],[16.596,-6.033],[16.624,-6.0395],[16.663,-6.091],[16.7135,-6.1295],[16.7305,-6.167],[16.704,-6.203],[16.7035,-6.2655],[16.7195,-6.331],[16.678,-6.382],[16.718,-6.451],[16.7055,-6.4765],[16.7445,-6.511],[16.7325,-6.586],[16.754,-6.6315],[16.7655,-6.713],[16.7975,-6.7265],[16.802,-6.7935],[16.8365,-6.8145],[16.846,-6.884],[16.8735,-6.8755],[16.9105,-6.912],[16.9,-6.983],[16.9665,-7.0525],[16.9555,-7.1045],[16.925,-7.141],[16.955,-7.2115],[16.941,-7.236],[17.0205,-7.2925],[17.0365,-7.317],[17.1085,-7.362],[17.135,-7.4055],[17.1735,-7.424],[17.15,-7.471],[17.195,-7.496],[17.2125,-7.572],[17.302,-7.6335],[17.2905,-7.687],[17.316,-7.7155],[17.335,-7.782],[17.377,-7.7765],[17.42,-7.8555],[17.45,-7.942],[17.484,-7.9615],[17.4805,-8.0015],[17.514,-8.0165],[17.5035,-8.066],[17.539,-8.1115],[17.614,-8.131],[17.6795,-8.101],[17.7625,-8.1005],[17.7965,-8.1135],[17.874,-8.0805],[17.976,-8.096],[18.1035,-8.0965],[18.093,-8.056],[18.1425,-8.0355],[18.1965,-7.986],[18.2835,-7.987],[18.3115,-8.0155],[18.3715,-8.0245],[18.4075,-8.0],[18.532,-8.0],[18.5305,-7.9165],[18.762,-7.9165],[18.7965,-8.0],[19.3815,-8.0],[19.3585,-7.9495],[19.3635,-7.8075],[19.3835,-7.789],[19.406,-7.6705],[19.3695,-7.597],[19.383,-7.572],[19.4735,-7.572],[19.486,-7.5045],[19.53,-7.4625],[19.5225,-7.3935],[19.4945,-7.3635],[19.488,-7.3105],[19.505,-7.249],[19.4985,-7.168],[19.562,-7.0555],[19.548,-7.0],[20.303,-7.0],[20.322,-6.9165],[20.627,-6.917],[20.5955,-7.0605],[20.5615,-7.1175],[20.548,-7.229],[20.553,-7.2835],[21.242,-7.2835],[21.789,-7.2835],[21.8435,-7.374],[21.8345,-7.4085],[21.8605,-7.4475],[21.842,-7.5305],[21.8525,-7.6045],[21.7755,-7.7735],[21.7835,-7.829],[21.776,-7.9085],[21.7525,-7.945],[21.7745,-8.025],[21.8235,-8.0705],[21.8915,-8.253],[21.8925,-8.293],[21.925,-8.307],[21.9225,-8.397],[21.9485,-8.442],[21.9525,-8.504],[21.9245,-8.567],[21.892,-8.7],[21.8965,-8.7835],[21.8525,-8.949],[21.8345,-9.0605],[21.8395,-9.1305],[21.862,-9.1945],[21.81,-9.3295],[21.791,-9.4075],[21.8315,-9.464],[21.8335,-9.51],[21.8645,-9.5595],[21.86,-9.5945],[21.935,-9.707],[22.0015,-9.762],[22.013,-9.82],[22.0695,-9.875],[22.1455,-9.886],[22.1915,-9.933],[22.193,-9.993],[22.2155,-10.0535],[22.215,-10.1585],[22.235,-10.2165],[22.275,-10.2575],[22.324,-10.383],[22.2715,-10.5075],[22.307,-10.531],[22.323,-10.719],[22.3075,-10.7795],[22.2675,-10.785],[22.209,-10.819],[22.1675,-10.8635],[22.203,-10.9305],[22.2175,-11.1125],[22.2685,-11.1805],[22.254,-11.213],[22.271,-11.263],[22.344,-11.2025],[22.346,-11.1825],[22.4385,-11.177],[22.5025,-11.112],[22.489,-11.0645],[22.5775,-11.028],[22.6275,-11.047],[22.647,-11.079],[22.71,-11.1135],[22.7735,-11.1185],[22.8515,-11.065],[22.9065,-11.0865],[23.041,-11.0905],[23.08,-11.113],[23.1515,-11.0815],[23.196,-11.108],[23.2555,-11.0715],[23.299,-11.0215],[23.3975,-10.9605],[23.484,-10.9385],[23.5315,-10.9455],[23.597,-10.9865],[23.6685,-11.003],[23.778,-10.994],[23.863,-11.0355],[23.8975,-10.9765],[23.9615,-10.935],[24.0,-10.89],[24.065,-10.8885],[24.1325,-10.9245],[24.144,-11.031],[24.186,-11.0205],[24.256,-11.045],[24.302,-11.0415],[24.3795,-11.085],[24.4015,-11.1995],[24.4015,-11.2645],[24.3415,-11.367],[24.3645,-11.4005],[24.42,-11.427],[24.4385,-11.4665],[24.5275,-11.465],[24.5915,-11.42],[24.6415,-11.401],[24.672,-11.3525],[24.7505,-11.303],[24.7945,-11.31],[24.8635,-11.2915],[24.873,-11.2655],[25.028,-11.245],[25.06,-11.259],[25.1455,-11.2375],[25.205,-11.236],[25.318,-11.1885],[25.354,-11.201],[25.2945,-11.301],[25.2835,-11.397],[25.306,-11.4335],[25.3135,-11.518],[25.3065,-11.565],[25.332,-11.627],[25.4955,-11.7145],[25.5055,-11.7915],[25.656,-11.733],[25.671,-11.7755],[25.721,-11.817],[25.8305,-11.8295],[25.887,-11.8085],[25.891,-11.852],[25.927,-11.886],[25.968,-11.8825],[26.048,-11.9365],[26.1855,-11.938],[26.2065,-11.921],[26.303,-11.9475],[26.3125,-11.9635],[26.4235,-11.9115],[26.479,-11.9195],[26.5,-11.952],[26.576,-11.9855],[26.6905,-11.993],[26.709,-12.0065],[26.776,-11.956],[26.8195,-11.987],[26.891,-11.9775],[26.9155,-11.9375],[26.961,-11.916],[26.996,-11.8285],[27.0065,-11.745],[27.0475,-11.707],[27.016,-11.618],[27.0535,-11.593],[27.1605,-11.601],[27.2075,-11.5685],[27.2355,-11.685],[27.219,-11.746],[27.231,-11.787],[27.287,-11.8035],[27.3955,-11.8725],[27.4765,-11.9545],[27.4665,-12.044],[27.496,-12.0565],[27.5245,-12.1615],[27.615,-12.241],[27.65,-12.286],[27.7685,-12.2745],[27.823,-12.2275],[27.932,-12.2425],[27.961,-12.3145],[28.043,-12.3555],[28.083,-12.3515],[28.122,-12.438],[28.1695,-12.378],[28.194,-12.4045],[28.3395,-12.4315],[28.399,-12.5005],[28.4385,-12.514],[28.4455,-12.563],[28.4925,-12.5885],[28.534,-12.635],[28.5085,-12.6895],[28.467,-12.69],[28.4515,-12.722],[28.543,-12.8235],[28.543,-12.868],[28.5805,-12.899],[28.609,-12.8335],[28.654,-12.8145],[28.7125,-12.866],[28.754,-12.9415],[28.781,-12.9375],[28.8255,-13.005],[28.8235,-13.08],[28.8475,-13.111],[28.8475,-13.1555],[28.8905,-13.154],[28.918,-13.1905],[28.922,-13.2345],[28.959,-13.334],[28.9625,-13.3765],[29.0055,-13.423],[29.0895,-13.3795],[29.1435,-13.379],[29.183,-13.4415],[29.3615,-13.3255],[29.4345,-13.315],[29.53,-13.229],[29.576,-13.2055],[29.678,-13.262],[29.6465,-13.2945],[29.6515,-13.347],[29.613,-13.4035],[29.7265,-13.459],[29.7645,-13.4355],[29.815,-13.4445],[29.815,-13.097],[29.815,-12.4565],[29.815,-12.15],[29.7455,-12.1675],[29.721,-12.2185],[29.6475,-12.2345],[29.5985,-12.1955],[29.562,-12.2025],[29.479,-12.254],[29.459,-12.3095],[29.4815,-12.388],[29.53,-12.422],[29.4795,-12.46],[29.3825,-12.415],[29.3465,-12.421],[29.2695,-12.3605],[29.2395,-12.379],[29.177,-12.3725],[29.1205,-12.395],[29.0405,-12.3835],[29.0095,-12.2935],[28.9175,-12.1725],[28.8545,-12.135],[28.807,-12.067],[28.7775,-12.0475],[28.765,-11.9935],[28.719,-11.9905],[28.634,-11.9415],[28.61,-11.9065],[28.5755,-11.911],[28.5135,-11.877],[28.493,-11.845],[28.4355,-11.816],[28.4555,-11.775],[28.4305,-11.73],[28.434,-11.6515],[28.386,-11.5875],[28.396,-11.4755],[28.456,-11.3715],[28.457,-11.2925],[28.49,-11.238],[28.4825,-11.1975],[28.5,-11.147],[28.4765,-11.1035],[28.5125,-11.0205],[28.5105,-10.97],[28.5405,-10.9475],[28.544,-10.869],[28.562,-10.8215],[28.6255,-10.7155],[28.695,-10.6765],[28.6585,-10.6265],[28.675,-10.5685],[28.63,-10.5185],[28.644,-10.425],[28.6185,-10.3645],[28.636,-10.3105],[28.577,-10.221],[28.627,-10.161],[28.629,-10.066],[28.644,-10.02],[28.6215,-9.9935],[28.626,-9.9475],[28.6595,-9.883],[28.6755,-9.812],[28.6685,-9.751],[28.636,-9.747],[28.6055,-9.619],[28.6095,-9.589],[28.57,-9.545],[28.574,-9.493],[28.5115,-9.44],[28.518,-9.3545],[28.431,-9.324],[28.379,-9.2935],[28.3735,-9.2555],[28.3995,-9.226],[28.512,-9.1705],[28.6695,-9.058],[28.734,-9.0],[28.8865,-8.8135],[28.956,-8.686],[28.962,-8.6105],[28.9365,-8.545],[28.991,-8.462],[29.56,-8.381],[29.6255,-8.415],[29.702,-8.3695],[30.429,-8.275],[30.4985,-8.2965],[30.537,-8.2795],[30.567,-8.2975],[30.796,-8.2765]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/6f/Flag_of_the_Democratic_Republic_of_the_Congo.svg","name:en":"Democratic Republic of the Congo","wikidata":"Q974","ISO3166-1:alpha2":"CD","ISO3166-1:alpha3":"COD","ISO3166-1:numeric":"180"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[29.3755,-22.1955],[29.288,-22.1215],[29.264,-22.0715],[29.139,-22.072],[29.075,-22.042],[29.0405,-22.0035],[29.0225,-21.904],[29.065,-21.804],[28.861,-21.755],[28.7475,-21.701],[28.6645,-21.6735],[28.5825,-21.6305],[28.5035,-21.669],[28.3665,-21.603],[28.2925,-21.5895],[28.199,-21.6035],[28.0995,-21.5785],[28.022,-21.576],[27.921,-21.335],[27.8055,-21.176],[27.7515,-21.1545],[27.693,-21.0875],[27.7045,-21.037],[27.6895,-20.9335],[27.7275,-20.7975],[27.7325,-20.706],[27.7035,-20.6575],[27.7025,-20.604],[27.73,-20.523],[27.6955,-20.4905],[27.622,-20.4795],[27.5765,-20.4945],[27.4715,-20.468],[27.434,-20.4825],[27.3625,-20.4685],[27.2885,-20.499],[27.3045,-20.331],[27.285,-20.232],[27.217,-20.0935],[27.1435,-20.0795],[27.046,-20.011],[26.9805,-20.015],[26.8515,-19.962],[26.7265,-19.94],[26.703,-19.8875],[26.622,-19.883],[26.583,-19.804],[26.5335,-19.77],[26.445,-19.751],[26.388,-19.6695],[26.3285,-19.6515],[26.3585,-19.615],[26.3125,-19.576],[26.2465,-19.585],[26.1655,-19.5385],[26.142,-19.438],[26.0435,-19.2365],[26.042,-19.2105],[25.975,-19.1315],[25.967,-19.0635],[25.9965,-19.0315],[25.985,-18.9735],[25.952,-18.913],[25.8255,-18.8375],[25.7905,-18.72],[25.803,-18.687],[25.7825,-18.6245],[25.692,-18.573],[25.648,-18.4965],[25.6105,-18.4835],[25.5235,-18.384],[25.492,-18.3],[25.3935,-18.121],[25.319,-18.078],[25.2885,-18.027],[25.2655,-17.9485],[25.2375,-17.9125],[25.263,-17.7915],[25.262,-17.7905],[25.1625,-17.7785],[25.144,-17.808],[25.0835,-17.837],[25.052,-17.808],[25.0075,-17.8385],[24.954,-17.8005],[24.9105,-17.8105],[24.864,-17.8455],[24.732,-17.8925],[24.6965,-17.9445],[24.6655,-17.95],[24.6185,-17.996],[24.579,-18.07],[24.5055,-18.06],[24.482,-18.0105],[24.4265,-17.9535],[24.372,-17.949],[24.294,-18.0305],[24.1925,-18.02],[24.149,-18.075],[24.091,-18.1205],[23.9315,-18.2045],[23.925,-18.2565],[23.8965,-18.263],[23.806,-18.3415],[23.7895,-18.382],[23.722,-18.433],[23.6825,-18.436],[23.6565,-18.4785],[23.616,-18.5025],[23.5725,-18.482],[23.558,-18.336],[23.5205,-18.2695],[23.4105,-18.2035],[23.379,-18.135],[23.324,-18.082],[23.297,-18.001],[23.0985,-18.001],[22.5,-18.1175],[22.048,-18.205],[21.453,-18.3175],[20.999,-18.3175],[20.999,-19.166],[20.999,-19.866],[20.999,-20.5435],[20.999,-21.006],[20.999,-21.746],[20.9985,-22.0005],[20.58,-22.0005],[19.999,-22.0],[19.999,-22.281],[19.999,-23.309],[19.999,-23.863],[19.999,-24.434],[19.999,-24.764],[20.038,-24.8095],[20.0905,-24.833],[20.1155,-24.8805],[20.2035,-24.8965],[20.2655,-24.9285],[20.286,-24.9695],[20.384,-25.0345],[20.4125,-25.0825],[20.4465,-25.199],[20.4965,-25.269],[20.566,-25.395],[20.5985,-25.422],[20.643,-25.4985],[20.631,-25.526],[20.6975,-25.589],[20.6765,-25.6835],[20.7135,-25.7115],[20.7615,-25.7915],[20.7885,-25.803],[20.7875,-25.86],[20.807,-25.926],[20.84,-25.962],[20.817,-26.005],[20.862,-26.1355],[20.8155,-26.192],[20.7895,-26.2715],[20.761,-26.2855],[20.646,-26.435],[20.6175,-26.4445],[20.604,-26.521],[20.6315,-26.5845],[20.635,-26.665],[20.6145,-26.6865],[20.6505,-26.81],[20.676,-26.861],[20.763,-26.8665],[20.818,-26.823],[20.885,-26.7975],[20.978,-26.8115],[21.0065,-26.8445],[21.083,-26.8495],[21.1335,-26.8735],[21.264,-26.837],[21.404,-26.822],[21.486,-26.8415],[21.6045,-26.846],[21.627,-26.8665],[21.6945,-26.8615],[21.78,-26.8025],[21.7935,-26.7705],[21.7875,-26.676],[21.8235,-26.6595],[21.953,-26.6685],[22.0485,-26.635],[22.0775,-26.5815],[22.166,-26.504],[22.201,-26.4205],[22.1935,-26.395],[22.2475,-26.347],[22.367,-26.319],[22.422,-26.223],[22.4745,-26.2],[22.5495,-26.226],[22.5795,-26.157],[22.673,-26.0735],[22.669,-26.0145],[22.721,-26.0185],[22.723,-25.9085],[22.7695,-25.733],[22.8,-25.723],[22.8535,-25.6115],[22.814,-25.583],[22.8525,-25.5355],[22.864,-25.4795],[22.91,-25.4225],[22.9675,-25.3835],[22.978,-25.34],[23.1135,-25.3035],[23.1365,-25.317],[23.1925,-25.2775],[23.274,-25.2745],[23.294,-25.294],[23.3605,-25.286],[23.42,-25.3135],[23.4415,-25.2775],[23.5945,-25.397],[23.677,-25.427],[23.759,-25.469],[23.7615,-25.5005],[23.817,-25.51],[23.8435,-25.5515],[23.929,-25.638],[23.9665,-25.615],[24.003,-25.648],[24.066,-25.6505],[24.1065,-25.63],[24.1955,-25.622],[24.2885,-25.7255],[24.379,-25.765],[24.4485,-25.734],[24.606,-25.799],[24.678,-25.819],[24.713,-25.8055],[24.7935,-25.8255],[24.912,-25.798],[25.038,-25.7215],[25.1695,-25.7665],[25.199,-25.76],[25.337,-25.771],[25.514,-25.684],[25.5815,-25.638],[25.6635,-25.468],[25.6905,-25.3745],[25.7015,-25.289],[25.7315,-25.249],[25.8615,-24.9225],[25.8885,-24.882],[25.859,-24.7555],[25.956,-24.7475],[26.009,-24.7235],[26.1835,-24.688],[26.3935,-24.637],[26.4705,-24.5905],[26.5145,-24.485],[26.6015,-24.41],[26.665,-24.3795],[26.704,-24.322],[26.8,-24.3],[26.866,-24.2485],[26.8805,-24.197],[26.863,-24.0995],[26.909,-24.029],[26.928,-23.9225],[26.955,-23.874],[26.9415,-23.8435],[26.9645,-23.7775],[26.9715,-23.703],[26.9995,-23.653],[27.071,-23.67],[27.064,-23.627],[27.108,-23.5705],[27.148,-23.5515],[27.1925,-23.4985],[27.3035,-23.4625],[27.327,-23.4045],[27.4015,-23.4115],[27.462,-23.384],[27.5285,-23.3855],[27.564,-23.3485],[27.573,-23.266],[27.6045,-23.216],[27.7145,-23.2285],[27.784,-23.1735],[27.7825,-23.143],[27.9195,-23.0685],[27.944,-23.031],[27.935,-22.963],[28.0365,-22.914],[28.0395,-22.841],[28.11,-22.801],[28.163,-22.7555],[28.1585,-22.7215],[28.213,-22.6635],[28.2685,-22.6385],[28.345,-22.5715],[28.48,-22.571],[28.5195,-22.5875],[28.566,-22.5595],[28.6425,-22.5575],[28.709,-22.515],[28.8325,-22.4875],[28.869,-22.4475],[28.922,-22.458],[28.971,-22.378],[28.964,-22.319],[29.0375,-22.217],[29.1495,-22.216],[29.2175,-22.1785],[29.3755,-22.1955]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/fa/Flag_of_Botswana.svg","name:en":"Botswana","wikidata":"Q963","ISO3166-1:alpha2":"BW","ISO3166-1:alpha3":"BWA","ISO3166-1:numeric":"072"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[124.273,-9.419],[124.2775,-9.5025],[124.3415,-9.4825],[124.3515,-9.426],[124.404,-9.34],[124.462,-9.2995],[124.475,-9.1655],[124.433,-9.113],[124.3295,-9.117],[124.155,-9.178],[124.048,-9.231],[124.0415,-9.34],[124.1005,-9.41],[124.133,-9.4255],[124.218,-9.3665],[124.273,-9.419]]],[[[126.7625,-8.232],[126.147,-8.2895],[125.883,-8.314],[125.8275,-8.251],[125.696,-8.101],[125.6725,-8.0895],[125.34,-8.2325],[125.3215,-8.2915],[125.24,-8.444],[125.098,-8.519],[124.936,-8.7415],[124.9525,-8.9665],[124.9345,-8.995],[124.941,-9.047],[124.9845,-9.066],[125.0895,-9.011],[125.1135,-8.9655],[125.1855,-9.0265],[125.1715,-9.126],[125.176,-9.1725],[125.098,-9.2005],[125.0745,-9.1765],[125.014,-9.171],[124.983,-9.191],[124.9825,-9.2395],[125.0065,-9.295],[125.0795,-9.3925],[125.087,-9.463],[125.24,-9.5645],[125.584,-9.4345],[126.065,-9.2445],[126.6525,-9.0545],[127.179,-8.8095],[127.4375,-8.5945],[127.5335,-8.419],[127.397,-8.2785],[127.189,-8.2235],[126.7995,-8.2285],[126.7625,-8.232]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/26/Flag_of_East_Timor.svg","name:en":"East Timor","wikidata":"Q574","ISO3166-1:alpha2":"TL","ISO3166-1:alpha3":"TLS","ISO3166-1:numeric":"626"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[8.388,4.3675],[8.428,4.3185],[8.538,4.2855],[8.6185,4.2845],[8.7475,4.178],[8.792,4.021],[8.8315,3.9605],[8.9835,3.906],[9.047,3.856],[9.1255,3.771],[9.2875,3.7155],[9.414,3.6575],[9.438,3.618],[9.434,3.5195],[9.4575,3.459],[9.498,3.4065],[9.5905,3.3375],[9.699,3.2265],[9.754,3.0955],[9.716,3.0125],[9.6905,2.905],[9.6845,2.82],[9.6535,2.7225],[9.6265,2.5995],[9.621,2.45],[9.762,2.3905],[9.8375,2.325],[9.848,2.2455],[9.906,2.2075],[10.035,2.163],[10.167,2.152],[10.19,2.175],[10.656,2.174],[11.0,2.171],[11.36,2.172],[11.352,2.2225],[11.3965,2.3025],[11.61,2.2955],[11.7015,2.319],[11.754,2.271],[11.8695,2.2845],[12.015,2.2905],[12.156,2.2765],[12.2075,2.282],[12.249,2.2565],[12.304,2.2905],[12.3665,2.2675],[12.4545,2.252],[12.528,2.253],[12.5745,2.2705],[12.6415,2.24],[12.6835,2.244],[12.7515,2.2245],[12.8185,2.2525],[12.8615,2.2275],[12.9975,2.252],[13.0535,2.2395],[13.157,2.286],[13.2195,2.261],[13.248,2.2735],[13.3055,2.207],[13.294,2.1705],[13.8195,2.172],[14.292,2.172],[14.3555,2.1855],[14.413,2.1815],[14.443,2.1575],[14.572,2.179],[14.595,2.202],[14.644,2.1325],[14.718,2.1275],[14.808,2.0595],[14.8565,2.1015],[14.911,2.064],[14.8935,2.0155],[14.9685,2.008],[14.979,2.0355],[15.045,1.9795],[15.105,1.983],[15.122,2.014],[15.2015,2.0385],[15.2495,2.028],[15.305,1.969],[15.3035,1.9425],[15.347,1.912],[15.4855,1.9835],[15.616,1.9385],[15.7475,1.92],[15.8055,1.856],[15.8685,1.8285],[15.8855,1.7905],[15.96,1.7665],[16.021,1.766],[16.019,1.6785],[16.0575,1.652],[16.0825,1.6905],[16.145,1.6905],[16.134,1.8045],[16.0835,1.8995],[16.0515,2.0045],[16.0835,2.0475],[16.0815,2.1905],[16.184,2.2055],[16.1885,2.227],[16.144,2.3525],[16.078,2.4485],[16.0655,2.5295],[16.083,2.5965],[16.066,2.641],[16.0735,2.7095],[16.056,3.0205],[15.7755,3.27],[15.7335,3.2435],[15.3655,3.6795],[15.0745,4.0205],[15.135,4.037],[15.1445,4.068],[15.108,4.121],[15.0825,4.3085],[15.028,4.367],[15.014,4.415],[14.8875,4.4695],[14.871,4.4965],[14.81,4.5275],[14.73,4.6115],[14.7185,4.6455],[14.7125,4.868],[14.687,4.9245],[14.691,4.971],[14.673,5.0865],[14.6935,5.099],[14.651,5.215],[14.5675,5.239],[14.528,5.2745],[14.572,5.3825],[14.5995,5.416],[14.6025,5.4655],[14.626,5.518],[14.591,5.608],[14.6265,5.711],[14.6195,5.888],[14.603,5.921],[14.549,5.905],[14.485,5.92],[14.4165,6.0395],[14.43,6.0885],[14.553,6.1925],[14.5805,6.189],[14.7405,6.2625],[14.805,6.3465],[14.797,6.39],[14.8255,6.431],[14.966,6.7565],[15.0425,6.7615],[15.0645,6.788],[15.1195,6.9255],[15.1585,7.0585],[15.219,7.115],[15.211,7.224],[15.243,7.2675],[15.422,7.4175],[15.4935,7.525],[15.567,7.5945],[15.5855,7.668],[15.5875,7.774],[15.5065,7.792],[15.452,7.8855],[15.394,8.0465],[15.395,8.0935],[15.2,8.5125],[15.154,8.572],[15.151,8.606],[15.109,8.6595],[15.06,8.681],[14.9825,8.689],[14.989,8.7285],[14.9225,8.7785],[14.9,8.8135],[14.844,8.812],[14.745,8.8795],[14.5665,9.014],[14.4905,9.058],[14.464,9.115],[14.407,9.148],[14.3475,9.2085],[14.373,9.294],[14.339,9.31],[14.3045,9.3715],[14.2685,9.358],[14.204,9.4465],[14.15,9.5025],[14.1045,9.518],[14.0925,9.5505],[14.04,9.602],[13.9765,9.638],[14.0225,9.728],[14.131,9.82],[14.1735,9.904],[14.2065,10.002],[14.4635,10.002],[14.8025,9.935],[14.958,9.983],[15.033,9.9655],[15.06,9.9455],[15.1485,9.9945],[15.248,9.9895],[15.3645,9.959],[15.414,9.9335],[15.5235,9.952],[15.6885,9.993],[15.617,10.0455],[15.502,10.099],[15.4405,10.1975],[15.3455,10.298],[15.304,10.312],[15.2795,10.4055],[15.216,10.498],[15.1555,10.529],[15.1425,10.592],[15.161,10.626],[15.138,10.6865],[15.096,10.748],[15.0675,10.8235],[15.095,10.876],[15.079,10.958],[15.046,11.004],[15.092,11.0335],[15.095,11.168],[15.068,11.2015],[15.0485,11.2805],[15.0735,11.3265],[15.058,11.4145],[15.1445,11.5625],[15.102,11.5845],[15.0635,11.712],[15.122,11.7885],[15.089,11.855],[15.0495,11.8585],[15.0395,11.9105],[15.085,12.002],[15.051,12.0145],[15.0605,12.06],[15.038,12.104],[14.9935,12.088],[14.956,12.0995],[14.8855,12.165],[14.9095,12.1915],[14.8935,12.3075],[14.9085,12.3805],[14.848,12.518],[14.8545,12.576],[14.823,12.64],[14.772,12.635],[14.7615,12.6775],[14.7095,12.7265],[14.669,12.7195],[14.5945,12.746],[14.547,12.7925],[14.565,12.8365],[14.5605,12.9205],[14.535,12.946],[14.4665,13.0835],[14.0835,13.0835],[14.2035,12.538],[14.1775,12.481],[14.1895,12.405],[14.2225,12.362],[14.334,12.3735],[14.3765,12.3595],[14.439,12.3675],[14.4825,12.3525],[14.5255,12.2915],[14.591,12.2295],[14.6175,12.186],[14.659,12.198],[14.656,12.1385],[14.624,12.0495],[14.6445,11.9725],[14.643,11.912],[14.6045,11.8695],[14.6065,11.799],[14.5555,11.7055],[14.6,11.698],[14.644,11.65],[14.647,11.572],[14.618,11.51],[14.5175,11.468],[14.4715,11.428],[14.4325,11.4225],[14.3645,11.3595],[14.239,11.296],[14.1785,11.24],[13.976,11.311],[13.9345,11.2065],[13.856,11.0955],[13.815,11.0645],[13.7895,11.003],[13.7355,11.006],[13.7115,10.9635],[13.73,10.924],[13.717,10.863],[13.6505,10.813],[13.6265,10.7115],[13.5885,10.698],[13.5745,10.635],[13.547,10.6125],[13.5785,10.537],[13.531,10.4575],[13.535,10.4],[13.5005,10.3905],[13.5015,10.3375],[13.466,10.246],[13.4835,10.196],[13.47,10.161],[13.412,10.1215],[13.3395,10.114],[13.299,10.087],[13.2865,10.046],[13.2475,10.0055],[13.288,9.9795],[13.265,9.927],[13.237,9.911],[13.249,9.8575],[13.302,9.827],[13.2625,9.78],[13.234,9.614],[13.2095,9.557],[13.1245,9.5265],[13.0345,9.506],[12.9755,9.4645],[12.9455,9.422],[12.8785,9.394],[12.9025,9.3545],[12.9175,9.2485],[12.888,9.1775],[12.901,9.114],[12.823,8.9715],[12.8,8.8565],[12.819,8.8305],[12.784,8.7455],[12.7205,8.763],[12.6985,8.669],[12.575,8.614],[12.4875,8.643],[12.4465,8.6025],[12.4615,8.537],[12.342,8.4585],[12.3135,8.4255],[12.2675,8.448],[12.244,8.3865],[12.249,8.216],[12.256,8.1765],[12.1925,8.108],[12.201,8.009],[12.214,7.9835],[12.136,7.862],[12.098,7.8475],[12.0525,7.7355],[11.9965,7.667],[12.0115,7.6305],[12.005,7.5805],[12.019,7.5185],[11.9315,7.4865],[11.928,7.394],[11.879,7.3475],[11.847,7.2545],[11.8565,7.1685],[11.8805,7.108],[11.863,7.0775],[11.8025,7.0825],[11.779,7.046],[11.7375,7.05],[11.631,6.9895],[11.6035,6.909],[11.573,6.8995],[11.5795,6.8415],[11.5695,6.773],[11.585,6.7375],[11.5465,6.701],[11.5175,6.613],[11.462,6.611],[11.4275,6.579],[11.422,6.532],[11.316,6.5065],[11.28,6.538],[11.222,6.5395],[11.167,6.5],[11.097,6.5205],[11.0965,6.6795],[11.0305,6.7145],[10.9925,6.687],[10.9455,6.687],[10.916,6.7095],[10.914,6.7575],[10.8395,6.811],[10.8145,6.8535],[10.8415,6.9305],[10.7985,6.9625],[10.7665,6.9555],[10.7205,6.9885],[10.6795,7.0385],[10.6265,7.049],[10.5955,7.0785],[10.595,7.1475],[10.5715,7.162],[10.56,7.032],[10.5415,6.9395],[10.4815,6.9015],[10.462,6.916],[10.2155,6.8895],[10.172,6.942],[10.181,6.968],[10.1505,7.0385],[10.0125,6.904],[9.996,6.898],[9.863,6.776],[9.774,6.7845],[9.751,6.6525],[9.706,6.512],[9.5955,6.5285],[9.587,6.4735],[9.529,6.4425],[9.4675,6.456],[9.431,6.3155],[9.347,6.3535],[9.3345,6.292],[9.307,6.263],[9.2645,6.1815],[9.2115,6.1685],[9.169,6.1335],[9.1535,6.094],[9.0545,6.0005],[8.8605,5.845],[8.8505,5.805],[8.884,5.775],[8.842,5.6795],[8.904,5.619],[8.9215,5.564],[8.8335,5.4305],[8.8415,5.3915],[8.8145,5.284],[8.821,5.1845],[8.7835,5.113],[8.745,5.098],[8.724,5.041],[8.6955,5.013],[8.653,4.9175],[8.6205,4.9055],[8.607,4.8645],[8.6255,4.821],[8.544,4.8015],[8.526,4.737],[8.539,4.702],[8.4525,4.6165],[8.4075,4.5335],[8.403,4.442],[8.388,4.3675]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/4/4f/Flag_of_Cameroon.svg","name:en":"Cameroon","wikidata":"Q1009","ISO3166-1:alpha2":"CM","ISO3166-1:alpha3":"CMR","ISO3166-1:numeric":"120"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[24.256,8.687],[24.1685,8.6985],[24.127,8.6855],[23.926,8.7185],[23.8835,8.708],[23.8305,8.727],[23.734,8.705],[23.597,8.7345],[23.5585,8.705],[23.5265,8.7085],[23.4975,8.773],[23.509,8.812],[23.5495,8.847],[23.5805,8.9015],[23.583,8.9945],[23.5335,8.9605],[23.4575,8.9905],[23.4715,9.1245],[23.4935,9.174],[23.5515,9.1805],[23.65,9.2755],[23.6405,9.346],[23.666,9.436],[23.632,9.4495],[23.6265,9.547],[23.6965,9.6715],[23.6695,9.867],[23.3065,10.459],[23.252,10.493],[23.151,10.6005],[23.013,10.6955],[22.8905,10.8825],[22.878,10.9205],[22.7855,10.931],[22.7675,10.955],[22.653,10.966],[22.6005,10.9855],[22.529,10.9765],[22.466,11.0015],[22.415,10.963],[22.323,10.9415],[22.271,10.9035],[22.2505,10.912],[22.202,10.8705],[22.176,10.814],[22.113,10.8325],[22.0475,10.8305],[22.015,10.808],[22.0085,10.7515],[21.9075,10.714],[21.8615,10.669],[21.811,10.677],[21.7165,10.6355],[21.7015,10.5145],[21.748,10.4065],[21.7245,10.366],[21.7155,10.2905],[21.688,10.2845],[21.667,10.236],[21.6145,10.2135],[21.5355,10.212],[21.4735,10.148],[21.432,10.038],[21.342,9.9585],[21.2765,9.9805],[21.225,9.9425],[21.1885,9.8805],[21.1155,9.822],[21.103,9.7725],[21.015,9.7385],[20.986,9.612],[20.9565,9.6055],[20.896,9.5215],[20.826,9.458],[20.831,9.4285],[20.7745,9.4055],[20.738,9.3705],[20.678,9.3595],[20.668,9.2985],[20.6035,9.298],[20.538,9.3185],[20.498,9.277],[20.488,9.2095],[20.434,9.137],[20.3715,9.1085],[20.2535,9.115],[20.207,9.1395],[20.147,9.1115],[20.062,9.1345],[20.0165,9.093],[19.8785,9.0525],[19.7865,9.048],[19.684,9.0135],[19.5715,9.0295],[19.51,9.0185],[19.2635,9.016],[19.1775,9.027],[19.147,9.0095],[19.0725,9.015],[18.978,8.9405],[18.9115,8.9235],[18.8615,8.878],[18.907,8.8505],[19.0335,8.7315],[19.1005,8.7005],[19.1065,8.664],[19.0465,8.5935],[19.039,8.5375],[18.9295,8.4375],[18.919,8.387],[18.8495,8.3455],[18.8335,8.29],[18.7865,8.2545],[18.6735,8.212],[18.63,8.1465],[18.637,8.091],[18.6015,8.0465],[18.192,8.018],[18.032,8.0095],[17.9215,7.9585],[17.6845,7.983],[17.606,7.9295],[17.535,7.925],[17.5105,7.8725],[17.4725,7.9],[17.36,7.856],[17.2765,7.8105],[17.258,7.753],[17.208,7.7495],[17.1675,7.7185],[17.1525,7.67],[17.106,7.695],[17.0355,7.639],[16.9525,7.645],[16.9015,7.6035],[16.86,7.545],[16.809,7.5375],[16.776,7.607],[16.73,7.639],[16.6845,7.6395],[16.66,7.672],[16.6615,7.742],[16.5895,7.774],[16.577,7.874],[16.506,7.8455],[16.479,7.7895],[16.432,7.81],[16.407,7.7705],[16.4235,7.7155],[16.398,7.683],[16.296,7.6545],[16.2475,7.612],[16.1855,7.6145],[16.1635,7.5945],[16.0565,7.5775],[16.039,7.534],[15.975,7.4835],[15.8095,7.441],[15.743,7.4785],[15.728,7.519],[15.5465,7.511],[15.4935,7.525],[15.422,7.4175],[15.243,7.2675],[15.211,7.224],[15.219,7.115],[15.1585,7.0585],[15.1195,6.9255],[15.0645,6.788],[15.0425,6.7615],[14.966,6.7565],[14.8255,6.431],[14.797,6.39],[14.805,6.3465],[14.7405,6.2625],[14.5805,6.189],[14.553,6.1925],[14.43,6.0885],[14.4165,6.0395],[14.485,5.92],[14.549,5.905],[14.603,5.921],[14.6195,5.888],[14.6265,5.711],[14.591,5.608],[14.626,5.518],[14.6025,5.4655],[14.5995,5.416],[14.572,5.3825],[14.528,5.2745],[14.5675,5.239],[14.651,5.215],[14.6935,5.099],[14.673,5.0865],[14.691,4.971],[14.687,4.9245],[14.7125,4.868],[14.7185,4.6455],[14.73,4.6115],[14.81,4.5275],[14.871,4.4965],[14.8875,4.4695],[15.014,4.415],[15.028,4.367],[15.0825,4.3085],[15.108,4.121],[15.1445,4.068],[15.135,4.037],[15.0745,4.0205],[15.3655,3.6795],[15.7335,3.2435],[15.7755,3.27],[16.056,3.0205],[16.0735,2.7095],[16.066,2.641],[16.083,2.5965],[16.0655,2.5295],[16.078,2.4485],[16.144,2.3525],[16.1885,2.227],[16.184,2.2055],[16.207,2.221],[16.499,2.843],[16.496,2.8845],[16.466,2.9225],[16.469,2.981],[16.512,3.0605],[16.4825,3.132],[16.484,3.162],[16.5355,3.2485],[16.529,3.2755],[16.561,3.339],[16.572,3.444],[16.589,3.482],[16.6595,3.5335],[16.767,3.55],[16.7975,3.526],[16.862,3.5245],[16.8765,3.566],[16.9605,3.556],[16.988,3.5355],[17.0335,3.5405],[17.0715,3.5755],[17.234,3.5845],[17.2565,3.617],[17.3035,3.6265],[17.3605,3.618],[17.414,3.6795],[17.4595,3.7085],[17.5025,3.706],[17.564,3.6535],[17.6155,3.6295],[17.723,3.6265],[17.834,3.6105],[17.854,3.5375],[17.9475,3.573],[17.995,3.5395],[18.0435,3.566],[18.1195,3.5605],[18.16,3.533],[18.178,3.4835],[18.222,3.4905],[18.265,3.577],[18.4425,3.5955],[18.4715,3.641],[18.5335,3.599],[18.594,3.485],[18.626,3.471],[18.608,3.518],[18.6045,3.617],[18.5785,3.777],[18.5935,3.818],[18.6095,3.925],[18.6475,3.95],[18.659,3.986],[18.6465,4.0615],[18.545,4.321],[18.603,4.371],[18.621,4.3565],[18.7175,4.369],[18.786,4.4275],[18.806,4.468],[18.8195,4.5545],[18.8365,4.587],[18.9215,4.6525],[18.9385,4.701],[19.0195,4.767],[19.107,4.941],[19.197,4.9415],[19.223,4.995],[19.362,5.0735],[19.3705,5.0965],[19.437,5.1325],[19.4805,5.122],[19.5285,5.1495],[19.613,5.13],[19.6795,5.1465],[19.7215,5.1265],[19.8195,5.1075],[19.863,5.033],[19.9135,4.9825],[20.0075,4.9715],[20.1065,4.9025],[20.173,4.892],[20.254,4.789],[20.352,4.7665],[20.3855,4.7335],[20.4075,4.663],[20.4415,4.646],[20.464,4.596],[20.447,4.567],[20.4655,4.524],[20.5215,4.4565],[20.5805,4.4125],[20.7095,4.433],[20.797,4.423],[20.8415,4.4545],[20.9485,4.446],[21.0765,4.4],[21.116,4.34],[21.2265,4.293],[21.282,4.345],[21.3415,4.2935],[21.387,4.281],[21.429,4.293],[21.478,4.2645],[21.5585,4.253],[21.6485,4.3125],[21.737,4.312],[21.8095,4.287],[21.859,4.2465],[21.949,4.2335],[21.9965,4.2455],[22.0885,4.218],[22.165,4.155],[22.2585,4.115],[22.3815,4.121],[22.4525,4.1345],[22.546,4.214],[22.544,4.288],[22.575,4.344],[22.596,4.48],[22.62,4.4915],[22.6895,4.4695],[22.731,4.5565],[22.7355,4.6305],[22.782,4.7145],[22.816,4.727],[22.842,4.6995],[22.893,4.75],[22.8995,4.815],[22.977,4.834],[23.01,4.757],[23.1105,4.7115],[23.157,4.7395],[23.196,4.723],[23.2305,4.6755],[23.266,4.6665],[23.3285,4.608],[23.429,4.599],[23.427,4.6495],[23.4615,4.6785],[23.5025,4.6775],[23.5945,4.762],[23.676,4.765],[23.7125,4.7865],[23.7665,4.7835],[23.828,4.8325],[23.891,4.833],[23.956,4.81],[23.962,4.875],[24.0485,4.867],[24.111,4.9185],[24.136,4.895],[24.2155,4.954],[24.2665,4.969],[24.282,4.9965],[24.3555,5.006],[24.393,5.0295],[24.363,5.0725],[24.4095,5.102],[24.432,5.0635],[24.4695,5.1045],[24.534,5.083],[24.5685,5.033],[24.625,5.013],[24.6305,4.977],[24.672,4.9675],[24.6785,4.908],[24.783,4.8965],[24.8,4.9265],[24.9115,4.952],[24.962,4.9875],[24.996,4.9585],[25.0645,4.928],[25.086,4.9775],[25.2485,5.026],[25.312,5.031],[25.344,5.11],[25.308,5.191],[25.335,5.261],[25.4425,5.337],[25.5,5.344],[25.579,5.3785],[25.604,5.339],[25.7075,5.301],[25.752,5.244],[25.781,5.259],[25.8265,5.2015],[25.9485,5.2045],[25.9805,5.247],[26.0615,5.1995],[26.093,5.246],[26.1575,5.2615],[26.214,5.204],[26.244,5.2025],[26.2935,5.1635],[26.386,5.1515],[26.4535,5.0945],[26.451,5.068],[26.515,5.0485],[26.571,5.083],[26.6385,5.0935],[26.6595,5.08],[26.747,5.109],[26.862,5.038],[26.88,5.0485],[26.9295,5.1375],[27.022,5.1865],[27.086,5.2085],[27.1355,5.2075],[27.2295,5.153],[27.2625,5.151],[27.4415,5.074],[27.449,5.0195],[27.466,5.0855],[27.4355,5.099],[27.4135,5.148],[27.318,5.2175],[27.3035,5.28],[27.254,5.3235],[27.2345,5.429],[27.2635,5.5185],[27.287,5.54],[27.2815,5.601],[27.2375,5.606],[27.244,5.651],[27.2005,5.744],[27.103,5.8105],[27.0685,5.8005],[26.9875,5.8645],[26.9335,5.865],[26.9195,5.904],[26.829,5.9015],[26.7825,6.0005],[26.7025,6.0175],[26.6615,5.997],[26.5965,6.032],[26.569,6.028],[26.514,6.1155],[26.5305,6.224],[26.4695,6.2235],[26.489,6.2795],[26.3965,6.31],[26.3635,6.352],[26.3,6.3965],[26.32,6.5125],[26.403,6.6175],[26.415,6.6535],[26.345,6.6815],[26.31,6.7105],[26.2655,6.6965],[26.2485,6.739],[26.184,6.757],[26.175,6.8125],[26.109,6.8165],[26.0785,6.85],[26.0585,6.957],[26.0395,7.003],[25.9385,7.0405],[25.895,7.099],[25.841,7.111],[25.8205,7.156],[25.6535,7.205],[25.57,7.238],[25.536,7.278],[25.484,7.27],[25.4055,7.341],[25.369,7.3445],[25.3405,7.426],[25.287,7.47],[25.1975,7.495],[25.1725,7.5745],[25.2305,7.6335],[25.2895,7.652],[25.282,7.7835],[25.2465,7.846],[25.1775,7.9105],[25.0875,7.8955],[25.047,7.9445],[24.969,7.977],[24.9125,8.0315],[24.8805,8.0935],[24.8585,8.1695],[24.8,8.1955],[24.7625,8.1865],[24.7225,8.2105],[24.6345,8.221],[24.539,8.2055],[24.483,8.2345],[24.4705,8.2685],[24.3335,8.2665],[24.2305,8.285],[24.163,8.3315],[24.141,8.3765],[24.1635,8.474],[24.268,8.592],[24.229,8.6305],[24.256,8.687]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/6/6f/Flag_of_the_Central_African_Republic.svg","name:en":"Central African Republic","wikidata":"Q929","ISO3166-1:alpha2":"CF","ISO3166-1:alpha3":"CAF","ISO3166-1:numeric":"140"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[36.5605,14.2575],[36.6335,14.3135],[36.6955,14.3015],[36.744,14.3225],[36.853,14.322],[36.965,14.295],[37.014,14.2515],[37.092,14.2715],[37.1015,14.336],[37.1355,14.4095],[37.2095,14.44],[37.312,14.4475],[37.373,14.3835],[37.404,14.3345],[37.406,14.29],[37.4715,14.251],[37.4675,14.2155],[37.5275,14.1845],[37.9125,14.894],[38.0165,14.746],[38.0565,14.7155],[38.0915,14.7165],[38.1435,14.6755],[38.2325,14.692],[38.2655,14.6705],[38.271,14.617],[38.319,14.557],[38.4295,14.453],[38.4555,14.4135],[38.525,14.4165],[38.596,14.442],[38.647,14.4425],[38.6895,14.4645],[38.7945,14.4665],[38.9005,14.505],[38.936,14.54],[38.9785,14.545],[39.0295,14.637],[39.0995,14.6355],[39.154,14.653],[39.1575,14.6085],[39.2055,14.5655],[39.241,14.563],[39.2635,14.49],[39.234,14.4515],[39.36,14.4835],[39.3705,14.537],[39.4475,14.5055],[39.4895,14.505],[39.5095,14.552],[39.5865,14.609],[39.6435,14.605],[39.713,14.5555],[39.765,14.5485],[39.821,14.4835],[39.8385,14.4905],[39.9305,14.415],[40.0325,14.4785],[40.037,14.5045],[40.0905,14.548],[40.1475,14.5395],[40.213,14.387],[40.2595,14.411],[40.365,14.3665],[40.4515,14.307],[40.5725,14.2695],[40.8105,14.172],[40.9435,14.0805],[40.995,14.0165],[41.1155,13.8275],[41.172,13.728],[41.2505,13.6105],[41.309,13.5795],[41.403,13.501],[41.449,13.4885],[41.503,13.4455],[41.6425,13.385],[41.6685,13.3235],[41.7215,13.2735],[41.738,13.2365],[41.8105,13.1665],[41.8905,13.0745],[41.9665,12.9235],[42.03,12.868],[42.0575,12.801],[42.2195,12.7625],[42.2785,12.6355],[42.404,12.4685],[42.464,12.524],[42.567,12.476],[42.688,12.3625],[42.752,12.385],[42.764,12.4115],[42.825,12.434],[42.7975,12.477],[42.8255,12.541],[42.8595,12.5495],[42.8895,12.617],[42.9195,12.613],[42.9815,12.6495],[43.151,12.7205],[43.298,12.7925],[43.249,12.8675],[43.2125,12.9695],[43.145,13.068],[43.079,13.1335],[42.989,13.2085],[42.9295,13.2365],[42.824,13.2505],[42.8545,13.3585],[42.834,13.4275],[42.7235,13.458],[42.637,13.5975],[42.6275,13.6585],[42.5965,13.741],[42.4965,13.6985],[42.464,13.6685],[42.4235,13.7155],[42.3265,13.879],[42.27,13.928],[42.191,13.9545],[42.163,14.0095],[42.1175,14.0555],[42.061,14.085],[41.9875,14.0955],[41.876,14.1365],[41.858,14.1955],[41.813,14.255],[41.749,14.2945],[41.691,14.3075],[41.6505,14.368],[41.5945,14.4255],[41.523,14.5255],[41.487,14.5995],[41.452,14.644],[41.377,14.7065],[41.3255,14.7745],[41.286,14.801],[41.163,14.848],[41.07,14.8685],[41.019,14.951],[40.969,15.003],[40.862,15.044],[40.751,15.126],[40.6985,15.1545],[40.738,15.194],[40.8645,15.2875],[40.9715,15.319],[41.0175,15.353],[41.062,15.41],[41.082,15.469],[41.079,15.551],[41.0405,15.6275],[41.052,15.692],[41.0405,15.761],[41.005,15.8215],[40.875,15.922],[40.8395,15.968],[40.717,16.064],[40.607,16.102],[40.5285,16.1045],[40.4825,16.092],[40.431,16.154],[40.4515,16.2385],[40.448,16.3825],[40.394,16.4825],[40.3945,16.544],[40.372,16.627],[40.3195,16.6985],[40.2585,16.7355],[40.151,16.752],[40.069,16.734],[40.006,16.733],[39.9015,16.683],[39.8115,16.724],[39.7365,16.725],[39.5655,16.656],[39.5335,16.664],[39.501,16.7345],[39.4125,16.804],[39.322,16.8215],[39.2655,16.959],[39.138,17.4315],[39.0765,17.573],[38.997,17.724],[38.852,17.93],[38.8355,17.983],[38.788,18.071],[38.5825,18.0205],[38.452,17.8995],[38.3445,17.6445],[38.2735,17.603],[38.262,17.5355],[38.2225,17.529],[38.19,17.559],[38.1335,17.5485],[38.137,17.504],[38.0905,17.502],[38.087,17.5495],[38.046,17.548],[37.9685,17.5015],[37.934,17.4585],[37.8955,17.4415],[37.831,17.483],[37.791,17.4685],[37.7445,17.382],[37.5835,17.3485],[37.502,17.3165],[37.502,17.197],[37.396,17.0545],[37.307,17.061],[37.252,17.025],[37.2035,17.0325],[37.158,17.0155],[37.099,17.0525],[37.026,17.077],[36.9885,16.9375],[37.0135,16.9135],[37.009,16.7825],[36.9805,16.706],[36.9165,16.6505],[36.9195,16.593],[36.8985,16.537],[36.906,16.4865],[36.9575,16.419],[36.9505,16.3475],[36.9695,16.3055],[36.9655,16.256],[36.9205,16.2245],[36.7635,15.808],[36.698,15.753],[36.6105,15.437],[36.5485,15.252],[36.4335,15.1675],[36.4605,14.983],[36.5235,14.3645],[36.5415,14.278],[36.5605,14.2575]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/2/29/Flag_of_Eritrea.svg","name:en":"Eritrea","wikidata":"Q986","ISO3166-1:alpha2":"ER","ISO3166-1:alpha3":"ERI","ISO3166-1:numeric":"232"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[33.067,34.617],[33.1515,34.6065],[33.231,34.545],[33.2675,34.4995],[33.47,34.546],[33.7045,34.633],[33.79,34.685],[33.8355,34.74],[33.7595,34.8795],[33.7155,34.9295],[33.7,35.033],[33.7645,35.0395],[33.818,35.0715],[33.86,34.974],[33.921,34.9585],[33.9445,34.9285],[33.9805,34.875],[33.9865,34.766],[34.116,34.754],[34.193,34.773],[34.28,34.831],[34.329,34.92],[34.3295,34.999],[34.306,35.066],[34.2305,35.1765],[34.288,35.238],[34.4485,35.325],[34.7235,35.488],[34.767,35.526],[34.83,35.6205],[34.8545,35.6945],[34.8375,35.786],[34.7955,35.8425],[34.7185,35.8915],[34.657,35.909],[34.5755,35.9115],[34.5135,35.8985],[34.3305,35.839],[34.0765,35.747],[33.937,35.6665],[33.6815,35.604],[33.5535,35.562],[33.302,35.554],[33.156,35.5695],[32.97,35.601],[32.869,35.6015],[32.7935,35.5775],[32.742,35.5445],[32.6955,35.4905],[32.671,35.399],[32.6085,35.397],[32.442,35.3575],[32.363,35.3055],[32.2775,35.317],[32.183,35.3005],[32.115,35.2645],[32.0575,35.2005],[32.032,35.131],[32.0265,35.0095],[32.0895,34.807],[32.1385,34.751],[32.1925,34.651],[32.265,34.5875],[32.4115,34.5125],[32.6285,34.4485],[32.744,34.439],[32.7765,34.604],[32.7545,34.6495],[32.827,34.706],[32.9005,34.665],[32.9435,34.671],[32.9695,34.639],[33.014,34.644],[33.067,34.617]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/d4/Flag_of_Cyprus.svg","name:en":"Cyprus","wikidata":"Q229","ISO3166-1:alpha2":"CY","ISO3166-1:alpha3":"CYP","ISO3166-1:numeric":"196"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[44.8095,39.6275],[44.9035,39.577],[44.91,39.525],[44.952,39.492],[44.964,39.424],[45.0175,39.406],[45.0865,39.351],[45.185,39.2205],[45.2475,39.1855],[45.3135,39.2],[45.3525,39.133],[45.4525,39.055],[45.455,38.9905],[45.6185,38.9425],[45.69,38.9515],[45.737,38.9275],[45.918,38.8735],[45.979,38.879],[46.112,38.865],[46.1405,38.8445],[46.1495,38.8895],[46.1095,38.954],[46.1015,39.016],[46.07,39.078],[46.031,39.0925],[45.9895,39.2005],[45.9985,39.2915],[45.8615,39.3565],[45.7925,39.369],[45.804,39.428],[45.838,39.4685],[45.799,39.5715],[45.6945,39.6035],[45.6235,39.5635],[45.5905,39.57],[45.492,39.5115],[45.342,39.542],[45.243,39.6115],[45.172,39.593],[45.187,39.677],[45.1345,39.7435],[45.061,39.7945],[45.007,39.7505],[44.9425,39.7265],[44.888,39.7485],[44.7635,39.7145],[44.8095,39.6275]]],[[[49.2125,38.4085],[49.3115,38.709],[49.467,39.18],[49.603,39.5885],[49.711,39.904],[49.799,40.064],[49.919,40.144],[50.058,40.1835],[50.9115,40.15],[51.009,40.404],[50.475,40.555],[49.952,40.703],[49.851,40.75],[49.717,40.8455],[49.2285,41.4455],[48.814,41.9505],[48.5925,41.843],[48.5555,41.7825],[48.491,41.7275],[48.3775,41.591],[48.2845,41.561],[48.203,41.5125],[48.065,41.4925],[48.003,41.4165],[47.9915,41.3555],[47.8905,41.2875],[47.9115,41.255],[47.8845,41.2185],[47.8205,41.222],[47.7835,41.185],[47.7265,41.1935],[47.701,41.226],[47.6185,41.234],[47.564,41.198],[47.5065,41.226],[47.4985,41.2685],[47.377,41.2725],[47.3005,41.308],[47.252,41.3985],[47.222,41.419],[47.1715,41.527],[47.11,41.575],[47.0515,41.5545],[46.9915,41.595],[47.0125,41.6275],[46.8665,41.7205],[46.7655,41.801],[46.757,41.8625],[46.6215,41.824],[46.5565,41.8205],[46.5515,41.867],[46.5085,41.8895],[46.4635,41.8655],[46.422,41.908],[46.3985,41.8445],[46.3045,41.7755],[46.216,41.7635],[46.1815,41.7345],[46.2075,41.6535],[46.1955,41.63],[46.2975,41.572],[46.331,41.5015],[46.5225,41.4115],[46.6165,41.3905],[46.697,41.3195],[46.7,41.2415],[46.6675,41.219],[46.66,41.131],[46.631,41.098],[46.55,41.1125],[46.4925,41.0555],[46.458,41.098],[46.369,41.1195],[46.2915,41.174],[46.1895,41.192],[45.953,41.178],[45.887,41.211],[45.817,41.222],[45.7415,41.2585],[45.7005,41.298],[45.7405,41.344],[45.6485,41.379],[45.601,41.3735],[45.564,41.407],[45.4545,41.455],[45.3915,41.4275],[45.309,41.473],[45.165,41.4065],[45.093,41.339],[45.014,41.2965],[45.052,41.2395],[45.0515,41.193],[45.127,41.1995],[45.202,41.138],[45.15,41.1135],[45.099,41.12],[45.0755,41.069],[45.215,41.0385],[45.251,41.0135],[45.3685,41.008],[45.454,40.969],[45.4765,40.93],[45.602,40.8825],[45.608,40.8505],[45.5455,40.7745],[45.43,40.7465],[45.3635,40.655],[45.388,40.6185],[45.4595,40.5815],[45.4385,40.52],[45.512,40.4555],[45.5895,40.4305],[45.652,40.367],[45.697,40.367],[45.7855,40.329],[45.9305,40.297],[45.9595,40.2755],[45.9785,40.1905],[45.955,40.135],[45.904,40.104],[45.912,40.0755],[45.8805,40.021],[45.834,39.99],[45.796,40.0255],[45.6215,40.021],[45.611,39.974],[45.701,39.968],[45.7805,39.947],[45.826,39.826],[45.941,39.7875],[45.969,39.792],[46.08,39.685],[46.155,39.651],[46.1715,39.615],[46.2495,39.601],[46.3345,39.636],[46.4125,39.631],[46.434,39.569],[46.489,39.587],[46.5665,39.572],[46.5735,39.541],[46.51,39.525],[46.5055,39.483],[46.4585,39.4495],[46.3855,39.433],[46.39,39.388],[46.448,39.3395],[46.494,39.336],[46.547,39.26],[46.5895,39.2355],[46.544,39.1755],[46.462,39.1995],[46.44,39.1705],[46.531,39.0945],[46.546,39.0035],[46.5125,38.936],[46.534,38.867],[46.6035,38.91],[46.6735,38.978],[46.6955,39.018],[46.762,39.037],[46.7905,39.087],[46.8665,39.1405],[46.9255,39.1645],[46.9635,39.1405],[47.054,39.194],[47.058,39.238],[47.133,39.292],[47.2155,39.319],[47.296,39.367],[47.4205,39.465],[47.753,39.606],[47.8125,39.659],[47.9145,39.6615],[47.9855,39.709],[48.032,39.6925],[48.332,39.4285],[48.361,39.394],[48.248,39.3305],[48.211,39.329],[48.13,39.271],[48.141,39.208],[48.2135,39.1665],[48.2305,39.134],[48.303,39.109],[48.339,39.034],[48.271,38.9675],[48.1455,38.946],[48.088,38.947],[48.028,38.8995],[48.0205,38.838],[48.1075,38.77],[48.192,38.756],[48.249,38.726],[48.2525,38.662],[48.295,38.6475],[48.321,38.602],[48.425,38.6135],[48.472,38.5535],[48.5915,38.453],[48.608,38.4155],[48.6595,38.3935],[48.7385,38.411],[48.7915,38.4515],[49.2125,38.4085]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/d/dd/Flag_of_Azerbaijan.svg","name:en":"Azerbaijan","wikidata":"Q227","ISO3166-1:alpha2":"AZ","ISO3166-1:alpha3":"AZE","ISO3166-1:numeric":"031"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[61.274,35.605],[61.2825,35.538],[61.2335,35.4625],[61.2265,35.4215],[61.1875,35.3995],[61.1905,35.293],[61.092,35.2635],[61.093,35.183],[61.14,35.102],[61.1085,35.03],[61.0975,34.952],[61.0575,34.9075],[61.068,34.8125],[61.003,34.7085],[60.9845,34.62],[60.922,34.623],[60.8975,34.5675],[60.8485,34.542],[60.7425,34.527],[60.8075,34.462],[60.8495,34.3685],[60.9185,34.305],[60.6865,34.3105],[60.669,34.272],[60.6205,34.244],[60.5375,34.1505],[60.5175,34.062],[60.582,33.8055],[60.547,33.7315],[60.5515,33.64],[60.5815,33.597],[60.7035,33.5455],[60.903,33.54],[60.851,33.482],[60.8665,33.4215],[60.8245,33.4],[60.634,33.228],[60.5835,33.13],[60.6295,33.021],[60.7095,32.696],[60.815,32.4815],[60.859,32.2665],[60.883,32.1975],[60.819,32.0115],[60.8325,31.98],[60.818,31.89],[60.8135,31.7085],[60.856,31.4865],[61.7065,31.376],[61.7785,31.3025],[61.777,31.214],[61.8305,31.092],[61.814,30.9555],[61.782,30.911],[61.805,30.8395],[61.5115,30.5385],[61.343,30.359],[60.873,29.8585],[61.564,29.658],[61.8975,29.56],[62.471,29.3895],[63.233,29.4575],[63.5765,29.487],[64.0545,29.4075],[64.128,29.3785],[64.166,29.408],[64.142,29.4365],[64.1795,29.4835],[64.249,29.499],[64.2635,29.522],[64.3445,29.525],[64.5715,29.5865],[65.065,29.5295],[65.493,29.6445],[65.6965,29.705],[65.8095,29.7295],[66.25,29.8495],[66.332,29.92],[66.373,29.9715],[66.232,30.063],[66.289,30.153],[66.3265,30.2475],[66.3415,30.3845],[66.3625,30.4185],[66.3565,30.4765],[66.2865,30.5255],[66.288,30.577],[66.392,30.9405],[66.5785,30.9765],[66.688,31.0825],[66.7155,31.186],[66.813,31.223],[66.834,31.265],[66.956,31.308],[67.033,31.3105],[67.024,31.2565],[67.07,31.214],[67.1695,31.2455],[67.1975,31.217],[67.279,31.1995],[67.4,31.211],[67.4855,31.2325],[67.678,31.2935],[67.722,31.327],[67.7875,31.3325],[67.796,31.383],[67.75,31.4165],[67.651,31.3925],[67.571,31.5245],[67.6465,31.5285],[67.7165,31.514],[67.8575,31.624],[67.9745,31.6405],[68.0705,31.696],[68.1465,31.8045],[68.1795,31.817],[68.2655,31.8035],[68.2795,31.757],[68.425,31.756],[68.4615,31.735],[68.523,31.7355],[68.5655,31.7145],[68.591,31.753],[68.475,31.7735],[68.5755,31.834],[68.643,31.778],[68.7085,31.771],[68.728,31.6955],[68.7875,31.6545],[68.7895,31.6245],[68.908,31.5965],[68.96,31.649],[69.02,31.6295],[69.0405,31.6615],[69.116,31.7005],[69.193,31.847],[69.33,31.9295],[69.3025,31.987],[69.292,32.095],[69.27,32.162],[69.278,32.3615],[69.2395,32.4645],[69.278,32.529],[69.371,32.5625],[69.454,32.6585],[69.438,32.731],[69.3875,32.768],[69.441,32.804],[69.5065,32.896],[69.4955,32.933],[69.4995,33.0205],[69.573,33.0985],[69.672,33.101],[69.7985,33.131],[69.879,33.0945],[69.941,33.131],[70.0205,33.1385],[70.0735,33.22],[70.096,33.205],[70.166,33.2215],[70.3285,33.343],[70.297,33.43],[70.251,33.44],[70.1995,33.4875],[70.1715,33.539],[70.1985,33.6195],[70.1435,33.658],[70.1535,33.695],[69.9715,33.7585],[69.9155,33.887],[69.856,33.949],[69.9045,34.0395],[70.0485,34.035],[70.0875,34.0085],[70.149,34.0145],[70.194,33.983],[70.2905,33.9815],[70.325,33.966],[70.4145,33.9675],[70.4595,33.945],[70.547,33.943],[70.584,33.9625],[70.643,33.9525],[70.777,33.962],[70.822,33.9785],[70.8835,33.974],[71.0305,34.054],[71.0825,34.0635],[71.071,34.1095],[71.13,34.1645],[71.13,34.2825],[71.173,34.365],[71.1155,34.377],[71.1075,34.4335],[71.0595,34.4245],[71.024,34.4505],[71.011,34.534],[71.025,34.5595],[71.1145,34.628],[71.0895,34.6785],[71.187,34.7495],[71.2775,34.7995],[71.296,34.8775],[71.351,34.9145],[71.475,34.9495],[71.507,35.006],[71.5525,35.0225],[71.532,35.091],[71.625,35.139],[71.6815,35.2095],[71.6335,35.2255],[71.564,35.2785],[71.5445,35.3125],[71.6555,35.437],[71.594,35.5],[71.6205,35.571],[71.521,35.6065],[71.4995,35.6295],[71.5365,35.6695],[71.553,35.7225],[71.494,35.7495],[71.4775,35.8215],[71.431,35.888],[71.396,35.8915],[71.368,35.968],[71.3225,35.959],[71.197,36.041],[71.214,36.0825],[71.3605,36.204],[71.436,36.2325],[71.4505,36.272],[71.583,36.345],[71.558,36.3725],[71.616,36.403],[71.657,36.4835],[71.8065,36.3995],[71.8205,36.4345],[71.8095,36.508],[71.9165,36.5085],[71.936,36.5465],[72.0035,36.5575],[72.0305,36.592],[72.088,36.5965],[72.0965,36.647],[72.2095,36.6635],[72.1845,36.7115],[72.2535,36.7525],[72.2985,36.74],[72.3355,36.7665],[72.5025,36.784],[72.5615,36.829],[72.6525,36.852],[72.7175,36.837],[72.768,36.854],[72.818,36.8415],[72.93,36.843],[72.943,36.868],[73.0295,36.8615],[73.083,36.887],[73.1775,36.879],[73.4005,36.899],[73.548,36.891],[73.6915,36.916],[73.8,36.8905],[73.836,36.9255],[73.8905,36.9125],[73.9035,36.876],[73.9575,36.8425],[74.048,36.8265],[74.121,36.838],[74.1805,36.9165],[74.237,36.895],[74.3095,36.919],[74.35,36.9625],[74.4135,36.9755],[74.4195,37.0075],[74.5435,36.967],[74.519,37.0175],[74.5645,37.031],[74.4605,37.1295],[74.49,37.1775],[74.501,37.2395],[74.582,37.2355],[74.6285,37.2615],[74.6585,37.2345],[74.7155,37.282],[74.7495,37.2845],[74.809,37.2145],[74.89,37.234],[74.887,37.258],[74.804,37.3555],[74.674,37.389],[74.566,37.3725],[74.5575,37.397],[74.482,37.413],[74.4015,37.392],[74.375,37.4245],[74.276,37.402],[74.185,37.3345],[74.0635,37.3125],[74.0165,37.2915],[73.965,37.299],[73.852,37.2575],[73.843,37.234],[73.6305,37.2495],[73.671,37.31],[73.7325,37.3155],[73.7705,37.344],[73.776,37.44],[73.7195,37.447],[73.6405,37.4335],[73.5135,37.4745],[73.452,37.474],[73.3835,37.4465],[73.3005,37.462],[73.21,37.404],[73.1495,37.4045],[73.094,37.325],[72.9525,37.2905],[72.891,37.243],[72.818,37.2325],[72.7755,37.195],[72.7395,37.119],[72.6625,37.0175],[72.622,37.029],[72.5695,37.0075],[72.4735,36.9945],[72.441,37.0065],[72.3255,36.9815],[72.209,36.9245],[72.193,36.906],[72.0185,36.811],[71.958,36.756],[71.903,36.734],[71.8435,36.6805],[71.6755,36.671],[71.635,36.69],[71.563,36.764],[71.513,36.898],[71.468,36.9515],[71.4625,37.0235],[71.432,37.0565],[71.4535,37.207],[71.485,37.245],[71.4865,37.336],[71.5035,37.451],[71.5265,37.48],[71.4955,37.5335],[71.5045,37.607],[71.526,37.6315],[71.5515,37.7365],[71.532,37.7615],[71.596,37.8075],[71.591,37.9235],[71.524,37.953],[71.3275,37.887],[71.3135,37.919],[71.261,37.9215],[71.2755,38.006],[71.3215,38.0675],[71.3745,38.2555],[71.3285,38.306],[71.252,38.3105],[71.1835,38.347],[71.163,38.388],[71.0465,38.4105],[71.0315,38.461],[70.9885,38.491],[70.956,38.439],[70.856,38.4415],[70.771,38.4565],[70.7565,38.428],[70.674,38.4045],[70.6845,38.364],[70.611,38.3465],[70.6055,38.283],[70.5455,38.2435],[70.4925,38.1215],[70.4315,38.0995],[70.3285,37.999],[70.291,37.9875],[70.262,37.9375],[70.171,37.93],[70.1855,37.85],[70.2795,37.816],[70.3005,37.7035],[70.261,37.6395],[70.266,37.6115],[70.145,37.525],[70.1125,37.5245],[69.998,37.567],[69.9405,37.608],[69.8415,37.6035],[69.802,37.569],[69.7625,37.5915],[69.7135,37.5745],[69.6225,37.5695],[69.511,37.5805],[69.457,37.494],[69.3895,37.4495],[69.371,37.379],[69.393,37.36],[69.425,37.246],[69.4035,37.168],[69.37,37.166],[69.3235,37.118],[69.2535,37.0935],[69.108,37.1865],[69.0295,37.2565],[68.9995,37.308],[68.962,37.325],[68.8085,37.3065],[68.826,37.2695],[68.6715,37.2755],[68.617,37.1985],[68.543,37.167],[68.406,37.145],[68.39,37.098],[68.3155,37.1105],[68.2905,37.09],[68.2885,37.0315],[68.253,37.005],[68.174,37.0145],[68.0515,36.9285],[68.0155,36.9255],[67.972,36.9805],[67.9105,37.0145],[67.8895,37.0565],[67.7905,37.086],[67.787,37.1855],[67.7235,37.219],[67.558,37.2225],[67.517,37.265],[67.453,37.2365],[67.27,37.182],[67.2235,37.244],[67.1065,37.2915],[67.1125,37.327],[67.045,37.3805],[66.95,37.3985],[66.85,37.354],[66.801,37.3635],[66.6925,37.357],[66.652,37.3235],[66.5935,37.3685],[66.5515,37.3545],[66.431,37.319],[66.307,37.32],[66.246,37.356],[66.167,37.3695],[66.085,37.4395],[65.974,37.467],[65.894,37.4755],[65.8185,37.5],[65.803,37.523],[65.706,37.5395],[65.646,37.4385],[65.6435,37.3295],[65.556,37.2405],[65.2835,37.228],[65.2285,37.251],[65.1905,37.236],[65.1235,37.244],[64.99,37.218],[64.7555,37.1125],[64.7975,36.922],[64.707,36.796],[64.6185,36.6365],[64.6365,36.4425],[64.58,36.3515],[64.445,36.2425],[64.3155,36.208],[64.284,36.1515],[64.17,36.163],[64.0595,36.0985],[64.0685,35.9975],[63.989,36.0365],[63.7035,35.9675],[63.5365,35.948],[63.5005,35.8985],[63.299,35.8565],[63.121,35.862],[63.109,35.827],[63.195,35.713],[63.249,35.681],[63.1115,35.6335],[63.095,35.6185],[63.13,35.544],[63.1025,35.4285],[63.016,35.4125],[62.8775,35.345],[62.824,35.3],[62.7855,35.301],[62.713,35.2395],[62.611,35.2345],[62.4775,35.279],[62.326,35.145],[62.2985,35.138],[62.291,35.256],[62.2655,35.2955],[62.1535,35.341],[62.0645,35.4345],[61.968,35.454],[61.7795,35.411],[61.588,35.437],[61.45,35.5205],[61.3855,35.569],[61.3605,35.6295],[61.274,35.605]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9a/Flag_of_Afghanistan.svg","name:en":"Afghanistan","wikidata":"Q889","ISO3166-1:alpha2":"AF","ISO3166-1:alpha3":"AFG","ISO3166-1:numeric":"004"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[12.368,56.214],[12.3415,56.184],[12.033,56.282],[11.997,56.368],[11.7495,56.404],[11.5815,56.4015],[11.5065,56.382],[11.253,56.1365],[11.1485,56.0965],[11.0,55.9415],[10.7935,55.772],[10.8,55.7085],[10.7065,55.6615],[10.709,55.7585],[10.75,55.8385],[10.8835,55.93],[11.2675,56.311],[11.3265,56.4285],[11.3195,56.4825],[11.388,56.5045],[11.507,56.4845],[11.723,56.501],[11.81,56.5285],[11.9085,56.6015],[11.846,56.7545],[11.712,56.936],[11.462,56.925],[11.3705,56.908],[11.27,56.8685],[11.1965,56.816],[11.1475,56.715],[11.0815,56.682],[10.886,56.734],[10.712,56.7375],[10.645,56.832],[10.662,56.88],[10.756,57.045],[10.927,57.0005],[11.0715,57.001],[11.222,57.0305],[11.3105,57.069],[11.507,57.1915],[11.3145,57.428],[11.224,57.5235],[11.0135,57.5615],[11.0245,57.731],[10.9755,57.7845],[10.7265,57.941],[10.516,57.9475],[10.412,57.929],[10.297,57.8915],[10.076,57.793],[9.9495,57.7965],[9.8285,57.784],[9.7405,57.7595],[9.63,57.701],[9.5645,57.639],[9.455,57.5635],[9.3905,57.4815],[9.266,57.364],[9.1865,57.343],[9.092,57.358],[8.9375,57.3585],[8.7395,57.317],[8.554,57.3265],[8.4145,57.303],[8.3335,57.2705],[8.0465,57.0625],[7.9275,56.933],[7.886,56.869],[7.843,56.757],[7.7655,56.6115],[7.749,56.546],[7.7595,56.195],[7.7405,56.099],[7.7535,55.9625],[7.786,55.908],[7.818,55.775],[7.729,55.6155],[7.716,55.549],[7.7615,55.4595],[7.8705,55.392],[7.989,55.358],[8.055,55.285],[8.0445,55.099],[8.29,55.065],[8.3955,55.0695],[8.557,54.993],[8.5555,54.921],[8.6865,54.909],[8.948,54.9025],[9.0475,54.872],[9.1555,54.8705],[9.2405,54.85],[9.25,54.8095],[9.342,54.8035],[9.383,54.839],[9.6045,54.8545],[9.74,54.8235],[9.8945,54.842],[10.0515,54.766],[10.1695,54.738],[10.2,54.8535],[10.25,54.845],[10.271,54.779],[10.42,54.6445],[10.67,54.5745],[10.715,54.5765],[10.825,54.6425],[10.754,54.6735],[10.828,54.747],[10.9,54.756],[10.905,54.7085],[11.0,54.6735],[11.1335,54.6635],[11.255,54.634],[11.2965,54.6065],[11.4465,54.554],[11.795,54.4515],[12.0635,54.455],[12.145,54.4685],[12.1615,54.525],[12.24,54.6265],[12.6915,54.8045],[12.838,54.8555],[12.891,54.901],[12.904,54.9865],[12.85,55.1115],[12.7225,55.1385],[12.6035,55.2235],[12.59,55.325],[12.642,55.3375],[12.6105,55.4315],[12.7155,55.489],[12.7295,55.541],[12.8815,55.614],[12.896,55.6435],[12.7085,55.827],[12.6525,55.9265],[12.642,56.057],[12.368,56.214]]],[[[14.3335,55.0915],[14.375,55.0],[14.4315,54.9535],[14.5575,54.891],[14.858,54.8095],[15.08,54.7835],[15.22,54.8005],[15.3185,54.8365],[15.4385,54.9255],[15.4985,55.029],[15.5095,55.1465],[15.4885,55.202],[15.5415,55.268],[15.553,55.3205],[15.5155,55.41],[15.423,55.4775],[15.2395,55.53],[15.1005,55.529],[14.9325,55.4795],[14.8505,55.4915],[14.5265,55.28],[14.3445,55.1475],[14.3335,55.0915]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9c/Flag_of_Denmark.svg","name:en":"Denmark","wikidata":"Q35","ISO3166-1:alpha2":"DK","ISO3166-1:alpha3":"DNK","ISO3166-1:numeric":"208"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[31.7815,52.112],[31.781,52.1855],[31.711,52.215],[31.6965,52.258],[31.6145,52.3275],[31.6325,52.398],[31.6025,52.4235],[31.652,52.545],[31.564,52.5945],[31.5695,52.6345],[31.504,52.6985],[31.567,52.708],[31.6005,52.746],[31.5895,52.7915],[31.441,52.881],[31.3725,52.9335],[31.3305,53.042],[31.335,53.091],[31.4185,53.1875],[31.5005,53.2045],[31.5435,53.191],[31.6455,53.2195],[31.7865,53.1795],[31.831,53.1105],[31.887,53.1145],[31.9345,53.083],[32.018,53.091],[32.095,53.076],[32.2545,53.1315],[32.302,53.1275],[32.339,53.172],[32.4145,53.186],[32.4925,53.2535],[32.5225,53.3065],[32.5735,53.298],[32.6265,53.3305],[32.7335,53.3325],[32.723,53.374],[32.757,53.458],[32.478,53.549],[32.426,53.6075],[32.499,53.681],[32.4605,53.7375],[32.358,53.7205],[32.3205,53.758],[32.22,53.7705],[32.208,53.7995],[32.1,53.8145],[31.867,53.7825],[31.769,53.8355],[31.892,53.9665],[31.854,54.0045],[31.898,54.083],[31.7745,54.113],[31.6765,54.1175],[31.4925,54.1615],[31.383,54.2325],[31.3135,54.2485],[31.3225,54.3405],[31.236,54.464],[31.1085,54.492],[31.093,54.5295],[31.2105,54.632],[31.178,54.67],[31.0955,54.6615],[31.012,54.6745],[31.0255,54.706],[30.9535,54.743],[30.7515,54.8095],[30.835,54.9075],[30.8345,54.9485],[30.9085,54.949],[31.028,55.0625],[30.9905,55.077],[30.996,55.1445],[30.9235,55.2005],[30.83,55.3345],[30.9345,55.4],[30.901,55.4735],[30.959,55.501],[30.9325,55.617],[30.872,55.63],[30.8095,55.5905],[30.757,55.5945],[30.734,55.6545],[30.6705,55.6395],[30.648,55.71],[30.595,55.747],[30.5335,55.7505],[30.4815,55.8125],[30.3695,55.8085],[30.2865,55.8315],[30.239,55.872],[30.107,55.8315],[29.976,55.8715],[29.895,55.8625],[29.8065,55.7835],[29.755,55.8005],[29.623,55.78],[29.5155,55.7015],[29.4,55.7535],[29.3605,55.7985],[29.426,55.9505],[29.3055,55.9915],[29.214,55.989],[29.156,56.0265],[29.088,56.034],[28.858,55.9885],[28.829,55.9635],[28.723,55.9785],[28.62,56.0995],[28.5485,56.116],[28.458,56.1025],[28.32,56.0595],[28.1515,56.17],[28.026,56.1195],[27.972,56.1205],[27.906,56.052],[27.833,56.0235],[27.8005,55.9845],[27.653,55.9295],[27.6155,55.787],[27.429,55.795],[27.378,55.8075],[27.2875,55.785],[27.1605,55.85],[27.015,55.8285],[26.9205,55.788],[26.8705,55.714],[26.8,55.698],[26.659,55.706],[26.6305,55.6805],[26.628,55.5725],[26.524,55.51],[26.557,55.4635],[26.554,55.389],[26.4415,55.3475],[26.6025,55.321],[26.6685,55.3385],[26.792,55.321],[26.8355,55.2855],[26.7315,55.245],[26.675,55.1975],[26.6765,55.159],[26.461,55.1285],[26.3575,55.1505],[26.2295,55.1075],[26.271,55.0775],[26.186,54.9915],[26.121,54.9895],[26.081,54.9545],[25.9555,54.951],[25.858,54.9275],[25.853,54.8965],[25.734,54.8025],[25.7495,54.7645],[25.734,54.677],[25.7625,54.577],[25.6825,54.5365],[25.626,54.4565],[25.629,54.417],[25.562,54.366],[25.5525,54.315],[25.677,54.324],[25.7855,54.2335],[25.781,54.1595],[25.7105,54.169],[25.65,54.1285],[25.5155,54.1755],[25.5845,54.2345],[25.513,54.3085],[25.3535,54.264],[25.215,54.256],[25.2025,54.221],[25.0945,54.1505],[25.016,54.1375],[24.953,54.17],[24.866,54.147],[24.779,54.1],[24.839,54.021],[24.7265,53.967],[24.626,54.0105],[24.5075,53.9605],[24.448,53.904],[24.352,53.897],[24.2015,53.97],[24.103,53.9405],[23.983,53.924],[23.908,53.967],[23.7545,53.9275],[23.6305,53.928],[23.515,53.9565],[23.549,53.768],[23.7075,53.4365],[23.819,53.244],[23.915,53.162],[23.8735,53.087],[23.9255,53.0245],[23.9165,52.939],[23.9395,52.813],[23.9385,52.713],[23.773,52.623],[23.6415,52.6075],[23.4665,52.5495],[23.3565,52.469],[23.2155,52.3295],[23.2035,52.2265],[23.3955,52.201],[23.49,52.1685],[23.5565,52.1115],[23.64,52.0855],[23.6885,51.994],[23.612,51.9175],[23.6315,51.78],[23.531,51.7435],[23.553,51.715],[23.5405,51.601],[23.5655,51.534],[23.618,51.508],[23.6645,51.577],[23.6055,51.617],[23.6785,51.653],[23.7825,51.6675],[23.867,51.643],[23.8805,51.6085],[23.9955,51.5805],[24.0755,51.619],[24.1205,51.6665],[24.2685,51.716],[24.3195,51.751],[24.3,51.814],[24.388,51.882],[24.5675,51.8895],[24.625,51.9025],[24.7495,51.881],[24.81,51.912],[24.934,51.891],[25.1005,51.9535],[25.2635,51.9685],[25.41,51.9215],[25.596,51.9235],[25.708,51.916],[25.819,51.929],[25.9205,51.916],[25.99,51.932],[26.093,51.9125],[26.1555,51.866],[26.371,51.863],[26.4665,51.7995],[26.5465,51.796],[26.6115,51.8245],[26.755,51.8035],[26.8095,51.7565],[26.8505,51.767],[26.9505,51.736],[26.9935,51.7685],[27.207,51.774],[27.213,51.6665],[27.2735,51.6465],[27.2675,51.606],[27.393,51.605],[27.55,51.637],[27.619,51.6055],[27.7275,51.6045],[27.6835,51.541],[27.742,51.4775],[27.807,51.533],[27.858,51.6305],[27.9115,51.6125],[27.946,51.558],[28.1175,51.583],[28.1735,51.644],[28.2645,51.6815],[28.287,51.6235],[28.3615,51.558],[28.3975,51.551],[28.4715,51.5935],[28.559,51.573],[28.6355,51.574],[28.688,51.4445],[28.772,51.4295],[28.7615,51.4875],[28.807,51.5485],[28.9125,51.59],[28.9995,51.5735],[29.106,51.651],[29.1635,51.6525],[29.1775,51.6075],[29.2665,51.531],[29.251,51.4955],[29.309,51.454],[29.3405,51.3855],[29.4215,51.415],[29.4955,51.397],[29.542,51.4825],[29.7165,51.53],[29.7495,51.457],[29.7975,51.4465],[29.8935,51.4855],[29.9715,51.475],[30.0355,51.504],[30.12,51.4875],[30.18,51.5125],[30.347,51.4235],[30.324,51.3605],[30.424,51.3055],[30.4625,51.3065],[30.5385,51.2625],[30.618,51.288],[30.6555,51.376],[30.5285,51.563],[30.529,51.602],[30.578,51.6805],[30.6485,51.7505],[30.707,51.8685],[30.805,51.947],[30.888,51.9685],[30.9915,52.0775],[31.1365,52.103],[31.253,52.042],[31.2975,52.0515],[31.331,52.107],[31.4025,52.1425],[31.466,52.1205],[31.6585,52.1175],[31.722,52.096],[31.7815,52.112]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/85/Flag_of_Belarus.svg","name:en":"Belarus","wikidata":"Q184","ISO3166-1:alpha2":"BY","ISO3166-1:alpha3":"BLR","ISO3166-1:numeric":"112"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[115.052,4.8795],[115.0535,4.9155],[115.0905,4.9705],[115.156,4.9825],[115.1315,5.0705],[115.0675,5.101],[114.9575,5.0665],[114.8675,5.029],[114.742,4.9635],[114.4725,4.7565],[114.388,4.7115],[114.084,4.645],[114.077,4.5835],[114.162,4.5735],[114.26,4.507],[114.307,4.4185],[114.307,4.366],[114.333,4.349],[114.3165,4.2635],[114.382,4.265],[114.454,4.242],[114.496,4.1465],[114.5455,4.125],[114.553,4.084],[114.649,4.006],[114.7185,4.0435],[114.8075,4.1495],[114.794,4.1635],[114.8575,4.2695],[114.88,4.3705],[114.8775,4.4265],[114.8295,4.4295],[114.8185,4.4765],[114.8025,4.6755],[114.775,4.696],[114.8585,4.7975],[114.8955,4.8155],[114.9715,4.808],[114.9875,4.871],[115.025,4.8965],[115.052,4.8795]]],[[[115.1425,4.9155],[115.084,4.911],[115.0495,4.8595],[115.027,4.807],[115.0225,4.75],[115.099,4.4685],[115.1125,4.3725],[115.1555,4.383],[115.246,4.341],[115.296,4.338],[115.3225,4.2965],[115.3495,4.352],[115.2725,4.4475],[115.268,4.5275],[115.289,4.604],[115.248,4.7015],[115.2375,4.796],[115.1505,4.872],[115.1425,4.9155]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/9c/Flag_of_Brunei.svg","name:en":"Brunei","wikidata":"Q921","ISO3166-1:alpha2":"BN","ISO3166-1:alpha3":"BRN","ISO3166-1:numeric":"096"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[91.5695,27.8175],[91.5585,27.8575],[91.619,27.8635],[91.6255,27.892],[91.4835,27.9445],[91.4655,28.0065],[91.4065,28.021],[91.3425,28.0615],[91.309,28.0605],[91.263,28.071],[91.2155,27.992],[91.191,27.9865],[91.1645,27.9425],[90.9935,27.831],[90.872,27.85],[90.8265,27.8855],[90.795,27.9595],[90.797,28.0455],[90.6915,28.081],[90.5835,28.023],[90.5075,28.0665],[90.372,28.0665],[90.362,28.097],[90.3065,28.156],[90.209,28.148],[90.161,28.192],[90.0895,28.1515],[90.0235,28.144],[89.977,28.1945],[89.8965,28.183],[89.8605,28.23],[89.819,28.241],[89.773,28.2225],[89.765,28.1865],[89.683,28.1845],[89.5965,28.164],[89.5735,28.127],[89.5125,28.0945],[89.46,28.0305],[89.4525,27.9765],[89.389,27.8905],[89.308,27.8575],[89.2255,27.7835],[89.228,27.734],[89.14,27.648],[89.128,27.615],[89.073,27.6095],[89.0345,27.58],[89.0105,27.503],[88.969,27.4055],[89.0045,27.327],[88.9595,27.312],[88.9215,27.3275],[88.9045,27.273],[88.8025,27.2485],[88.7995,27.2085],[88.7465,27.142],[88.87,27.11],[88.874,26.954],[88.9225,26.993],[88.9795,26.918],[89.0155,26.94],[89.0955,26.8915],[89.102,26.836],[89.141,26.812],[89.2625,26.8155],[89.3175,26.8515],[89.379,26.8625],[89.4395,26.8405],[89.4765,26.802],[89.557,26.8135],[89.649,26.7705],[89.679,26.7395],[89.745,26.73],[89.771,26.702],[89.8625,26.7015],[89.902,26.723],[90.045,26.73],[90.1905,26.768],[90.2005,26.835],[90.248,26.86],[90.3,26.8485],[90.3545,26.9015],[90.418,26.9045],[90.5475,26.8165],[90.691,26.7715],[90.822,26.7765],[90.9955,26.7905],[91.0555,26.7815],[91.0985,26.8225],[91.235,26.8125],[91.3385,26.7805],[91.378,26.796],[91.41,26.8395],[91.4945,26.7925],[91.627,26.821],[91.7245,26.814],[91.825,26.864],[91.8595,26.9135],[91.894,26.9195],[91.987,26.861],[92.0565,26.8495],[92.1035,26.8695],[92.12,26.9715],[92.0815,27.0405],[92.0445,27.052],[92.023,27.11],[92.0275,27.1625],[92.0715,27.238],[92.0465,27.2695],[92.1235,27.2865],[92.065,27.3275],[92.056,27.4],[92.017,27.4805],[91.9435,27.46],[91.925,27.473],[91.7775,27.4655],[91.6515,27.484],[91.566,27.584],[91.573,27.661],[91.6285,27.6985],[91.645,27.77],[91.6145,27.8215],[91.5695,27.8175]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/9/91/Flag_of_Bhutan.svg","name:en":"Bhutan","wikidata":"Q917","ISO3166-1:alpha2":"BT","ISO3166-1:alpha3":"BTN","ISO3166-1:numeric":"064"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[74.89,37.234],[74.809,37.2145],[74.7495,37.2845],[74.7155,37.282],[74.6585,37.2345],[74.6285,37.2615],[74.582,37.2355],[74.501,37.2395],[74.49,37.1775],[74.4605,37.1295],[74.5645,37.031],[74.702,37.0825],[74.739,37.0215],[74.8405,37.02],[74.906,36.9295],[74.919,36.979],[75.1255,37.0125],[75.2335,36.959],[75.2855,36.9745],[75.406,36.9365],[75.432,36.83],[75.4195,36.7735],[75.4695,36.716],[75.534,36.7715],[75.6375,36.77],[75.7195,36.752],[75.804,36.71],[75.9405,36.593],[75.926,36.573],[75.9875,36.5025],[76.0355,36.409],[75.985,36.3415],[75.995,36.3075],[76.0575,36.246],[76.0065,36.234],[76.014,36.1725],[75.9695,36.1635],[75.9465,36.119],[75.957,36.046],[76.0045,36.017],[76.101,36.016],[76.107,35.977],[76.1595,35.917],[76.145,35.8375],[76.2245,35.8425],[76.3565,35.8315],[76.3665,35.8635],[76.427,35.8525],[76.4685,35.891],[76.5175,35.8865],[76.556,35.927],[76.599,35.9],[76.561,35.8225],[76.6155,35.7615],[76.691,35.7485],[76.776,35.658],[76.815,35.67],[76.9575,35.5965],[77.011,35.611],[77.194,35.522],[77.3025,35.5455],[77.3815,35.4735],[77.4425,35.462],[77.501,35.4895],[77.5595,35.487],[77.6295,35.4625],[77.719,35.4615],[77.7425,35.4955],[77.812,35.523],[77.911,35.462],[77.968,35.4945],[78.025,35.4685],[78.098,35.4995],[78.101,35.4305],[78.023,35.359],[78.003,35.243],[78.0565,35.175],[78.0495,35.114],[78.1275,35.1005],[78.1145,35.032],[78.2015,34.973],[78.1785,34.9285],[78.237,34.868],[78.2085,34.7205],[78.272,34.7015],[78.2625,34.6635],[78.29,34.615],[78.3855,34.6065],[78.4825,34.5785],[78.552,34.5715],[78.5635,34.5095],[78.634,34.544],[78.7095,34.526],[78.7565,34.4845],[78.7425,34.453],[78.851,34.4155],[78.902,34.381],[78.947,34.3895],[78.982,34.357],[78.9855,34.314],[78.944,34.225],[78.9255,34.1545],[78.862,34.1655],[78.826,34.1245],[78.7425,34.0925],[78.6575,34.0745],[78.6575,34.0315],[78.7425,34.0],[78.7315,33.9275],[78.7655,33.836],[78.754,33.7845],[78.775,33.738],[78.731,33.6835],[78.6785,33.667],[78.741,33.601],[78.74,33.554],[78.8035,33.4895],[78.836,33.4265],[78.9365,33.387],[78.9625,33.3395],[79.027,33.32],[79.035,33.2725],[79.073,33.223],[79.1625,33.1675],[79.14,33.106],[79.1605,33.015],[79.3065,32.928],[79.303,32.892],[79.407,32.7855],[79.4145,32.737],[79.4605,32.71],[79.399,32.604],[79.41,32.519],[79.311,32.56],[79.248,32.5165],[79.184,32.498],[79.1175,32.4545],[79.1045,32.3745],[79.058,32.387],[78.9895,32.37],[78.9685,32.3355],[78.8685,32.4135],[78.813,32.434],[78.7575,32.567],[78.7815,32.6165],[78.723,32.6745],[78.635,32.6445],[78.611,32.6005],[78.5465,32.619],[78.502,32.5845],[78.4145,32.566],[78.3925,32.538],[78.4725,32.4435],[78.476,32.3325],[78.4965,32.276],[78.597,32.158],[78.7065,32.063],[78.74,32.0015],[78.779,31.9665],[78.7425,31.902],[78.7355,31.8325],[78.702,31.807],[78.761,31.675],[78.8465,31.607],[78.8225,31.5785],[78.7445,31.542],[78.7205,31.5075],[78.795,31.444],[78.753,31.385],[78.778,31.3125],[78.833,31.294],[78.913,31.31],[78.944,31.3655],[79.0185,31.349],[79.019,31.4265],[79.075,31.459],[79.1425,31.432],[79.2235,31.346],[79.25,31.2935],[79.2265,31.2605],[79.301,31.219],[79.321,31.1385],[79.414,31.1065],[79.427,31.0235],[79.507,31.0325],[79.553,30.9575],[79.601,30.939],[79.663,30.9645],[79.776,30.986],[79.8575,30.9755],[79.889,30.9175],[79.929,30.8825],[79.9885,30.877],[80.05,30.841],[80.1085,30.7815],[80.1795,30.806],[80.1975,30.765],[80.2385,30.7625],[80.249,30.7205],[80.1925,30.666],[80.2195,30.643],[80.2085,30.588],[80.2545,30.5645],[80.3155,30.5645],[80.3455,30.5205],[80.4195,30.515],[80.497,30.488],[80.541,30.449],[80.6065,30.4715],[80.693,30.413],[80.715,30.414],[80.7875,30.3405],[80.8335,30.313],[80.9065,30.3035],[80.927,30.267],[80.981,30.2705],[81.031,30.247],[81.0345,30.197],[81.109,30.0855],[81.092,30.0535],[81.1655,30.0105],[81.2715,30.0445],[81.2825,30.123],[81.3955,30.207],[81.39,30.2345],[81.4225,30.3055],[81.396,30.3235],[81.429,30.3835],[81.5395,30.373],[81.5645,30.4295],[81.6065,30.4115],[81.634,30.445],[81.75,30.3885],[81.9375,30.3475],[81.988,30.322],[82.1065,30.349],[82.127,30.304],[82.117,30.258],[82.141,30.197],[82.185,30.19],[82.1855,30.111],[82.1665,30.076],[82.2845,30.0585],[82.313,30.0385],[82.4215,30.0055],[82.497,29.9475],[82.5335,29.971],[82.603,29.889],[82.697,29.8565],[82.738,29.814],[82.765,29.731],[82.8185,29.6965],[82.869,29.687],[82.928,29.7],[82.9565,29.662],[83.038,29.649],[83.0695,29.61],[83.15,29.6245],[83.2175,29.605],[83.282,29.499],[83.345,29.495],[83.3715,29.4285],[83.4135,29.422],[83.4435,29.2995],[83.5145,29.2555],[83.518,29.2185],[83.5705,29.203],[83.632,29.159],[83.711,29.244],[83.7685,29.241],[83.814,29.3025],[83.903,29.327],[84.0915,29.294],[84.168,29.2005],[84.187,29.081],[84.249,29.0365],[84.2255,28.9435],[84.226,28.893],[84.3285,28.8615],[84.392,28.86],[84.435,28.821],[84.4375,28.77],[84.493,28.7365],[84.558,28.746],[84.6255,28.7365],[84.696,28.6365],[84.78,28.6105],[84.8565,28.571],[84.9205,28.595],[84.9485,28.5805],[85.058,28.6825],[85.1165,28.6855],[85.157,28.644],[85.1905,28.5695],[85.147,28.4875],[85.118,28.4855],[85.1275,28.3925],[85.1085,28.3465],[85.183,28.323],[85.204,28.3405],[85.255,28.293],[85.3375,28.3035],[85.377,28.2775],[85.4135,28.325],[85.46,28.3365],[85.5915,28.308],[85.6085,28.2565],[85.6625,28.303],[85.6835,28.3825],[85.7315,28.337],[85.7505,28.2365],[85.8495,28.1715],[85.897,28.111],[85.9,28.0545],[85.9775,27.988],[85.9515,27.945],[86.0,27.9115],[86.065,27.9],[86.1245,27.9275],[86.0805,28.022],[86.084,28.088],[86.118,28.091],[86.16,28.1385],[86.2185,28.1135],[86.2045,28.0785],[86.2265,27.9815],[86.2885,27.978],[86.3195,27.948],[86.372,27.942],[86.442,27.906],[86.468,27.946],[86.514,27.957],[86.5355,28.051],[86.575,28.1135],[86.6075,28.075],[86.6655,28.1025],[86.7485,28.0985],[86.7495,28.046],[86.9245,27.988],[86.9325,27.9615],[87.038,27.9505],[87.073,27.9205],[87.111,27.8455],[87.157,27.8245],[87.227,27.821],[87.2645,27.851],[87.3165,27.8275],[87.4255,27.8595],[87.4475,27.8225],[87.4895,27.846],[87.5785,27.862],[87.606,27.8185],[87.6645,27.8375],[87.725,27.8055],[87.7855,27.9005],[87.834,27.952],[87.866,27.911],[87.9305,27.918],[87.983,27.888],[88.027,27.9055],[88.091,27.8715],[88.135,27.8815],[88.118,27.918],[88.1425,27.9655],[88.1875,27.9425],[88.2375,27.9695],[88.2635,27.9555],[88.3225,27.98],[88.468,28.017],[88.492,28.0485],[88.546,28.034],[88.5575,28.0755],[88.64,28.116],[88.667,28.0765],[88.7545,28.0805],[88.836,28.0155],[88.843,27.956],[88.888,27.8565],[88.857,27.8155],[88.8565,27.717],[88.8445,27.662],[88.8095,27.6375],[88.8065,27.5965],[88.7715,27.558],[88.783,27.4535],[88.8075,27.4045],[88.9215,27.3275],[88.9595,27.312],[89.0045,27.327],[88.969,27.4055],[89.0105,27.503],[89.0345,27.58],[89.073,27.6095],[89.128,27.615],[89.14,27.648],[89.228,27.734],[89.2255,27.7835],[89.308,27.8575],[89.389,27.8905],[89.4525,27.9765],[89.46,28.0305],[89.5125,28.0945],[89.5735,28.127],[89.5965,28.164],[89.683,28.1845],[89.765,28.1865],[89.773,28.2225],[89.819,28.241],[89.8605,28.23],[89.8965,28.183],[89.977,28.1945],[90.0235,28.144],[90.0895,28.1515],[90.161,28.192],[90.209,28.148],[90.3065,28.156],[90.362,28.097],[90.372,28.0665],[90.5075,28.0665],[90.5835,28.023],[90.6915,28.081],[90.797,28.0455],[90.9285,28.0425],[90.981,28.002],[91.026,28.0235],[91.075,28.004],[91.191,27.9865],[91.2155,27.992],[91.263,28.071],[91.309,28.0605],[91.3425,28.0615],[91.4065,28.021],[91.4655,28.0065],[91.4835,27.9445],[91.6255,27.892],[91.619,27.8635],[91.5585,27.8575],[91.5695,27.8175],[91.6125,27.839],[91.6605,27.829],[91.722,27.783],[91.8015,27.7725],[91.829,27.788],[91.8725,27.72],[91.925,27.7165],[91.979,27.7745],[92.036,27.7755],[92.108,27.803],[92.143,27.835],[92.2445,27.888],[92.2905,27.873],[92.3205,27.8],[92.422,27.8355],[92.4775,27.8365],[92.5815,27.89],[92.6505,27.915],[92.7235,27.9735],[92.7375,28.0415],[92.6645,28.0705],[92.6775,28.151],[92.739,28.154],[92.791,28.1875],[92.8265,28.175],[92.9215,28.2005],[92.9325,28.249],[92.9915,28.273],[93.1485,28.3665],[93.197,28.545],[93.23,28.5915],[93.3075,28.527],[93.3895,28.5325],[93.4575,28.668],[93.512,28.6675],[93.623,28.6885],[93.643,28.6575],[93.707,28.6645],[93.7845,28.7135],[93.7875,28.733],[93.8965,28.7575],[93.975,28.8215],[94.0785,28.8825],[94.1315,28.889],[94.1785,28.936],[94.2605,28.9315],[94.274,28.968],[94.342,29.002],[94.3125,29.079],[94.2845,29.0865],[94.293,29.1525],[94.379,29.154],[94.3905,29.184],[94.452,29.189],[94.5105,29.231],[94.541,29.2195],[94.5905,29.272],[94.6935,29.318],[94.735,29.287],[94.7515,29.2295],[94.7945,29.2175],[94.8095,29.165],[94.8475,29.1825],[94.9945,29.144],[95.097,29.142],[95.136,29.0885],[95.179,29.1045],[95.273,29.1055],[95.2995,29.1365],[95.379,29.137],[95.419,29.1805],[95.458,29.137],[95.5095,29.1265],[95.5085,29.195],[95.589,29.188],[95.6055,29.236],[95.648,29.2105],[95.7055,29.213],[95.7525,29.276],[95.737,29.298],[95.8125,29.3475],[95.8775,29.3145],[95.9655,29.376],[96.0165,29.3625],[96.0535,29.3825],[96.139,29.343],[96.1495,29.295],[96.196,29.2635],[96.261,29.2445],[96.2995,29.191],[96.235,29.1295],[96.183,29.111],[96.23,29.047],[96.2695,29.0965],[96.358,29.094],[96.362,29.048],[96.4345,29.0065],[96.441,28.9525],[96.508,28.9465],[96.519,28.8675],[96.5765,28.8185],[96.62,28.7275],[96.597,28.6965],[96.536,28.681],[96.537,28.6545],[96.451,28.583],[96.4815,28.555],[96.412,28.517],[96.4785,28.4905],[96.538,28.572],[96.6135,28.6135],[96.655,28.609],[96.7455,28.5715],[96.767,28.515],[96.861,28.4855],[96.893,28.4185],[96.8895,28.386],[96.977,28.3295],[97.027,28.33],[97.0785,28.3715],[97.146,28.353],[97.2485,28.264],[97.346,28.2145],[97.3955,28.2415],[97.425,28.298],[97.504,28.315],[97.478,28.3795],[97.5235,28.447],[97.502,28.495],[97.566,28.5465],[97.612,28.5185],[97.6635,28.5385],[97.7375,28.466],[97.7355,28.3985],[97.7785,28.3705],[97.797,28.3295],[97.842,28.3285],[97.8705,28.3675],[97.909,28.3685],[98.0205,28.258],[98.0115,28.208],[98.0765,28.2065],[98.097,28.167],[98.1385,28.1465],[98.1605,28.0895],[98.132,27.986],[98.184,27.9435],[98.206,27.892],[98.1705,27.854],[98.227,27.7965],[98.2345,27.6925],[98.284,27.6565],[98.311,27.5865],[98.317,27.523],[98.3765,27.511],[98.4305,27.5535],[98.43,27.6585],[98.475,27.6375],[98.5645,27.6405],[98.5865,27.593],[98.647,27.5685],[98.6745,27.586],[98.7045,27.522],[98.6845,27.4885],[98.7075,27.3645],[98.741,27.332],[98.7295,27.25],[98.6915,27.2],[98.7135,27.143],[98.712,27.078],[98.7665,27.052],[98.7335,27.006],[98.758,26.8855],[98.731,26.8545],[98.7625,26.802],[98.743,26.713],[98.782,26.606],[98.754,26.5655],[98.757,26.501],[98.734,26.3545],[98.682,26.31],[98.672,26.2455],[98.7115,26.2365],[98.736,26.19],[98.7095,26.121],[98.667,26.122],[98.6305,26.151],[98.573,26.122],[98.6035,26.0535],[98.619,25.975],[98.6815,25.9415],[98.708,25.86],[98.6325,25.8],[98.5315,25.8465],[98.475,25.783],[98.4605,25.6915],[98.4175,25.673],[98.4095,25.611],[98.3025,25.552],[98.2645,25.601],[98.205,25.62],[98.155,25.5275],[98.157,25.459],[98.1365,25.386],[98.0705,25.315],[98.0065,25.2805],[97.939,25.217],[97.904,25.2185],[97.8755,25.2615],[97.8395,25.2725],[97.779,25.126],[97.72,25.0215],[97.73,24.915],[97.797,24.8515],[97.772,24.831],[97.707,24.8385],[97.6515,24.7955],[97.547,24.742],[97.568,24.7235],[97.571,24.6035],[97.556,24.4965],[97.532,24.4375],[97.6645,24.453],[97.6755,24.409],[97.7135,24.3775],[97.661,24.339],[97.6665,24.3],[97.74,24.291],[97.768,24.263],[97.7295,24.23],[97.7525,24.172],[97.7285,24.1185],[97.632,24.038],[97.6285,24.008],[97.5725,23.986],[97.528,23.9295],[97.631,23.8815],[97.7035,23.867],[97.7685,23.936],[97.84,23.9635],[97.901,24.0175],[97.985,24.035],[98.0395,24.0735],[98.109,24.095],[98.1975,24.102],[98.2225,24.117],[98.3595,24.099],[98.4175,24.122],[98.543,24.1315],[98.6175,24.091],[98.679,24.102],[98.7165,24.1305],[98.758,24.1275],[98.887,24.143],[98.897,24.1075],[98.866,24.069],[98.754,23.983],[98.6785,23.9575],[98.6785,23.913],[98.704,23.8445],[98.698,23.787],[98.789,23.784],[98.83,23.7285],[98.8515,23.6345],[98.891,23.6175],[98.8035,23.542],[98.829,23.4785],[98.8755,23.4865],[98.921,23.4205],[98.9195,23.355],[98.9385,23.314],[98.931,23.269],[98.8855,23.183],[98.9225,23.1885],[99.0025,23.163],[99.058,23.165],[99.0475,23.123],[99.103,23.0915],[99.146,23.109],[99.249,23.08],[99.3445,23.1375],[99.384,23.102],[99.522,23.077],[99.5225,22.9905],[99.56,22.9515],[99.5605,22.909],[99.496,22.912],[99.441,22.9425],[99.4515,22.861],[99.3995,22.8285],[99.3855,22.765],[99.3145,22.7395],[99.3605,22.664],[99.385,22.5755],[99.358,22.537],[99.381,22.5045],[99.296,22.4145],[99.278,22.362],[99.233,22.297],[99.2355,22.2505],[99.174,22.189],[99.1675,22.1495],[99.2725,22.101],[99.4085,22.0995],[99.4735,22.136],[99.5155,22.104],[99.642,22.106],[99.67,22.077],[99.756,22.0735],[99.8545,22.026],[99.862,22.0595],[99.904,22.0695],[99.9625,22.0525],[99.997,21.977],[99.9435,21.825],[99.991,21.7065],[100.0725,21.694],[100.1185,21.706],[100.169,21.6665],[100.1115,21.603],[100.126,21.5115],[100.1685,21.486],[100.205,21.513],[100.247,21.4665],[100.2915,21.4795],[100.3455,21.5285],[100.431,21.5415],[100.4795,21.459],[100.538,21.471],[100.572,21.451],[100.6855,21.505],[100.7225,21.5125],[100.801,21.604],[100.8865,21.688],[101.014,21.71],[101.0875,21.776],[101.11,21.751],[101.115,21.6935],[101.1525,21.6705],[101.1695,21.5955],[101.1475,21.562],[101.217,21.556],[101.217,21.4925],[101.1995,21.436],[101.141,21.411],[101.185,21.3285],[101.2505,21.293],[101.2165,21.2315],[101.292,21.1755],[101.3875,21.228],[101.446,21.2265],[101.483,21.246],[101.6075,21.238],[101.5865,21.189],[101.671,21.2035],[101.7185,21.143],[101.757,21.144],[101.7935,21.206],[101.8305,21.2055],[101.8445,21.2525],[101.799,21.2915],[101.7335,21.323],[101.7385,21.406],[101.7615,21.5015],[101.75,21.583],[101.824,21.5905],[101.8095,21.63],[101.7695,21.6595],[101.746,21.7285],[101.7725,21.817],[101.739,21.873],[101.6165,21.977],[101.632,22.013],[101.596,22.064],[101.5735,22.126],[101.6005,22.135],[101.5505,22.234],[101.5695,22.275],[101.625,22.2755],[101.67,22.372],[101.6725,22.476],[101.7605,22.5085],[101.823,22.4615],[101.8315,22.4215],[101.899,22.381],[101.9155,22.44],[101.999,22.4325],[102.05,22.4565],[102.126,22.4325],[102.1445,22.4],[102.2495,22.461],[102.346,22.583],[102.4045,22.6335],[102.384,22.6795],[102.434,22.7],[102.452,22.7525],[102.5105,22.7785],[102.5665,22.722],[102.6075,22.732],[102.656,22.6895],[102.689,22.703],[102.789,22.6255],[102.8255,22.6265],[102.8835,22.589],[102.88,22.5605],[102.9235,22.507],[103.032,22.4425],[103.0805,22.451],[103.0725,22.4915],[103.14,22.5405],[103.1855,22.645],[103.2835,22.684],[103.2875,22.7375],[103.3205,22.7805],[103.372,22.7995],[103.44,22.7535],[103.4265,22.713],[103.489,22.6185],[103.531,22.595],[103.5795,22.664],[103.564,22.706],[103.6385,22.795],[103.767,22.6905],[103.826,22.6155],[103.962,22.5065],[104.0125,22.524],[104.029,22.6875],[104.046,22.734],[104.115,22.8115],[104.256,22.845],[104.269,22.743],[104.3395,22.723],[104.353,22.6935],[104.478,22.7635],[104.5785,22.855],[104.6735,22.8185],[104.7355,22.8275],[104.771,22.8955],[104.8395,22.9215],[104.8655,22.9625],[104.8315,23.0035],[104.802,23.116],[104.876,23.1255],[104.8815,23.166],[104.9275,23.1565],[104.9625,23.1985],[105.025,23.219],[105.082,23.267],[105.107,23.246],[105.179,23.288],[105.2275,23.26],[105.2585,23.3195],[105.322,23.393],[105.3515,23.345],[105.4115,23.288],[105.445,23.2955],[105.499,23.2025],[105.543,23.1935],[105.5735,23.161],[105.5695,23.0755],[105.645,23.083],[105.825,22.9965],[105.8725,22.9335],[106.003,22.9475],[106.001,22.992],[106.2,22.9865],[106.238,22.9515],[106.2865,22.8675],[106.4405,22.8895],[106.5005,22.909],[106.513,22.9485],[106.567,22.919],[106.593,22.933],[106.6485,22.867],[106.6915,22.8915],[106.783,22.8145],[106.833,22.797],[106.7645,22.7415],[106.753,22.6925],[106.6935,22.5845],[106.6485,22.5765],[106.607,22.5985],[106.5825,22.4825],[106.5575,22.459],[106.5855,22.378],[106.5715,22.3415],[106.6595,22.334],[106.69,22.279],[106.6985,22.2095],[106.673,22.181],[106.71,22.1015],[106.6825,22.002],[106.7845,22.004],[106.8125,21.973],[106.919,21.9745],[106.9335,21.9295],[106.988,21.9485],[107.05,21.928],[107.0635,21.896],[107.0045,21.8335],[107.0855,21.808],[107.1965,21.7225],[107.249,21.7055],[107.301,21.7425],[107.36,21.6645],[107.361,21.612],[107.4825,21.657],[107.4935,21.605],[107.5435,21.5895],[107.594,21.605],[107.6885,21.6115],[107.8155,21.6585],[107.872,21.647],[107.8965,21.596],[107.9425,21.57],[107.955,21.537],[108.0335,21.5475],[108.1005,21.4735],[108.0955,21.4525],[108.1345,21.2755],[108.205,21.299],[108.2895,21.311],[108.3775,21.354],[108.485,21.349],[108.576,21.382],[108.634,21.417],[108.718,21.392],[108.8375,21.392],[108.8715,21.326],[108.935,21.269],[108.957,21.218],[108.8875,21.138],[108.8695,21.074],[108.8785,20.964],[108.908,20.904],[108.9635,20.851],[109.01,20.826],[109.0705,20.75],[109.1315,20.717],[109.234,20.704],[109.493,20.707],[109.5505,20.546],[109.6085,20.478],[109.6485,20.395],[109.656,20.351],[109.706,20.216],[109.54,20.183],[109.47,20.152],[109.401,20.1],[109.295,20.117],[109.2525,20.113],[109.137,20.0645],[109.0215,19.957],[108.9725,19.89],[108.949,19.8255],[108.887,19.747],[108.761,19.636],[108.6605,19.5735],[108.5915,19.554],[108.4785,19.4775],[108.4385,19.4035],[108.3955,19.245],[108.389,19.1795],[108.413,18.8105],[108.466,18.4905],[108.4945,18.415],[108.5655,18.3405],[108.8285,18.159],[109.0375,18.0615],[109.086,18.0465],[109.532,17.9615],[109.617,17.962],[109.776,17.9955],[109.81,18.0115],[110.2575,18.2685],[110.6055,18.4915],[110.6775,18.564],[111.396,19.781],[111.4515,19.8655],[111.761,20.2905],[112.4895,21.286],[112.8485,21.373],[114.012,21.6125],[114.0585,21.627],[115.22,22.135],[116.582,22.751],[117.311,23.018],[117.382,23.057],[117.822,23.373],[117.8585,23.4065],[118.3885,24.015],[119.6055,24.813],[119.64,24.841],[120.1,25.2935],[120.129,25.3295],[120.597,26.0555],[120.7085,26.292],[121.0335,26.859],[121.321,27.3585],[122.0925,28.271],[122.466,28.779],[122.4825,28.805],[123.1545,30.084],[123.3815,30.6605],[123.388,30.7695],[123.354,30.8405],[123.3105,30.8855],[122.4465,31.536],[122.407,31.6415],[121.8665,33.077],[121.8345,33.1305],[121.5405,33.4805],[120.5915,35.3725],[121.0525,35.7455],[122.413,36.587],[122.665,36.733],[122.7445,36.798],[122.8125,36.9145],[122.949,37.3465],[122.956,37.417],[122.9315,37.4875],[122.8375,37.596],[122.7725,37.63],[122.6645,37.648],[122.5805,37.636],[122.5055,37.651],[122.3885,37.639],[122.2925,37.717],[122.211,37.75],[122.08,37.774],[122.026,37.77],[121.93,37.737],[121.8155,37.661],[121.6845,37.754],[121.6245,37.776],[121.5275,37.785],[121.4235,37.827],[121.338,37.834],[121.277,37.879],[121.1585,37.915],[121.1985,38.017],[121.186,38.089],[121.1245,38.17],[121.0835,38.197],[121.1475,38.266],[121.178,38.348],[121.1645,38.46],[121.217,38.523],[121.2965,38.539],[121.4075,38.609],[121.4385,38.4915],[121.5085,38.4275],[121.62,38.3975],[121.7315,38.411],[121.7935,38.444],[121.838,38.4925],[121.8645,38.589],[121.8345,38.664],[121.9475,38.6875],[121.9675,38.596],[122.0375,38.532],[122.149,38.502],[122.261,38.5155],[122.3225,38.5485],[122.387,38.638],[122.388,38.7225],[122.358,38.776],[122.306,38.8185],[122.238,38.844],[122.1635,38.849],[122.1755,38.883],[122.2745,38.949],[122.363,38.945],[122.4595,38.966],[122.517,38.889],[122.6265,38.829],[122.7275,38.81],[122.8515,38.824],[122.9855,38.873],[123.0935,38.833],[123.1645,38.827],[123.294,38.846],[123.4165,38.909],[123.4515,38.951],[123.4755,39.015],[123.453,39.123],[123.395,39.206],[123.3,39.273],[123.296,39.313],[123.3415,39.377],[123.366,39.506],[123.426,39.531],[123.6045,39.562],[123.7065,39.545],[123.854,39.564],[123.9485,39.605],[124.0915,39.612],[124.1595,39.743],[124.173,39.829],[124.21,39.8575],[124.2375,39.9265],[124.284,39.9275],[124.2925,39.968],[124.354,39.9705],[124.372,40.017],[124.3375,40.0465],[124.3505,40.0805],[124.412,40.139],[124.481,40.1725],[124.5095,40.2185],[124.6425,40.301],[124.706,40.313],[124.7495,40.379],[124.817,40.4045],[124.8895,40.4755],[124.922,40.4545],[125.0285,40.492],[125.0085,40.525],[125.0955,40.5565],[125.186,40.6075],[125.2575,40.613],[125.267,40.6475],[125.329,40.637],[125.4515,40.6745],[125.486,40.7215],[125.5245,40.7165],[125.5745,40.7825],[125.6295,40.799],[125.702,40.8635],[125.7955,40.865],[125.858,40.8835],[125.958,40.8805],[126.0185,40.9015],[126.0515,40.9635],[126.1035,41.005],[126.1305,41.058],[126.2345,41.145],[126.274,41.155],[126.3095,41.215],[126.3535,41.243],[126.3625,41.281],[126.433,41.352],[126.4865,41.371],[126.505,41.435],[126.588,41.5625],[126.5655,41.598],[126.725,41.705],[126.9445,41.805],[127.054,41.7],[127.03,41.672],[127.104,41.64],[127.1615,41.54],[127.3375,41.4635],[127.4105,41.4555],[127.493,41.4755],[127.559,41.43],[127.8475,41.4195],[127.967,41.4355],[128.032,41.391],[128.0825,41.393],[128.108,41.3605],[128.201,41.4085],[128.2355,41.4985],[128.2965,41.538],[128.311,41.589],[128.242,41.679],[128.1645,41.7105],[128.1085,41.789],[128.0965,41.838],[128.0995,41.945],[128.031,41.9955],[128.0845,42.0205],[128.285,42.024],[128.4575,42.0185],[128.506,41.997],[128.5765,42.0],[128.6305,42.037],[128.6765,42.012],[128.745,42.0515],[128.915,42.01],[129.0515,42.138],[129.1145,42.139],[129.203,42.2065],[129.1765,42.2595],[129.225,42.278],[129.2235,42.3525],[129.304,42.4155],[129.421,42.433],[129.4945,42.4125],[129.5325,42.3745],[129.607,42.437],[129.704,42.427],[129.7445,42.467],[129.732,42.4985],[129.785,42.6795],[129.76,42.708],[129.808,42.789],[129.8365,42.865],[129.8515,42.9615],[129.9005,43.005],[129.954,42.9785],[130.063,42.9675],[130.0985,42.9865],[130.138,42.902],[130.1725,42.914],[130.262,42.9035],[130.2375,42.8205],[130.253,42.7065],[130.37,42.6205],[130.4145,42.5675],[130.5245,42.547],[130.5785,42.4845],[130.5785,42.43],[130.637,42.4185],[130.5925,42.446],[130.592,42.4845],[130.5535,42.5185],[130.627,42.5975],[130.588,42.665],[130.5215,42.7015],[130.4575,42.686],[130.4055,42.729],[130.4595,42.77],[130.526,42.785],[130.5565,42.813],[130.659,42.845],[130.776,42.8395],[130.828,42.8805],[130.882,42.8505],[130.9415,42.8745],[131.0355,42.8605],[131.0105,42.9105],[131.1085,42.9135],[131.14,42.943],[131.0955,43.021],[131.1145,43.067],[131.21,43.1485],[131.1985,43.234],[131.2485,43.2675],[131.273,43.3755],[131.311,43.395],[131.2695,43.493],[131.207,43.5265],[131.203,43.582],[131.233,43.6655],[131.2095,43.833],[131.261,43.9365],[131.2345,43.965],[131.2555,44.0305],[131.303,44.044],[131.1045,44.7075],[131.0085,44.8105],[130.977,44.863],[131.0945,44.8945],[131.082,44.922],[131.152,44.9445],[131.1985,44.916],[131.271,44.9215],[131.35,44.9875],[131.427,44.965],[131.5355,45.017],[131.6245,45.0725],[131.6875,45.13],[131.643,45.157],[131.6745,45.2135],[131.781,45.244],[131.828,45.31],[131.91,45.337],[131.9235,45.2875],[132.004,45.252],[132.8645,45.0575],[132.9385,45.0285],[133.0375,45.0565],[133.0615,45.0945],[133.1305,45.128],[133.1045,45.2645],[133.1115,45.3505],[133.135,45.365],[133.141,45.434],[133.213,45.5135],[133.386,45.578],[133.44,45.6485],[133.435,45.703],[133.476,45.7805],[133.4615,45.8355],[133.505,45.8885],[133.5765,45.8665],[133.61,45.9415],[133.67,45.9435],[133.6755,45.9885],[133.7355,46.054],[133.682,46.1375],[133.823,46.2235],[133.9105,46.2635],[133.8705,46.3615],[133.9375,46.3795],[133.9275,46.4195],[133.8455,46.481],[133.883,46.521],[133.913,46.596],[134.0135,46.666],[134.0265,46.7545],[134.016,46.811],[134.0355,46.8855],[134.068,46.933],[134.0555,46.975],[134.0965,47.009],[134.14,47.0925],[134.218,47.1075],[134.22,47.187],[134.15,47.253],[134.1695,47.3185],[134.2555,47.3665],[134.311,47.4335],[134.486,47.443],[134.5705,47.4895],[134.5725,47.5185],[134.6805,47.598],[134.6755,47.625],[134.7435,47.6835],[134.775,47.74],[134.6635,47.825],[134.6705,47.8775],[134.607,47.9015],[134.593,47.9475],[134.544,47.985],[134.5445,48.0245],[134.6275,48.097],[134.6675,48.152],[134.676,48.2575],[134.717,48.28],[134.768,48.3575],[134.688,48.408],[134.5805,48.407],[134.4705,48.422],[134.4085,48.388],[134.337,48.379],[134.1885,48.3835],[134.14,48.338],[134.0555,48.346],[134.0075,48.309],[133.9495,48.3045],[133.7465,48.257],[133.7115,48.1875],[133.58,48.1885],[133.5565,48.1305],[133.4645,48.109],[133.3915,48.1235],[133.266,48.093],[133.182,48.1085],[133.0495,48.105],[133.008,48.0405],[132.863,47.9915],[132.7805,47.925],[132.719,47.962],[132.652,47.9355],[132.6805,47.872],[132.5985,47.8105],[132.6035,47.742],[132.5485,47.7145],[132.485,47.716],[132.3845,47.7505],[132.309,47.757],[132.253,47.708],[131.989,47.701],[131.9425,47.6615],[131.902,47.691],[131.812,47.667],[131.7305,47.7045],[131.678,47.7025],[131.622,47.657],[131.5665,47.665],[131.5475,47.7265],[131.425,47.7435],[131.366,47.7265],[131.2545,47.735],[131.175,47.6955],[131.0895,47.683],[130.9935,47.696],[130.9575,47.7205],[130.9515,47.815],[130.864,47.936],[130.6905,48.04],[130.6535,48.1075],[130.752,48.19],[130.765,48.2475],[130.8355,48.3015],[130.7665,48.3585],[130.7305,48.444],[130.758,48.4975],[130.66,48.4905],[130.6085,48.502],[130.6065,48.5735],[130.522,48.626],[130.607,48.775],[130.682,48.8655],[130.64,48.883],[130.5375,48.8535],[130.421,48.904],[130.294,48.869],[130.2245,48.865],[130.1905,48.9],[130.0505,48.972],[129.998,49.02],[129.928,49.0325],[129.9275,49.0735],[129.8585,49.1085],[129.8425,49.177],[129.7525,49.204],[129.7535,49.252],[129.7105,49.291],[129.6,49.276],[129.548,49.309],[129.5365,49.398],[129.4305,49.4415],[129.369,49.418],[129.378,49.3755],[129.309,49.357],[129.261,49.392],[129.1745,49.3885],[129.126,49.3505],[129.0735,49.3535],[128.9835,49.457],[128.8605,49.4895],[128.757,49.476],[128.747,49.513],[128.802,49.5505],[128.6585,49.57],[128.553,49.602],[128.367,49.5835],[128.336,49.542],[128.2345,49.5615],[128.2015,49.538],[128.0345,49.5555],[127.959,49.5965],[127.885,49.5695],[127.7985,49.5935],[127.7815,49.622],[127.687,49.667],[127.673,49.748],[127.6485,49.7765],[127.5565,49.7905],[127.5255,49.819],[127.5415,49.917],[127.499,49.972],[127.5015,50.0595],[127.572,50.1285],[127.6035,50.181],[127.6015,50.2375],[127.3805,50.285],[127.3255,50.335],[127.3615,50.396],[127.353,50.4435],[127.292,50.457],[127.311,50.524],[127.367,50.574],[127.2875,50.664],[127.2915,50.7545],[127.233,50.774],[127.135,50.9125],[127.0465,50.9605],[126.986,51.021],[126.9175,51.057],[126.894,51.2035],[126.973,51.298],[126.9455,51.3335],[126.8675,51.3095],[126.9155,51.2615],[126.8435,51.253],[126.8135,51.3295],[126.924,51.363],[126.896,51.408],[126.801,51.4205],[126.776,51.444],[126.833,51.5345],[126.7085,51.5685],[126.7215,51.6245],[126.7155,51.727],[126.671,51.727],[126.6175,51.7745],[126.538,51.885],[126.465,51.9365],[126.4385,52.0255],[126.5125,52.053],[126.5565,52.12],[126.49,52.1595],[126.3005,52.206],[126.346,52.2625],[126.311,52.329],[126.347,52.383],[126.2625,52.4735],[126.181,52.4775],[126.2015,52.531],[126.068,52.603],[126.012,52.5785],[125.973,52.6085],[125.9835,52.673],[126.053,52.676],[126.0375,52.7345],[126.096,52.7755],[126.0085,52.7925],[125.9395,52.763],[125.909,52.8185],[125.8295,52.8955],[125.6555,52.869],[125.6665,52.9225],[125.7275,52.944],[125.734,52.9915],[125.6725,53.0075],[125.605,53.0815],[125.5315,53.0545],[125.498,53.0885],[125.3025,53.146],[125.158,53.204],[124.9755,53.196],[124.824,53.143],[124.7115,53.1515],[124.717,53.187],[124.637,53.207],[124.4965,53.2035],[124.37,53.2525],[124.3205,53.329],[124.2325,53.378],[124.11,53.3465],[124.0615,53.399],[123.8795,53.4805],[123.6855,53.4985],[123.622,53.5455],[123.4785,53.528],[123.3755,53.5365],[123.3045,53.5595],[123.223,53.5495],[123.1375,53.498],[123.06,53.5075],[122.8495,53.4565],[122.596,53.464],[122.4295,53.443],[122.3495,53.5005],[122.2435,53.4635],[122.168,53.471],[122.079,53.4205],[121.9485,53.429],[121.8175,53.4155],[121.6945,53.3905],[121.572,53.3475],[121.41,53.317],[121.327,53.323],[121.276,53.289],[121.1275,53.275],[120.941,53.2955],[120.8155,53.2685],[120.816,53.241],[120.6835,53.171],[120.636,53.104],[120.5555,53.0805],[120.3615,52.943],[120.281,52.861],[120.0265,52.7765],[120.062,52.707],[120.027,52.6355],[120.0785,52.583],[120.1845,52.577],[120.282,52.622],[120.391,52.615],[120.4775,52.629],[120.6185,52.5705],[120.6865,52.5175],[120.6835,52.429],[120.618,52.361],[120.6215,52.3245],[120.7515,52.2555],[120.739,52.2045],[120.7795,52.1635],[120.755,52.103],[120.679,52.036],[120.712,52.007],[120.6475,51.9225],[120.5425,51.9075],[120.544,51.883],[120.3915,51.8305],[120.356,51.7875],[120.3045,51.781],[120.1665,51.678],[120.0505,51.6305],[120.045,51.5525],[119.978,51.502],[119.9955,51.458],[119.933,51.354],[119.8755,51.333],[119.8685,51.2935],[119.803,51.278],[119.812,51.2315],[119.7525,51.2125],[119.7815,51.172],[119.754,51.0885],[119.663,51.012],[119.5835,50.975],[119.5105,50.8975],[119.5205,50.862],[119.499,50.766],[119.442,50.694],[119.3735,50.68],[119.3475,50.628],[119.274,50.6035],[119.2425,50.4465],[119.145,50.388],[119.247,50.3415],[119.351,50.3575],[119.31,50.2165],[119.3295,50.172],[119.274,50.105],[119.084,49.9845],[118.9865,49.9765],[118.9375,49.9915],[118.7345,49.945],[118.648,49.9475],[118.555,49.922],[118.372,49.786],[118.2395,49.7375],[118.2045,49.69],[118.1125,49.658],[118.074,49.614],[117.974,49.62],[117.891,49.5935],[117.881,49.5155],[117.793,49.52],[117.634,49.5645],[117.4715,49.6265],[117.2735,49.631],[117.0615,49.6855],[116.7135,49.8455],[116.609,49.707],[116.3255,49.289],[116.0365,48.8675],[116.0725,48.8165],[116.0205,48.757],[115.811,48.547],[115.7985,48.4635],[115.8135,48.259],[115.5475,48.1615],[115.5215,48.111],[115.5455,48.067],[115.5705,47.919],[115.742,47.8035],[115.9355,47.681],[115.9555,47.6875],[116.1115,47.819],[116.2535,47.8785],[116.4395,47.838],[116.6765,47.889],[116.871,47.891],[117.087,47.8205],[117.375,47.64],[117.482,47.759],[117.805,48.014],[117.9135,48.0215],[118.0345,48.0125],[118.1,48.0315],[118.231,48.041],[118.2885,48.0035],[118.4145,48.014],[118.455,47.996],[118.555,47.9935],[118.755,47.772],[119.1215,47.664],[119.143,47.5425],[119.3575,47.4795],[119.3215,47.425],[119.4635,47.358],[119.4775,47.3275],[119.5525,47.301],[119.571,47.2435],[119.6235,47.244],[119.708,47.1935],[119.799,47.059],[119.7835,47.0245],[119.855,46.9205],[119.9215,46.9025],[119.8985,46.8655],[119.932,46.7955],[119.9015,46.7555],[119.929,46.7205],[119.89,46.6635],[119.807,46.6675],[119.7745,46.6255],[119.6805,46.5905],[119.6375,46.625],[119.4305,46.6385],[119.3835,46.6085],[119.3005,46.6085],[119.245,46.643],[119.101,46.6475],[119.0,46.751],[118.916,46.724],[118.897,46.776],[118.8425,46.7705],[118.7835,46.717],[118.792,46.687],[118.6735,46.696],[118.635,46.72],[118.5755,46.6935],[118.437,46.7065],[118.4025,46.727],[118.301,46.7385],[118.184,46.6815],[118.1155,46.6785],[118.0565,46.6345],[117.889,46.5915],[117.834,46.5315],[117.702,46.5135],[117.6325,46.579],[117.494,46.5985],[117.415,46.5805],[117.4405,46.5255],[117.392,46.478],[117.3685,46.3605],[117.243,46.365],[117.0885,46.3545],[116.8315,46.3835],[116.761,46.329],[116.658,46.321],[116.5775,46.2885],[116.566,46.2535],[116.4345,46.1375],[116.398,46.126],[116.264,45.9615],[116.2375,45.8725],[116.268,45.852],[116.28,45.7705],[116.2145,45.7415],[116.17,45.6885],[116.0305,45.6825],[116.015,45.656],[115.932,45.6295],[115.691,45.458],[115.5575,45.436],[115.356,45.3895],[115.165,45.396],[114.974,45.376],[114.9155,45.3815],[114.737,45.4375],[114.541,45.3845],[114.528,45.2925],[114.456,45.206],[114.3845,45.1435],[114.177,45.034],[114.1335,44.9665],[114.056,44.9255],[113.907,44.9145],[113.877,44.88],[113.7765,44.839],[113.6255,44.7425],[113.506,44.772],[113.1275,44.7955],[112.931,44.8395],[112.8635,44.837],[112.702,44.881],[112.585,44.936],[112.519,45.0125],[112.4255,45.074],[112.3745,45.0615],[112.1115,45.0715],[112.009,45.092],[111.874,45.038],[111.7695,44.9805],[111.605,44.756],[111.5535,44.6455],[111.561,44.5715],[111.4635,44.4715],[111.4095,44.3445],[111.425,44.3175],[111.519,44.271],[111.539,44.192],[111.609,44.106],[111.693,44.0355],[111.788,43.996],[111.874,43.932],[111.9545,43.8275],[111.968,43.744],[111.946,43.69],[111.883,43.672],[111.799,43.6695],[111.573,43.491],[111.4535,43.4895],[111.4015,43.4765],[111.327,43.425],[111.213,43.3995],[111.006,43.322],[110.759,43.095],[110.6825,43.035],[110.6295,42.9395],[110.464,42.8325],[110.436,42.782],[110.334,42.736],[110.1365,42.672],[110.101,42.639],[109.9035,42.6305],[109.669,42.5515],[109.5285,42.4675],[109.469,42.4535],[109.284,42.4345],[109.0245,42.454],[108.96,42.4415],[108.8385,42.3955],[108.7955,42.414],[108.716,42.4095],[108.5275,42.441],[108.306,42.436],[108.241,42.4605],[108.0165,42.4315],[107.919,42.4025],[107.7275,42.412],[107.566,42.4115],[107.496,42.455],[107.453,42.4565],[107.293,42.408],[107.257,42.363],[107.041,42.3145],[106.786,42.2915],[106.5595,42.219],[106.507,42.194],[105.697,41.931],[105.386,41.795],[105.289,41.747],[105.217,41.7255],[105.108,41.6545],[105.013,41.581],[104.9165,41.6525],[104.682,41.644],[104.517,41.6595],[104.499,41.6795],[104.4975,41.7725],[104.5235,41.8735],[104.078,41.8005],[103.891,41.7955],[103.411,41.8815],[102.976,42.0375],[102.767,42.1255],[102.5505,42.159],[102.432,42.147],[102.1715,42.204],[102.0965,42.2],[102.0245,42.224],[102.0485,42.2525],[101.8005,42.5035],[101.567,42.5255],[100.848,42.672],[100.3185,42.687],[100.268,42.6355],[99.964,42.646],[99.5045,42.5655],[98.9005,42.61],[98.5425,42.6375],[98.1925,42.652],[97.5555,42.742],[97.1715,42.7945],[96.9775,42.7545],[96.7475,42.755],[96.3875,42.7245],[96.363,42.899],[95.909,43.2355],[95.877,43.277],[95.8575,43.4135],[95.736,43.5945],[95.6475,43.7765],[95.623,43.8515],[95.523,44.005],[95.442,44.005],[95.3225,44.0255],[95.3475,44.089],[95.3725,44.2255],[95.4065,44.2415],[95.41,44.294],[94.9985,44.251],[94.945,44.288],[94.713,44.345],[94.6105,44.4425],[94.5165,44.476],[94.4625,44.5105],[94.3605,44.515],[94.3265,44.5825],[94.276,44.605],[94.2115,44.6675],[94.15,44.6835],[94.062,44.7325],[93.7305,44.8625],[93.671,44.91],[93.5225,44.9575],[93.428,44.9565],[93.366,44.988],[93.2855,44.9825],[93.168,45.0135],[92.9295,45.0155],[92.8815,45.0465],[92.776,45.05],[92.645,45.0205],[92.5495,45.0175],[92.4905,45.0],[92.3135,45.027],[92.235,45.0135],[92.0995,45.0755],[92.0575,45.083],[91.801,45.0815],[91.691,45.062],[91.609,45.07],[91.492,45.1045],[91.43,45.1565],[91.373,45.109],[91.329,45.129],[91.2415,45.132],[91.122,45.214],[90.995,45.214],[90.931,45.192],[90.8645,45.204],[90.895,45.2505],[90.8115,45.325],[90.77,45.4285],[90.6705,45.487],[90.6785,45.6055],[90.715,45.7275],[90.848,45.8875],[91.022,46.0225],[91.0105,46.1245],[90.975,46.1625],[90.949,46.229],[90.8915,46.3125],[90.9695,46.3605],[91.0095,46.461],[91.0525,46.511],[91.066,46.5755],[91.0145,46.5805],[91.0485,46.72],[91.016,46.764],[90.937,46.826],[90.9555,46.8775],[90.902,46.9575],[90.8295,46.9895],[90.778,46.992],[90.622,47.155],[90.5945,47.168],[90.484,47.313],[90.5205,47.377],[90.458,47.407],[90.4715,47.491],[90.4,47.539],[90.298,47.6925],[90.1395,47.7225],[90.0655,47.7925],[90.0675,47.874],[89.9595,47.887],[89.954,47.8345],[89.7565,47.829],[89.727,47.895],[89.6545,47.9055],[89.5925,47.968],[89.582,48.03],[89.4015,48.0305],[89.291,48.012],[89.234,47.976],[89.156,47.995],[89.0625,47.9885],[89.0095,48.05],[88.911,48.109],[88.824,48.1],[88.715,48.174],[88.6375,48.1785],[88.566,48.276],[88.603,48.339],[88.5135,48.3795],[88.437,48.387],[88.3495,48.4355],[88.357,48.4585],[88.2425,48.501],[88.175,48.499],[88.1425,48.5275],[87.969,48.5755],[88.0675,48.6805],[87.9995,48.7605],[87.935,48.7555],[87.83,48.7985],[87.7815,48.8695],[87.734,48.881],[87.754,48.9285],[87.868,48.948],[87.8765,49.0145],[87.827,49.051],[87.866,49.1115],[87.8145,49.17],[87.695,49.1755],[87.564,49.135],[87.4265,49.0695],[87.286,49.116],[87.199,49.143],[87.104,49.151],[87.0565,49.1295],[86.996,49.1425],[86.887,49.1325],[86.8475,49.0655],[86.749,49.0145],[86.727,48.9505],[86.7565,48.894],[86.8165,48.8565],[86.761,48.804],[86.773,48.7205],[86.6355,48.627],[86.584,48.54],[86.407,48.4785],[86.3215,48.488],[86.2325,48.432],[85.9115,48.436],[85.7875,48.4175],[85.7255,48.373],[85.6595,48.242],[85.5935,48.196],[85.5595,48.149],[85.5295,48.025],[85.543,48.0095],[85.6145,47.54],[85.608,47.5095],[85.6805,47.434],[85.6745,47.312],[85.6985,47.288],[85.6825,47.223],[85.5765,47.1375],[85.5295,47.0515],[85.4125,47.06],[85.3825,47.046],[85.2995,47.065],[85.217,47.0525],[85.194,47.0125],[85.0955,46.964],[85.0785,46.931],[84.983,46.915],[84.944,46.863],[84.858,46.9285],[84.8475,46.954],[84.7095,47.0095],[84.5795,46.9995],[84.5065,46.9755],[84.436,47.009],[84.379,46.996],[84.2585,47.003],[84.1655,46.994],[84.1265,46.9675],[84.0565,46.9685],[83.9845,46.9955],[83.9175,46.973],[83.7835,47.0245],[83.701,47.0225],[83.578,47.0605],[83.4575,47.132],[83.4135,47.116],[83.354,47.1745],[83.2395,47.179],[83.151,47.2345],[83.0515,47.2255],[82.993,47.0645],[82.938,47.016],[82.9325,46.972],[82.869,46.83],[82.8295,46.7775],[82.782,46.669],[82.725,46.4915],[82.608,46.2985],[82.512,46.1545],[82.456,45.977],[82.3755,45.964],[82.3355,45.939],[82.345,45.7955],[82.288,45.709],[82.259,45.6165],[82.28,45.535],[82.4375,45.4595],[82.543,45.421],[82.5875,45.3445],[82.582,45.2215],[82.475,45.177],[82.3405,45.209],[82.2675,45.2415],[82.151,45.222],[82.088,45.243],[81.922,45.229],[81.774,45.386],[81.7135,45.359],[81.6325,45.3565],[81.452,45.262],[81.382,45.264],[81.282,45.2395],[81.2035,45.237],[81.1195,45.215],[81.0245,45.1635],[80.957,45.1675],[80.8985,45.125],[80.74,45.1615],[80.698,45.1335],[80.576,45.11],[80.4375,45.097],[80.382,45.04],[80.3255,45.0695],[80.2135,45.0235],[80.1525,45.0525],[80.062,45.036],[80.013,44.98],[79.9555,44.9615],[79.882,44.9105],[79.9535,44.882],[79.9445,44.85],[80.034,44.804],[80.128,44.823],[80.173,44.7935],[80.2195,44.7305],[80.3135,44.7035],[80.4105,44.6105],[80.347,44.4825],[80.384,44.3775],[80.4065,44.2495],[80.396,44.11],[80.4455,44.071],[80.4545,43.982],[80.506,43.906],[80.521,43.8245],[80.6855,43.5795],[80.751,43.469],[80.735,43.393],[80.6855,43.3375],[80.698,43.316],[80.7785,43.3115],[80.765,43.267],[80.8075,43.1775],[80.7815,43.138],[80.6575,43.15],[80.5865,43.1365],[80.556,43.102],[80.485,43.0705],[80.384,43.046],[80.388,43.003],[80.4855,42.945],[80.5395,42.936],[80.5985,42.8945],[80.329,42.8275],[80.2775,42.838],[80.223,42.713],[80.1765,42.6715],[80.1625,42.625],[80.2205,42.533],[80.267,42.503],[80.2075,42.4675],[80.2335,42.4045],[80.232,42.349],[80.2835,42.2355],[80.1745,42.211],[80.1655,42.101],[80.225,42.0595],[80.138,42.0315],[80.0265,42.049],[79.912,42.042],[79.8545,42.022],[79.802,41.9195],[79.765,41.893],[79.638,41.8935],[79.6075,41.857],[79.4975,41.8365],[79.4095,41.841],[79.347,41.7935],[79.323,41.811],[79.2095,41.725],[79.124,41.7225],[79.083,41.689],[78.941,41.6445],[78.815,41.5585],[78.7245,41.555],[78.6445,41.469],[78.5575,41.4765],[78.532,41.442],[78.382,41.3915],[78.1895,41.394],[78.146,41.3675],[78.1215,41.2275],[78.0215,41.193],[77.912,41.186],[77.8045,41.1225],[77.796,41.0485],[77.765,41.015],[77.687,41.0035],[77.6465,41.0145],[77.5835,40.994],[77.4675,40.9985],[77.3705,41.0405],[77.2625,41.0045],[77.242,41.0265],[77.1175,41.027],[77.0855,41.063],[76.9635,41.0585],[76.94,41.0305],[76.878,41.0275],[76.8195,40.977],[76.7625,40.953],[76.7025,40.7875],[76.64,40.762],[76.654,40.622],[76.6115,40.6105],[76.552,40.5455],[76.5385,40.474],[76.44,40.389],[76.3395,40.3495],[76.3125,40.406],[76.2515,40.418],[76.1855,40.38],[76.1315,40.397],[75.962,40.3745],[75.93,40.302],[75.8115,40.3245],[75.718,40.287],[75.6635,40.355],[75.68,40.4215],[75.7235,40.472],[75.647,40.505],[75.6235,40.5455],[75.63,40.623],[75.5955,40.6475],[75.539,40.6475],[75.462,40.603],[75.4085,40.5525],[75.3725,40.5485],[75.2385,40.461],[75.124,40.458],[75.09,40.435],[75.018,40.4665],[74.987,40.452],[74.921,40.493],[74.838,40.522],[74.796,40.435],[74.9055,40.3535],[74.862,40.324],[74.79,40.3535],[74.701,40.325],[74.6605,40.273],[74.5905,40.282],[74.5255,40.209],[74.3445,40.0935],[74.304,40.115],[74.2,40.1235],[74.066,40.0785],[74.042,40.0995],[73.983,40.0485],[73.977,40.005],[73.907,39.9205],[73.903,39.8615],[73.848,39.8345],[73.832,39.7815],[73.904,39.7445],[73.949,39.6215],[73.8785,39.5425],[73.8745,39.483],[73.7255,39.461],[73.638,39.474],[73.6005,39.4595],[73.592,39.4115],[73.526,39.3915],[73.5585,39.355],[73.535,39.323],[73.569,39.244],[73.6135,39.2475],[73.662,39.165],[73.7205,39.112],[73.751,39.0255],[73.8125,39.043],[73.854,38.9525],[73.8065,38.933],[73.7575,38.9425],[73.699,38.878],[73.768,38.778],[73.744,38.732],[73.805,38.664],[73.8035,38.612],[73.8985,38.581],[73.9235,38.5425],[73.9895,38.5245],[74.0395,38.544],[74.0745,38.611],[74.1215,38.6415],[74.187,38.6405],[74.2845,38.5985],[74.5065,38.4715],[74.6505,38.446],[74.6955,38.425],[74.6655,38.3805],[74.706,38.2825],[74.698,38.228],[74.8,38.2025],[74.8205,38.0855],[74.8685,38.0255],[74.9165,38.0245],[74.913,37.8565],[74.952,37.809],[74.967,37.752],[74.897,37.6655],[74.9395,37.603],[74.932,37.5685],[75.0315,37.501],[75.0575,37.5245],[75.1485,37.421],[75.096,37.368],[75.1285,37.323],[74.9105,37.275],[74.89,37.234]]],[[[110.9815,15.7675],[111.0035,15.6905],[111.041,15.6385],[111.1015,15.595],[111.164,15.575],[111.2435,15.5765],[112.5485,15.822],[112.656,15.862],[112.753,15.9415],[112.7985,16.026],[112.9475,16.616],[112.947,16.7125],[112.9205,16.772],[112.8585,16.838],[112.4685,17.108],[112.3855,17.1615],[112.2805,17.1965],[111.525,17.319],[111.4285,17.3015],[111.357,17.273],[111.2975,17.229],[111.243,17.128],[110.9865,15.8245],[110.9815,15.7675]]],[[[112.1905,15.7105],[112.23,15.6845],[112.29,15.72],[112.265,15.7585],[112.2075,15.7455],[112.1905,15.7105]]],[[[112.857,9.5385],[112.89,9.523],[112.954,9.5475],[113.064,9.64],[113.078,9.6755],[113.05,9.7015],[112.9435,9.6615],[112.857,9.5385]]],[[[113.5365,15.575],[113.6145,15.4875],[113.876,15.363],[114.069,15.3605],[114.1785,15.375],[114.279,15.424],[114.3545,15.544],[114.5705,15.543],[114.655,15.592],[114.7435,15.6845],[114.966,16.021],[114.993,16.136],[114.9045,16.275],[114.8205,16.335],[114.67,16.2955],[114.5125,16.195],[114.2165,16.1435],[113.977,16.03],[113.83,15.866],[113.7835,15.7035],[113.617,15.638],[113.5365,15.575]]],[[[114.041,10.9125],[114.0865,10.891],[114.1165,10.911],[114.114,10.95],[114.0715,10.9545],[114.041,10.9125]]],[[[115.4735,9.9085],[115.4975,9.8615],[115.578,9.863],[115.602,9.907],[115.5695,9.9445],[115.506,9.9565],[115.4735,9.9085]]],[[[117.6955,15.21],[117.7015,15.1325],[117.7255,15.0925],[117.826,15.086],[117.855,15.1],[117.86,15.1645],[117.804,15.19],[117.767,15.23],[117.71,15.2395],[117.6955,15.21]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/f/fa/Flag_of_the_People%27s_Republic_of_China.svg","name:en":"China","wikidata":"Q148","ISO3166-1:alpha2":"CN","ISO3166-1:alpha3":"CHN","ISO3166-1:numeric":"156"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[-61.7725,-50.9875],[-61.7585,-51.0575],[-61.659,-51.1525],[-61.5995,-51.177],[-61.669,-51.8225],[-61.657,-51.8915],[-61.6065,-51.954],[-61.1995,-52.29],[-61.0895,-52.347],[-60.799,-52.4375],[-60.7315,-52.453],[-59.8035,-52.591],[-59.1715,-52.646],[-58.901,-52.65],[-58.7875,-52.6385],[-58.6465,-52.579],[-58.1785,-52.2365],[-57.528,-51.8765],[-57.3995,-51.7665],[-57.366,-51.6625],[-57.4025,-51.546],[-57.4105,-51.463],[-57.459,-51.4005],[-57.61,-51.278],[-57.7155,-51.2165],[-57.89,-51.165],[-58.905,-51.0375],[-59.0095,-51.035],[-59.482,-51.0715],[-59.848,-51.0135],[-60.996,-50.8355],[-61.2695,-50.802],[-61.4455,-50.7975],[-61.5865,-50.815],[-61.6855,-50.8595],[-61.7475,-50.919],[-61.7725,-50.9875]]],[[[-59.524,-52.905],[-59.5055,-52.981],[-59.452,-53.042],[-59.37,-53.087],[-59.2595,-53.1145],[-59.144,-53.1165],[-58.9735,-53.0705],[-58.8985,-53.015],[-58.8525,-52.938],[-58.8495,-52.866],[-58.8975,-52.7865],[-58.986,-52.7295],[-59.0895,-52.6995],[-59.242,-52.6945],[-59.3795,-52.729],[-59.4615,-52.78],[-59.5085,-52.842],[-59.524,-52.905]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/8/83/Flag_of_the_Falkland_Islands.svg","name:en":"Falkland Islands","wikidata":"Q9648","ISO3166-1:alpha2":"FK","ISO3166-1:alpha3":"FLK","ISO3166-1:numeric":"238"}}, -{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-62.7675,18.163],[-62.734,18.2035],[-62.7145,18.264],[-62.7165,18.3325],[-62.743,18.3965],[-62.79,18.448],[-62.8695,18.4875],[-62.9615,18.499],[-63.0595,18.471],[-63.242,18.487],[-63.2115,18.5805],[-63.2215,18.6555],[-63.2595,18.722],[-63.319,18.7695],[-63.3915,18.793],[-63.4675,18.7905],[-63.568,18.7395],[-63.6185,18.674],[-63.639,18.5765],[-63.6245,18.508],[-63.5605,18.425],[-63.455,18.3825],[-63.486,18.286],[-63.474,18.211],[-63.433,18.144],[-63.379,18.1025],[-63.3605,18.0615],[-63.2095,18.098],[-62.9485,18.181],[-62.8765,18.1905],[-62.7675,18.163]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/b/b4/Flag_of_Anguilla.svg","name:en":"Anguilla","wikidata":"Q25228","ISO3166-1:alpha2":"AI","ISO3166-1:alpha3":"AIA","ISO3166-1:numeric":"660"}}, -{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[34.295,31.704],[34.1655,31.5615],[34.069,31.478],[34.219,31.3235],[34.2675,31.22],[34.3665,31.2905],[34.3645,31.3615],[34.3805,31.3895],[34.478,31.476],[34.547,31.513],[34.565,31.5425],[34.488,31.597],[34.295,31.704]]],[[[35.555,32.389],[35.419,32.417],[35.403,32.501],[35.358,32.5185],[35.2955,32.5095],[35.2245,32.552],[35.0655,32.449],[35.0515,32.367],[35.0165,32.3385],[35.0305,32.266],[34.9595,32.1755],[34.9905,32.142],[34.985,32.0945],[35.005,32.022],[34.9905,31.961],[35.039,31.907],[35.0335,31.859],[35.0835,31.8525],[35.1085,31.8235],[35.178,31.808],[35.264,31.8265],[35.239,31.7095],[35.127,31.7295],[35.085,31.6905],[35.0065,31.6525],[34.9525,31.5945],[34.944,31.51],[34.894,31.415],[34.882,31.393],[34.92,31.3435],[35.006,31.3575],[35.1345,31.355],[35.2305,31.3745],[35.3945,31.4915],[35.475,31.4965],[35.4915,31.621],[35.5275,31.7215],[35.5555,31.7515],[35.549,31.8655],[35.5245,31.907],[35.5445,31.97],[35.519,32.0355],[35.533,32.108],[35.5705,32.1915],[35.5655,32.258],[35.559,32.3365],[35.5565,32.3685],[35.555,32.386],[35.555,32.389]]]]},"properties":{"flag":"http://upload.wikimedia.org/wikipedia/commons/0/00/Flag_of_Palestine.svg","name:en":"Palestinian Territories","wikidata":"Q219060","ISO3166-1:alpha2":"PS","ISO3166-1:alpha3":"PSE","ISO3166-1:numeric":"275"}}]} \ No newline at end of file +{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"id":"IN-AS"},"geometry":{"type":"Polygon","coordinates":[[[89.71298,26.26755],[89.73581,26.15818],[89.77865,26.08387],[89.77728,26.04254],[89.86592,25.93115],[89.80585,25.82489],[89.84388,25.70042],[89.86129,25.61714],[89.81208,25.37244],[89.89562,25.5635],[90.01922,25.60314],[89.89906,25.73867],[90.10642,25.96113],[90.48065,26.0031],[90.61729,25.87714],[90.95443,25.95001],[91.24969,25.71887],[91.84432,26.10982],[91.94732,25.99755],[92.30438,26.06788],[92.13958,25.69846],[92.6477,25.57465],[92.79464,25.21612],[92.39147,25.01471],[92.49887,24.88796],[92.38626,24.86055],[92.25854,24.9191],[92.15796,24.54435],[92.22953,24.50245],[92.27931,24.39213],[92.21786,24.25259],[92.29819,24.25406],[92.42317,24.25635],[92.44239,24.14299],[92.52685,24.16617],[92.76168,24.52088],[92.8379,24.39588],[93.02329,24.40026],[93.10569,24.81883],[93.17985,24.80169],[93.47236,25.3074],[93.31924,25.53872],[93.51905,25.67433],[93.69964,25.92717],[93.78341,25.97594],[93.79371,25.81472],[93.96537,25.90185],[93.99902,26.16468],[94.27093,26.5658],[94.30801,26.45459],[94.39659,26.52772],[94.40551,26.61922],[94.78248,26.79771],[94.88548,26.92451],[95.19515,27.02915],[95.46295,27.12209],[95.49041,27.2473],[95.89279,27.27294],[95.99647,27.37481],[95.86189,27.43333],[95.88523,27.52836],[95.76335,27.73519],[95.97518,27.9665],[95.63117,27.96105],[95.51994,27.88157],[95.316,27.87125],[94.86968,27.74036],[94.46937,27.5728],[94.216,27.62331],[94.26269,27.52471],[94.15489,27.4839],[93.80882,27.15142],[93.83354,27.07746],[93.68385,26.97838],[93.50257,26.93859],[93.38035,26.96308],[93.03291,26.919],[92.90313,27.00591],[92.64289,27.03894],[92.6441,26.98495],[92.11863,26.893],[92.05523,26.8692],[91.83181,26.87318],[91.50067,26.79223],[90.67715,26.77215],[90.48504,26.8594],[90.39271,26.90704],[90.30402,26.85098],[90.04535,26.72422],[89.86124,26.73307],[89.86885,26.46258],[89.84653,26.40078],[89.71298,26.26755]]]}},{"type":"Feature","properties":{"id":"IN-LD"},"geometry":{"type":"Polygon","coordinates":[[[71.96044,11.88348],[72.15131,7.6285],[74.03744,7.70688],[74.10827,11.89423],[71.96044,11.88348]]]}},{"type":"Feature","properties":{"id":"CN-HE"},"geometry":{"type":"Polygon","coordinates":[[[113.47297,36.6976],[113.59554,36.4616],[113.72909,36.36103],[114.02435,36.33172],[114.61418,36.12345],[114.91287,36.13066],[114.91493,36.04354],[115.19714,36.22544],[115.31936,36.07518],[115.48072,36.15506],[115.27336,36.47927],[115.47866,36.75759],[115.62629,36.79828],[115.83366,37.0475],[115.96755,37.33304],[116.23466,37.35978],[116.21887,37.46177],[116.31912,37.58485],[116.42143,37.46995],[116.79153,37.84015],[117.40745,37.83636],[117.55439,38.06323],[117.69378,38.07296],[117.84484,38.26514],[118.33648,38.49229],[117.59559,38.61472],[117.42736,38.61204],[117.24128,38.56373],[117.21931,38.63189],[117.09297,38.58682],[117.02567,38.69837],[116.87187,38.68658],[116.85539,38.74658],[116.75514,38.74176],[116.70364,38.93751],[116.75926,39.04372],[116.85882,39.05598],[116.91581,39.13112],[116.85539,39.16467],[116.87942,39.34385],[116.81899,39.34491],[116.87049,39.43354],[116.77848,39.46005],[116.80732,39.61415],[116.52065,39.59193],[116.46366,39.52946],[116.43722,39.44494],[116.32942,39.4566],[116.23809,39.51649],[116.22058,39.5787],[115.91365,39.57552],[115.81031,39.50933],[115.74851,39.51251],[115.66268,39.60833],[115.51574,39.6041],[115.47042,39.74177],[115.41755,39.77925],[115.56518,39.81011],[115.42098,39.96449],[115.50338,40.07649],[115.76808,40.15736],[115.8467,40.14633],[115.95382,40.27481],[115.90541,40.35544],[115.857,40.36145],[115.76568,40.44668],[115.77632,40.46196],[115.73272,40.51145],[115.77907,40.56128],[115.81615,40.5575],[115.82267,40.5871],[116.11278,40.62646],[116.24565,40.79067],[116.46537,40.7652],[116.31465,40.93037],[116.47602,40.89586],[116.44306,40.98145],[116.6209,40.97989],[116.62605,41.06485],[116.98379,40.68896],[117.21794,40.69938],[117.30789,40.65199],[117.43972,40.68532],[117.51663,40.65069],[117.47749,40.63167],[117.44419,40.65042],[117.42977,40.61851],[117.41432,40.63701],[117.40882,40.56206],[117.3072,40.57719],[117.24781,40.54902],[117.25227,40.50857],[117.20626,40.50126],[117.25913,40.43701],[117.22824,40.41245],[117.21811,40.36616],[117.29587,40.27612],[117.32814,40.2879],[117.34291,40.23131],[117.5537,40.22607],[117.75558,40.05389],[117.78648,39.96659],[117.53517,39.98711],[117.50427,39.88971],[117.54753,39.7584],[117.58872,39.73993],[117.65945,39.63848],[117.71026,39.52787],[117.76245,39.59828],[117.92861,39.57499],[117.85274,39.38685],[117.79197,39.36668],[117.84656,39.35421],[117.84072,39.32712],[117.96363,39.31331],[118.06079,39.25166],[118.02577,39.21789],[118.35983,38.73266],[119.98931,39.77661],[119.73586,40.11431],[119.58137,40.36799],[119.55253,40.54876],[119.26277,40.53154],[119.12406,40.67647],[118.90296,40.75297],[118.88992,40.9576],[119.01695,40.97523],[118.92631,41.06382],[119.07325,41.08608],[119.24972,41.27264],[119.23562,41.3149],[119.1481,41.29638],[118.79585,41.3598],[118.38729,41.31082],[118.20396,41.62314],[118.11538,41.76567],[118.34335,41.85728],[118.26232,42.08446],[118.18267,42.02838],[117.98973,42.25952],[118.01376,42.39962],[117.7851,42.61678],[117.44453,42.59151],[117.39921,42.46449],[117.00782,42.45994],[116.88697,42.37985],[116.90757,42.18477],[116.78054,42.19902],[116.86981,42.00236],[116.70158,41.93037],[116.30058,41.99675],[116.10763,41.84399],[116.06574,41.77131],[115.91194,41.93804],[115.81787,41.93191],[115.31112,41.67291],[115.33927,41.59541],[114.8545,41.59593],[114.93484,41.85882],[114.84626,42.14456],[114.50637,42.11095],[114.43702,41.9457],[114.23309,41.69547],[114.21455,41.50703],[114.01336,41.52503],[113.85612,41.41338],[113.99208,41.19054],[113.83621,41.08452],[114.06829,40.85485],[114.05834,40.79795],[114.1246,40.74569],[114.28527,40.51327],[114.30519,40.36695],[114.54482,40.3366],[113.89114,40.0192],[114.41093,39.83121],[114.39376,39.60568],[114.5613,39.55276],[114.3402,39.07997],[113.94676,39.09489],[113.75518,38.94499],[113.84101,38.76854],[113.53683,38.50787],[113.55194,38.23871],[113.82797,38.16263],[114.02984,37.72972],[114.127,37.69387],[114.09851,37.58594],[113.74488,37.0738],[113.78917,36.88071],[113.47297,36.6976]]]}},{"type":"Feature","properties":{"id":"IN-AN"},"geometry":{"type":"Polygon","coordinates":[[[91.66991,10.83331],[93.82619,5.95573],[94.98735,6.60903],[94.6395,14.00732],[93.69443,13.6468],[92.61282,13.95915],[91.66991,10.83331]]]}},{"type":"Feature","properties":{"id":"CN-SD"},"geometry":{"type":"Polygon","coordinates":[[[114.82429,34.994],[115.13122,35.00187],[115.21465,34.94814],[115.19439,34.90817],[115.42545,34.8014],[115.45394,34.63659],[115.67916,34.55577],[116.09596,34.60665],[116.19792,34.51759],[116.37405,34.64676],[116.43859,34.89944],[116.96456,34.88367],[117.15957,34.52692],[117.78991,34.51447],[117.93411,34.68404],[118.14559,34.54389],[118.17718,34.36837],[118.42849,34.44655],[118.51226,34.69194],[118.76495,34.73822],[118.88442,35.04349],[119.30259,35.07833],[123.85601,37.49093],[123.90497,38.79949],[120.97044,38.45359],[117.84484,38.26514],[117.69378,38.07296],[117.55439,38.06323],[117.40745,37.83636],[116.79153,37.84015],[116.42143,37.46995],[116.31912,37.58485],[116.21887,37.46177],[116.23466,37.35978],[115.96755,37.33304],[115.83366,37.0475],[115.62629,36.79828],[115.47866,36.75759],[115.27336,36.47927],[115.48072,36.15506],[115.43197,36.01078],[115.35026,35.95021],[115.35644,35.77771],[115.49171,35.92297],[115.64414,35.91936],[116.0939,36.11069],[116.03073,35.963],[115.87005,35.91185],[115.67985,35.76211],[115.41206,35.64111],[115.32966,35.47744],[115.07903,35.40416],[114.91218,35.19962],[114.82429,34.994]]]}},{"type":"Feature","properties":{"id":"IN-CT"},"geometry":{"type":"Polygon","coordinates":[[[80.24825,18.95565],[80.36636,18.83091],[80.27503,18.72104],[80.34782,18.59158],[80.51055,18.62802],[81.05026,17.77615],[81.39221,17.81014],[81.40165,17.88727],[81.44988,17.89707],[81.52679,18.16248],[81.50722,18.19217],[81.54275,18.26864],[81.61468,18.31052],[81.706,18.39916],[81.69158,18.42196],[81.79664,18.477],[81.84402,18.5714],[81.90101,18.64266],[82.16468,18.79094],[82.17945,18.90401],[82.2512,18.91473],[82.06375,19.78221],[81.82617,19.92558],[81.93809,20.09527],[82.34939,19.83776],[82.45513,19.91461],[82.58628,19.86263],[82.58285,19.76444],[82.72258,19.85036],[82.70439,20.00141],[82.39437,20.05302],[82.34252,20.85688],[82.4517,20.82608],[82.67555,21.16008],[83.1792,21.11044],[83.27499,21.3722],[83.40236,21.33958],[83.3385,21.50226],[83.46828,21.72569],[83.48167,21.81242],[83.58844,21.84078],[83.54347,22.05159],[83.65436,22.22967],[84.00421,22.37261],[84.04129,22.46005],[83.99425,22.53602],[84.40177,22.89325],[84.3695,22.97704],[84.14909,22.97546],[84.02961,23.16592],[84.06978,23.33059],[83.97039,23.37424],[84.02652,23.63068],[83.78929,23.58853],[83.71564,23.68587],[83.69487,23.82209],[83.55342,23.8783],[83.4185,24.08596],[83.32134,24.10131],[83.15963,23.90467],[82.95226,23.87642],[82.80876,23.96492],[82.65666,23.90216],[82.49599,23.7844],[81.90685,23.85569],[81.79218,23.80764],[81.72214,23.83999],[81.66274,23.92821],[81.59614,23.88834],[81.68712,23.71809],[81.57091,23.58113],[81.62567,23.48875],[81.75338,23.56619],[81.94942,23.49347],[82.03886,23.38433],[82.19361,23.32066],[82.13687,23.16608],[82.16245,23.15077],[82.1149,23.10247],[81.93886,23.07823],[81.91543,22.94701],[81.75991,22.85086],[81.76849,22.65108],[81.39633,22.45291],[81.35684,22.52175],[81.0918,22.43102],[80.98571,22.03441],[80.90606,22.13112],[80.80203,21.74036],[80.65784,21.32967],[80.64308,21.25418],[80.42129,21.09923],[80.46935,20.92681],[80.54214,20.92681],[80.5799,20.6694],[80.60806,20.32273],[80.38284,20.23256],[80.54488,20.07528],[80.51467,19.92687],[80.8937,19.47306],[80.72341,19.27355],[80.55587,19.40313],[80.24825,18.95565]]]}},{"type":"Feature","properties":{"id":"CN-XZ"},"geometry":{"type":"Polygon","coordinates":[[[78.38897,32.53938],[78.4645,32.45367],[78.49609,32.2762],[78.68754,32.10256],[78.74404,32.00384],[78.78036,31.99478],[78.69933,31.78723],[78.84516,31.60631],[78.71032,31.50197],[78.77898,31.31209],[79.01931,31.42817],[79.14016,31.43403],[79.22805,31.34963],[79.59884,30.93943],[79.93255,30.88288],[80.20721,30.58541],[80.54504,30.44936],[80.83343,30.32023],[81.03953,30.20059],[81.12842,30.01395],[81.24362,30.0126],[81.29032,30.08806],[81.2623,30.14596],[81.33355,30.15303],[81.39928,30.21862],[81.41018,30.42153],[81.62033,30.44703],[81.99082,30.33423],[82.10135,30.35439],[82.10757,30.23745],[82.19475,30.16884],[82.16984,30.0692],[82.38622,30.02608],[82.5341,29.9735],[82.73024,29.81695],[83.07116,29.61957],[83.28131,29.56813],[83.44787,29.30513],[83.63156,29.16249],[83.82303,29.30513],[83.97559,29.33091],[84.18107,29.23451],[84.24801,29.02783],[84.2231,28.89571],[84.47528,28.74023],[84.62317,28.73887],[84.85511,28.58041],[85.06059,28.68562],[85.19135,28.62825],[85.18668,28.54076],[85.10729,28.34092],[85.38127,28.28336],[85.4233,28.32996],[85.59765,28.30529],[85.60854,28.25045],[85.69105,28.38475],[85.71907,28.38064],[85.74864,28.23126],[85.84672,28.18187],[85.90743,28.05144],[85.97813,27.99023],[85.94946,27.9401],[86.06309,27.90021],[86.12069,27.93047],[86.08333,28.02121],[86.088,28.09264],[86.18607,28.17364],[86.22966,27.9786],[86.42736,27.91122],[86.51609,27.96623],[86.56265,28.09569],[86.74181,28.10638],[86.75582,28.04182],[87.03757,27.94835],[87.11696,27.84104],[87.56996,27.84517],[87.72718,27.80938],[87.82681,27.95248],[88.13378,27.88015],[88.1278,27.95417],[88.25332,27.9478],[88.54858,28.06057],[88.63235,28.12356],[88.83559,28.01936],[88.88091,27.85192],[88.77517,27.45415],[88.82981,27.38814],[88.91901,27.32483],[88.93678,27.33777],[88.96947,27.30319],[89.00216,27.32532],[88.95355,27.4106],[88.97213,27.51671],[89.0582,27.60985],[89.12825,27.62502],[89.59525,28.16433],[89.79762,28.23979],[90.13387,28.19178],[90.58842,28.02838],[90.69894,28.07784],[91.20019,27.98715],[91.25779,28.07509],[91.46327,28.0064],[91.48973,27.93903],[91.5629,27.84823],[91.6469,27.76358],[91.84722,27.76325],[91.87057,27.7195],[92.27432,27.89077],[92.32101,27.79363],[92.42538,27.80092],[92.7275,27.98662],[92.73025,28.05814],[92.65472,28.07632],[92.67486,28.15018],[92.93075,28.25671],[93.14635,28.37035],[93.18069,28.50319],[93.44621,28.67189],[93.72797,28.68821],[94.35897,29.01965],[94.2752,29.11687],[94.69318,29.31739],[94.81353,29.17804],[95.0978,29.14446],[95.11291,29.09527],[95.2214,29.10727],[95.26122,29.07727],[95.3038,29.13847],[95.41091,29.13007],[95.50842,29.13487],[95.72086,29.20797],[95.75149,29.32063],[95.84899,29.31464],[96.05361,29.38167],[96.31316,29.18643],[96.18682,29.11087],[96.20467,29.02325],[96.3626,29.10607],[96.61391,28.72742],[96.40929,28.51526],[96.48895,28.42955],[96.6455,28.61657],[96.85561,28.4875],[96.88445,28.39452],[96.98882,28.32564],[97.1289,28.3619],[97.34547,28.21385],[97.41729,28.29783],[97.47085,28.2688],[97.50518,28.49716],[97.56835,28.55628],[97.70705,28.5056],[97.79632,28.33168],[97.90069,28.3776],[98.15337,28.12114],[98.16696,28.21002],[98.26789,28.24421],[98.20129,28.35666],[98.28987,28.39804],[98.36952,28.26084],[98.39355,28.10953],[98.60881,28.1725],[98.69361,28.21789],[98.75884,28.33218],[98.63697,28.49072],[98.5968,28.68622],[98.63113,28.69103],[98.68125,28.73319],[98.66254,28.79549],[98.65447,28.8585],[98.62495,28.9721],[98.78974,29.01054],[98.83197,28.80406],[98.97548,28.82933],[98.97376,28.87564],[98.91815,28.88796],[98.92501,28.98111],[99.0184,29.03425],[98.96003,29.18663],[99.11487,29.22679],[99.05479,29.30586],[99.06234,29.45051],[98.98956,29.66359],[99.01119,29.8189],[99.05651,29.93708],[99.0438,30.07979],[98.99642,30.15344],[98.90613,30.68457],[98.95523,30.74862],[98.78528,30.92431],[98.80725,30.98496],[98.75404,31.03293],[98.71009,31.11997],[98.60469,31.18725],[98.63559,31.33839],[98.69052,31.33751],[98.77567,31.24949],[98.88896,31.37767],[98.84433,31.42954],[98.71971,31.50626],[98.56246,31.67705],[98.409,31.83089],[98.43475,32.00458],[98.30497,32.12619],[98.21639,32.33936],[97.99255,32.46748],[97.72544,32.52886],[97.66399,32.47704],[97.37663,32.5306],[97.30865,32.07501],[97.22557,32.10962],[97.16583,32.03049],[97.00309,32.06628],[96.9564,31.99351],[96.725,32.02612],[96.8431,31.7083],[96.5657,31.7194],[96.37069,31.85539],[96.33636,31.95682],[96.24435,31.9341],[96.13929,31.82623],[96.21963,31.76145],[96.25053,31.55396],[96.20109,31.53816],[96.14822,31.69078],[95.7891,31.75327],[95.61881,31.77896],[95.51032,31.74685],[95.22571,32.3872],[94.91981,32.413],[94.61254,32.67001],[94.14733,32.43561],[93.72161,32.57343],[93.48953,32.4947],[93.02398,32.73646],[92.22335,32.72144],[92.20275,32.88766],[91.97891,32.86113],[91.51405,33.11339],[90.70175,33.13985],[90.51567,33.2651],[90.38177,33.2605],[90.24993,33.42857],[89.99656,33.55913],[89.93751,33.80083],[89.63882,34.04583],[89.87708,34.2277],[89.73358,34.65862],[89.81941,34.90395],[89.57908,34.90113],[89.45274,35.22991],[89.68482,35.42207],[89.80224,35.859],[89.42802,35.91602],[89.40811,36.01522],[89.691,36.0935],[88.94119,36.35716],[88.76438,36.29077],[88.53332,36.48755],[86.2619,36.19995],[86.09298,35.8679],[85.57662,35.64055],[85.26489,35.80333],[84.19784,35.35881],[83.1253,35.39688],[82.966,35.62716],[82.45238,35.7309],[82.01568,35.34201],[81.66961,35.24337],[80.45287,35.45172],[79.83283,34.48958],[79.05418,34.4154],[79.05364,34.32482],[78.99802,34.3027],[78.91769,34.15452],[78.66225,34.08858],[78.65657,34.03195],[78.73367,34.01121],[78.77349,33.73871],[78.67599,33.66445],[78.73636,33.56521],[79.15252,33.17156],[79.14016,33.02545],[79.46562,32.69668],[79.26768,32.53277],[79.13174,32.47766],[79.0979,32.38051],[78.99322,32.37948],[78.96713,32.33655],[78.7831,32.46873],[78.73916,32.69438],[78.38897,32.53938]]]}},{"type":"Feature","properties":{"id":"CN-HI"},"geometry":{"type":"Polygon","coordinates":[[[107.44022,18.66249],[110.2534,15.19951],[112.88221,15.61902],[111.04979,20.2622],[108.26073,20.07614],[107.44022,18.66249]]]}},{"type":"Feature","properties":{"id":"IN-DN"},"geometry":{"type":"Polygon","coordinates":[[[72.92346,20.26348],[72.9808,20.21323],[72.98492,20.11784],[73.19675,20.05625],[73.23383,20.14266],[73.171,20.19744],[73.06354,20.18487],[73.06766,20.21806],[73.18508,20.29407],[73.12156,20.36909],[72.94578,20.35331],[72.92346,20.26348]]]}},{"type":"Feature","properties":{"id":"CN-NX"},"geometry":{"type":"Polygon","coordinates":[[[104.29321,37.4367],[105.18997,36.95208],[105.51544,36.0996],[105.32592,35.99911],[105.48454,35.72756],[106.05857,35.48639],[106.36344,35.23889],[106.4994,35.35993],[106.44241,35.69466],[106.921,35.76824],[106.9313,36.12456],[106.49047,36.30848],[106.66076,37.19751],[107.30346,37.0979],[107.2705,37.47921],[107.66139,37.87999],[107.1627,38.16155],[106.47743,38.31903],[106.95396,38.94819],[106.78161,39.37518],[106.59484,39.36934],[106.13479,39.15615],[105.85121,38.62116],[105.8258,38.34219],[105.80039,37.94149],[105.76606,37.79513],[105.10619,37.63707],[104.99084,37.5424],[104.29321,37.4367]]]}},{"type":"Feature","properties":{"id":"IN-MP"},"geometry":{"type":"Polygon","coordinates":[[[74.05677,22.48115],[74.27787,22.38373],[74.08149,22.35896],[74.07909,22.24652],[74.17282,22.06846],[74.14947,21.95323],[74.43717,22.03282],[74.52609,21.90769],[74.51408,21.72314],[74.64317,21.65583],[74.91783,21.63062],[75.07575,21.55209],[75.11455,21.45306],[75.22304,21.40928],[75.96324,21.39618],[76.15653,21.2625],[76.17301,21.08386],[76.38656,21.07809],[76.65847,21.28201],[76.80198,21.59519],[76.90429,21.60349],[77.07733,21.72474],[77.23422,21.7158],[77.49893,21.76332],[77.56484,21.38019],[78.00842,21.41887],[78.37989,21.62296],[78.43654,21.50099],[78.9347,21.49268],[78.91136,21.59295],[79.14585,21.62583],[79.33021,21.70719],[79.4914,21.67306],[79.53861,21.54634],[79.75662,21.60062],[79.91489,21.52207],[79.95025,21.5572],[80.06732,21.55528],[80.13427,21.61115],[80.20946,21.6354],[80.28499,21.59742],[80.38696,21.49619],[80.40824,21.3738],[80.56377,21.36037],[80.65784,21.32967],[80.80203,21.74036],[80.90606,22.13112],[80.98571,22.03441],[81.0918,22.43102],[81.35684,22.52175],[81.39633,22.45291],[81.76849,22.65108],[81.75991,22.85086],[81.91543,22.94701],[81.93886,23.07823],[82.1149,23.10247],[82.16245,23.15077],[82.13687,23.16608],[82.19361,23.32066],[82.03886,23.38433],[81.94942,23.49347],[81.75338,23.56619],[81.62567,23.48875],[81.57091,23.58113],[81.68712,23.71809],[81.59614,23.88834],[81.66274,23.92821],[81.72214,23.83999],[81.79218,23.80764],[81.90685,23.85569],[82.49599,23.7844],[82.65666,23.90216],[82.80876,23.96492],[82.79708,24.00319],[82.70267,24.09693],[82.66216,24.12513],[82.6752,24.16695],[82.71915,24.13876],[82.77854,24.29312],[82.76618,24.3754],[82.71606,24.37305],[82.71846,24.52713],[82.80361,24.55274],[82.69374,24.69755],[82.55195,24.65575],[82.41634,24.70504],[82.42561,24.59458],[82.30854,24.60831],[82.20691,24.78392],[81.95869,24.83301],[81.90101,24.88768],[81.90376,24.99943],[81.79389,25.00783],[81.73587,25.05574],[81.69605,25.03863],[81.56112,25.19748],[81.4904,25.07938],[81.27822,25.16703],[81.22741,24.95431],[80.80375,24.94154],[80.84426,24.99788],[80.88958,25.19375],[80.71723,25.14342],[80.77972,25.05823],[80.61561,25.10425],[80.25649,25.02401],[80.41648,25.1633],[80.29014,25.42281],[79.86854,25.23786],[79.86442,25.1086],[79.39269,25.11731],[79.47303,25.27512],[79.2794,25.35395],[79.31373,25.14404],[79.04182,25.1459],[78.92681,25.56753],[78.73146,25.47086],[78.81214,25.43056],[78.75789,25.33968],[78.66588,25.38807],[78.71051,25.45102],[78.56975,25.39676],[78.57868,25.34961],[78.52306,25.36419],[78.5464,25.3133],[78.42109,25.28164],[78.55464,25.26984],[78.63395,25.0887],[78.65558,24.91197],[78.77471,24.86027],[78.75686,24.60519],[78.87634,24.64483],[78.98483,24.44527],[78.9759,24.35397],[78.80767,24.15677],[78.51516,24.39025],[78.38882,24.26511],[78.2666,24.45277],[78.28033,24.5671],[78.16635,24.87647],[78.30642,24.97454],[78.34178,25.08155],[78.44306,25.12787],[78.30642,25.3707],[78.44066,25.56133],[78.52752,25.57031],[78.82003,25.6375],[78.74914,25.73589],[78.88458,25.90864],[79.12902,26.32665],[79.01779,26.63518],[78.74999,26.77994],[78.21029,26.82407],[76.91493,26.09533],[76.79408,25.94353],[76.59187,25.87745],[76.48544,25.71795],[76.52046,25.5319],[76.59942,25.39304],[76.68079,25.34309],[76.83734,25.32944],[76.93691,25.28071],[77.0763,25.33813],[77.19646,25.30647],[77.27508,25.42746],[77.35645,25.42932],[77.35507,25.2776],[77.41069,25.22109],[77.39559,25.11979],[77.31044,25.07938],[77.27439,25.11482],[77.00248,25.07316],[76.85554,25.03646],[76.94274,24.86401],[76.78481,24.83098],[76.85211,24.74745],[76.95304,24.75805],[77.06737,24.64639],[77.05879,24.52838],[76.94789,24.4509],[76.91802,24.54181],[76.82224,24.544],[76.83494,24.3718],[76.94343,24.20751],[76.91768,24.13735],[76.35875,24.25103],[76.21215,24.21283],[76.18846,24.33364],[76.0889,24.08564],[75.96324,24.02357],[75.98384,23.93574],[75.87879,23.88489],[75.73596,23.89651],[75.6879,23.7602],[75.45993,23.9144],[75.53203,24.0659],[75.70953,23.96617],[75.84377,24.10257],[75.7418,24.13766],[75.82076,24.24727],[75.73081,24.38118],[75.78987,24.47183],[75.88737,24.42401],[75.92101,24.51838],[75.78712,24.7699],[75.62919,24.68632],[75.58593,24.72562],[75.46989,24.68944],[75.18527,24.75057],[75.42629,24.8855],[75.30715,24.90138],[75.35659,25.03397],[75.17291,25.05356],[75.11352,24.88986],[75.03078,24.84563],[74.83543,24.98294],[74.84607,24.81135],[75.03318,24.75431],[74.90066,24.65107],[74.80522,24.79483],[74.80659,24.67322],[74.74616,24.539],[74.86907,24.48996],[74.90375,24.46058],[74.81002,24.41714],[74.75269,24.27576],[74.87182,24.27607],[74.91371,24.24226],[74.88143,24.21816],[74.98958,24.03235],[74.90924,23.86166],[74.93877,23.6376],[74.78702,23.54321],[74.61124,23.45694],[74.53605,23.30095],[74.69707,23.27572],[74.75063,23.22841],[74.53502,23.09868],[74.39769,23.11004],[74.3201,23.0573],[74.47769,22.86004],[74.36714,22.62858],[74.26929,22.64633],[74.05677,22.48115]]]}},{"type":"Feature","properties":{"id":"CN-JX"},"geometry":{"type":"Polygon","coordinates":[[[113.5976,27.42114],[113.62232,27.41017],[113.62232,27.34859],[113.875,27.38548],[113.77715,27.11781],[113.91517,26.94716],[113.83895,26.79342],[113.86402,26.65513],[113.91208,26.61277],[114.104,26.57624],[114.07482,26.40847],[113.94058,26.18193],[114.23789,26.20042],[114.02606,26.021],[114.00787,25.89258],[113.91448,25.69908],[113.98315,25.40916],[114.00924,25.28319],[114.19464,25.29685],[114.5565,25.42281],[114.74739,25.13036],[114.57092,25.08746],[114.17541,24.6545],[114.35462,24.58865],[114.4178,24.48464],[114.72576,24.6055],[114.8442,24.58178],[114.85897,24.55805],[114.9266,24.67478],[114.93415,24.6467],[115.06599,24.70753],[115.10822,24.66792],[115.37738,24.76803],[115.46699,24.76584],[115.56381,24.62954],[115.65444,24.61799],[115.69358,24.54056],[115.84327,24.5671],[115.78559,24.63703],[115.80379,24.69131],[115.76499,24.71221],[115.76362,24.79109],[115.82405,24.91539],[115.86696,24.86743],[115.89889,24.87833],[115.88859,24.94123],[115.8625,25.22544],[116.00601,25.32789],[116.14265,25.87899],[116.36444,25.971],[116.50039,26.15728],[116.38572,26.23368],[116.64321,26.49024],[116.51412,26.70145],[116.60476,26.92513],[117.05451,27.1062],[117.16918,27.2943],[117.01469,27.66163],[117.31269,27.76801],[117.28523,27.87671],[117.56332,27.96408],[117.67249,27.82268],[117.7518,27.83027],[117.85274,27.94891],[118.08792,27.99167],[118.16413,28.05743],[118.35296,28.09409],[118.36875,28.19369],[118.31245,28.22878],[118.42121,28.29239],[118.48308,28.32856],[118.43364,28.41193],[118.47381,28.47925],[118.40343,28.57457],[118.4254,28.68486],[118.3509,28.8164],[118.25134,28.92523],[118.0323,29.10057],[118.07281,29.2852],[118.20052,29.38178],[118.1195,29.42853],[118.12705,29.53523],[117.69584,29.55852],[117.45483,29.69222],[117.24952,29.89899],[117.06893,29.82634],[117.09091,29.69759],[116.70913,29.58301],[116.64939,29.70117],[116.91993,29.94541],[116.74278,30.06077],[116.57936,30.04769],[116.52992,29.89899],[116.12823,29.82754],[115.93803,29.71906],[115.65994,29.85851],[115.50064,29.8323],[115.40107,29.67492],[115.26786,29.63674],[115.11199,29.68029],[115.16693,29.50176],[114.95063,29.55852],[114.88128,29.38397],[114.25231,29.31993],[114.23034,29.2193],[114.0525,29.20761],[113.9447,29.05196],[114.01817,28.89758],[114.14932,28.77187],[114.07653,28.55919],[114.25094,28.38233],[113.99963,28.15253],[114.03945,28.06289],[113.74351,27.9477],[113.72085,27.8755],[113.75656,27.81782],[113.59863,27.63365],[113.5976,27.42114]]]}},{"type":"Feature","properties":{"id":"IN-SK"},"geometry":{"type":"Polygon","coordinates":[[[88.01646,27.21612],[88.04932,27.21631],[88.08331,27.16501],[88.08563,27.14072],[88.22656,27.11842],[88.30226,27.12682],[88.33505,27.10176],[88.45161,27.07655],[88.52045,27.17753],[88.62842,27.1731],[88.74219,27.144],[88.91901,27.32483],[88.82981,27.38814],[88.77517,27.45415],[88.88091,27.85192],[88.83559,28.01936],[88.63235,28.12356],[88.54858,28.06057],[88.25332,27.9478],[88.1278,27.95417],[88.13378,27.88015],[88.1973,27.85067],[88.19107,27.79285],[88.04008,27.49223],[88.07277,27.43007],[88.01646,27.21612]]]}},{"type":"Feature","properties":{"id":"IN-CH"},"geometry":{"type":"Polygon","coordinates":[[[76.69014,30.74699],[76.71306,30.7419],[76.71967,30.73202],[76.73014,30.72479],[76.73894,30.70136],[76.7513,30.68512],[76.76095,30.68619],[76.78945,30.67054],[76.8025,30.67527],[76.81468,30.68693],[76.82825,30.76411],[76.79254,30.76647],[76.80413,30.779],[76.79632,30.78623],[76.78104,30.77392],[76.76911,30.77683],[76.777,30.78483],[76.75975,30.79928],[76.73864,30.7908],[76.72285,30.77067],[76.70808,30.77045],[76.69066,30.75968],[76.69014,30.74699]]]}},{"type":"Feature","properties":{"id":"IN-NL"},"geometry":{"type":"Polygon","coordinates":[[[93.31924,25.53872],[93.47236,25.3074],[93.61175,25.19748],[93.86993,25.55854],[94.33685,25.50588],[94.58953,25.69289],[94.55932,25.51084],[94.68032,25.47003],[94.80117,25.49359],[95.18556,26.07338],[95.11428,26.1019],[95.12801,26.38397],[95.05798,26.45408],[95.23513,26.68499],[95.19515,27.02915],[94.88548,26.92451],[94.78248,26.79771],[94.40551,26.61922],[94.39659,26.52772],[94.30801,26.45459],[94.27093,26.5658],[93.99902,26.16468],[93.96537,25.90185],[93.79371,25.81472],[93.78341,25.97594],[93.69964,25.92717],[93.51905,25.67433],[93.31924,25.53872]]]}},{"type":"Feature","properties":{"id":"TT"},"geometry":{"type":"Polygon","coordinates":[[[-62.08693,10.04435],[-60.89962,9.81445],[-60.07172,11.77667],[-61.62505,11.18974],[-62.08693,10.04435]]]}},{"type":"Feature","properties":{"id":"AI"},"geometry":{"type":"Polygon","coordinates":[[[-63.95092,18.07976],[-63.35989,18.06012],[-62.86666,18.19278],[-62.75637,18.13489],[-62.64209,18.3662],[-63.3414,18.89029],[-63.90607,18.93262],[-63.95092,18.07976]]]}},{"type":"Feature","properties":{"id":"SX"},"geometry":{"type":"Polygon","coordinates":[[[-63.33064,17.9615],[-63.29212,17.90532],[-63.07669,17.79659],[-62.93924,18.02904],[-63.02323,18.05757],[-63.04039,18.05619],[-63.0579,18.06614],[-63.07759,18.04943],[-63.09686,18.04608],[-63.11096,18.05368],[-63.13584,18.0541],[-63.33064,17.9615]]]}},{"type":"Feature","properties":{"id":"VC"},"geometry":{"type":"Polygon","coordinates":[[[-61.73897,12.61191],[-61.38256,12.52991],[-61.13395,12.51526],[-60.70539,13.41452],[-61.43129,13.68336],[-61.73897,12.61191]]]}},{"type":"Feature","properties":{"id":"CW"},"geometry":{"type":"Polygon","coordinates":[[[-69.5195,12.75292],[-69.4514,12.18025],[-68.99639,11.79035],[-68.33524,11.78151],[-68.90012,12.62309],[-69.5195,12.75292]]]}},{"type":"Feature","properties":{"id":"CN-HL"},"geometry":{"type":"Polygon","coordinates":[[[121.20391,52.57468],[121.87133,52.27152],[122.19817,52.50786],[122.7365,52.20255],[122.96447,51.31173],[124.27871,51.304],[125.31005,51.62824],[126.06674,50.96621],[125.78521,50.7408],[125.78933,50.53263],[125.51467,50.39626],[125.18989,49.93442],[125.25649,49.32691],[125.2153,49.23777],[125.10681,49.12377],[124.86099,49.17945],[124.67834,48.83037],[124.61036,48.74894],[124.53552,48.46928],[124.50118,48.12485],[124.26086,48.52933],[123.55361,48.03493],[122.84637,47.67648],[122.3973,47.34626],[122.69393,47.08041],[123.00842,46.72385],[123.46778,46.96291],[123.59275,46.69042],[123.00498,46.56877],[123.17046,46.2283],[123.90655,46.28812],[124.13452,45.61692],[124.55612,45.41002],[125.68771,45.50346],[126.00768,45.12296],[126.65313,45.23621],[127.08846,44.93369],[127.03765,44.59242],[127.53753,44.55525],[127.71331,44.03429],[128.43429,44.50825],[128.88198,43.50374],[129.94903,44.06193],[130.07537,43.8048],[130.38574,44.03824],[130.44616,43.63905],[131.29402,43.46695],[131.19492,43.53047],[131.21105,43.82383],[131.26176,43.94011],[131.23583,43.96085],[131.25484,44.03131],[131.30365,44.04262],[131.1108,44.70266],[130.95639,44.85154],[131.48415,44.99513],[131.68466,45.12374],[131.66852,45.2196],[131.76532,45.22609],[131.86903,45.33636],[131.99417,45.2567],[132.83978,45.05916],[132.96373,45.0212],[133.12293,45.1332],[133.09279,45.25693],[133.19419,45.51913],[133.41083,45.57723],[133.48457,45.86203],[133.60442,45.90053],[133.67569,45.9759],[133.72695,46.05576],[133.68047,46.14697],[133.88097,46.25066],[133.91496,46.4274],[133.84104,46.46681],[134.03538,46.75668],[134.20016,47.33458],[134.50898,47.4812],[134.7671,47.72051],[134.55508,47.98651],[134.67098,48.1564],[134.75328,48.36763],[134.49516,48.42884],[132.66989,47.96491],[132.57309,47.71741],[131.90448,47.68011],[131.2635,47.73325],[131.09871,47.6852],[130.95985,47.6957],[130.90915,47.90623],[130.65103,48.10052],[130.84462,48.30942],[130.52147,48.61745],[130.66946,48.88251],[130.43232,48.90844],[130.2355,48.86741],[129.85416,49.11067],[129.67598,49.29596],[129.50685,49.42398],[129.40398,49.44194],[129.35317,49.3481],[129.23232,49.40353],[129.11153,49.36813],[128.72896,49.58676],[127.83476,49.5748],[127.53516,49.84306],[127.49299,50.01251],[127.60515,50.23503],[127.37384,50.28393],[127.36009,50.43787],[127.28765,50.46585],[127.36335,50.58306],[127.28165,50.72075],[127.14586,50.91152],[126.93135,51.0841],[126.90369,51.3238],[126.68349,51.70607],[126.44606,51.98254],[126.558,52.13738],[125.6131,53.07229],[125.17522,53.20225],[124.46078,53.21881],[123.86158,53.49391],[123.26989,53.54843],[122.85966,53.47395],[122.35063,53.49565],[121.39213,53.31888],[121.82738,53.03956],[121.20391,52.57468]]]}},{"type":"Feature","properties":{"id":"HT"},"geometry":{"type":"Polygon","coordinates":[[[-74.76465,18.06252],[-72.29523,17.48026],[-71.75671,18.03456],[-71.73783,18.07177],[-71.74994,18.11115],[-71.75465,18.14405],[-71.78271,18.18302],[-71.69952,18.34101],[-71.90875,18.45821],[-71.88102,18.50125],[-72.00201,18.62312],[-71.95412,18.64939],[-71.82556,18.62551],[-71.71885,18.78423],[-71.72624,18.87802],[-71.77766,18.95007],[-71.88102,18.95007],[-71.74088,19.0437],[-71.71088,19.08353],[-71.69938,19.10916],[-71.65337,19.11759],[-71.62642,19.21212],[-71.73229,19.26686],[-71.77766,19.33823],[-71.69448,19.37866],[-71.6802,19.45008],[-71.71268,19.53374],[-71.71449,19.55364],[-71.7429,19.58445],[-71.75865,19.70231],[-71.77419,19.73128],[-72.17094,20.08703],[-72.94479,20.79216],[-73.62304,20.6935],[-73.98196,19.51903],[-74.7289,18.71009],[-74.76465,18.06252]]]}},{"type":"Feature","properties":{"id":"KY"},"geometry":{"type":"Polygon","coordinates":[[[-81.81969,19.51758],[-81.52417,18.7521],[-79.33932,19.50496],[-79.63484,20.26689],[-81.81969,19.51758]]]}},{"type":"Feature","properties":{"id":"CU"},"geometry":{"type":"Polygon","coordinates":[[[-85.9092,21.8218],[-85.29304,20.76169],[-80.28428,20.93037],[-78.19353,19.33462],[-73.98196,19.51903],[-73.62304,20.6935],[-80.16442,23.44484],[-82.02215,24.23074],[-85.9092,21.8218]]]}},{"type":"Feature","properties":{"id":"TC"},"geometry":{"type":"Polygon","coordinates":[[[-72.94479,20.79216],[-71.13087,20.98822],[-70.63262,21.53631],[-72.41726,22.40371],[-72.94479,20.79216]]]}},{"type":"Feature","properties":{"id":"MT"},"geometry":{"type":"Polygon","coordinates":[[[13.4634,35.88474],[14.74801,35.36688],[15.10171,36.26215],[14.02721,36.53141],[13.4634,35.88474]]]}},{"type":"Feature","properties":{"id":"GR"},"geometry":{"type":"Polygon","coordinates":[[[19.0384,40.35325],[19.20409,39.7532],[22.5213,33.45682],[29.73302,35.92555],[29.69611,36.10365],[29.61805,36.14179],[29.61002,36.1731],[29.48192,36.18377],[29.30783,36.01033],[28.23708,36.56812],[27.95037,36.46155],[27.89482,36.69898],[27.46117,36.53789],[27.24613,36.71622],[27.45627,36.9008],[27.20312,36.94571],[27.14757,37.32],[26.95583,37.64989],[26.99377,37.69034],[27.16428,37.72343],[27.05537,37.9131],[26.21136,38.17558],[26.24183,38.44695],[26.32173,38.48731],[26.21136,38.65436],[26.61814,38.81372],[26.70773,39.0312],[26.43357,39.43096],[25.94257,39.39358],[25.61285,40.17161],[26.04292,40.3958],[25.94795,40.72797],[26.03489,40.73051],[26.0754,40.72772],[26.08638,40.73214],[26.12495,40.74283],[26.12854,40.77339],[26.15685,40.80709],[26.21351,40.83298],[26.20856,40.86048],[26.26169,40.9168],[26.29441,40.89119],[26.28623,40.93005],[26.32259,40.94042],[26.35894,40.94292],[26.33297,40.98388],[26.3606,41.02027],[26.31928,41.07386],[26.32259,41.24929],[26.39861,41.25053],[26.5209,41.33993],[26.5837,41.32131],[26.62997,41.34613],[26.61767,41.42281],[26.59742,41.48058],[26.59196,41.60491],[26.5209,41.62592],[26.47958,41.67037],[26.35957,41.71149],[26.30255,41.70925],[26.2654,41.71544],[26.22888,41.74139],[26.21325,41.73223],[26.16841,41.74858],[26.06148,41.70345],[26.07083,41.64584],[26.15146,41.60828],[26.14328,41.55496],[26.17951,41.55409],[26.176,41.50072],[26.14796,41.47533],[26.20288,41.43943],[26.16548,41.42278],[26.12926,41.35878],[25.87919,41.30526],[25.8266,41.34563],[25.70507,41.29209],[25.66183,41.31316],[25.61042,41.30614],[25.55082,41.31667],[25.52394,41.2798],[25.48187,41.28506],[25.28322,41.23411],[25.11611,41.34212],[24.942,41.38685],[24.90928,41.40876],[24.86136,41.39298],[24.82514,41.4035],[24.8041,41.34913],[24.71529,41.41928],[24.61129,41.42278],[24.52599,41.56808],[24.30513,41.51297],[24.27124,41.57682],[24.18126,41.51735],[24.10063,41.54796],[24.06323,41.53222],[24.06908,41.46132],[23.96975,41.44118],[23.91483,41.47971],[23.89613,41.45257],[23.80148,41.43943],[23.76525,41.40175],[23.67644,41.41139],[23.63203,41.37632],[23.52453,41.40262],[23.40416,41.39999],[23.33639,41.36317],[23.31301,41.40525],[23.22771,41.37106],[23.21953,41.33773],[23.1833,41.31755],[22.93334,41.34104],[22.81199,41.3398],[22.76408,41.32225],[22.74538,41.16321],[22.71266,41.13945],[22.65306,41.18168],[22.62852,41.14385],[22.58295,41.11568],[22.5549,41.13065],[22.42285,41.11921],[22.26744,41.16409],[22.17629,41.15969],[22.1424,41.12449],[22.06527,41.15617],[21.90869,41.09191],[21.91102,41.04786],[21.7556,40.92525],[21.69601,40.9429],[21.57448,40.86076],[21.53007,40.90759],[21.41555,40.9173],[21.35595,40.87578],[21.25779,40.86165],[21.21105,40.8855],[21.15262,40.85546],[20.97887,40.85475],[20.98396,40.79109],[20.95752,40.76982],[20.98134,40.76046],[21.05833,40.66586],[21.03932,40.56299],[20.96908,40.51526],[20.94925,40.46625],[20.83688,40.47882],[20.7906,40.42726],[20.78234,40.35803],[20.71789,40.27739],[20.67162,40.09433],[20.62566,40.0897],[20.61081,40.07866],[20.55593,40.06524],[20.51297,40.08168],[20.48487,40.06271],[20.42373,40.06777],[20.37911,39.99058],[20.31135,39.99438],[20.41546,39.82832],[20.41475,39.81437],[20.38572,39.78516],[20.30804,39.81563],[20.29152,39.80421],[20.31961,39.72799],[20.27412,39.69884],[20.22707,39.67459],[20.22376,39.64532],[20.15988,39.652],[20.12956,39.65805],[20.05189,39.69112],[20.00957,39.69227],[19.98042,39.6504],[19.92466,39.69533],[19.97622,39.78684],[19.95905,39.82857],[19.0384,40.35325]]]}},{"type":"Feature","properties":{"id":"PN"},"geometry":{"type":"Polygon","coordinates":[[[-133.61511,-21.93325],[-133.59543,-28.4709],[-122.0366,-24.55017],[-133.61511,-21.93325]]]}},{"type":"Feature","properties":{"id":"TO"},"geometry":{"type":"Polygon","coordinates":[[[-180,-24.21376],[-173.10761,-24.19665],[-173.11048,-23.23027],[-173.13438,-14.94228],[-174.17905,-14.94502],[-176.76826,-14.95183],[-176.74538,-22.89767],[-180,-22.90585],[-180,-24.21376]]]}},{"type":"Feature","properties":{"id":"WS"},"geometry":{"type":"Polygon","coordinates":[[[-174.18596,-12.48057],[-174.17905,-14.94502],[-173.13438,-14.94228],[-171.14262,-14.93704],[-171.14953,-12.4725],[-174.18596,-12.48057]]]}},{"type":"Feature","properties":{"id":"IN-HR"},"geometry":{"type":"Polygon","coordinates":[[[74.46464,29.78106],[74.50035,29.74053],[74.61158,29.76199],[74.57244,29.56449],[74.62188,29.52985],[74.57382,29.45992],[74.59785,29.32472],[74.80453,29.39563],[75.05207,29.281],[75.08159,29.22889],[75.33462,29.28909],[75.41084,29.19982],[75.36294,29.14301],[75.44448,29.01609],[75.51315,29.01504],[75.51744,28.9733],[75.4656,28.92689],[75.56877,28.61225],[75.80223,28.40227],[75.94333,28.36663],[76.09336,28.1498],[76.01886,28.16948],[75.93097,28.0959],[76.04032,28.08561],[75.91964,27.93329],[75.99449,27.85789],[76.22177,27.81296],[76.17267,28.01849],[76.20614,28.02486],[76.17216,28.05546],[76.22451,28.04986],[76.24958,28.07031],[76.31635,28.01925],[76.34519,28.02804],[76.35618,28.07591],[76.30262,28.09999],[76.36184,28.12543],[76.27,28.17538],[76.49333,28.15404],[76.54792,27.97393],[76.66225,28.01774],[76.65607,28.09954],[76.79958,28.16796],[76.80747,28.21562],[76.86635,28.22681],[76.96317,28.14269],[76.88575,27.67075],[76.96884,27.65555],[77.03235,27.78623],[77.28126,27.80689],[77.52468,27.9204],[77.53635,27.99167],[77.47283,28.08409],[77.54699,28.17613],[77.48794,28.19792],[77.53532,28.23725],[77.46528,28.30831],[77.48828,28.35515],[77.4979,28.40891],[77.46811,28.3997],[77.47361,28.41918],[77.45704,28.43586],[77.43086,28.4259],[77.41584,28.44039],[77.42477,28.46122],[77.41447,28.47465],[77.38752,28.46506],[77.37447,28.47035],[77.34615,28.51651],[77.32563,28.49004],[77.31413,28.4837],[77.30855,28.48823],[77.30053,28.49007],[77.30053,28.49419],[77.28832,28.49673],[77.27527,28.49358],[77.26991,28.48791],[77.26238,28.48762],[77.24298,28.47917],[77.23483,28.46982],[77.23156,28.45609],[77.24101,28.45616],[77.24628,28.4496],[77.24169,28.42763],[77.22058,28.41344],[77.17818,28.40921],[77.17389,28.40446],[77.17208,28.40559],[77.16161,28.42922],[77.14651,28.43692],[77.14043,28.43848],[77.13076,28.43984],[77.11277,28.4731],[77.11973,28.4952],[77.09775,28.50493],[77.09575,28.50713],[77.09863,28.51146],[77.09265,28.51434],[77.08003,28.51815],[77.07505,28.51877],[77.07235,28.52025],[77.07153,28.51787],[77.06703,28.51199],[77.06428,28.51285],[77.06093,28.51225],[77.05746,28.51297],[77.05226,28.51512],[77.0463,28.5167],[77.04862,28.52107],[77.0434,28.52409],[77.04344,28.52513],[77.03209,28.53118],[77.02424,28.5328],[77.0139,28.54068],[77.00544,28.53947],[77.00098,28.53114],[77.01476,28.52398],[77.01703,28.52104],[77.00982,28.51466],[76.9969,28.51949],[76.99111,28.51365],[76.97845,28.5213],[76.95334,28.50509],[76.92034,28.50678],[76.90635,28.51395],[76.90206,28.50671],[76.89657,28.50686],[76.89116,28.50037],[76.88043,28.50543],[76.88738,28.51998],[76.87391,28.5282],[76.86249,28.54487],[76.84584,28.55037],[76.83915,28.58301],[76.86429,28.58602],[76.8903,28.63274],[76.90738,28.62393],[76.91725,28.63395],[76.93528,28.61865],[76.94601,28.63289],[76.92378,28.64999],[76.93751,28.66942],[76.95502,28.66988],[76.95776,28.68448],[76.96781,28.69917],[76.94832,28.71264],[76.96068,28.73161],[76.95811,28.7432],[76.94403,28.75419],[76.95579,28.76841],[76.94807,28.78097],[76.95433,28.79045],[76.94292,28.79955],[76.95116,28.81798],[76.96146,28.81474],[76.97064,28.82783],[76.98077,28.82113],[76.99398,28.84068],[77.04282,28.8355],[77.06171,28.86963],[77.07939,28.87135],[77.08316,28.88315],[77.09166,28.87098],[77.11063,28.86918],[77.12265,28.8573],[77.13406,28.86301],[77.14616,28.85572],[77.14282,28.83858],[77.15681,28.8367],[77.17457,28.85865],[77.21157,28.8573],[77.22358,28.89939],[77.14187,29.09577],[77.10411,29.50415],[77.12882,29.75305],[77.34443,30.06315],[77.58613,30.31006],[77.5542,30.40278],[77.22083,30.49246],[76.99802,30.80024],[76.92386,30.83415],[76.90017,30.89751],[76.7704,30.9087],[76.82825,30.76411],[76.81468,30.68693],[76.81949,30.66139],[76.83794,30.65755],[76.84902,30.66693],[76.85923,30.65762],[76.85846,30.6416],[76.87133,30.63997],[76.91193,30.60504],[76.89931,30.55206],[76.89571,30.53579],[76.92026,30.52618],[76.88798,30.44038],[76.91579,30.40145],[76.92987,30.39686],[76.88833,30.35569],[76.877,30.36265],[76.88438,30.38516],[76.84885,30.40604],[76.83151,30.43328],[76.80747,30.41196],[76.75769,30.43727],[76.69864,30.39257],[76.73375,30.36458],[76.56045,30.26381],[76.63873,30.20493],[76.6238,30.14497],[76.60903,30.07978],[76.50089,30.0783],[76.44664,30.10385],[76.43394,30.15195],[76.2276,30.12656],[76.18057,29.88947],[76.2355,29.88649],[76.24168,29.85761],[76.11602,29.80222],[76.08169,29.80877],[76.04049,29.74798],[75.9423,29.73069],[75.86162,29.75424],[75.83003,29.81354],[75.70232,29.81145],[75.69339,29.75573],[75.65288,29.77987],[75.60173,29.7456],[75.44448,29.80788],[75.39813,29.76378],[75.37891,29.71161],[75.33908,29.68984],[75.34046,29.66747],[75.27934,29.60779],[75.31162,29.58122],[75.22716,29.54598],[75.21858,29.61495],[75.15747,29.66747],[75.1966,29.69073],[75.22991,29.75603],[75.20072,29.832],[75.17806,29.83826],[75.14099,29.77063],[75.1015,29.81294],[75.09155,29.91774],[74.98821,29.86357],[74.87285,29.96296],[74.80144,29.99092],[74.69467,29.9695],[74.63115,29.90494],[74.52094,29.94303],[74.55116,29.85553],[74.46464,29.78106]]]}},{"type":"Feature","properties":{"id":"WF"},"geometry":{"type":"Polygon","coordinates":[[[-178.60852,-12.49232],[-178.60161,-14.95666],[-176.76826,-14.95183],[-174.17905,-14.94502],[-174.18596,-12.48057],[-178.60852,-12.49232]]]}},{"type":"Feature","properties":{"id":"IN-MN"},"geometry":{"type":"Polygon","coordinates":[[[92.98416,24.11354],[93.32351,24.04468],[93.34735,24.10151],[93.41415,24.07854],[93.46633,23.97067],[93.50616,23.94432],[93.62871,24.00922],[93.75952,24.0003],[93.80279,23.92549],[93.92089,23.95812],[94.14081,23.83333],[94.30215,24.23752],[94.32362,24.27692],[94.45279,24.56656],[94.50729,24.59281],[94.5526,24.70764],[94.60204,24.70889],[94.73937,25.00545],[94.74212,25.13606],[94.57458,25.20318],[94.68032,25.47003],[94.55932,25.51084],[94.58953,25.69289],[94.33685,25.50588],[93.86993,25.55854],[93.61175,25.19748],[93.47236,25.3074],[93.17985,24.80169],[93.10569,24.81883],[93.02329,24.40026],[92.98416,24.11354]]]}},{"type":"Feature","properties":{"id":"PF"},"geometry":{"type":"Polygon","coordinates":[[[-156.4957,-12.32002],[-156.46451,-23.21255],[-156.44843,-28.52556],[-133.59543,-28.4709],[-133.61511,-21.93325],[-133.65593,-7.46952],[-149.6249,-7.51261],[-149.61166,-12.30171],[-156.4957,-12.32002]]]}},{"type":"Feature","properties":{"id":"AS"},"geometry":{"type":"Polygon","coordinates":[[[-174.18596,-12.48057],[-171.14953,-12.4725],[-171.14262,-14.93704],[-167.73854,-14.92809],[-167.75195,-10.12005],[-174.17993,-10.13616],[-174.18596,-12.48057]]]}},{"type":"Feature","properties":{"id":"US-HI"},"geometry":{"type":"Polygon","coordinates":[[[-179.2458,29.18869],[-179.23433,18.15359],[-154.13058,18.17333],[-154.14205,29.20682],[-176.83456,29.19028],[-176.81808,27.68129],[-177.84531,27.68616],[-177.8563,29.18961],[-179.2458,29.18869]]]}},{"type":"Feature","properties":{"id":"CN-AH"},"geometry":{"type":"Polygon","coordinates":[[[114.88128,32.97295],[115.20675,32.84844],[115.1889,32.59946],[115.44982,32.53813],[115.56312,32.38634],[115.91812,32.57922],[115.86181,32.45705],[115.93872,32.06861],[115.87005,31.77195],[115.64002,31.76145],[115.4718,31.65045],[115.36165,31.40228],[115.57823,31.14465],[115.69667,31.20604],[115.77461,31.10527],[115.87692,31.1423],[116.07776,30.96966],[115.84156,30.8312],[115.85082,30.75865],[115.7698,30.6701],[115.90061,30.50992],[115.91949,30.30472],[116.08222,30.12434],[116.12823,29.82754],[116.52992,29.89899],[116.57936,30.04769],[116.74278,30.06077],[116.91993,29.94541],[116.64939,29.70117],[116.70913,29.58301],[117.09091,29.69759],[117.06893,29.82634],[117.24952,29.89899],[117.45483,29.69222],[117.69584,29.55852],[118.12705,29.53523],[118.1195,29.42853],[118.20052,29.38178],[118.33717,29.48503],[118.48548,29.52447],[118.75808,29.76258],[118.89816,30.02332],[118.85627,30.16709],[118.90914,30.20508],[118.89404,30.35391],[119.22912,30.28871],[119.38705,30.37761],[119.31152,30.53032],[119.23393,30.53062],[119.24663,30.61575],[119.38671,30.69018],[119.43134,30.64145],[119.57382,30.85743],[119.58412,30.97407],[119.63149,31.1329],[119.57656,31.11174],[119.50378,31.1611],[119.36782,31.19107],[119.35134,31.30143],[119.27238,31.25272],[119.17968,31.29908],[119.07257,31.23394],[118.78761,31.23394],[118.71482,31.29967],[118.86314,31.43745],[118.8652,31.62415],[118.73954,31.67851],[118.71894,31.62415],[118.64204,31.64812],[118.69354,31.7194],[118.47587,31.78246],[118.49716,31.84373],[118.35605,31.93788],[118.39004,32.02612],[118.50128,32.14393],[118.50299,32.19479],[118.64444,32.21657],[118.6956,32.36198],[118.68049,32.45647],[118.54659,32.58442],[118.89747,32.58905],[119.08218,32.45531],[119.22225,32.60756],[119.17762,32.83286],[118.85559,32.95855],[118.7059,32.71624],[118.37425,32.72144],[118.22456,32.9332],[118.20121,33.2203],[118.03024,33.12777],[117.96775,33.33052],[118.18405,33.74546],[117.71026,33.74718],[117.74322,33.89264],[117.50907,34.06176],[117.02567,34.15556],[116.95014,34.39841],[116.37405,34.64676],[116.19792,34.51759],[116.2429,34.37177],[116.57867,34.27537],[116.53266,34.09588],[116.64974,33.96585],[116.63806,33.8858],[116.22951,33.72148],[116.14986,33.71148],[116.03176,33.83563],[116.05545,33.85787],[115.96034,33.90376],[115.99845,33.97439],[115.76431,34.07598],[115.59059,34.02563],[115.54801,33.8821],[115.62286,33.57115],[115.34957,33.5185],[115.30769,33.20709],[115.13465,33.08348],[114.91287,33.14387],[114.88128,32.97295]]]}},{"type":"Feature","properties":{"id":"CV"},"geometry":{"type":"Polygon","coordinates":[[[-25.86,17.60587],[-25.82546,14.43014],[-22.19117,14.46693],[-22.22571,17.64208],[-25.86,17.60587]]]}},{"type":"Feature","properties":{"id":"SH"},"geometry":{"type":"Polygon","coordinates":[[[-14.91926,-6.63386],[-14.82771,-8.70814],[-13.48367,-36.6746],[-13.41694,-37.88844],[-13.29655,-40.02846],[-9.34669,-41.00353],[-4.97086,-15.55882],[-13.33271,-8.07391],[-14.91926,-6.63386]]]}},{"type":"Feature","properties":{"id":"CN-NM"},"geometry":{"type":"Polygon","coordinates":[[[97.1777,42.7964],[98.3139,40.56806],[99.76958,40.97575],[100.28045,40.67439],[99.70229,39.98659],[100.84075,39.18224],[101.7279,38.64154],[101.8872,39.06931],[102.45712,39.23757],[102.96798,39.10981],[103.9389,39.46482],[104.18884,39.12047],[103.54476,38.15615],[103.36074,38.08809],[103.39507,37.88352],[103.83865,37.65773],[104.29321,37.4367],[104.99084,37.5424],[105.10619,37.63707],[105.76606,37.79513],[105.80039,37.94149],[105.8258,38.34219],[105.85121,38.62116],[106.13479,39.15615],[106.59484,39.36934],[106.78161,39.37518],[106.95396,38.94819],[106.47743,38.31903],[107.1627,38.16155],[107.66139,37.87999],[107.96607,37.79269],[108.01174,37.66561],[108.78936,37.68436],[108.83193,38.0662],[108.93836,37.9182],[109.02831,38.01618],[109.18521,38.03592],[108.93356,38.17883],[108.9624,38.35673],[109.55428,38.80119],[109.70809,39.05011],[109.89795,39.14683],[110.20866,39.28488],[110.10944,39.42876],[110.23063,39.4566],[110.38135,39.30826],[110.43662,39.38261],[110.52005,39.3834],[110.59661,39.27744],[110.68759,39.26522],[110.88363,39.50854],[111.15074,39.58478],[111.04808,39.43022],[111.09289,39.35859],[111.11881,39.36403],[111.12945,39.4025],[111.21288,39.42638],[111.33235,39.42081],[111.36188,39.47489],[111.4199,39.50245],[111.43295,39.64006],[111.53217,39.65698],[111.67121,39.62525],[111.72615,39.59537],[111.91909,39.61468],[111.97059,39.78822],[112.10758,39.97527],[112.30293,40.25463],[112.45399,40.29995],[112.61947,40.23891],[112.73963,40.1626],[112.84572,40.20169],[112.88761,40.32822],[113.24809,40.41349],[113.31504,40.31304],[113.53443,40.3345],[113.6721,40.4425],[113.85234,40.44511],[113.93783,40.50544],[114.07001,40.54093],[114.0652,40.67634],[114.1246,40.74569],[114.05834,40.79795],[114.06829,40.85485],[113.83621,41.08452],[113.99208,41.19054],[113.85612,41.41338],[114.01336,41.52503],[114.21455,41.50703],[114.23309,41.69547],[114.43702,41.9457],[114.50637,42.11095],[114.84626,42.14456],[114.93484,41.85882],[114.8545,41.59593],[115.33927,41.59541],[115.31112,41.67291],[115.81787,41.93191],[115.91194,41.93804],[116.06574,41.77131],[116.10763,41.84399],[116.30058,41.99675],[116.70158,41.93037],[116.86981,42.00236],[116.78054,42.19902],[116.90757,42.18477],[116.88697,42.37985],[117.00782,42.45994],[117.39921,42.46449],[117.44453,42.59151],[117.7851,42.61678],[118.01376,42.39962],[117.98973,42.25952],[118.18267,42.02838],[118.26232,42.08446],[118.34335,41.85728],[118.11538,41.76567],[118.20396,41.62314],[118.38729,41.31082],[118.79585,41.3598],[119.1481,41.29638],[119.23562,41.3149],[119.29435,41.32732],[119.36576,41.43191],[119.39392,41.58566],[119.32456,41.62519],[119.28268,41.78155],[119.3795,42.08803],[119.29916,42.12522],[119.23736,42.19596],[119.27032,42.25901],[119.50584,42.39709],[119.54498,42.29356],[119.83474,42.21428],[120.03662,41.81277],[120.02975,41.71341],[120.09498,41.68932],[120.18424,41.84245],[120.40878,41.98297],[120.5722,42.16747],[121.03774,42.27019],[121.28494,42.43359],[121.56646,42.51968],[121.66534,42.43967],[121.86309,42.53588],[121.92077,42.67032],[122.41241,42.8659],[122.80517,42.73087],[123.24737,42.98255],[123.55224,42.99862],[123.68682,43.3756],[123.32153,43.48979],[123.53301,43.64203],[123.3229,44.06045],[123.37715,44.15215],[123.1327,44.34938],[123.143,44.52294],[122.33001,44.22256],[122.11715,44.57237],[122.08213,44.91327],[122.1453,45.2971],[122.16522,45.41484],[122.01965,45.48324],[121.99836,45.6366],[121.95098,45.71097],[121.74568,45.68267],[121.64337,45.73877],[121.82121,45.8728],[121.75735,45.99505],[121.8727,46.04083],[122.2586,45.79434],[122.39868,45.9139],[122.52433,45.7771],[122.72003,45.70474],[122.79418,45.94064],[123.17046,46.2283],[123.00498,46.56877],[123.59275,46.69042],[123.46778,46.96291],[123.00842,46.72385],[122.69393,47.08041],[122.3973,47.34626],[122.84637,47.67648],[123.55361,48.03493],[124.26086,48.52933],[124.50118,48.12485],[124.53552,48.46928],[124.61036,48.74894],[124.67834,48.83037],[124.86099,49.17945],[125.10681,49.12377],[125.2153,49.23777],[125.25649,49.32691],[125.18989,49.93442],[125.51467,50.39626],[125.78933,50.53263],[125.78521,50.7408],[126.06674,50.96621],[125.31005,51.62824],[124.27871,51.304],[122.96447,51.31173],[122.7365,52.20255],[122.19817,52.50786],[121.87133,52.27152],[121.20391,52.57468],[121.82738,53.03956],[121.39213,53.31888],[120.85633,53.28499],[120.0451,52.7359],[120.04049,52.58773],[120.46454,52.63811],[120.71673,52.54099],[120.61346,52.32447],[120.77337,52.20805],[120.65907,51.93544],[120.10963,51.671],[119.13553,50.37412],[119.38598,50.35162],[119.27996,50.13348],[119.11003,50.00276],[118.61623,49.93809],[117.82343,49.52696],[117.48208,49.62324],[117.27597,49.62544],[117.07142,49.68482],[116.71193,49.83813],[116.03781,48.87014],[116.06565,48.81716],[115.78876,48.51781],[115.811,48.25699],[115.52082,48.15367],[115.57128,47.91988],[115.94296,47.67741],[116.08431,47.80693],[116.2527,47.87766],[116.4465,47.83662],[116.67405,47.89039],[116.87527,47.88836],[117.08918,47.82242],[117.37875,47.63627],[117.50181,47.77216],[117.80196,48.01661],[118.03676,48.00982],[118.11009,48.04],[118.22677,48.03853],[118.29654,48.00246],[118.55766,47.99277],[118.7564,47.76947],[119.12343,47.66458],[119.13995,47.53997],[119.35892,47.48104],[119.31964,47.42617],[119.54918,47.29505],[119.56019,47.24874],[119.62403,47.24575],[119.71209,47.19192],[119.85518,46.92196],[119.91242,46.90091],[119.89261,46.66423],[119.80455,46.67631],[119.77373,46.62947],[119.68127,46.59015],[119.65265,46.62342],[119.42827,46.63783],[119.37306,46.61132],[119.30261,46.6083],[119.24978,46.64761],[119.10448,46.65516],[119.00541,46.74273],[118.92616,46.72765],[118.89974,46.77139],[118.8337,46.77742],[118.78747,46.68689],[118.30534,46.73519],[117.69554,46.50991],[117.60748,46.59771],[117.41782,46.57862],[117.36609,46.36335],[117.07252,46.35818],[116.83166,46.38637],[116.75551,46.33083],[116.58612,46.30211],[116.26678,45.96479],[116.24012,45.8778],[116.27366,45.78637],[116.16989,45.68603],[115.91898,45.6227],[115.69688,45.45761],[115.35757,45.39106],[114.94546,45.37377],[114.74612,45.43585],[114.54801,45.38337],[114.5166,45.27189],[114.08071,44.92847],[113.909,44.91444],[113.63821,44.74326],[112.74662,44.86297],[112.4164,45.06858],[111.98695,45.09074],[111.76275,44.98032],[111.40498,44.3461],[111.96289,43.81596],[111.93776,43.68709],[111.79758,43.6637],[111.59087,43.51207],[111.0149,43.3289],[110.4327,42.78293],[110.08401,42.6411],[109.89402,42.63111],[109.452,42.44842],[109.00679,42.45302],[108.84489,42.40246],[108.23156,42.45532],[107.57258,42.40898],[107.49681,42.46221],[107.29755,42.41395],[107.24774,42.36107],[106.76517,42.28741],[105.24708,41.7442],[105.01119,41.58382],[104.91272,41.64619],[104.51667,41.66113],[104.52258,41.8706],[103.92804,41.78246],[103.3685,41.89696],[102.72403,42.14675],[102.42826,42.15137],[102.07645,42.22519],[101.80515,42.50074],[101.28833,42.58524],[100.84979,42.67087],[100.33297,42.68231],[99.50671,42.56535],[97.1777,42.7964]]]}},{"type":"Feature","properties":{"id":"CP"},"geometry":{"type":"Polygon","coordinates":[[[-109.6462,9.84394],[-108.755,9.84085],[-108.75183,10.72712],[-109.64303,10.7302],[-109.6462,9.84394]]]}},{"type":"Feature","properties":{"id":"MX"},"geometry":{"type":"Polygon","coordinates":[[[-120.12904,18.41089],[-92.37213,14.39277],[-92.2261,14.53423],[-92.1454,14.6804],[-92.18161,14.84147],[-92.1423,14.88647],[-92.1454,14.98143],[-92.0621,15.07406],[-92.20983,15.26077],[-91.73182,16.07371],[-90.44567,16.07573],[-90.40499,16.40524],[-90.61212,16.49832],[-90.69064,16.70697],[-91.04436,16.92175],[-91.43809,17.25373],[-90.99199,17.25192],[-90.98678,17.81655],[-89.14985,17.81563],[-89.15105,17.95104],[-89.03839,18.0067],[-88.8716,17.89535],[-88.71505,18.0707],[-88.48242,18.49164],[-88.3268,18.49048],[-88.29909,18.47591],[-88.26593,18.47617],[-88.03238,18.41778],[-88.03165,18.16657],[-87.90671,18.15213],[-87.87604,18.18313],[-87.86657,18.19971],[-87.85693,18.18266],[-87.84815,18.18511],[-87.24084,17.80373],[-85.9092,21.8218],[-96.92418,25.97377],[-97.13927,25.96583],[-97.35946,25.92189],[-97.37332,25.83854],[-97.42511,25.83969],[-97.45669,25.86874],[-97.49828,25.89877],[-97.52025,25.88518],[-97.66511,26.01708],[-97.95155,26.0625],[-97.97017,26.05232],[-98.24603,26.07191],[-98.27075,26.09457],[-98.30491,26.10475],[-98.35126,26.15129],[-99.00546,26.3925],[-99.03053,26.41249],[-99.08477,26.39849],[-99.53573,27.30926],[-99.49744,27.43746],[-99.482,27.47128],[-99.48045,27.49016],[-99.50208,27.50021],[-99.52955,27.49747],[-99.51478,27.55836],[-99.55409,27.61314],[-100.50029,28.66117],[-100.51222,28.70679],[-100.5075,28.74066],[-100.52313,28.75598],[-100.59809,28.88197],[-100.63689,28.90812],[-100.67294,29.09744],[-100.79696,29.24688],[-100.87982,29.296],[-100.94056,29.33371],[-100.94579,29.34523],[-100.96725,29.3477],[-101.01128,29.36947],[-101.05686,29.44738],[-101.47277,29.7744],[-102.60596,29.8192],[-103.15787,28.93865],[-104.37752,29.54255],[-104.39363,29.55396],[-104.3969,29.57105],[-104.5171,29.64671],[-104.77674,30.4236],[-106.00363,31.39181],[-106.09025,31.40569],[-106.20346,31.46305],[-106.23711,31.51262],[-106.24612,31.54193],[-106.28084,31.56173],[-106.30305,31.62154],[-106.33419,31.66303],[-106.34864,31.69663],[-106.3718,31.71165],[-106.38003,31.73151],[-106.41773,31.75196],[-106.43419,31.75478],[-106.45244,31.76523],[-106.46726,31.75998],[-106.47298,31.75054],[-106.48815,31.74769],[-106.50111,31.75714],[-106.50962,31.76155],[-106.51251,31.76922],[-106.52266,31.77509],[-106.529,31.784],[-108.20899,31.78534],[-108.20979,31.33316],[-109.05235,31.3333],[-111.07523,31.33232],[-112.34553,31.7357],[-114.82011,32.49609],[-114.79524,32.55731],[-114.81141,32.55543],[-114.80584,32.62028],[-114.76736,32.64094],[-114.71871,32.71894],[-115.88053,32.63624],[-117.1243,32.53427],[-118.48109,32.5991],[-120.12904,18.41089]]]}},{"type":"Feature","properties":{"id":"IE"},"geometry":{"type":"Polygon","coordinates":[[[-13.3292,54.24486],[-10.17712,50.85267],[-5.79914,52.03902],[-5.37267,53.63269],[-5.83481,53.87749],[-6.26218,54.09785],[-6.29003,54.11278],[-6.32694,54.09337],[-6.36279,54.11248],[-6.36605,54.07234],[-6.47849,54.06947],[-6.62842,54.03503],[-6.66264,54.0666],[-6.6382,54.17071],[-6.70175,54.20218],[-6.74575,54.18788],[-6.81583,54.22791],[-6.85179,54.29176],[-6.87775,54.34682],[-7.02034,54.4212],[-7.19145,54.31296],[-7.14908,54.22732],[-7.25012,54.20063],[-7.26316,54.13863],[-7.29493,54.12013],[-7.29687,54.1354],[-7.28017,54.16714],[-7.29157,54.17191],[-7.34005,54.14698],[-7.30553,54.11869],[-7.32834,54.11475],[-7.44567,54.1539],[-7.4799,54.12239],[-7.55812,54.12239],[-7.69501,54.20731],[-7.81397,54.20159],[-7.8596,54.21779],[-7.87101,54.29299],[-8.04555,54.36292],[-8.179,54.46763],[-8.04538,54.48941],[-7.99812,54.54427],[-7.8596,54.53671],[-7.70315,54.62077],[-7.93293,54.66603],[-7.83352,54.73854],[-7.75041,54.7103],[-7.64449,54.75265],[-7.54671,54.74606],[-7.54508,54.79401],[-7.47626,54.83084],[-7.4473,54.87003],[-7.44404,54.9403],[-7.40004,54.94498],[-7.4033,55.00391],[-7.34464,55.04688],[-7.2471,55.06933],[-6.9734,55.19878],[-6.71944,55.27952],[-6.79943,55.54107],[-7.93366,55.84142],[-13.3292,54.24486]]]}},{"type":"Feature","properties":{"id":"ST"},"geometry":{"type":"Polygon","coordinates":[[[5.9107,-0.09539],[6.69416,-0.53945],[8.0168,1.79377],[7.23334,2.23756],[5.9107,-0.09539]]]}},{"type":"Feature","properties":{"id":"GD"},"geometry":{"type":"Polygon","coordinates":[[[-62.14806,11.87638],[-61.57265,11.65795],[-61.13395,12.51526],[-61.38256,12.52991],[-61.73897,12.61191],[-62.14806,11.87638]]]}},{"type":"Feature","properties":{"id":"AG"},"geometry":{"type":"Polygon","coordinates":[[[-62.62949,16.82364],[-62.52079,16.69392],[-62.14123,17.02632],[-61.83929,16.66647],[-61.44461,16.81958],[-61.45764,17.9187],[-62.12601,17.9235],[-62.27053,17.22145],[-62.62949,16.82364]]]}},{"type":"Feature","properties":{"id":"AF"},"geometry":{"type":"Polygon","coordinates":[[[60.50209,34.13992],[60.5838,33.80793],[60.5485,33.73422],[60.57762,33.59772],[60.69573,33.56054],[60.91133,33.55596],[60.88908,33.50219],[60.56485,33.12944],[60.86191,32.22565],[60.84541,31.49561],[61.70929,31.37391],[61.80569,31.16167],[61.80957,31.12576],[61.83257,31.0452],[61.8335,30.97669],[61.78268,30.92724],[61.80829,30.84224],[60.87231,29.86514],[62.47751,29.40782],[63.5876,29.50456],[64.12966,29.39157],[64.19796,29.50407],[64.62116,29.58903],[65.04005,29.53957],[66.24175,29.85181],[66.36042,29.9583],[66.23609,30.06321],[66.34869,30.404],[66.28413,30.57001],[66.39194,30.9408],[66.42645,30.95309],[66.58175,30.97532],[66.68166,31.07597],[66.72561,31.20526],[66.83273,31.26867],[67.04147,31.31561],[67.03323,31.24519],[67.29964,31.19586],[67.78854,31.33203],[67.7748,31.4188],[67.62374,31.40473],[67.58323,31.52772],[67.72056,31.52304],[67.86887,31.63536],[68.00071,31.6564],[68.1655,31.82691],[68.25614,31.80357],[68.27605,31.75863],[68.44222,31.76446],[68.57475,31.83158],[68.6956,31.75687],[68.79997,31.61665],[68.91078,31.59687],[68.95995,31.64822],[69.00939,31.62249],[69.11514,31.70782],[69.20577,31.85957],[69.3225,31.93186],[69.27032,32.14141],[69.27932,32.29119],[69.23599,32.45946],[69.2868,32.53938],[69.38155,32.56601],[69.44747,32.6678],[69.43649,32.7302],[69.38018,32.76601],[69.47082,32.85834],[69.5436,32.8768],[69.49854,32.88843],[69.49004,33.01509],[69.57656,33.09911],[69.71526,33.09911],[69.79766,33.13247],[69.85259,33.09451],[70.02563,33.14282],[70.07369,33.22557],[70.13686,33.21064],[70.32775,33.34496],[70.17062,33.53535],[70.20141,33.64387],[70.14785,33.6553],[70.14236,33.71701],[70.00503,33.73528],[69.85671,33.93719],[69.87307,33.9689],[69.90203,34.04194],[70.54336,33.9463],[70.88119,33.97933],[71.07345,34.06242],[71.06933,34.10564],[71.09307,34.11961],[71.09453,34.13524],[71.13078,34.16503],[71.12815,34.26619],[71.17662,34.36769],[71.02401,34.44835],[71.0089,34.54568],[71.11602,34.63047],[71.08718,34.69034],[71.28356,34.80882],[71.29472,34.87728],[71.50329,34.97328],[71.49917,35.00478],[71.55273,35.02615],[71.52938,35.09023],[71.67495,35.21262],[71.5541,35.28776],[71.54294,35.31037],[71.65435,35.4479],[71.49917,35.6267],[71.55273,35.71483],[71.37969,35.95865],[71.19505,36.04134],[71.60491,36.39429],[71.80267,36.49924],[72.18135,36.71838],[72.6323,36.84601],[73.82685,36.91421],[74.04856,36.82648],[74.43389,37.00977],[74.53739,36.96224],[74.56453,37.03023],[74.49981,37.24518],[74.80605,37.21565],[74.88887,37.23275],[74.8294,37.3435],[74.68383,37.3948],[74.56161,37.37734],[74.41055,37.3948],[74.23339,37.41116],[74.20308,37.34208],[73.8564,37.26158],[73.82552,37.22659],[73.64974,37.23643],[73.61129,37.27469],[73.76647,37.33913],[73.77197,37.4417],[73.29633,37.46495],[73.06884,37.31729],[72.79693,37.22222],[72.66381,37.02014],[72.54095,37.00007],[72.31676,36.98115],[71.83229,36.68084],[71.67083,36.67346],[71.57195,36.74943],[71.51502,36.89128],[71.48481,36.93218],[71.46923,36.99925],[71.45578,37.03094],[71.43097,37.05855],[71.44127,37.11856],[71.4494,37.18137],[71.4555,37.21418],[71.47386,37.2269],[71.48339,37.23937],[71.4824,37.24921],[71.48536,37.26017],[71.50674,37.31502],[71.49821,37.31975],[71.4862,37.33405],[71.47685,37.40281],[71.49612,37.4279],[71.5256,37.47971],[71.50616,37.50733],[71.49693,37.53527],[71.5065,37.60912],[71.51972,37.61945],[71.54186,37.69691],[71.55234,37.73209],[71.53053,37.76534],[71.54324,37.77104],[71.55752,37.78677],[71.59255,37.79956],[71.58843,37.92425],[71.51565,37.95349],[71.32871,37.88564],[71.296,37.93403],[71.2809,37.91995],[71.24969,37.93031],[71.27278,37.96496],[71.27622,37.99946],[71.28922,38.01272],[71.29878,38.04429],[71.36444,38.15358],[71.37803,38.25641],[71.33869,38.27335],[71.33114,38.30339],[71.21291,38.32797],[71.1451,38.40106],[71.10957,38.40671],[71.10592,38.42077],[71.09542,38.42517],[71.0556,38.40176],[71.03545,38.44779],[70.98693,38.48862],[70.92728,38.43021],[70.88719,38.46826],[70.84376,38.44688],[70.82538,38.45394],[70.81697,38.44507],[70.80521,38.44447],[70.79766,38.44944],[70.78702,38.45031],[70.78581,38.45502],[70.77132,38.45548],[70.75455,38.4252],[70.72485,38.4131],[70.69807,38.41861],[70.67438,38.40597],[70.6761,38.39144],[70.69189,38.37031],[70.64966,38.34999],[70.61526,38.34774],[70.60407,38.28046],[70.54673,38.24541],[70.4898,38.12546],[70.17206,37.93276],[70.1863,37.84296],[70.27694,37.81258],[70.28243,37.66706],[70.15015,37.52519],[69.95971,37.5659],[69.93362,37.61378],[69.84435,37.60616],[69.80041,37.5746],[69.51888,37.5844],[69.44954,37.4869],[69.36645,37.40462],[69.45022,37.23315],[69.39529,37.16752],[69.25152,37.09426],[69.03274,37.25174],[68.96407,37.32603],[68.88168,37.33368],[68.91189,37.26704],[68.80889,37.32494],[68.81438,37.23862],[68.6798,37.27906],[68.61851,37.19815],[68.41888,37.13906],[68.41201,37.10402],[68.29253,37.10621],[68.27605,37.00977],[68.18542,37.02074],[68.02194,36.91923],[67.87917,37.0591],[67.7803,37.08978],[67.78329,37.1834],[67.51868,37.26102],[67.2581,37.17216],[67.2224,37.24545],[67.13039,37.27168],[67.08232,37.35469],[66.95598,37.40162],[66.64699,37.32958],[66.55743,37.35409],[66.30993,37.32409],[65.72274,37.55438],[65.64137,37.45061],[65.64263,37.34388],[65.51778,37.23881],[64.97945,37.21913],[64.61141,36.6351],[64.62514,36.44311],[64.57295,36.34362],[64.43288,36.24401],[64.05385,36.10433],[63.98519,36.03773],[63.56496,35.95106],[63.53475,35.90881],[63.29579,35.85985],[63.12276,35.86208],[63.10318,35.81782],[63.23262,35.67487],[63.10079,35.63024],[63.12276,35.53196],[63.0898,35.43131],[62.90853,35.37086],[62.74098,35.25432],[62.62288,35.22067],[62.48006,35.28796],[62.29878,35.13312],[62.29191,35.25964],[62.15871,35.33278],[62.05709,35.43803],[61.97743,35.4604],[61.77693,35.41341],[61.58742,35.43803],[61.27371,35.61482],[61.18187,35.30249],[61.0991,35.27845],[61.12831,35.09938],[61.06926,34.82139],[61.00197,34.70631],[60.99922,34.63064],[60.72316,34.52857],[60.91321,34.30411],[60.66502,34.31539],[60.50209,34.13992]]]}},{"type":"Feature","properties":{"id":"AO"},"geometry":{"type":"Polygon","coordinates":[[[10.5065,-17.25284],[11.75063,-17.25013],[12.07076,-17.15165],[12.52111,-17.24495],[12.97145,-16.98567],[13.36212,-16.98048],[13.95896,-17.43141],[14.28743,-17.38814],[18.39229,-17.38927],[18.84226,-17.80375],[21.14283,-17.94318],[21.42741,-18.02787],[23.47474,-17.62877],[23.20038,-17.47563],[22.17217,-16.50269],[22.00323,-16.18028],[21.97988,-13.00148],[24.03339,-12.99091],[23.90937,-12.844],[24.06672,-12.29058],[23.98804,-12.13149],[24.02603,-11.15368],[24.00027,-10.89356],[23.86868,-11.02856],[23.45631,-10.946],[23.16602,-11.10577],[22.54205,-11.05784],[22.25951,-11.24911],[22.17954,-10.85884],[22.32604,-10.76291],[22.19039,-9.94628],[21.84856,-9.59871],[21.79824,-7.29628],[20.56263,-7.28566],[20.61689,-6.90876],[20.31846,-6.91953],[20.30218,-6.98955],[19.5469,-7.00195],[19.33698,-7.99743],[18.33635,-8.00126],[17.5828,-8.13784],[16.96282,-7.21787],[16.55507,-5.85631],[13.04371,-5.87078],[12.42245,-6.07585],[11.95767,-5.94705],[12.20376,-5.76338],[12.26557,-5.74031],[12.52318,-5.74353],[12.52301,-5.17481],[12.53599,-5.1618],[12.53586,-5.14658],[12.51589,-5.1332],[12.49815,-5.14058],[12.46297,-5.09408],[12.60251,-5.01715],[12.63465,-4.94632],[12.70868,-4.95505],[12.8733,-4.74346],[13.11195,-4.67745],[13.09648,-4.63739],[12.91489,-4.47907],[12.87096,-4.40315],[12.76844,-4.38709],[12.64835,-4.55937],[12.40964,-4.60609],[12.32324,-4.78415],[12.25587,-4.79437],[12.20901,-4.75642],[12.16068,-4.90089],[12.00924,-5.02627],[11.50888,-5.33417],[10.5065,-17.25284]]]}},{"type":"Feature","properties":{"id":"AL"},"geometry":{"type":"Polygon","coordinates":[[[19.0384,40.35325],[19.95905,39.82857],[19.97622,39.78684],[19.92466,39.69533],[19.98042,39.6504],[20.00957,39.69227],[20.05189,39.69112],[20.12956,39.65805],[20.15988,39.652],[20.22376,39.64532],[20.22707,39.67459],[20.27412,39.69884],[20.31961,39.72799],[20.29152,39.80421],[20.30804,39.81563],[20.38572,39.78516],[20.41475,39.81437],[20.41546,39.82832],[20.31135,39.99438],[20.37911,39.99058],[20.42373,40.06777],[20.48487,40.06271],[20.51297,40.08168],[20.55593,40.06524],[20.61081,40.07866],[20.62566,40.0897],[20.67162,40.09433],[20.71789,40.27739],[20.78234,40.35803],[20.7906,40.42726],[20.83688,40.47882],[20.94925,40.46625],[20.96908,40.51526],[21.03932,40.56299],[21.05833,40.66586],[20.98134,40.76046],[20.95752,40.76982],[20.98396,40.79109],[20.97887,40.85475],[20.97693,40.90103],[20.94305,40.92399],[20.83671,40.92752],[20.81567,40.89662],[20.73504,40.9081],[20.71634,40.91781],[20.65558,41.08009],[20.63454,41.0889],[20.59832,41.09066],[20.58546,41.11179],[20.59715,41.13644],[20.51068,41.2323],[20.49432,41.33679],[20.52119,41.34381],[20.55976,41.4087],[20.51301,41.442],[20.49039,41.49277],[20.45331,41.51436],[20.45809,41.5549],[20.52103,41.56473],[20.55508,41.58113],[20.51769,41.65975],[20.52937,41.69292],[20.51301,41.72433],[20.53405,41.78099],[20.57144,41.7897],[20.55976,41.87068],[20.59524,41.8818],[20.57946,41.91593],[20.63069,41.94913],[20.59434,42.03879],[20.55633,42.08173],[20.56955,42.12097],[20.48857,42.25444],[20.3819,42.3029],[20.34479,42.32656],[20.24399,42.32168],[20.21797,42.41237],[20.17127,42.50469],[20.07761,42.55582],[20.01834,42.54622],[20.00842,42.5109],[19.9324,42.51699],[19.82333,42.46581],[19.76549,42.50237],[19.74731,42.57422],[19.77375,42.58517],[19.73244,42.66299],[19.65972,42.62774],[19.4836,42.40831],[19.42352,42.36546],[19.42,42.33019],[19.28623,42.17745],[19.40687,42.10024],[19.37548,42.06835],[19.36867,42.02564],[19.37691,41.96977],[19.34601,41.95675],[19.33812,41.90669],[19.37451,41.8842],[19.37597,41.84849],[19.26406,41.74971],[19.0384,40.35325]]]}},{"type":"Feature","properties":{"id":"AD"},"geometry":{"type":"Polygon","coordinates":[[[1.41245,42.53539],[1.44759,42.54431],[1.46661,42.50949],[1.41648,42.48315],[1.43838,42.47848],[1.44529,42.43724],[1.5127,42.42959],[1.55073,42.43299],[1.55937,42.45808],[1.57953,42.44957],[1.58933,42.46275],[1.65674,42.47125],[1.66826,42.50779],[1.70571,42.48867],[1.72515,42.50338],[1.73683,42.55492],[1.7858,42.57698],[1.72588,42.59098],[1.73452,42.61515],[1.68267,42.62533],[1.6625,42.61982],[1.63485,42.62957],[1.60085,42.62703],[1.55418,42.65669],[1.50867,42.64483],[1.48043,42.65203],[1.46718,42.63296],[1.47986,42.61346],[1.44197,42.60217],[1.42512,42.58292],[1.44529,42.56722],[1.4234,42.55959],[1.41245,42.53539]]]}},{"type":"Feature","properties":{"id":"CN-SC"},"geometry":{"type":"Polygon","coordinates":[[[97.33989,32.9038],[97.37834,32.86978],[97.37766,32.80718],[97.4271,32.7122],[97.48168,32.65556],[97.5325,32.64241],[97.54417,32.62332],[97.66296,32.55781],[97.72544,32.52886],[97.99255,32.46748],[98.21639,32.33936],[98.30497,32.12619],[98.43475,32.00458],[98.409,31.83089],[98.56246,31.67705],[98.71971,31.50626],[98.84433,31.42954],[98.88896,31.37767],[98.77567,31.24949],[98.69052,31.33751],[98.63559,31.33839],[98.60469,31.18725],[98.71009,31.11997],[98.75404,31.03293],[98.80725,30.98496],[98.78528,30.92431],[98.95523,30.74862],[98.90613,30.68457],[98.99642,30.15344],[99.0438,30.07979],[99.05651,29.93708],[99.01119,29.8189],[98.98956,29.66359],[99.06234,29.45051],[99.05479,29.30586],[99.11487,29.22679],[99.15504,28.43488],[99.39742,28.16463],[99.38713,28.51033],[99.66384,28.82362],[99.96116,28.56582],[100.00785,28.21063],[100.33607,27.72608],[100.71166,27.83907],[101.15867,27.0316],[101.37428,26.88778],[101.46629,26.60387],[101.37908,26.60571],[101.79725,26.16653],[101.81167,26.05061],[102.10075,26.07652],[102.38708,26.29095],[102.957,26.34019],[103.05725,26.53079],[102.90412,26.90308],[102.91992,27.13248],[102.88352,27.25585],[102.93777,27.41078],[103.09295,27.39676],[103.57601,27.97135],[103.40434,28.04077],[103.63574,28.26719],[103.70304,28.19974],[103.76552,28.23453],[103.87367,28.30256],[103.85959,28.38807],[103.78749,28.51757],[103.85616,28.68004],[103.89015,28.62672],[104.08241,28.61014],[104.36977,28.65293],[104.46659,28.61556],[104.23725,28.54532],[104.30076,28.30679],[104.35432,28.34366],[104.44805,28.11801],[104.28909,28.05834],[104.56409,27.85],[104.87205,27.90766],[105.03616,28.09742],[105.17074,28.07258],[105.31219,27.71088],[105.60676,27.69751],[105.92262,27.72973],[106.35864,27.83907],[106.20826,28.13497],[106.13857,28.16948],[105.9233,28.1277],[105.8876,28.23785],[105.65895,28.308],[105.61981,28.43488],[105.68778,28.57547],[105.88142,28.602],[105.96588,28.7496],[106.36756,28.52662],[106.26113,28.83715],[106.0033,28.97811],[105.90408,28.9054],[105.74958,29.01894],[105.7101,29.30047],[105.65036,29.24357],[105.43888,29.31783],[105.44128,29.40131],[105.37261,29.42285],[105.29193,29.58122],[105.45707,29.67612],[105.60127,29.83707],[105.70667,29.83796],[105.75302,30.01619],[105.59062,30.11216],[105.61431,30.26381],[105.68778,30.26618],[105.79627,30.44393],[106.16397,30.30413],[106.21067,30.18134],[106.54643,30.32843],[106.76582,30.01738],[106.96941,30.08484],[107.03155,30.04532],[107.19291,30.18727],[107.50431,30.63732],[107.42637,30.7318],[107.48508,30.84476],[107.63683,30.81233],[107.69657,30.876],[107.84866,30.79405],[107.99114,30.91076],[107.92282,30.92578],[108.07182,31.18049],[108.02032,31.24803],[108.54011,31.67559],[108.27369,31.92885],[108.50234,32.20641],[108.25309,32.28365],[107.97569,32.13782],[107.42362,32.55433],[107.25677,32.40779],[107.1215,32.48543],[107.1009,32.67174],[106.85851,32.71855],[106.43073,32.6307],[106.11007,32.72144],[106.04484,32.86805],[105.62461,32.70526],[105.47878,32.89406],[105.43647,32.94875],[105.39321,32.72433],[105.11032,32.60004],[104.40238,32.79189],[104.4326,33.00636],[104.33921,33.1979],[104.45526,33.32938],[104.28634,33.35978],[104.10026,33.68435],[103.77891,33.66606],[103.16162,33.7974],[103.17672,34.07484],[102.89039,34.33266],[102.66792,34.07541],[102.45849,34.09929],[102.3912,33.97753],[102.14332,33.98379],[102.46879,33.47211],[101.81579,33.10937],[101.94625,33.58773],[101.76223,33.46925],[101.64001,33.09844],[101.1621,33.22835],[101.22665,32.76071],[101.1185,32.63619],[100.94032,32.60756],[100.71819,32.67492],[100.66463,32.52481],[100.54687,32.5714],[100.49554,32.65671],[99.8822,33.04781],[99.73388,32.72375],[99.36035,32.90092],[98.85497,33.14675],[98.73962,33.43717],[98.42651,33.85217],[98.41689,34.09816],[97.66158,34.12431],[97.65266,33.93538],[97.39517,33.89492],[97.40409,33.63062],[97.7584,33.40536],[97.62348,33.33769],[97.59841,33.25964],[97.4858,33.166],[97.49061,33.11512],[97.53078,32.99167],[97.4319,32.9813],[97.33989,32.9038]]]}},{"type":"Feature","properties":{"id":"AR"},"geometry":{"type":"Polygon","coordinates":[[[-73.55259,-49.92488],[-73.15765,-50.78337],[-72.31343,-50.58411],[-72.33873,-51.59954],[-71.99889,-51.98018],[-69.97824,-52.00845],[-68.41683,-52.33516],[-68.60702,-52.65781],[-68.60733,-54.9125],[-68.01394,-54.8753],[-67.46182,-54.92205],[-67.11046,-54.94199],[-66.07313,-55.19618],[-63.07977,-55.04486],[-62.78369,-53.1401],[-62.3754,-50.36819],[-55.71154,-35.78518],[-57.83001,-34.69099],[-58.34425,-34.15035],[-58.44442,-33.84033],[-58.40475,-33.11777],[-58.1224,-32.98842],[-58.22362,-32.52416],[-58.10036,-32.25338],[-58.20252,-31.86966],[-58.00076,-31.65016],[-58.0023,-31.53084],[-58.07569,-31.44916],[-57.98127,-31.3872],[-57.9908,-31.34924],[-57.86729,-31.06352],[-57.89476,-30.95994],[-57.8024,-30.77193],[-57.89115,-30.49572],[-57.64859,-30.35095],[-57.61478,-30.25165],[-57.65132,-30.19229],[-57.09386,-29.74211],[-56.81251,-29.48154],[-56.62789,-29.18073],[-56.57295,-29.11357],[-56.54171,-29.11447],[-56.05265,-28.62651],[-56.00458,-28.60421],[-56.01729,-28.51223],[-55.65418,-28.18304],[-55.6262,-28.17124],[-55.33303,-27.94661],[-55.16872,-27.86224],[-55.1349,-27.89759],[-54.90805,-27.73149],[-54.90159,-27.63132],[-54.67657,-27.57214],[-54.50416,-27.48232],[-54.41888,-27.40882],[-54.19268,-27.30751],[-54.19062,-27.27639],[-54.15978,-27.2889],[-53.80144,-27.09844],[-53.73372,-26.6131],[-53.68269,-26.33359],[-53.64505,-26.28089],[-53.64186,-26.25976],[-53.64632,-26.24798],[-53.63881,-26.25075],[-53.63739,-26.2496],[-53.65237,-26.23289],[-53.65018,-26.19501],[-53.73968,-26.10012],[-53.73391,-26.07006],[-53.7264,-26.0664],[-53.73086,-26.05842],[-53.73511,-26.04211],[-53.83691,-25.94849],[-53.90831,-25.55513],[-54.52926,-25.62846],[-54.5502,-25.58915],[-54.59398,-25.59224],[-54.62063,-25.91213],[-54.60664,-25.9691],[-54.67359,-25.98607],[-54.69333,-26.37705],[-54.70732,-26.45099],[-54.80868,-26.55669],[-55.00584,-26.78754],[-55.06351,-26.80195],[-55.16948,-26.96068],[-55.25243,-26.93808],[-55.39611,-26.97679],[-55.62322,-27.1941],[-55.59094,-27.32444],[-55.74475,-27.44485],[-55.89195,-27.3467],[-56.18313,-27.29851],[-56.85337,-27.5165],[-58.04205,-27.2387],[-58.59549,-27.29973],[-58.65321,-27.14028],[-58.3198,-26.83443],[-58.1188,-26.16704],[-57.87176,-25.93604],[-57.57431,-25.47269],[-57.80821,-25.13863],[-58.25492,-24.92528],[-58.33055,-24.97099],[-59.33886,-24.49935],[-59.45482,-24.34787],[-60.03367,-24.00701],[-60.28163,-24.04436],[-60.99754,-23.80934],[-61.0782,-23.62932],[-61.9756,-23.0507],[-62.22768,-22.55807],[-62.51761,-22.37684],[-62.64455,-22.25091],[-62.8078,-22.12534],[-62.81124,-21.9987],[-63.66482,-21.99918],[-63.68113,-22.0544],[-63.70963,-21.99934],[-63.93287,-21.99934],[-64.22918,-22.55807],[-64.31489,-22.88824],[-64.35108,-22.73282],[-64.4176,-22.67692],[-64.58888,-22.25035],[-64.67174,-22.18957],[-64.90014,-22.12136],[-64.99524,-22.08255],[-65.47435,-22.08908],[-65.57743,-22.07675],[-65.58694,-22.09794],[-65.61166,-22.09504],[-65.7467,-22.10105],[-65.9261,-21.93335],[-66.04832,-21.9187],[-66.03836,-21.84829],[-66.24077,-21.77837],[-66.29714,-22.08741],[-66.7298,-22.23644],[-67.18382,-22.81525],[-66.99632,-22.99839],[-67.33563,-24.04237],[-68.24825,-24.42596],[-68.56909,-24.69831],[-68.38372,-25.08636],[-68.57622,-25.32505],[-68.38372,-26.15353],[-68.56909,-26.28146],[-68.59048,-26.49861],[-68.27677,-26.90626],[-68.43363,-27.08414],[-68.77586,-27.16029],[-69.22504,-27.95042],[-69.66709,-28.44055],[-69.80969,-29.07185],[-69.99507,-29.28351],[-69.8596,-30.26131],[-70.14479,-30.36595],[-70.55832,-31.51559],[-69.88099,-33.34489],[-69.87386,-34.13344],[-70.49416,-35.24145],[-70.38008,-36.02375],[-70.95047,-36.4321],[-71.24279,-37.20264],[-70.89532,-38.6923],[-71.37826,-38.91474],[-71.92726,-40.72714],[-71.74901,-42.11711],[-72.15541,-42.15941],[-72.14828,-42.85321],[-71.64206,-43.64774],[-71.81318,-44.38097],[-71.16436,-44.46244],[-71.26418,-44.75684],[-72.06985,-44.81756],[-71.35687,-45.22075],[-71.75614,-45.61611],[-71.68577,-46.55385],[-71.94152,-47.13595],[-72.50478,-47.80586],[-72.27662,-48.28727],[-72.54042,-48.52392],[-72.56894,-48.81116],[-73.09655,-49.14342],[-73.45156,-49.79461],[-73.55259,-49.92488]]]}},{"type":"Feature","properties":{"id":"CN-YN"},"geometry":{"type":"Polygon","coordinates":[[[97.5247,23.94032],[97.64667,23.84574],[97.72302,23.89288],[97.79456,23.94836],[97.79416,23.95663],[97.84328,23.97603],[97.86545,23.97723],[97.88811,23.97446],[97.8955,23.97758],[97.89676,23.97931],[97.89683,23.98389],[97.88814,23.98605],[97.88414,23.99405],[97.88616,24.00463],[97.90998,24.02094],[97.93951,24.01953],[97.98691,24.03897],[97.99583,24.04932],[98.04709,24.07616],[98.05302,24.07408],[98.05671,24.07961],[98.0607,24.07812],[98.06703,24.08028],[98.07806,24.07988],[98.20666,24.11406],[98.54476,24.13119],[98.59256,24.08371],[98.85319,24.13042],[98.87998,24.15624],[98.89632,24.10612],[98.67797,23.9644],[98.68209,23.80492],[98.79607,23.77947],[98.82933,23.72921],[98.81775,23.694],[98.88396,23.59555],[98.80294,23.5345],[98.82877,23.47908],[98.87683,23.48995],[98.92104,23.36946],[98.87573,23.33038],[98.93958,23.31414],[98.92515,23.29535],[98.88597,23.18656],[99.05975,23.16382],[99.04601,23.12215],[99.25741,23.09025],[99.34127,23.13099],[99.52214,23.08218],[99.54218,22.90014],[99.43537,22.94086],[99.45654,22.85726],[99.31243,22.73893],[99.38247,22.57544],[99.37972,22.50188],[99.28771,22.4105],[99.17318,22.18025],[99.19176,22.16983],[99.1552,22.15874],[99.33166,22.09656],[99.47585,22.13345],[99.85351,22.04183],[99.96612,22.05965],[99.99084,21.97053],[99.94003,21.82782],[99.98654,21.71064],[100.04956,21.66843],[100.12679,21.70539],[100.17486,21.65306],[100.10757,21.59945],[100.12542,21.50365],[100.1625,21.48704],[100.18447,21.51898],[100.25863,21.47043],[100.35201,21.53176],[100.42892,21.54325],[100.4811,21.46148],[100.57861,21.45637],[100.72143,21.51898],[100.87265,21.67396],[101.11744,21.77659],[101.15156,21.56129],[101.2124,21.56422],[101.19349,21.41959],[101.26912,21.36482],[101.2229,21.23271],[101.29326,21.17254],[101.54563,21.25668],[101.6068,21.23329],[101.59491,21.18621],[101.60886,21.17947],[101.66977,21.20004],[101.70548,21.14911],[101.7622,21.14813],[101.79266,21.19025],[101.76745,21.21571],[101.83887,21.20983],[101.84412,21.25291],[101.74014,21.30967],[101.74224,21.48276],[101.7727,21.51794],[101.7475,21.5873],[101.80001,21.57461],[101.83257,21.61562],[101.74555,21.72852],[101.7791,21.83019],[101.62566,21.96574],[101.57525,22.13026],[101.60675,22.13513],[101.53638,22.24794],[101.56789,22.28876],[101.61306,22.27515],[101.68973,22.46843],[101.7685,22.50337],[101.86828,22.38397],[101.90714,22.38688],[101.91344,22.44417],[101.98487,22.42766],[102.03633,22.46164],[102.1245,22.43372],[102.14099,22.40092],[102.16621,22.43336],[102.26428,22.41321],[102.25339,22.4607],[102.41061,22.64184],[102.38415,22.67919],[102.42618,22.69212],[102.46665,22.77108],[102.51802,22.77969],[102.57095,22.7036],[102.60675,22.73376],[102.8636,22.60735],[102.9321,22.48659],[103.0722,22.44775],[103.07843,22.50097],[103.17961,22.55705],[103.15782,22.59873],[103.18895,22.64471],[103.28079,22.68063],[103.32282,22.8127],[103.43179,22.75816],[103.43646,22.70648],[103.52675,22.59155],[103.57812,22.65764],[103.56255,22.69499],[103.64506,22.79979],[103.87904,22.56683],[103.93286,22.52703],[103.94513,22.52553],[103.95191,22.5134],[103.96352,22.50584],[103.96783,22.51173],[103.97384,22.50634],[103.99247,22.51958],[104.01088,22.51823],[104.03734,22.72945],[104.11384,22.80363],[104.27084,22.8457],[104.25683,22.76534],[104.35593,22.69353],[104.47225,22.75813],[104.58122,22.85571],[104.60457,22.81841],[104.65283,22.83419],[104.72755,22.81984],[104.77114,22.90017],[104.84942,22.93631],[104.86765,22.95178],[104.8334,23.01484],[104.79478,23.12934],[104.87382,23.12854],[104.87992,23.17141],[104.91435,23.18666],[104.9486,23.17235],[104.96532,23.20463],[104.98712,23.19176],[105.07002,23.26248],[105.11672,23.25247],[105.17276,23.28679],[105.22569,23.27249],[105.32376,23.39684],[105.40782,23.28107],[105.42805,23.30824],[105.49966,23.20669],[105.56037,23.16806],[105.59509,23.31766],[105.8773,23.53314],[106.00089,23.4519],[106.14097,23.5772],[106.15608,23.90592],[106.00364,24.12858],[105.64796,24.03831],[105.57174,24.13798],[105.49552,24.01949],[105.16868,24.14988],[105.19615,24.34209],[105.0238,24.43839],[104.71481,24.43777],[104.70588,24.31018],[104.56718,24.44527],[104.4659,24.65044],[104.52804,24.73498],[104.60151,24.89889],[104.71206,25.00348],[104.72545,25.19096],[104.83119,25.172],[104.78622,25.28195],[104.66022,25.2745],[104.52152,25.52695],[104.44633,25.47861],[104.309,25.65947],[104.47002,26.02007],[104.59258,26.31926],[104.68666,26.3691],[104.56031,26.59405],[104.47963,26.58422],[104.40925,26.73028],[104.34162,26.62444],[104.15279,26.67323],[104.00104,26.51389],[103.8153,26.53417],[103.7051,26.83173],[103.78063,26.949],[103.68621,27.06248],[103.61377,27.00591],[103.62716,27.11872],[103.83865,27.27202],[103.94165,27.45375],[104.18334,27.2708],[104.37217,27.47233],[104.50984,27.40712],[104.6046,27.30528],[104.85145,27.34523],[104.86312,27.28362],[105.08079,27.42114],[105.21057,27.37603],[105.31219,27.71088],[105.23254,27.90584],[105.17074,28.07258],[105.03616,28.09742],[104.87205,27.90766],[104.56409,27.85],[104.28909,28.05834],[104.44805,28.11801],[104.35432,28.34366],[104.30076,28.30679],[104.23725,28.54532],[104.46659,28.61556],[104.36977,28.65293],[104.08241,28.61014],[103.89015,28.62672],[103.85616,28.68004],[103.78749,28.51757],[103.85959,28.38807],[103.87367,28.30256],[103.76552,28.23453],[103.70304,28.19974],[103.63574,28.26719],[103.40434,28.04077],[103.57601,27.97135],[103.09295,27.39676],[102.93777,27.41078],[102.88352,27.25585],[102.91992,27.13248],[102.90412,26.90308],[103.05725,26.53079],[102.957,26.34019],[102.38708,26.29095],[102.10075,26.07652],[101.81167,26.05061],[101.79725,26.16653],[101.37908,26.60571],[101.46629,26.60387],[101.37428,26.88778],[101.15867,27.0316],[100.71166,27.83907],[100.33607,27.72608],[100.00785,28.21063],[99.96116,28.56582],[99.66384,28.82362],[99.38713,28.51033],[99.39742,28.16463],[99.15504,28.43488],[99.11487,29.22679],[98.96003,29.18663],[99.0184,29.03425],[98.92501,28.98111],[98.91815,28.88796],[98.97376,28.87564],[98.97548,28.82933],[98.83197,28.80406],[98.78974,29.01054],[98.62495,28.9721],[98.65447,28.8585],[98.66254,28.79549],[98.68125,28.73319],[98.63113,28.69103],[98.5968,28.68622],[98.63697,28.49072],[98.75884,28.33218],[98.69361,28.21789],[98.60881,28.1725],[98.39355,28.10953],[98.36952,28.26084],[98.28987,28.39804],[98.20129,28.35666],[98.26789,28.24421],[98.16696,28.21002],[98.15337,28.12114],[98.13964,27.9478],[98.32641,27.51385],[98.42529,27.55404],[98.43353,27.67086],[98.69582,27.56499],[98.7333,26.85615],[98.77547,26.61994],[98.72741,26.36183],[98.67797,26.24487],[98.7329,26.17218],[98.66884,26.09165],[98.63128,26.15492],[98.57085,26.11547],[98.60763,26.01512],[98.70818,25.86241],[98.63128,25.79937],[98.54064,25.85129],[98.40606,25.61129],[98.31268,25.55307],[98.25774,25.6051],[98.16848,25.62739],[98.18084,25.56298],[98.12591,25.50722],[98.14925,25.41547],[97.92541,25.20815],[97.83614,25.2715],[97.77023,25.11492],[97.72216,25.08508],[97.72903,24.91332],[97.79949,24.85655],[97.76481,24.8289],[97.73127,24.83015],[97.70181,24.84557],[97.64354,24.79171],[97.56648,24.76475],[97.56383,24.75535],[97.5542,24.74943],[97.54675,24.74202],[97.56525,24.72838],[97.56286,24.54535],[97.52757,24.43748],[97.60029,24.4401],[97.66998,24.45288],[97.7098,24.35658],[97.65624,24.33781],[97.66723,24.30027],[97.71941,24.29652],[97.76799,24.26365],[97.72998,24.2302],[97.72799,24.18883],[97.75305,24.16902],[97.72903,24.12606],[97.62363,24.00506],[97.5247,23.94032]]]}},{"type":"Feature","properties":{"id":"IN-TR"},"geometry":{"type":"Polygon","coordinates":[[[91.15579,23.6599],[91.28293,23.37538],[91.36453,23.06612],[91.40848,23.07117],[91.4035,23.27522],[91.46615,23.2328],[91.54993,23.01051],[91.61571,22.93929],[91.7324,23.00043],[91.81634,23.08001],[91.76417,23.26619],[91.84789,23.42235],[91.95642,23.47361],[91.95093,23.73284],[92.04706,23.64229],[92.15417,23.73409],[92.26541,23.70392],[92.31777,23.86543],[92.29819,24.25406],[92.21786,24.25259],[92.27931,24.39213],[92.22953,24.50245],[92.15796,24.54435],[92.11662,24.38997],[91.96603,24.3799],[91.89258,24.14674],[91.82596,24.22345],[91.76004,24.23848],[91.73257,24.14703],[91.65292,24.22095],[91.63782,24.1132],[91.55542,24.08687],[91.37414,24.10693],[91.35741,23.99072],[91.29587,24.0041],[91.22308,23.89616],[91.25192,23.83463],[91.15579,23.6599]]]}},{"type":"Feature","properties":{"id":"AT"},"geometry":{"type":"Polygon","coordinates":[[[9.53116,47.27029],[9.56766,47.24281],[9.55176,47.22585],[9.56981,47.21926],[9.58264,47.20673],[9.56539,47.17124],[9.62623,47.14685],[9.63395,47.08443],[9.61216,47.07732],[9.60717,47.06091],[9.87935,47.01337],[9.88266,46.93343],[9.98058,46.91434],[10.10715,46.84296],[10.22675,46.86942],[10.24128,46.93147],[10.30031,46.92093],[10.36933,47.00212],[10.48376,46.93891],[10.47197,46.85698],[10.54783,46.84505],[10.66405,46.87614],[10.75753,46.82258],[10.72974,46.78972],[11.00764,46.76896],[11.10618,46.92966],[11.33355,46.99862],[11.50739,47.00644],[11.74789,46.98484],[12.19254,47.09331],[12.21781,47.03996],[12.11675,47.01241],[12.2006,46.88854],[12.27591,46.88651],[12.38708,46.71529],[12.59992,46.6595],[12.94445,46.60401],[13.27627,46.56059],[13.64088,46.53438],[13.7148,46.5222],[13.89837,46.52331],[14.00422,46.48474],[14.04002,46.49117],[14.12097,46.47724],[14.15989,46.43327],[14.28326,46.44315],[14.314,46.43327],[14.42608,46.44614],[14.45877,46.41717],[14.52176,46.42617],[14.56463,46.37208],[14.5942,46.43434],[14.66892,46.44936],[14.72185,46.49974],[14.81836,46.51046],[14.83549,46.56614],[14.86419,46.59411],[14.87129,46.61],[14.92283,46.60848],[14.96002,46.63459],[14.98024,46.6009],[15.01451,46.641],[15.14215,46.66131],[15.23711,46.63994],[15.41235,46.65556],[15.45514,46.63697],[15.46906,46.61321],[15.54431,46.6312],[15.55333,46.64988],[15.54533,46.66985],[15.59826,46.68908],[15.62317,46.67947],[15.63255,46.68069],[15.6365,46.6894],[15.6543,46.69228],[15.6543,46.70616],[15.67411,46.70735],[15.69523,46.69823],[15.72279,46.69548],[15.73823,46.70011],[15.76771,46.69863],[15.78518,46.70712],[15.8162,46.71897],[15.87691,46.7211],[15.94864,46.68769],[15.98512,46.68463],[15.99988,46.67947],[16.04036,46.6549],[16.04347,46.68694],[16.02808,46.71094],[15.99769,46.7266],[15.98432,46.74991],[15.99126,46.78199],[15.99054,46.82772],[16.05786,46.83927],[16.10983,46.867],[16.19904,46.94134],[16.22403,46.939],[16.27594,46.9643],[16.28202,47.00159],[16.51369,47.00084],[16.43936,47.03548],[16.52176,47.05747],[16.46134,47.09395],[16.52863,47.13974],[16.44932,47.14418],[16.46442,47.16845],[16.4523,47.18812],[16.42801,47.18422],[16.41739,47.20649],[16.43663,47.21127],[16.44142,47.25079],[16.47782,47.25918],[16.45104,47.41181],[16.49908,47.39416],[16.52414,47.41007],[16.57152,47.40868],[16.6718,47.46139],[16.64821,47.50155],[16.71059,47.52692],[16.64193,47.63114],[16.58699,47.61772],[16.4222,47.66537],[16.55129,47.72268],[16.53514,47.73837],[16.54779,47.75074],[16.61183,47.76171],[16.65679,47.74197],[16.72089,47.73469],[16.7511,47.67878],[16.82938,47.68432],[16.86509,47.72268],[16.87538,47.68895],[17.08893,47.70928],[17.05048,47.79377],[17.07039,47.81129],[17.00997,47.86245],[17.08275,47.87719],[17.11022,47.92461],[17.09786,47.97336],[17.16001,48.00636],[17.07039,48.0317],[17.09168,48.09366],[17.05735,48.14179],[17.02919,48.13996],[16.97701,48.17385],[16.89461,48.31332],[16.90903,48.32519],[16.84243,48.35258],[16.83317,48.38138],[16.83588,48.3844],[16.8497,48.38321],[16.85204,48.44968],[16.94611,48.53614],[16.93955,48.60371],[16.90354,48.71541],[16.79779,48.70998],[16.71883,48.73806],[16.68518,48.7281],[16.67008,48.77699],[16.46134,48.80865],[16.40915,48.74576],[16.37345,48.729],[16.06034,48.75436],[15.84404,48.86921],[15.78087,48.87644],[15.75341,48.8516],[15.6921,48.85973],[15.61622,48.89541],[15.51357,48.91549],[15.48027,48.94481],[15.34823,48.98444],[15.28305,48.98831],[15.26177,48.95766],[15.16358,48.94278],[15.15534,48.99056],[14.99878,49.01444],[14.97612,48.96983],[14.98917,48.90082],[14.95072,48.79101],[14.98032,48.77959],[14.9782,48.7766],[14.98112,48.77524],[14.9758,48.76857],[14.95641,48.75915],[14.94773,48.76268],[14.81545,48.7874],[14.80821,48.77711],[14.80584,48.73489],[14.72756,48.69502],[14.71794,48.59794],[14.66762,48.58215],[14.60808,48.62881],[14.56139,48.60429],[14.4587,48.64695],[14.43076,48.58855],[14.33909,48.55852],[14.20691,48.5898],[14.09104,48.5943],[14.01482,48.63788],[14.06151,48.66873],[13.84023,48.76988],[13.82266,48.75544],[13.81863,48.73257],[13.79337,48.71375],[13.81791,48.69832],[13.81283,48.68426],[13.81901,48.6761],[13.82609,48.62345],[13.80038,48.59487],[13.80519,48.58026],[13.76921,48.55324],[13.7513,48.5624],[13.74816,48.53058],[13.72802,48.51208],[13.66113,48.53558],[13.65186,48.55092],[13.62508,48.55501],[13.59705,48.57013],[13.57535,48.55912],[13.51291,48.59023],[13.50131,48.58091],[13.50663,48.57506],[13.46967,48.55157],[13.45214,48.56472],[13.43695,48.55776],[13.45727,48.51092],[13.42527,48.45711],[13.43929,48.43386],[13.40709,48.37292],[13.30897,48.31575],[13.26039,48.29422],[13.18093,48.29577],[13.126,48.27867],[13.0851,48.27711],[13.02083,48.25689],[12.95306,48.20629],[12.87126,48.20318],[12.84475,48.16556],[12.836,48.1647],[12.8362,48.15876],[12.82673,48.15245],[12.80676,48.14979],[12.78595,48.12445],[12.7617,48.12796],[12.74973,48.10885],[12.76141,48.07373],[12.8549,48.01122],[12.87476,47.96195],[12.91683,47.95647],[12.9211,47.95135],[12.91985,47.94069],[12.92668,47.93879],[12.93419,47.94063],[12.93642,47.94436],[12.93886,47.94046],[12.94163,47.92927],[13.00588,47.84374],[12.98543,47.82896],[12.96311,47.79957],[12.93202,47.77302],[12.94371,47.76281],[12.9353,47.74788],[12.91711,47.74026],[12.90274,47.72513],[12.91333,47.7178],[12.92969,47.71094],[12.98578,47.7078],[13.01382,47.72116],[13.07692,47.68814],[13.09562,47.63304],[13.06407,47.60075],[13.06641,47.58577],[13.04537,47.58183],[13.05355,47.56291],[13.03252,47.53373],[13.04537,47.49426],[12.9998,47.46267],[12.98344,47.48716],[12.9624,47.47452],[12.85256,47.52741],[12.84672,47.54556],[12.80699,47.54477],[12.77427,47.58025],[12.82101,47.61493],[12.76492,47.64485],[12.77777,47.66689],[12.7357,47.6787],[12.6071,47.6741],[12.57438,47.63238],[12.53816,47.63553],[12.50076,47.62293],[12.44117,47.6741],[12.43883,47.6977],[12.37222,47.68433],[12.336,47.69534],[12.27991,47.68827],[12.26004,47.67725],[12.24017,47.69534],[12.26238,47.73544],[12.2542,47.7433],[12.22571,47.71776],[12.18303,47.70065],[12.16217,47.70105],[12.16769,47.68167],[12.18347,47.66663],[12.18507,47.65984],[12.19895,47.64085],[12.20801,47.61082],[12.20398,47.60667],[12.18568,47.6049],[12.17737,47.60121],[12.18145,47.61019],[12.17824,47.61506],[12.13734,47.60639],[12.05788,47.61742],[12.02282,47.61033],[12.0088,47.62451],[11.85572,47.60166],[11.84052,47.58354],[11.63934,47.59202],[11.60681,47.57881],[11.58811,47.55515],[11.58578,47.52281],[11.52618,47.50939],[11.4362,47.51413],[11.38128,47.47465],[11.4175,47.44621],[11.33804,47.44937],[11.29597,47.42566],[11.27844,47.39956],[11.22002,47.3964],[11.25157,47.43277],[11.20482,47.43198],[11.12536,47.41222],[11.11835,47.39719],[10.97111,47.39561],[10.97111,47.41617],[10.98513,47.42882],[10.92437,47.46991],[10.93839,47.48018],[10.90918,47.48571],[10.87061,47.4786],[10.86945,47.5015],[10.91268,47.51334],[10.88814,47.53701],[10.77596,47.51729],[10.7596,47.53228],[10.6965,47.54253],[10.68832,47.55752],[10.63456,47.5591],[10.60337,47.56755],[10.56912,47.53584],[10.48849,47.54057],[10.47329,47.58552],[10.43473,47.58394],[10.44992,47.5524],[10.4324,47.50111],[10.44291,47.48453],[10.46278,47.47901],[10.47446,47.43318],[10.4359,47.41183],[10.4324,47.38494],[10.39851,47.37623],[10.33424,47.30813],[10.23257,47.27088],[10.17531,47.27167],[10.17648,47.29149],[10.2147,47.31014],[10.19998,47.32832],[10.23757,47.37609],[10.22774,47.38904],[10.2127,47.38019],[10.17648,47.38889],[10.16362,47.36674],[10.11805,47.37228],[10.09819,47.35724],[10.06897,47.40709],[10.1052,47.4316],[10.09001,47.46005],[10.07131,47.45531],[10.03859,47.48927],[10.00003,47.48216],[9.96029,47.53899],[9.92407,47.53111],[9.87733,47.54688],[9.87499,47.52953],[9.8189,47.54688],[9.82591,47.58158],[9.80254,47.59419],[9.76748,47.5934],[9.72736,47.53457],[9.55125,47.53629],[9.56312,47.49495],[9.58208,47.48344],[9.59482,47.46305],[9.60205,47.46165],[9.60484,47.46358],[9.60841,47.47178],[9.62158,47.45858],[9.62475,47.45685],[9.6423,47.45599],[9.65728,47.45383],[9.65863,47.44847],[9.64483,47.43842],[9.6446,47.43233],[9.65043,47.41937],[9.65136,47.40504],[9.6629,47.39591],[9.67334,47.39191],[9.67445,47.38429],[9.6711,47.37824],[9.66243,47.37136],[9.65427,47.36824],[9.62476,47.36639],[9.59978,47.34671],[9.58513,47.31334],[9.55857,47.29919],[9.54773,47.2809],[9.53116,47.27029]]]}},{"type":"Feature","properties":{"id":"AZ-NX"},"geometry":{"type":"Polygon","coordinates":[[[44.75779,39.7148],[44.80977,39.65768],[44.81043,39.62677],[44.88916,39.59653],[44.96746,39.42998],[45.05932,39.36435],[45.08751,39.35052],[45.16168,39.21952],[45.30489,39.18333],[45.40148,39.09007],[45.40452,39.07224],[45.44811,39.04927],[45.44966,38.99243],[45.6131,38.964],[45.6155,38.94304],[45.65172,38.95199],[45.83883,38.90768],[45.90266,38.87739],[45.94624,38.89072],[46.00228,38.87376],[46.06766,38.87861],[46.14785,38.84206],[46.06973,39.0744],[46.02303,39.09978],[45.99774,39.28931],[45.79225,39.3695],[45.83,39.46487],[45.80804,39.56716],[45.70547,39.60174],[45.46992,39.49888],[45.29606,39.57654],[45.30385,39.61373],[45.23535,39.61373],[45.21784,39.58074],[45.17464,39.58614],[45.18554,39.67846],[45.06604,39.79277],[44.92869,39.72157],[44.88354,39.74432],[44.75779,39.7148]]]}},{"type":"Feature","properties":{"id":"BI"},"geometry":{"type":"Polygon","coordinates":[[[29.00167,-2.78523],[29.00404,-2.81978],[29.0505,-2.81774],[29.09119,-2.87871],[29.09797,-2.91935],[29.16037,-2.95457],[29.17258,-2.99385],[29.25633,-3.05471],[29.21463,-3.3514],[29.23708,-3.75856],[29.43673,-4.44845],[29.63827,-4.44681],[29.75109,-4.45836],[29.77289,-4.41733],[29.82885,-4.36153],[29.88172,-4.35743],[30.03323,-4.26631],[30.22042,-4.01738],[30.45915,-3.56532],[30.84165,-3.25152],[30.83823,-2.97837],[30.6675,-2.98987],[30.57926,-2.89791],[30.4987,-2.9573],[30.40662,-2.86151],[30.52747,-2.65841],[30.41789,-2.66266],[30.54501,-2.41404],[30.42933,-2.31064],[30.14034,-2.43626],[29.95911,-2.33348],[29.88237,-2.75105],[29.36805,-2.82933],[29.32234,-2.6483],[29.0562,-2.58632],[29.04081,-2.7416],[29.00167,-2.78523]]]}},{"type":"Feature","properties":{"id":"BJ"},"geometry":{"type":"Polygon","coordinates":[[[0.77666,10.37665],[1.35507,9.99525],[1.36624,9.5951],[1.33675,9.54765],[1.41746,9.3226],[1.5649,9.16941],[1.61838,9.0527],[1.64249,6.99562],[1.55877,6.99737],[1.61812,6.74843],[1.58105,6.68619],[1.76906,6.43189],[1.79826,6.28221],[1.62913,6.24075],[1.67336,6.02702],[2.74181,6.13349],[2.70566,6.38038],[2.70464,6.50831],[2.74334,6.57291],[2.7325,6.64057],[2.78204,6.70514],[2.78823,6.76356],[2.73405,6.78508],[2.74024,6.92802],[2.71702,6.95722],[2.76965,7.13543],[2.74489,7.42565],[2.79442,7.43486],[2.78668,7.5116],[2.73405,7.5423],[2.73095,7.7755],[2.67523,7.87825],[2.77907,9.06924],[3.08017,9.10006],[3.14147,9.28375],[3.13928,9.47167],[3.25093,9.61632],[3.34726,9.70696],[3.32099,9.78032],[3.35383,9.83641],[3.54429,9.87739],[3.66908,10.18136],[3.57275,10.27185],[3.6844,10.46351],[3.78292,10.40538],[3.84243,10.59316],[3.71505,11.13015],[3.49175,11.29765],[3.59375,11.70269],[3.48187,11.86092],[3.31613,11.88495],[3.25352,12.01467],[2.83978,12.40585],[2.6593,12.30631],[2.37783,12.24804],[2.39657,12.10952],[2.45824,11.98672],[2.39723,11.89473],[2.29983,11.68254],[2.00988,11.42227],[1.42823,11.46822],[1.03409,11.04719],[0.9813,11.08876],[0.91245,10.99597],[0.8804,10.803],[0.80358,10.71459],[0.77666,10.37665]]]}},{"type":"Feature","properties":{"id":"BF"},"geometry":{"type":"Polygon","coordinates":[[[-5.51058,10.43177],[-5.39602,10.2929],[-5.12465,10.29788],[-4.96453,9.99923],[-4.96621,9.89132],[-4.6426,9.70696],[-4.31392,9.60062],[-4.25999,9.76012],[-3.69703,9.94279],[-3.31779,9.91125],[-3.27228,9.84981],[-3.19306,9.93781],[-3.16609,9.85147],[-3.00765,9.74019],[-2.93012,9.57403],[-2.76494,9.40778],[-2.68802,9.49343],[-2.76534,9.56589],[-2.74174,9.83172],[-2.83108,10.40252],[-2.94232,10.64281],[-2.83373,11.0067],[-0.67143,10.99811],[-0.61937,10.91305],[-0.44298,11.04292],[-0.42391,11.11661],[-0.38219,11.12596],[-0.35955,11.07801],[-0.28566,11.12713],[-0.27374,11.17157],[-0.13493,11.14075],[0.50388,11.01011],[0.48852,10.98561],[0.50521,10.98035],[0.4958,10.93269],[0.66104,10.99964],[0.91245,10.99597],[0.9813,11.08876],[1.03409,11.04719],[1.42823,11.46822],[2.00988,11.42227],[2.29983,11.68254],[2.39723,11.89473],[2.05785,12.35539],[2.26349,12.41915],[0.99167,13.10727],[0.99253,13.37515],[1.18873,13.31771],[1.21217,13.37853],[1.24516,13.33968],[1.28509,13.35488],[1.24429,13.39373],[1.20088,13.38951],[1.02813,13.46635],[0.99514,13.5668],[0.77637,13.64442],[0.77377,13.6866],[0.61924,13.68491],[0.38051,14.05575],[0.16936,14.51654],[0.23859,15.00135],[0.06588,14.96961],[-0.24673,15.07805],[-0.72004,15.08655],[-1.05875,14.7921],[-1.32166,14.72774],[-1.68083,14.50023],[-1.97945,14.47709],[-1.9992,14.19011],[-2.10223,14.14878],[-2.47587,14.29671],[-2.66175,14.14713],[-2.84667,14.05532],[-2.90831,13.81174],[-2.88189,13.64921],[-3.26407,13.70699],[-3.28396,13.5422],[-3.23599,13.29035],[-3.43507,13.27272],[-3.4313,13.1588],[-3.54454,13.1781],[-3.7911,13.36665],[-3.96282,13.38164],[-3.90558,13.44375],[-3.96501,13.49778],[-4.34477,13.12927],[-4.21819,12.95722],[-4.238,12.71467],[-4.47356,12.71252],[-4.41412,12.31922],[-4.57703,12.19875],[-4.54841,12.1385],[-4.62546,12.13204],[-4.62987,12.06531],[-4.70692,12.06746],[-4.72893,12.01579],[-5.07897,11.97918],[-5.26389,11.84778],[-5.40258,11.8327],[-5.26389,11.75728],[-5.29251,11.61715],[-5.22867,11.60421],[-5.20665,11.43811],[-5.25509,11.36905],[-5.25949,11.24816],[-5.32553,11.21578],[-5.32994,11.13371],[-5.49284,11.07538],[-5.41579,10.84628],[-5.47083,10.75329],[-5.46643,10.56074],[-5.51058,10.43177]]]}},{"type":"Feature","properties":{"id":"BD"},"geometry":{"type":"Polygon","coordinates":[[[88.00683,24.66477],[88.08786,24.63232],[88.12296,24.51301],[88.50934,24.32474],[88.68801,24.31464],[88.74841,24.1959],[88.6976,24.14703],[88.73743,23.91751],[88.66189,23.87607],[88.58087,23.87105],[88.56507,23.64044],[88.74841,23.47361],[88.79351,23.50535],[88.79254,23.46028],[88.71133,23.2492],[88.99148,23.21134],[88.86377,23.08759],[88.88327,23.03885],[88.87063,22.95235],[88.96713,22.83346],[88.9151,22.75228],[88.94614,22.66941],[88.9367,22.58527],[89.07114,22.15335],[89.03553,21.77397],[89.13927,21.60785],[89.13606,21.42955],[92.39837,20.38919],[92.4302,20.5688],[92.31348,20.57137],[92.28464,20.63179],[92.37665,20.72172],[92.26071,21.05697],[92.17752,21.17445],[92.20087,21.337],[92.37939,21.47764],[92.43158,21.37025],[92.55105,21.3856],[92.60187,21.24615],[92.68152,21.28454],[92.59775,21.6092],[92.62187,21.87037],[92.60949,21.97638],[92.56616,22.13554],[92.60029,22.1522],[92.5181,22.71441],[92.37665,22.9435],[92.38214,23.28705],[92.26541,23.70392],[92.15417,23.73409],[92.04706,23.64229],[91.95093,23.73284],[91.95642,23.47361],[91.84789,23.42235],[91.76417,23.26619],[91.81634,23.08001],[91.7324,23.00043],[91.61571,22.93929],[91.54993,23.01051],[91.46615,23.2328],[91.4035,23.27522],[91.40848,23.07117],[91.36453,23.06612],[91.28293,23.37538],[91.15579,23.6599],[91.25192,23.83463],[91.22308,23.89616],[91.29587,24.0041],[91.35741,23.99072],[91.37414,24.10693],[91.55542,24.08687],[91.63782,24.1132],[91.65292,24.22095],[91.73257,24.14703],[91.76004,24.23848],[91.82596,24.22345],[91.89258,24.14674],[91.96603,24.3799],[92.11662,24.38997],[92.15796,24.54435],[92.25854,24.9191],[92.38626,24.86055],[92.49887,24.88796],[92.39147,25.01471],[92.33957,25.07593],[92.0316,25.1834],[91.63648,25.12846],[91.25517,25.20677],[90.87427,25.15799],[90.65042,25.17788],[90.40034,25.1534],[90.1155,25.22686],[89.90478,25.31038],[89.87629,25.28337],[89.83371,25.29548],[89.84086,25.31854],[89.81208,25.37244],[89.86129,25.61714],[89.84388,25.70042],[89.80585,25.82489],[89.86592,25.93115],[89.77728,26.04254],[89.77865,26.08387],[89.73581,26.15818],[89.70201,26.15138],[89.63968,26.22595],[89.57101,25.9682],[89.53515,26.00382],[89.35953,26.0077],[89.15869,26.13708],[89.08899,26.38845],[88.95612,26.4564],[88.92357,26.40711],[88.91321,26.37984],[89.05328,26.2469],[88.85004,26.23211],[88.78961,26.31093],[88.67837,26.26291],[88.69485,26.38353],[88.62144,26.46783],[88.4298,26.54489],[88.41196,26.63837],[88.33093,26.48929],[88.35153,26.45241],[88.36938,26.48683],[88.48749,26.45855],[88.51649,26.35923],[88.35153,26.29123],[88.34757,26.22216],[88.1844,26.14417],[88.16581,26.0238],[88.08804,25.91334],[88.13138,25.78773],[88.242,25.80811],[88.45103,25.66245],[88.4559,25.59227],[88.677,25.46959],[88.81296,25.51546],[88.85278,25.34679],[89.01105,25.30303],[89.00463,25.26583],[88.94067,25.18534],[88.44766,25.20149],[88.46277,25.07468],[88.33917,24.86803],[88.27325,24.88796],[88.21832,24.96642],[88.14004,24.93529],[88.15515,24.85806],[88.00683,24.66477]]]}},{"type":"Feature","properties":{"id":"BG"},"geometry":{"type":"Polygon","coordinates":[[[22.34773,42.31725],[22.38136,42.30339],[22.47251,42.20393],[22.50289,42.19527],[22.51224,42.15457],[22.67701,42.06614],[22.86749,42.02275],[22.90254,41.87587],[22.96682,41.77137],[23.01239,41.76527],[23.03342,41.71034],[22.95513,41.63265],[22.96331,41.35782],[22.93334,41.34104],[23.1833,41.31755],[23.21953,41.33773],[23.22771,41.37106],[23.31301,41.40525],[23.33639,41.36317],[23.40416,41.39999],[23.52453,41.40262],[23.63203,41.37632],[23.67644,41.41139],[23.76525,41.40175],[23.80148,41.43943],[23.89613,41.45257],[23.91483,41.47971],[23.96975,41.44118],[24.06908,41.46132],[24.06323,41.53222],[24.10063,41.54796],[24.18126,41.51735],[24.27124,41.57682],[24.30513,41.51297],[24.52599,41.56808],[24.61129,41.42278],[24.71529,41.41928],[24.8041,41.34913],[24.82514,41.4035],[24.86136,41.39298],[24.90928,41.40876],[24.942,41.38685],[25.11611,41.34212],[25.28322,41.23411],[25.48187,41.28506],[25.52394,41.2798],[25.55082,41.31667],[25.61042,41.30614],[25.66183,41.31316],[25.70507,41.29209],[25.8266,41.34563],[25.87919,41.30526],[26.12926,41.35878],[26.16548,41.42278],[26.20288,41.43943],[26.14796,41.47533],[26.176,41.50072],[26.17951,41.55409],[26.14328,41.55496],[26.15146,41.60828],[26.07083,41.64584],[26.06148,41.70345],[26.16841,41.74858],[26.21325,41.73223],[26.22888,41.74139],[26.2654,41.71544],[26.30255,41.70925],[26.35957,41.71149],[26.32952,41.73637],[26.33589,41.76802],[26.36952,41.82265],[26.53968,41.82653],[26.57961,41.90024],[26.56051,41.92995],[26.62996,41.97644],[26.79143,41.97386],[26.95638,42.00741],[27.03277,42.0809],[27.08486,42.08735],[27.19251,42.06028],[27.22376,42.10152],[27.27411,42.10409],[27.45478,41.96591],[27.52379,41.93756],[27.55191,41.90928],[27.69949,41.97515],[27.81235,41.94803],[27.83492,41.99709],[27.91479,41.97902],[28.02971,41.98066],[28.32297,41.98371],[29.24336,43.70874],[28.23293,43.76],[27.99558,43.84193],[27.92008,44.00761],[27.73468,43.95326],[27.64542,44.04958],[27.60834,44.01206],[27.39757,44.0141],[27.26845,44.12602],[26.95141,44.13555],[26.62712,44.05698],[26.38764,44.04356],[26.10115,43.96908],[26.05584,43.90925],[25.94911,43.85745],[25.72792,43.69263],[25.39528,43.61866],[25.17144,43.70261],[25.10718,43.6831],[24.96682,43.72693],[24.73542,43.68523],[24.62281,43.74082],[24.50264,43.76314],[24.35364,43.70211],[24.18149,43.68218],[23.73978,43.80627],[23.61687,43.79289],[23.4507,43.84936],[23.26772,43.84843],[23.05288,43.79494],[22.85314,43.84452],[22.83753,43.88055],[22.87873,43.9844],[23.01674,44.01946],[23.04988,44.07694],[22.67173,44.21564],[22.61711,44.16938],[22.61688,44.06534],[22.41449,44.00514],[22.35558,43.81281],[22.41043,43.69566],[22.47582,43.6558],[22.53397,43.47225],[22.82036,43.33665],[22.89727,43.22417],[23.00806,43.19279],[22.98104,43.11199],[22.89521,43.03625],[22.78397,42.98253],[22.74826,42.88701],[22.54302,42.87774],[22.43309,42.82057],[22.4997,42.74144],[22.43983,42.56851],[22.55669,42.50144],[22.51961,42.3991],[22.47498,42.3915],[22.45919,42.33822],[22.34773,42.31725]]]}},{"type":"Feature","properties":{"id":"BH"},"geometry":{"type":"Polygon","coordinates":[[[50.26923,26.08243],[50.302,25.87592],[50.57069,25.57887],[50.80824,25.54641],[50.7801,25.595],[50.86149,25.6965],[50.81266,25.88946],[50.93865,26.30758],[50.71771,26.73086],[50.38162,26.53976],[50.26923,26.08243]]]}},{"type":"Feature","properties":{"id":"BA"},"geometry":{"type":"Polygon","coordinates":[[[15.72584,44.82334],[15.8255,44.71501],[15.89348,44.74964],[16.05828,44.61538],[16.00884,44.58605],[16.03012,44.55572],[16.10566,44.52586],[16.16814,44.40679],[16.12969,44.38275],[16.21346,44.35231],[16.18688,44.27012],[16.36864,44.08263],[16.43662,44.07523],[16.43629,44.02826],[16.50528,44.0244],[16.55472,43.95326],[16.70922,43.84887],[16.75316,43.77157],[16.80736,43.76011],[17.00585,43.58037],[17.15828,43.49376],[17.24411,43.49376],[17.29699,43.44542],[17.25579,43.40353],[17.286,43.33065],[17.46986,43.16559],[17.64268,43.08595],[17.70879,42.97223],[17.5392,42.92787],[17.6444,42.88641],[17.68151,42.92725],[17.7948,42.89556],[17.80854,42.9182],[17.88201,42.83668],[18.24318,42.6112],[18.36197,42.61423],[18.43735,42.55921],[18.49778,42.58409],[18.53751,42.57376],[18.55504,42.58409],[18.52232,42.62279],[18.57373,42.64429],[18.54841,42.68328],[18.54603,42.69171],[18.55221,42.69045],[18.56789,42.72074],[18.47324,42.74992],[18.45921,42.81682],[18.47633,42.85829],[18.4935,42.86433],[18.49661,42.89306],[18.49076,42.95553],[18.52232,43.01451],[18.66254,43.03928],[18.64735,43.14766],[18.66605,43.2056],[18.71747,43.2286],[18.6976,43.25243],[18.76538,43.29838],[18.85342,43.32426],[18.84794,43.33735],[18.83912,43.34795],[18.90911,43.36383],[18.95819,43.32899],[18.95001,43.29327],[19.00844,43.24988],[19.04233,43.30008],[19.08206,43.29668],[19.08673,43.31453],[19.04071,43.397],[19.01078,43.43854],[18.96053,43.45042],[18.95469,43.49367],[18.91379,43.50299],[19.01078,43.55806],[19.04934,43.50384],[19.13933,43.5282],[19.15685,43.53943],[19.22807,43.5264],[19.24774,43.53061],[19.2553,43.5938],[19.33426,43.58833],[19.36653,43.60921],[19.41941,43.54056],[19.42696,43.57987],[19.50455,43.58385],[19.5176,43.71403],[19.3986,43.79668],[19.23465,43.98764],[19.24363,44.01502],[19.38439,43.96611],[19.52515,43.95573],[19.56498,43.99922],[19.61836,44.01464],[19.61991,44.05254],[19.57467,44.04716],[19.55999,44.06894],[19.51167,44.08158],[19.47321,44.1193],[19.48386,44.14332],[19.47338,44.15034],[19.43905,44.13088],[19.40927,44.16722],[19.3588,44.18353],[19.34773,44.23244],[19.32464,44.27185],[19.26945,44.26957],[19.23306,44.26097],[19.20508,44.2917],[19.18328,44.28383],[19.16741,44.28648],[19.13332,44.31492],[19.13556,44.338],[19.11547,44.34218],[19.1083,44.3558],[19.11865,44.36712],[19.10298,44.36924],[19.10365,44.37795],[19.10704,44.38249],[19.10749,44.39421],[19.11785,44.40313],[19.14681,44.41463],[19.14837,44.45253],[19.12278,44.50132],[19.13369,44.52521],[19.16699,44.52197],[19.26388,44.65412],[19.32543,44.74058],[19.36722,44.88164],[19.18183,44.92055],[19.01994,44.85493],[18.8704,44.85097],[18.76347,44.90669],[18.76369,44.93707],[18.80661,44.93561],[18.78357,44.97741],[18.65723,45.07544],[18.47939,45.05871],[18.41896,45.11083],[18.32077,45.1021],[18.24387,45.13699],[18.1624,45.07654],[18.03121,45.12632],[18.01594,45.15163],[17.99479,45.14958],[17.97834,45.13831],[17.97336,45.12245],[17.93706,45.08016],[17.87148,45.04645],[17.84826,45.04489],[17.66571,45.13408],[17.59104,45.10816],[17.51469,45.10791],[17.47589,45.12656],[17.45615,45.12523],[17.4498,45.16119],[17.41229,45.13335],[17.33573,45.14521],[17.32092,45.16246],[17.26815,45.18444],[17.25131,45.14957],[17.24325,45.146],[17.18438,45.14764],[17.0415,45.20759],[16.9385,45.22742],[16.92405,45.27607],[16.83804,45.18951],[16.81137,45.18434],[16.78219,45.19002],[16.74845,45.20393],[16.64962,45.20714],[16.60194,45.23042],[16.56559,45.22307],[16.5501,45.2212],[16.52982,45.22713],[16.49155,45.21153],[16.4634,45.14522],[16.40023,45.1147],[16.38309,45.05955],[16.38219,45.05139],[16.3749,45.05206],[16.35863,45.03529],[16.35404,45.00241],[16.29036,44.99732],[16.12153,45.09616],[15.98412,45.23088],[15.83512,45.22459],[15.76371,45.16508],[15.78842,45.11519],[15.74585,45.0638],[15.78568,44.97401],[15.74723,44.96818],[15.76096,44.87045],[15.79472,44.8455],[15.72584,44.82334]]]}},{"type":"Feature","properties":{"id":"BY"},"geometry":{"type":"Polygon","coordinates":[[[23.18196,52.28812],[23.20071,52.22848],[23.47859,52.18215],[23.54314,52.12148],[23.61,52.11264],[23.64066,52.07626],[23.68733,51.9906],[23.61523,51.92066],[23.62691,51.78208],[23.53198,51.74298],[23.57053,51.55938],[23.56236,51.53673],[23.62751,51.50512],[23.6736,51.50255],[23.60906,51.62122],[23.7766,51.66809],[23.91118,51.63316],[23.8741,51.59734],[23.99907,51.58369],[24.13075,51.66979],[24.3163,51.75063],[24.29021,51.80841],[24.37123,51.88222],[24.98784,51.91273],[25.20228,51.97143],[25.46163,51.92205],[25.73673,51.91973],[25.80574,51.94556],[25.83217,51.92587],[26.00408,51.92967],[26.19084,51.86781],[26.39367,51.87315],[26.46962,51.80501],[26.69759,51.82284],[26.80043,51.75777],[26.9489,51.73788],[26.99422,51.76933],[27.20602,51.77291],[27.20948,51.66713],[27.26613,51.65957],[27.24828,51.60161],[27.47212,51.61184],[27.51058,51.5854],[27.55727,51.63486],[27.71932,51.60672],[27.67125,51.50854],[27.76052,51.47604],[27.85253,51.62293],[27.91844,51.61952],[27.95827,51.56065],[28.10658,51.57857],[28.23452,51.66988],[28.37592,51.54505],[28.47051,51.59734],[28.64429,51.5664],[28.69161,51.44695],[28.73143,51.46236],[28.75615,51.41442],[28.78224,51.45294],[28.76027,51.48802],[28.81795,51.55552],[28.95528,51.59222],[28.99098,51.56833],[29.1187,51.65872],[29.16402,51.64679],[29.20659,51.56918],[29.25603,51.57089],[29.25191,51.49828],[29.32881,51.37843],[29.42357,51.4187],[29.49773,51.39814],[29.54372,51.48372],[29.7408,51.53417],[29.77376,51.4461],[30.17888,51.51025],[30.34642,51.42555],[30.36153,51.33984],[30.56203,51.25655],[30.64992,51.35014],[30.51946,51.59649],[30.68804,51.82806],[30.76443,51.89739],[30.90897,52.00699],[30.95589,52.07775],[31.13332,52.1004],[31.25142,52.04131],[31.38326,52.12991],[31.7822,52.11406],[31.77877,52.18636],[31.6895,52.1973],[31.70735,52.26711],[31.57971,52.32146],[31.62084,52.33849],[31.61397,52.48843],[31.56316,52.51518],[31.63869,52.55361],[31.50406,52.69707],[31.57277,52.71613],[31.592,52.79011],[31.35667,52.97854],[31.24147,53.031],[31.32283,53.04101],[31.33519,53.08805],[31.3915,53.09712],[31.36403,53.13504],[31.40523,53.21406],[31.56316,53.19432],[31.62496,53.22886],[31.787,53.18033],[31.82373,53.10042],[32.15368,53.07594],[32.40773,53.18856],[32.51725,53.28431],[32.73257,53.33494],[32.74968,53.45597],[32.47777,53.5548],[32.40499,53.6656],[32.50112,53.68594],[32.45717,53.74039],[32.36663,53.7166],[32.12621,53.81586],[31.89137,53.78099],[31.77028,53.80015],[31.85019,53.91801],[31.88744,54.03653],[31.89599,54.0837],[31.57002,54.14535],[31.30791,54.25315],[31.3177,54.34067],[31.22945,54.46585],[31.08543,54.50361],[31.21399,54.63113],[31.19339,54.66947],[30.99187,54.67046],[30.98226,54.68872],[31.0262,54.70698],[30.97127,54.71967],[30.95479,54.74346],[30.75165,54.80699],[30.8264,54.90062],[30.81759,54.94064],[30.93144,54.9585],[30.95754,54.98609],[30.9081,55.02232],[30.94243,55.03964],[31.00972,55.02783],[31.02071,55.06167],[30.97369,55.17134],[30.87944,55.28223],[30.81946,55.27931],[30.8257,55.3313],[30.93144,55.3914],[30.90123,55.46621],[30.95204,55.50667],[30.93419,55.6185],[30.86003,55.63169],[30.7845,55.58514],[30.72957,55.66268],[30.67464,55.64176],[30.63344,55.73079],[30.51037,55.76568],[30.51346,55.78982],[30.48257,55.81066],[30.30987,55.83592],[30.27776,55.86819],[30.12136,55.8358],[29.97975,55.87281],[29.80672,55.79569],[29.61446,55.77716],[29.51283,55.70294],[29.3604,55.75862],[29.44692,55.95978],[29.21717,55.98971],[29.08299,56.03427],[28.73418,55.97131],[28.63668,56.07262],[28.68337,56.10173],[28.5529,56.11705],[28.43068,56.09407],[28.37987,56.11399],[28.36888,56.05805],[28.30571,56.06035],[28.15217,56.16964],[27.97865,56.11849],[27.63065,55.89687],[27.61683,55.78558],[27.3541,55.8089],[27.27804,55.78299],[27.1559,55.85032],[26.97153,55.8102],[26.87448,55.7172],[26.76872,55.67658],[26.71802,55.70645],[26.64888,55.70515],[26.63231,55.67968],[26.63167,55.57887],[26.55094,55.5093],[26.5522,55.40277],[26.44937,55.34832],[26.5709,55.32572],[26.6714,55.33902],[26.80929,55.31642],[26.83266,55.30444],[26.835,55.28182],[26.73017,55.24226],[26.72983,55.21788],[26.68075,55.19787],[26.69243,55.16718],[26.54753,55.14181],[26.51481,55.16051],[26.46249,55.12814],[26.35121,55.1525],[26.30628,55.12536],[26.23202,55.10439],[26.26941,55.08032],[26.20397,54.99729],[26.13386,54.98924],[26.05907,54.94631],[25.99129,54.95705],[25.89462,54.93438],[25.74122,54.80108],[25.75977,54.57252],[25.68045,54.5321],[25.64813,54.48704],[25.62203,54.4656],[25.63371,54.42075],[25.5376,54.33158],[25.55425,54.31591],[25.68513,54.31727],[25.78553,54.23327],[25.78563,54.15747],[25.71084,54.16704],[25.64875,54.1259],[25.54724,54.14925],[25.51452,54.17799],[25.56823,54.25212],[25.509,54.30267],[25.35559,54.26544],[25.22705,54.26271],[25.19199,54.219],[25.0728,54.13419],[24.991,54.14241],[24.96894,54.17589],[24.77131,54.11091],[24.85311,54.02862],[24.74279,53.96663],[24.69185,53.96543],[24.69652,54.01901],[24.62275,54.00217],[24.44411,53.90076],[24.34128,53.90076],[24.19638,53.96405],[23.98837,53.92554],[23.95098,53.9613],[23.81309,53.94205],[23.80543,53.89558],[23.71726,53.93379],[23.61677,53.92691],[23.51284,53.95052],[23.62004,53.60942],[23.81995,53.24131],[23.85657,53.22923],[23.91393,53.16469],[23.87548,53.0831],[23.92184,53.02079],[23.94689,52.95919],[23.91805,52.94016],[23.93763,52.71332],[23.73615,52.6149],[23.58296,52.59868],[23.45112,52.53774],[23.34141,52.44845],[23.18196,52.28812]]]}},{"type":"Feature","properties":{"id":"BZ"},"geometry":{"type":"Polygon","coordinates":[[[-89.22683,15.88619],[-89.17418,15.90898],[-89.02415,15.9063],[-88.95358,15.88698],[-88.40779,16.09624],[-87.3359,17.10872],[-87.24084,17.80373],[-87.84815,18.18511],[-87.85693,18.18266],[-87.86657,18.19971],[-87.87604,18.18313],[-87.90671,18.15213],[-88.03165,18.16657],[-88.03238,18.41778],[-88.26593,18.47617],[-88.29909,18.47591],[-88.3268,18.49048],[-88.48242,18.49164],[-88.71505,18.0707],[-88.8716,17.89535],[-89.03839,18.0067],[-89.15105,17.95104],[-89.14985,17.81563],[-89.15025,17.04813],[-89.22683,15.88619]]]}},{"type":"Feature","properties":{"id":"BO"},"geometry":{"type":"Polygon","coordinates":[[[-69.62883,-17.28142],[-69.46863,-17.37466],[-69.46897,-17.4988],[-69.46623,-17.60518],[-69.34126,-17.72753],[-69.28671,-17.94844],[-69.07496,-18.03715],[-69.14807,-18.16893],[-69.07432,-18.28259],[-68.94987,-18.93302],[-68.87082,-19.06003],[-68.80602,-19.08355],[-68.61989,-19.27584],[-68.41218,-19.40499],[-68.66761,-19.72118],[-68.54611,-19.84651],[-68.57132,-20.03134],[-68.74273,-20.08817],[-68.7276,-20.46178],[-68.44023,-20.62701],[-68.55383,-20.7355],[-68.53957,-20.91542],[-68.40403,-20.94562],[-68.18816,-21.28614],[-67.85114,-22.87076],[-67.54284,-22.89771],[-67.18382,-22.81525],[-66.7298,-22.23644],[-66.29714,-22.08741],[-66.24077,-21.77837],[-66.03836,-21.84829],[-66.04832,-21.9187],[-65.9261,-21.93335],[-65.7467,-22.10105],[-65.61166,-22.09504],[-65.58694,-22.09794],[-65.57743,-22.07675],[-65.47435,-22.08908],[-64.99524,-22.08255],[-64.90014,-22.12136],[-64.67174,-22.18957],[-64.58888,-22.25035],[-64.4176,-22.67692],[-64.35108,-22.73282],[-64.31489,-22.88824],[-64.22918,-22.55807],[-63.93287,-21.99934],[-63.70963,-21.99934],[-63.68113,-22.0544],[-63.66482,-21.99918],[-62.81124,-21.9987],[-62.8078,-22.12534],[-62.64455,-22.25091],[-62.2757,-21.06657],[-62.26883,-20.55311],[-61.93912,-20.10053],[-61.73723,-19.63958],[-60.00638,-19.2981],[-59.06965,-19.29148],[-58.23216,-19.80058],[-58.16225,-20.16193],[-57.8496,-19.98346],[-58.14215,-19.76276],[-57.78463,-19.03259],[-57.71113,-19.03161],[-57.69134,-19.00544],[-57.71995,-18.97546],[-57.71995,-18.89573],[-57.76764,-18.90087],[-57.56807,-18.25655],[-57.48237,-18.24219],[-57.69877,-17.8431],[-57.73949,-17.56095],[-57.90082,-17.44555],[-57.99661,-17.5273],[-58.32935,-17.28195],[-58.5058,-16.80958],[-58.30918,-16.3699],[-58.32431,-16.25861],[-58.41506,-16.32636],[-60.16069,-16.26479],[-60.23797,-15.50267],[-60.58224,-15.09887],[-60.23968,-15.09515],[-60.27887,-14.63021],[-60.46037,-14.22496],[-60.48053,-13.77981],[-61.05527,-13.50054],[-61.81151,-13.49564],[-63.76259,-12.42952],[-63.90248,-12.52544],[-64.22539,-12.45267],[-64.30708,-12.46398],[-64.99778,-11.98604],[-65.30027,-11.48749],[-65.28141,-10.86289],[-65.35402,-10.78685],[-65.37923,-10.35141],[-65.29019,-9.86253],[-65.40615,-9.63894],[-65.56244,-9.84266],[-65.68343,-9.75323],[-67.17784,-10.34016],[-68.71533,-11.14749],[-68.7651,-11.0496],[-68.75179,-11.03688],[-68.75265,-11.02383],[-68.74802,-11.00891],[-69.42792,-10.93451],[-69.47839,-10.95254],[-69.57156,-10.94555],[-68.98115,-11.8979],[-68.65044,-12.50689],[-68.85615,-12.87769],[-68.8864,-13.40792],[-69.05265,-13.68546],[-68.88135,-14.18639],[-69.36254,-14.94634],[-69.14856,-15.23478],[-69.40336,-15.61358],[-69.20291,-16.16668],[-69.09986,-16.22693],[-68.96238,-16.194],[-68.79464,-16.33272],[-68.98358,-16.42165],[-69.04027,-16.57214],[-69.00853,-16.66769],[-69.16896,-16.72233],[-69.62883,-17.28142]]]}},{"type":"Feature","properties":{"id":"BR"},"geometry":{"type":"Polygon","coordinates":[[[-73.96938,-7.58465],[-73.65485,-7.77897],[-73.76576,-7.89884],[-72.92886,-9.04074],[-73.21498,-9.40904],[-72.72216,-9.41397],[-72.31883,-9.5184],[-72.14742,-9.98049],[-71.23394,-9.9668],[-70.53373,-9.42628],[-70.58453,-9.58303],[-70.55429,-9.76692],[-70.62487,-9.80666],[-70.64134,-11.0108],[-70.51395,-10.92249],[-70.38791,-11.07096],[-69.90896,-10.92744],[-69.57835,-10.94051],[-69.57156,-10.94555],[-69.47839,-10.95254],[-69.42792,-10.93451],[-68.74802,-11.00891],[-68.75265,-11.02383],[-68.75179,-11.03688],[-68.7651,-11.0496],[-68.71533,-11.14749],[-67.17784,-10.34016],[-65.68343,-9.75323],[-65.56244,-9.84266],[-65.40615,-9.63894],[-65.29019,-9.86253],[-65.37923,-10.35141],[-65.35402,-10.78685],[-65.28141,-10.86289],[-65.30027,-11.48749],[-64.99778,-11.98604],[-64.30708,-12.46398],[-64.22539,-12.45267],[-63.90248,-12.52544],[-63.76259,-12.42952],[-61.81151,-13.49564],[-61.05527,-13.50054],[-60.48053,-13.77981],[-60.46037,-14.22496],[-60.27887,-14.63021],[-60.23968,-15.09515],[-60.58224,-15.09887],[-60.23797,-15.50267],[-60.16069,-16.26479],[-58.41506,-16.32636],[-58.32431,-16.25861],[-58.30918,-16.3699],[-58.5058,-16.80958],[-58.32935,-17.28195],[-57.99661,-17.5273],[-57.90082,-17.44555],[-57.73949,-17.56095],[-57.69877,-17.8431],[-57.48237,-18.24219],[-57.56807,-18.25655],[-57.76764,-18.90087],[-57.71995,-18.89573],[-57.71995,-18.97546],[-57.69134,-19.00544],[-57.71113,-19.03161],[-57.78463,-19.03259],[-58.14215,-19.76276],[-57.8496,-19.98346],[-58.16225,-20.16193],[-57.84536,-20.93155],[-57.93492,-21.65505],[-57.88239,-21.6868],[-57.94642,-21.73799],[-57.98625,-22.09157],[-56.6508,-22.28387],[-56.5212,-22.11556],[-56.45893,-22.08072],[-56.23206,-22.25347],[-55.8331,-22.29008],[-55.74941,-22.46436],[-55.741,-22.52018],[-55.72366,-22.5519],[-55.6986,-22.56268],[-55.68742,-22.58407],[-55.62493,-22.62765],[-55.63849,-22.95122],[-55.5446,-23.22811],[-55.52288,-23.2595],[-55.5555,-23.28237],[-55.43585,-23.87157],[-55.44117,-23.9185],[-55.41784,-23.9657],[-55.12292,-23.99669],[-55.0518,-23.98666],[-55.02691,-23.97317],[-54.6238,-23.83078],[-54.32807,-24.01865],[-54.28207,-24.07305],[-54.4423,-25.13381],[-54.62033,-25.46026],[-54.60196,-25.48397],[-54.59509,-25.53696],[-54.59398,-25.59224],[-54.5502,-25.58915],[-54.52926,-25.62846],[-53.90831,-25.55513],[-53.83691,-25.94849],[-53.73511,-26.04211],[-53.73086,-26.05842],[-53.7264,-26.0664],[-53.73391,-26.07006],[-53.73968,-26.10012],[-53.65018,-26.19501],[-53.65237,-26.23289],[-53.63739,-26.2496],[-53.63881,-26.25075],[-53.64632,-26.24798],[-53.64186,-26.25976],[-53.64505,-26.28089],[-53.68269,-26.33359],[-53.73372,-26.6131],[-53.80144,-27.09844],[-54.15978,-27.2889],[-54.19062,-27.27639],[-54.19268,-27.30751],[-54.41888,-27.40882],[-54.50416,-27.48232],[-54.67657,-27.57214],[-54.90159,-27.63132],[-54.90805,-27.73149],[-55.1349,-27.89759],[-55.16872,-27.86224],[-55.33303,-27.94661],[-55.6262,-28.17124],[-55.65418,-28.18304],[-56.01729,-28.51223],[-56.00458,-28.60421],[-56.05265,-28.62651],[-56.54171,-29.11447],[-56.57295,-29.11357],[-56.62789,-29.18073],[-56.81251,-29.48154],[-57.09386,-29.74211],[-57.65132,-30.19229],[-57.22502,-30.26121],[-56.90236,-30.02578],[-56.49267,-30.39471],[-56.4795,-30.3899],[-56.4619,-30.38457],[-55.87388,-31.05053],[-55.58866,-30.84117],[-55.5634,-30.8686],[-55.55373,-30.8732],[-55.55218,-30.88193],[-55.54572,-30.89051],[-55.53431,-30.89714],[-55.53276,-30.90218],[-55.52712,-30.89997],[-55.51862,-30.89828],[-55.50841,-30.9027],[-55.50821,-30.91349],[-54.17384,-31.86168],[-53.76024,-32.0751],[-53.39572,-32.58596],[-53.37671,-32.57005],[-53.1111,-32.71147],[-53.53459,-33.16843],[-53.52794,-33.68908],[-53.44031,-33.69344],[-53.39593,-33.75169],[-53.37138,-33.74313],[-53.18243,-33.86894],[-28.34015,-20.99094],[-28.99601,1.86593],[-51.35485,4.8383],[-51.63798,4.51394],[-51.61983,4.14596],[-51.79599,3.89336],[-51.82312,3.85825],[-51.85573,3.83427],[-52.31787,3.17896],[-52.6906,2.37298],[-52.96539,2.1881],[-53.78743,2.34412],[-54.16286,2.10779],[-54.6084,2.32856],[-55.01919,2.564],[-55.71493,2.40342],[-55.96292,2.53188],[-56.13054,2.27723],[-55.92159,2.05236],[-55.89863,1.89861],[-55.99278,1.83137],[-56.47045,1.95135],[-56.7659,1.89509],[-57.07092,1.95304],[-57.09109,2.01854],[-57.23981,1.95808],[-57.35073,1.98327],[-57.55743,1.69605],[-57.77281,1.73344],[-57.97336,1.64566],[-58.01873,1.51966],[-58.33887,1.58014],[-58.4858,1.48399],[-58.53571,1.29154],[-58.84229,1.17749],[-58.92072,1.31293],[-59.25583,1.40559],[-59.74066,1.87596],[-59.7264,2.27497],[-59.91177,2.36759],[-59.99733,2.92312],[-59.79769,3.37162],[-59.86899,3.57089],[-59.51963,3.91951],[-59.73353,4.20399],[-59.69361,4.34069],[-59.78878,4.45637],[-60.15953,4.53456],[-60.04189,4.69801],[-59.98129,5.07097],[-60.20944,5.28754],[-60.32352,5.21299],[-60.73204,5.20931],[-60.5802,4.94312],[-60.86539,4.70512],[-60.98303,4.54167],[-61.15703,4.49839],[-61.31457,4.54167],[-61.29675,4.44216],[-61.48569,4.43149],[-61.54629,4.2822],[-62.13094,4.08309],[-62.44822,4.18621],[-62.57656,4.04754],[-62.74411,4.03331],[-62.7655,3.73099],[-62.98296,3.59935],[-63.21111,3.96219],[-63.4464,3.9693],[-63.42233,3.89995],[-63.50611,3.83592],[-63.67099,4.01731],[-63.70218,3.91417],[-63.86082,3.94796],[-63.99183,3.90172],[-64.14512,4.12932],[-64.57648,4.12576],[-64.72977,4.28931],[-64.84028,4.24665],[-64.48379,3.7879],[-64.02908,2.79797],[-64.0257,2.48156],[-63.39114,2.4317],[-63.39827,2.16098],[-64.06135,1.94722],[-64.08274,1.64792],[-64.34654,1.35569],[-64.38932,1.5125],[-65.11657,1.12046],[-65.57288,0.62856],[-65.50158,0.92086],[-65.6727,1.01353],[-66.28507,0.74585],[-66.85795,1.22998],[-67.08222,1.17441],[-67.15784,1.80439],[-67.299,1.87494],[-67.40488,2.22258],[-67.9292,1.82455],[-68.18632,2.00091],[-68.26699,1.83463],[-68.18128,1.72881],[-69.38621,1.70865],[-69.53746,1.76408],[-69.83491,1.69353],[-69.82987,1.07864],[-69.26017,1.06856],[-69.14422,0.84172],[-69.20976,0.57958],[-69.47696,0.71065],[-70.04162,0.55437],[-70.03658,-0.19681],[-69.603,-0.51947],[-69.59796,-0.75136],[-69.4215,-1.01853],[-69.43395,-1.42219],[-69.94708,-4.2431],[-70.00888,-4.37833],[-70.11305,-4.27281],[-70.19582,-4.3607],[-70.33236,-4.15214],[-70.77601,-4.15717],[-70.96814,-4.36915],[-71.87003,-4.51661],[-72.64391,-5.0391],[-72.83973,-5.14765],[-73.24579,-6.05764],[-73.12983,-6.43852],[-73.73986,-6.87919],[-73.77011,-7.28944],[-73.96938,-7.58465]]]}},{"type":"Feature","properties":{"id":"BB"},"geometry":{"type":"Polygon","coordinates":[[[-59.92255,13.58015],[-59.88892,12.77667],[-59.14146,12.80638],[-59.17509,13.60976],[-59.92255,13.58015]]]}},{"type":"Feature","properties":{"id":"BN"},"geometry":{"type":"Polygon","coordinates":[[[114.07448,4.58441],[114.15813,4.57],[114.26876,4.49878],[114.32176,4.34942],[114.32176,4.2552],[114.4416,4.27588],[114.49922,4.13108],[114.64211,4.00694],[114.78539,4.12205],[114.88039,4.4257],[114.83189,4.42387],[114.77303,4.72871],[114.8266,4.75062],[114.88841,4.81905],[114.96982,4.81146],[114.99417,4.88201],[115.05038,4.90275],[115.02955,4.82087],[115.02278,4.74137],[115.04064,4.63706],[115.07737,4.53418],[115.09978,4.39123],[115.31275,4.30806],[115.36346,4.33563],[115.2851,4.42295],[115.27819,4.63661],[115.20737,4.8256],[115.15092,4.87604],[115.16236,5.01011],[115.02521,5.35005],[114.08532,4.64632],[114.07448,4.58441]]]}},{"type":"Feature","properties":{"id":"BT"},"geometry":{"type":"Polygon","coordinates":[[[88.74219,27.144],[88.86984,27.10937],[88.8714,26.97488],[88.92301,26.99286],[88.95807,26.92668],[89.09554,26.89089],[89.12825,26.81661],[89.1926,26.81329],[89.37913,26.86224],[89.38319,26.85963],[89.3901,26.84225],[89.42349,26.83727],[89.63369,26.74402],[89.86124,26.73307],[90.04535,26.72422],[90.30402,26.85098],[90.39271,26.90704],[90.48504,26.8594],[90.67715,26.77215],[91.50067,26.79223],[91.83181,26.87318],[92.05523,26.8692],[92.11863,26.893],[92.03457,27.07334],[92.04702,27.26861],[92.12019,27.27829],[92.01132,27.47352],[91.65007,27.48287],[91.55819,27.6144],[91.6469,27.76358],[91.5629,27.84823],[91.48973,27.93903],[91.46327,28.0064],[91.25779,28.07509],[91.20019,27.98715],[90.69894,28.07784],[90.58842,28.02838],[90.13387,28.19178],[89.79762,28.23979],[89.59525,28.16433],[89.12825,27.62502],[89.0582,27.60985],[88.97213,27.51671],[88.95355,27.4106],[89.00216,27.32532],[88.96947,27.30319],[88.93678,27.33777],[88.91901,27.32483],[88.74219,27.144]]]}},{"type":"Feature","properties":{"id":"BW"},"geometry":{"type":"Polygon","coordinates":[[[19.99817,-24.76768],[20.02809,-24.78725],[20.03678,-24.81004],[20.29826,-24.94869],[20.64795,-25.47827],[20.86081,-26.14892],[20.61754,-26.4692],[20.63275,-26.78181],[20.68596,-26.9039],[20.87031,-26.80047],[21.13353,-26.86661],[21.37869,-26.82083],[21.69322,-26.86152],[21.7854,-26.79199],[21.77114,-26.69015],[21.83291,-26.65959],[21.90703,-26.66808],[22.06192,-26.61882],[22.21206,-26.3773],[22.41921,-26.23078],[22.56365,-26.19668],[22.70808,-25.99186],[22.86012,-25.50572],[23.03497,-25.29971],[23.47588,-25.29971],[23.9244,-25.64286],[24.18287,-25.62916],[24.36531,-25.773],[24.44703,-25.73021],[24.67319,-25.81749],[24.8946,-25.80723],[25.01718,-25.72507],[25.12266,-25.75931],[25.33076,-25.76616],[25.58543,-25.6343],[25.6643,-25.4491],[25.69661,-25.29284],[25.72702,-25.25503],[25.88571,-24.87802],[25.84295,-24.78661],[25.8515,-24.75727],[26.39409,-24.63468],[26.46346,-24.60358],[26.51667,-24.47219],[26.84165,-24.24885],[26.99749,-23.65486],[27.33768,-23.40917],[27.52393,-23.37952],[27.6066,-23.21894],[27.74154,-23.2137],[27.93539,-23.04941],[27.93729,-22.96194],[28.04752,-22.90243],[28.04562,-22.8394],[28.34874,-22.5694],[28.63287,-22.55887],[28.91889,-22.44299],[29.0151,-22.22907],[29.10881,-22.21202],[29.15268,-22.21399],[29.18974,-22.18599],[29.21955,-22.17771],[29.37703,-22.19581],[29.3533,-22.18363],[29.24648,-22.05967],[29.1974,-22.07472],[29.14501,-22.07275],[29.08495,-22.04867],[29.04108,-22.00563],[29.02191,-21.95665],[29.02191,-21.90647],[29.04023,-21.85864],[29.07763,-21.81877],[28.58114,-21.63455],[28.49942,-21.66634],[28.29416,-21.59037],[28.01669,-21.57624],[27.91407,-21.31621],[27.69171,-21.08409],[27.72972,-20.51735],[27.69361,-20.48531],[27.28865,-20.49873],[27.29831,-20.28935],[27.21278,-20.08244],[26.72246,-19.92707],[26.17227,-19.53709],[25.96226,-19.08152],[25.99837,-19.02943],[25.94326,-18.90362],[25.82353,-18.82808],[25.79217,-18.6355],[25.68859,-18.56165],[25.53465,-18.39041],[25.39972,-18.12691],[25.31799,-18.07091],[25.23909,-17.90832],[25.26433,-17.79571],[25.16882,-17.78253],[25.05895,-17.84452],[24.95586,-17.79674],[24.73364,-17.89338],[24.71887,-17.9218],[24.6303,-17.9863],[24.57485,-18.07151],[24.40577,-17.95726],[24.19416,-18.01919],[23.61088,-18.4881],[23.29618,-17.99855],[23.0996,-18.00075],[21.45556,-18.31795],[20.99904,-18.31743],[20.99751,-22.00026],[19.99912,-21.99991],[19.99817,-24.76768]]]}},{"type":"Feature","properties":{"id":"CF"},"geometry":{"type":"Polygon","coordinates":[[[14.42917,6.00508],[14.49455,5.91683],[14.60974,5.91838],[14.62375,5.70466],[14.58951,5.59777],[14.62531,5.51411],[14.52724,5.28319],[14.57083,5.23979],[14.65489,5.21343],[14.73383,4.6135],[15.00825,4.41458],[15.08609,4.30282],[15.10644,4.1362],[15.17482,4.05131],[15.07686,4.01805],[15.73522,3.24348],[15.77725,3.26835],[16.05449,3.02306],[16.08252,2.45708],[16.19357,2.21537],[16.50126,2.84739],[16.46701,2.92512],[16.57598,3.47999],[16.68283,3.54257],[17.01746,3.55136],[17.35649,3.63045],[17.46876,3.70515],[17.60966,3.63705],[17.83421,3.61068],[17.85842,3.53378],[18.05656,3.56893],[18.14902,3.54476],[18.17323,3.47665],[18.24148,3.50302],[18.2723,3.57992],[18.39558,3.58212],[18.49245,3.63924],[18.58711,3.49423],[18.62755,3.47564],[20.60184,4.42394],[20.90383,4.44877],[21.08793,4.39603],[21.11214,4.33895],[21.21341,4.29285],[21.25744,4.33676],[21.55904,4.25553],[21.6405,4.317],[22.10721,4.20723],[22.27682,4.11347],[22.45504,4.13039],[22.5431,4.22041],[22.60915,4.48821],[22.6928,4.47285],[22.78526,4.71423],[22.84691,4.69887],[22.89094,4.79321],[22.94817,4.82392],[23.38847,4.60013],[24.46719,5.0915],[24.71816,4.90509],[25.31256,5.03668],[25.34558,5.29101],[25.53271,5.37431],[25.86073,5.19455],[26.13371,5.25594],[26.48595,5.04984],[26.74572,5.10685],[26.85579,5.03887],[26.93064,5.13535],[27.09575,5.22305],[27.44012,5.07349],[27.26886,5.25876],[27.23017,5.37167],[27.28621,5.56382],[27.22705,5.62889],[27.22705,5.71254],[26.51721,6.09655],[26.58259,6.1987],[26.32729,6.36272],[26.38022,6.63493],[25.90076,7.09549],[25.37461,7.33024],[25.35281,7.42595],[25.20337,7.50312],[25.20649,7.61115],[25.29214,7.66675],[25.25319,7.8487],[24.98855,7.96588],[24.85156,8.16933],[24.35965,8.26177],[24.13238,8.36959],[24.25691,8.69288],[23.51905,8.71749],[23.59065,8.99743],[23.44744,8.99128],[23.4848,9.16959],[23.56263,9.19418],[23.64358,9.28637],[23.64981,9.44303],[23.62179,9.53823],[23.69155,9.67566],[23.67164,9.86923],[23.3128,10.45214],[23.02221,10.69235],[22.87758,10.91915],[22.45889,11.00246],[21.72139,10.64136],[21.71479,10.29932],[21.63553,10.217],[21.52766,10.2105],[21.34934,9.95907],[21.26348,9.97642],[20.82979,9.44696],[20.36748,9.11019],[19.06421,9.00367],[18.86388,8.87971],[19.11044,8.68172],[18.79783,8.25929],[18.67455,8.22226],[18.62612,8.14163],[18.64153,8.08714],[18.6085,8.05009],[18.02731,8.01085],[17.93926,7.95853],[17.67288,7.98905],[16.8143,7.53971],[16.6668,7.67281],[16.658,7.75353],[16.59415,7.76444],[16.58315,7.88657],[16.41583,7.77971],[16.40703,7.68809],[15.79942,7.44149],[15.73118,7.52006],[15.49743,7.52179],[15.23397,7.25135],[15.04717,6.77085],[14.96311,6.75693],[14.79966,6.39043],[14.80122,6.34866],[14.74206,6.26356],[14.56149,6.18928],[14.43073,6.08867],[14.42917,6.00508]]]}},{"type":"Feature","properties":{"id":"CA"},"geometry":{"type":"Polygon","coordinates":[[[-141.00555,72.20369],[-141.00116,60.30648],[-140.5227,60.22077],[-140.45648,60.30919],[-139.98024,60.18027],[-139.68991,60.33693],[-139.05831,60.35205],[-139.20603,60.08896],[-139.05365,59.99655],[-138.71149,59.90728],[-138.62145,59.76431],[-137.60623,59.24465],[-137.4925,58.89415],[-136.82619,59.16198],[-136.52365,59.16752],[-136.47323,59.46617],[-136.33727,59.44466],[-136.22381,59.55526],[-136.31566,59.59083],[-135.48007,59.79937],[-135.03069,59.56208],[-135.00267,59.28745],[-134.7047,59.2458],[-134.55699,59.1297],[-134.48059,59.13231],[-134.27175,58.8634],[-133.84645,58.73543],[-133.38523,58.42773],[-131.8271,56.62247],[-130.77769,56.36185],[-130.33965,56.10849],[-130.10173,56.12178],[-130.00093,56.00325],[-130.00857,55.91344],[-130.15373,55.74895],[-129.97513,55.28029],[-130.08035,55.21556],[-130.18765,55.07744],[-130.27203,54.97174],[-130.44184,54.85377],[-130.64499,54.76912],[-130.61931,54.70835],[-133.92876,54.62289],[-133.36909,48.51151],[-125.03842,48.53282],[-123.50039,48.21223],[-123.15614,48.35395],[-123.26565,48.6959],[-123.0093,48.76586],[-123.0093,48.83186],[-123.32163,49.00419],[-117.03266,49.00056],[-116.04938,48.99999],[-114.0683,48.99885],[-110.0051,48.99901],[-104.05004,48.99925],[-101.36198,48.99935],[-97.24024,48.99952],[-95.15355,48.9996],[-95.15357,49.384],[-95.12903,49.37056],[-95.05825,49.35311],[-95.01419,49.35647],[-94.99532,49.36579],[-94.95681,49.37035],[-94.85381,49.32492],[-94.8159,49.32299],[-94.82487,49.29483],[-94.77355,49.11998],[-94.75017,49.09931],[-94.687,48.84077],[-94.70087,48.8339],[-94.70486,48.82365],[-94.69669,48.80918],[-94.69335,48.77883],[-94.58903,48.71803],[-94.54885,48.71543],[-94.53826,48.70216],[-94.44258,48.69223],[-94.4174,48.71049],[-94.27153,48.70232],[-94.25172,48.68404],[-94.25104,48.65729],[-94.23215,48.65202],[-93.85769,48.63284],[-93.83288,48.62745],[-93.80676,48.58232],[-93.80939,48.52439],[-93.79267,48.51631],[-93.66382,48.51845],[-93.47022,48.54357],[-93.44472,48.59147],[-93.40693,48.60948],[-93.39758,48.60364],[-93.3712,48.60599],[-93.33946,48.62787],[-93.25391,48.64266],[-92.94973,48.60866],[-92.7287,48.54005],[-92.6342,48.54133],[-92.62747,48.50278],[-92.69927,48.49573],[-92.71323,48.46081],[-92.65606,48.43471],[-92.50712,48.44921],[-92.45588,48.40624],[-92.48147,48.36609],[-92.37185,48.22259],[-92.27167,48.25046],[-92.30939,48.31251],[-92.26662,48.35651],[-92.202,48.35252],[-92.14732,48.36578],[-92.05339,48.35958],[-91.98929,48.25409],[-91.86125,48.21278],[-91.71231,48.19875],[-91.70451,48.11805],[-91.55649,48.10611],[-91.58025,48.04339],[-91.45829,48.07454],[-91.43248,48.04912],[-91.25025,48.08522],[-91.08016,48.18096],[-90.87588,48.2484],[-90.75045,48.09143],[-90.56444,48.12184],[-90.56312,48.09488],[-90.07418,48.11043],[-89.89974,47.98109],[-89.77248,48.02607],[-89.57972,48.00023],[-89.48837,48.01412],[-88.37033,48.30586],[-84.85871,46.88881],[-84.55635,46.45974],[-84.47607,46.45225],[-84.4481,46.48972],[-84.42101,46.49853],[-84.34174,46.50683],[-84.29893,46.49127],[-84.26351,46.49508],[-84.2264,46.53337],[-84.1945,46.54061],[-84.17723,46.52753],[-84.12885,46.53068],[-84.11196,46.50248],[-84.13451,46.39218],[-84.11254,46.32329],[-84.11615,46.2681],[-84.09756,46.25512],[-84.1096,46.23987],[-83.95399,46.05634],[-83.90453,46.05922],[-83.83329,46.12169],[-83.57017,46.105],[-83.43746,45.99749],[-83.59589,45.82131],[-82.48419,45.30225],[-82.42469,42.992],[-82.4146,42.97626],[-82.4253,42.95423],[-82.45331,42.93139],[-82.4826,42.8068],[-82.46613,42.76615],[-82.51063,42.66025],[-82.51858,42.611],[-82.57583,42.5718],[-82.58873,42.54984],[-82.64242,42.55594],[-82.82964,42.37355],[-83.02253,42.33045],[-83.07837,42.30978],[-83.09837,42.28877],[-83.12724,42.2376],[-83.14962,42.04089],[-83.11184,41.95671],[-82.67862,41.67615],[-80.53581,42.29896],[-79.77073,42.55308],[-78.93684,42.82887],[-78.90712,42.89733],[-78.90905,42.93022],[-78.93224,42.95229],[-78.96312,42.95509],[-78.98126,42.97],[-79.02074,42.98444],[-79.02424,43.01983],[-78.99941,43.05612],[-79.01055,43.06659],[-79.07486,43.07845],[-79.05671,43.10937],[-79.06881,43.12029],[-79.0427,43.13934],[-79.04652,43.16396],[-79.05384,43.17418],[-79.05002,43.20133],[-79.05544,43.21224],[-79.05512,43.25375],[-79.06921,43.26183],[-79.25796,43.54052],[-76.79706,43.63099],[-76.43859,44.09393],[-76.35324,44.13493],[-76.31222,44.19894],[-76.244,44.19643],[-76.1664,44.23051],[-76.16285,44.28262],[-76.00018,44.34896],[-75.95947,44.34463],[-75.8217,44.43176],[-75.76813,44.51537],[-75.41441,44.76614],[-75.2193,44.87821],[-75.01363,44.95608],[-74.99101,44.98051],[-74.8447,45.00606],[-74.66689,45.00646],[-74.32699,44.99029],[-73.35025,45.00942],[-71.50067,45.01357],[-71.48735,45.07784],[-71.42778,45.12624],[-71.40364,45.21382],[-71.44252,45.2361],[-71.37133,45.24624],[-71.29371,45.29996],[-71.22338,45.25184],[-71.19723,45.25438],[-71.14568,45.24128],[-71.08364,45.30623],[-71.01866,45.31573],[-71.0107,45.34819],[-70.95193,45.33895],[-70.91169,45.29849],[-70.89864,45.2398],[-70.84816,45.22698],[-70.80236,45.37444],[-70.82638,45.39828],[-70.78372,45.43269],[-70.65383,45.37592],[-70.62518,45.42286],[-70.72651,45.49771],[-70.68516,45.56964],[-70.54019,45.67291],[-70.38934,45.73215],[-70.41523,45.79497],[-70.25976,45.89675],[-70.24694,45.95138],[-70.31025,45.96424],[-70.23855,46.1453],[-70.29078,46.18832],[-70.18547,46.35357],[-70.05812,46.41768],[-69.99966,46.69543],[-69.22119,47.46461],[-69.05148,47.42012],[-69.05073,47.30076],[-69.05039,47.2456],[-68.89222,47.1807],[-68.70125,47.24399],[-68.60575,47.24659],[-68.57914,47.28431],[-68.38332,47.28723],[-68.37458,47.35851],[-68.23244,47.35712],[-67.94843,47.1925],[-67.87993,47.10377],[-67.78578,47.06473],[-67.78111,45.9392],[-67.75196,45.91814],[-67.80961,45.87531],[-67.75654,45.82324],[-67.80653,45.80022],[-67.80705,45.69528],[-67.6049,45.60725],[-67.43815,45.59162],[-67.42144,45.50584],[-67.50578,45.48971],[-67.42394,45.37969],[-67.48201,45.27351],[-67.34927,45.122],[-67.29754,45.14865],[-67.29748,45.18173],[-67.27039,45.1934],[-67.22751,45.16344],[-67.20349,45.1722],[-67.19603,45.16771],[-67.15965,45.16179],[-67.11316,45.11176],[-67.0216,44.95333],[-66.96824,44.90965],[-66.98249,44.87071],[-66.96824,44.83078],[-66.93432,44.82597],[-67.16117,44.20069],[-65.81187,42.91911],[-59.437,43.71683],[-57.60106,47.38123],[-56.67989,47.3339],[-56.25228,47.31192],[-55.8643,46.64935],[-51.16966,45.93987],[-45.64471,55.43944],[-53.68108,62.9266],[-74.12379,75.70014],[-73.91222,78.42484],[-67.48417,80.75493],[-63.1988,81.66522],[-59.93819,82.31398],[-62.36036,83.40597],[-85.36473,83.41631],[-110.08928,79.74266],[-141.00555,72.20369]]]}},{"type":"Feature","properties":{"id":"CN"},"geometry":{"type":"Polygon","coordinates":[[[73.5004,39.38402],[73.55396,39.3543],[73.54572,39.27567],[73.60638,39.24534],[73.75823,39.023],[73.81728,39.04007],[73.82964,38.91517],[73.7445,38.93867],[73.7033,38.84782],[73.80656,38.66449],[73.79806,38.61106],[73.97933,38.52945],[74.17022,38.65504],[74.51217,38.47034],[74.69619,38.42947],[74.69894,38.22155],[74.80331,38.19889],[74.82665,38.07359],[74.9063,38.03033],[74.92416,37.83428],[75.00935,37.77486],[74.8912,37.67576],[74.94338,37.55501],[75.06011,37.52779],[75.15899,37.41443],[75.09719,37.37297],[75.12328,37.31839],[74.88887,37.23275],[74.80605,37.21565],[74.49981,37.24518],[74.56453,37.03023],[75.13839,37.02622],[75.40481,36.95382],[75.45562,36.71971],[75.72737,36.7529],[75.92391,36.56986],[76.0324,36.41198],[76.00906,36.17511],[75.93028,36.13136],[76.15325,35.9264],[76.14913,35.82848],[76.33453,35.84296],[76.50961,35.8908],[76.77323,35.66062],[76.84539,35.67356],[76.96624,35.5932],[77.44277,35.46132],[77.70232,35.46244],[77.80532,35.52058],[78.11664,35.48022],[78.03466,35.3785],[78.00033,35.23954],[78.22692,34.88771],[78.18435,34.7998],[78.27781,34.61484],[78.54964,34.57283],[78.56475,34.50835],[78.74465,34.45174],[79.05364,34.32482],[78.99802,34.3027],[78.91769,34.15452],[78.66225,34.08858],[78.65657,34.03195],[78.73367,34.01121],[78.77349,33.73871],[78.67599,33.66445],[78.73636,33.56521],[79.15252,33.17156],[79.14016,33.02545],[79.46562,32.69668],[79.26768,32.53277],[79.13174,32.47766],[79.0979,32.38051],[78.99322,32.37948],[78.96713,32.33655],[78.7831,32.46873],[78.73916,32.69438],[78.38897,32.53938],[78.4645,32.45367],[78.49609,32.2762],[78.68754,32.10256],[78.74404,32.00384],[78.78036,31.99478],[78.69933,31.78723],[78.84516,31.60631],[78.71032,31.50197],[78.77898,31.31209],[79.01931,31.42817],[79.14016,31.43403],[79.22805,31.34963],[79.59884,30.93943],[79.93255,30.88288],[80.20721,30.58541],[80.54504,30.44936],[80.83343,30.32023],[81.03953,30.20059],[81.12842,30.01395],[81.24362,30.0126],[81.29032,30.08806],[81.2623,30.14596],[81.33355,30.15303],[81.39928,30.21862],[81.41018,30.42153],[81.62033,30.44703],[81.99082,30.33423],[82.10135,30.35439],[82.10757,30.23745],[82.19475,30.16884],[82.16984,30.0692],[82.38622,30.02608],[82.5341,29.9735],[82.73024,29.81695],[83.07116,29.61957],[83.28131,29.56813],[83.44787,29.30513],[83.63156,29.16249],[83.82303,29.30513],[83.97559,29.33091],[84.18107,29.23451],[84.24801,29.02783],[84.2231,28.89571],[84.47528,28.74023],[84.62317,28.73887],[84.85511,28.58041],[85.06059,28.68562],[85.19135,28.62825],[85.18668,28.54076],[85.10729,28.34092],[85.38127,28.28336],[85.4233,28.32996],[85.59765,28.30529],[85.60854,28.25045],[85.69105,28.38475],[85.71907,28.38064],[85.74864,28.23126],[85.84672,28.18187],[85.90743,28.05144],[85.97813,27.99023],[85.94946,27.9401],[86.06309,27.90021],[86.12069,27.93047],[86.08333,28.02121],[86.088,28.09264],[86.18607,28.17364],[86.22966,27.9786],[86.42736,27.91122],[86.51609,27.96623],[86.56265,28.09569],[86.74181,28.10638],[86.75582,28.04182],[87.03757,27.94835],[87.11696,27.84104],[87.56996,27.84517],[87.72718,27.80938],[87.82681,27.95248],[88.13378,27.88015],[88.1278,27.95417],[88.25332,27.9478],[88.54858,28.06057],[88.63235,28.12356],[88.83559,28.01936],[88.88091,27.85192],[88.77517,27.45415],[88.82981,27.38814],[88.91901,27.32483],[88.93678,27.33777],[88.96947,27.30319],[89.00216,27.32532],[88.95355,27.4106],[88.97213,27.51671],[89.0582,27.60985],[89.12825,27.62502],[89.59525,28.16433],[89.79762,28.23979],[90.13387,28.19178],[90.58842,28.02838],[90.69894,28.07784],[91.20019,27.98715],[91.25779,28.07509],[91.46327,28.0064],[91.48973,27.93903],[91.5629,27.84823],[91.6469,27.76358],[91.84722,27.76325],[91.87057,27.7195],[92.27432,27.89077],[92.32101,27.79363],[92.42538,27.80092],[92.7275,27.98662],[92.73025,28.05814],[92.65472,28.07632],[92.67486,28.15018],[92.93075,28.25671],[93.14635,28.37035],[93.18069,28.50319],[93.44621,28.67189],[93.72797,28.68821],[94.35897,29.01965],[94.2752,29.11687],[94.69318,29.31739],[94.81353,29.17804],[95.0978,29.14446],[95.11291,29.09527],[95.2214,29.10727],[95.26122,29.07727],[95.3038,29.13847],[95.41091,29.13007],[95.50842,29.13487],[95.72086,29.20797],[95.75149,29.32063],[95.84899,29.31464],[96.05361,29.38167],[96.31316,29.18643],[96.18682,29.11087],[96.20467,29.02325],[96.3626,29.10607],[96.61391,28.72742],[96.40929,28.51526],[96.48895,28.42955],[96.6455,28.61657],[96.85561,28.4875],[96.88445,28.39452],[96.98882,28.32564],[97.1289,28.3619],[97.34547,28.21385],[97.41729,28.29783],[97.47085,28.2688],[97.50518,28.49716],[97.56835,28.55628],[97.70705,28.5056],[97.79632,28.33168],[97.90069,28.3776],[98.15337,28.12114],[98.13964,27.9478],[98.32641,27.51385],[98.42529,27.55404],[98.43353,27.67086],[98.69582,27.56499],[98.7333,26.85615],[98.77547,26.61994],[98.72741,26.36183],[98.67797,26.24487],[98.7329,26.17218],[98.66884,26.09165],[98.63128,26.15492],[98.57085,26.11547],[98.60763,26.01512],[98.70818,25.86241],[98.63128,25.79937],[98.54064,25.85129],[98.40606,25.61129],[98.31268,25.55307],[98.25774,25.6051],[98.16848,25.62739],[98.18084,25.56298],[98.12591,25.50722],[98.14925,25.41547],[97.92541,25.20815],[97.83614,25.2715],[97.77023,25.11492],[97.72216,25.08508],[97.72903,24.91332],[97.79949,24.85655],[97.76481,24.8289],[97.73127,24.83015],[97.70181,24.84557],[97.64354,24.79171],[97.56648,24.76475],[97.56383,24.75535],[97.5542,24.74943],[97.54675,24.74202],[97.56525,24.72838],[97.56286,24.54535],[97.52757,24.43748],[97.60029,24.4401],[97.66998,24.45288],[97.7098,24.35658],[97.65624,24.33781],[97.66723,24.30027],[97.71941,24.29652],[97.76799,24.26365],[97.72998,24.2302],[97.72799,24.18883],[97.75305,24.16902],[97.72903,24.12606],[97.62363,24.00506],[97.5247,23.94032],[97.64667,23.84574],[97.72302,23.89288],[97.79456,23.94836],[97.79416,23.95663],[97.84328,23.97603],[97.86545,23.97723],[97.88811,23.97446],[97.8955,23.97758],[97.89676,23.97931],[97.89683,23.98389],[97.88814,23.98605],[97.88414,23.99405],[97.88616,24.00463],[97.90998,24.02094],[97.93951,24.01953],[97.98691,24.03897],[97.99583,24.04932],[98.04709,24.07616],[98.05302,24.07408],[98.05671,24.07961],[98.0607,24.07812],[98.06703,24.08028],[98.07806,24.07988],[98.20666,24.11406],[98.54476,24.13119],[98.59256,24.08371],[98.85319,24.13042],[98.87998,24.15624],[98.89632,24.10612],[98.67797,23.9644],[98.68209,23.80492],[98.79607,23.77947],[98.82933,23.72921],[98.81775,23.694],[98.88396,23.59555],[98.80294,23.5345],[98.82877,23.47908],[98.87683,23.48995],[98.92104,23.36946],[98.87573,23.33038],[98.93958,23.31414],[98.92515,23.29535],[98.88597,23.18656],[99.05975,23.16382],[99.04601,23.12215],[99.25741,23.09025],[99.34127,23.13099],[99.52214,23.08218],[99.54218,22.90014],[99.43537,22.94086],[99.45654,22.85726],[99.31243,22.73893],[99.38247,22.57544],[99.37972,22.50188],[99.28771,22.4105],[99.17318,22.18025],[99.19176,22.16983],[99.1552,22.15874],[99.33166,22.09656],[99.47585,22.13345],[99.85351,22.04183],[99.96612,22.05965],[99.99084,21.97053],[99.94003,21.82782],[99.98654,21.71064],[100.04956,21.66843],[100.12679,21.70539],[100.17486,21.65306],[100.10757,21.59945],[100.12542,21.50365],[100.1625,21.48704],[100.18447,21.51898],[100.25863,21.47043],[100.35201,21.53176],[100.42892,21.54325],[100.4811,21.46148],[100.57861,21.45637],[100.72143,21.51898],[100.87265,21.67396],[101.11744,21.77659],[101.15156,21.56129],[101.2124,21.56422],[101.19349,21.41959],[101.26912,21.36482],[101.2229,21.23271],[101.29326,21.17254],[101.54563,21.25668],[101.6068,21.23329],[101.59491,21.18621],[101.60886,21.17947],[101.66977,21.20004],[101.70548,21.14911],[101.7622,21.14813],[101.79266,21.19025],[101.76745,21.21571],[101.83887,21.20983],[101.84412,21.25291],[101.74014,21.30967],[101.74224,21.48276],[101.7727,21.51794],[101.7475,21.5873],[101.80001,21.57461],[101.83257,21.61562],[101.74555,21.72852],[101.7791,21.83019],[101.62566,21.96574],[101.57525,22.13026],[101.60675,22.13513],[101.53638,22.24794],[101.56789,22.28876],[101.61306,22.27515],[101.68973,22.46843],[101.7685,22.50337],[101.86828,22.38397],[101.90714,22.38688],[101.91344,22.44417],[101.98487,22.42766],[102.03633,22.46164],[102.1245,22.43372],[102.14099,22.40092],[102.16621,22.43336],[102.26428,22.41321],[102.25339,22.4607],[102.41061,22.64184],[102.38415,22.67919],[102.42618,22.69212],[102.46665,22.77108],[102.51802,22.77969],[102.57095,22.7036],[102.60675,22.73376],[102.8636,22.60735],[102.9321,22.48659],[103.0722,22.44775],[103.07843,22.50097],[103.17961,22.55705],[103.15782,22.59873],[103.18895,22.64471],[103.28079,22.68063],[103.32282,22.8127],[103.43179,22.75816],[103.43646,22.70648],[103.52675,22.59155],[103.57812,22.65764],[103.56255,22.69499],[103.64506,22.79979],[103.87904,22.56683],[103.93286,22.52703],[103.94513,22.52553],[103.95191,22.5134],[103.96352,22.50584],[103.96783,22.51173],[103.97384,22.50634],[103.99247,22.51958],[104.01088,22.51823],[104.03734,22.72945],[104.11384,22.80363],[104.27084,22.8457],[104.25683,22.76534],[104.35593,22.69353],[104.47225,22.75813],[104.58122,22.85571],[104.60457,22.81841],[104.65283,22.83419],[104.72755,22.81984],[104.77114,22.90017],[104.84942,22.93631],[104.86765,22.95178],[104.8334,23.01484],[104.79478,23.12934],[104.87382,23.12854],[104.87992,23.17141],[104.91435,23.18666],[104.9486,23.17235],[104.96532,23.20463],[104.98712,23.19176],[105.07002,23.26248],[105.11672,23.25247],[105.17276,23.28679],[105.22569,23.27249],[105.32376,23.39684],[105.40782,23.28107],[105.42805,23.30824],[105.49966,23.20669],[105.56037,23.16806],[105.57594,23.075],[105.72382,23.06641],[105.8726,22.92756],[105.90119,22.94168],[105.99568,22.94178],[106.00179,22.99049],[106.19705,22.98475],[106.27022,22.87722],[106.34961,22.86718],[106.49749,22.91164],[106.51306,22.94891],[106.55976,22.92311],[106.60179,22.92884],[106.6516,22.86862],[106.6734,22.89587],[106.71387,22.88296],[106.71128,22.85982],[106.78422,22.81532],[106.81271,22.8226],[106.83685,22.8098],[106.82404,22.7881],[106.76293,22.73491],[106.72321,22.63606],[106.71698,22.58432],[106.65316,22.5757],[106.61269,22.60301],[106.58395,22.474],[106.55665,22.46498],[106.57221,22.37],[106.55976,22.34841],[106.6516,22.33977],[106.69986,22.22309],[106.67495,22.1885],[106.6983,22.15102],[106.70142,22.02409],[106.68274,21.99811],[106.69276,21.96013],[106.72551,21.97923],[106.74345,22.00965],[106.81038,21.97934],[106.9178,21.97357],[106.92714,21.93459],[106.97228,21.92592],[106.99252,21.95191],[107.05634,21.92303],[107.06101,21.88982],[107.00964,21.85948],[107.02615,21.81981],[107.10771,21.79879],[107.20734,21.71493],[107.24625,21.7077],[107.29296,21.74674],[107.35834,21.6672],[107.35989,21.60063],[107.38636,21.59774],[107.41593,21.64839],[107.47197,21.6672],[107.49532,21.62958],[107.49065,21.59774],[107.54047,21.5934],[107.56537,21.61945],[107.66967,21.60787],[107.80355,21.66141],[107.86114,21.65128],[107.90006,21.5905],[107.92652,21.58906],[107.95232,21.5388],[107.96774,21.53601],[107.97074,21.54072],[107.97383,21.53961],[107.97932,21.54503],[108.02926,21.54997],[108.0569,21.53604],[108.10003,21.47338],[108.26073,20.07614],[107.44022,18.66249],[110.2534,15.19951],[112.88221,15.61902],[117.76968,23.10828],[118.41371,24.06775],[118.179,24.33015],[118.09488,24.38193],[118.28244,24.51231],[118.35291,24.51645],[118.42453,24.54644],[118.56434,24.49266],[120.49232,25.22863],[121.03532,26.8787],[123.5458,31.01942],[122.29378,31.76513],[122.80525,33.30571],[123.85601,37.49093],[123.90497,38.79949],[124.17532,39.8232],[124.23201,39.9248],[124.35029,39.95639],[124.37089,40.03004],[124.3322,40.05573],[124.38556,40.11047],[124.40719,40.13655],[124.86913,40.45387],[125.71172,40.85223],[125.76869,40.87908],[126.00335,40.92835],[126.242,41.15454],[126.53189,41.35206],[126.60631,41.65565],[126.90729,41.79955],[127.17841,41.59714],[127.29712,41.49473],[127.92943,41.44291],[128.02633,41.42103],[128.03311,41.39232],[128.12967,41.37931],[128.18546,41.41279],[128.20061,41.40895],[128.30716,41.60322],[128.15119,41.74568],[128.04487,42.01769],[128.94007,42.03537],[128.96068,42.06657],[129.15178,42.17224],[129.22285,42.26491],[129.22423,42.3553],[129.28541,42.41574],[129.42882,42.44702],[129.54701,42.37254],[129.60482,42.44461],[129.72541,42.43739],[129.75294,42.59409],[129.77183,42.69435],[129.7835,42.76521],[129.80719,42.79218],[129.83277,42.86746],[129.85261,42.96494],[129.8865,43.00395],[129.95082,43.01051],[129.96409,42.97306],[130.12957,42.98361],[130.09764,42.91425],[130.26095,42.9027],[130.23068,42.80125],[130.2385,42.71127],[130.41826,42.6011],[130.44361,42.54849],[130.50123,42.61636],[130.55143,42.52158],[130.62107,42.58413],[130.56576,42.68925],[130.40213,42.70788],[130.44361,42.76205],[130.66524,42.84753],[131.02438,42.86518],[131.02668,42.91246],[131.135,42.94114],[131.10274,43.04734],[131.20414,43.13654],[131.19031,43.21385],[131.30324,43.39498],[131.29402,43.46695],[131.19492,43.53047],[131.21105,43.82383],[131.26176,43.94011],[131.23583,43.96085],[131.25484,44.03131],[131.30365,44.04262],[131.1108,44.70266],[130.95639,44.85154],[131.48415,44.99513],[131.68466,45.12374],[131.66852,45.2196],[131.76532,45.22609],[131.86903,45.33636],[131.99417,45.2567],[132.83978,45.05916],[132.96373,45.0212],[133.12293,45.1332],[133.09279,45.25693],[133.19419,45.51913],[133.41083,45.57723],[133.48457,45.86203],[133.60442,45.90053],[133.67569,45.9759],[133.72695,46.05576],[133.68047,46.14697],[133.88097,46.25066],[133.91496,46.4274],[133.84104,46.46681],[134.03538,46.75668],[134.20016,47.33458],[134.50898,47.4812],[134.7671,47.72051],[134.55508,47.98651],[134.67098,48.1564],[134.75328,48.36763],[134.49516,48.42884],[132.66989,47.96491],[132.57309,47.71741],[131.90448,47.68011],[131.2635,47.73325],[131.09871,47.6852],[130.95985,47.6957],[130.90915,47.90623],[130.65103,48.10052],[130.84462,48.30942],[130.52147,48.61745],[130.66946,48.88251],[130.43232,48.90844],[130.2355,48.86741],[129.85416,49.11067],[129.67598,49.29596],[129.50685,49.42398],[129.40398,49.44194],[129.35317,49.3481],[129.23232,49.40353],[129.11153,49.36813],[128.72896,49.58676],[127.83476,49.5748],[127.53516,49.84306],[127.49299,50.01251],[127.60515,50.23503],[127.37384,50.28393],[127.36009,50.43787],[127.28765,50.46585],[127.36335,50.58306],[127.28165,50.72075],[127.14586,50.91152],[126.93135,51.0841],[126.90369,51.3238],[126.68349,51.70607],[126.44606,51.98254],[126.558,52.13738],[125.6131,53.07229],[125.17522,53.20225],[124.46078,53.21881],[123.86158,53.49391],[123.26989,53.54843],[122.85966,53.47395],[122.35063,53.49565],[121.39213,53.31888],[120.85633,53.28499],[120.0451,52.7359],[120.04049,52.58773],[120.46454,52.63811],[120.71673,52.54099],[120.61346,52.32447],[120.77337,52.20805],[120.65907,51.93544],[120.10963,51.671],[119.13553,50.37412],[119.38598,50.35162],[119.27996,50.13348],[119.11003,50.00276],[118.61623,49.93809],[117.82343,49.52696],[117.48208,49.62324],[117.27597,49.62544],[117.07142,49.68482],[116.71193,49.83813],[116.03781,48.87014],[116.06565,48.81716],[115.78876,48.51781],[115.811,48.25699],[115.52082,48.15367],[115.57128,47.91988],[115.94296,47.67741],[116.08431,47.80693],[116.2527,47.87766],[116.4465,47.83662],[116.67405,47.89039],[116.87527,47.88836],[117.08918,47.82242],[117.37875,47.63627],[117.50181,47.77216],[117.80196,48.01661],[118.03676,48.00982],[118.11009,48.04],[118.22677,48.03853],[118.29654,48.00246],[118.55766,47.99277],[118.7564,47.76947],[119.12343,47.66458],[119.13995,47.53997],[119.35892,47.48104],[119.31964,47.42617],[119.54918,47.29505],[119.56019,47.24874],[119.62403,47.24575],[119.71209,47.19192],[119.85518,46.92196],[119.91242,46.90091],[119.89261,46.66423],[119.80455,46.67631],[119.77373,46.62947],[119.68127,46.59015],[119.65265,46.62342],[119.42827,46.63783],[119.37306,46.61132],[119.30261,46.6083],[119.24978,46.64761],[119.10448,46.65516],[119.00541,46.74273],[118.92616,46.72765],[118.89974,46.77139],[118.8337,46.77742],[118.78747,46.68689],[118.30534,46.73519],[117.69554,46.50991],[117.60748,46.59771],[117.41782,46.57862],[117.36609,46.36335],[117.07252,46.35818],[116.83166,46.38637],[116.75551,46.33083],[116.58612,46.30211],[116.26678,45.96479],[116.24012,45.8778],[116.27366,45.78637],[116.16989,45.68603],[115.91898,45.6227],[115.69688,45.45761],[115.35757,45.39106],[114.94546,45.37377],[114.74612,45.43585],[114.54801,45.38337],[114.5166,45.27189],[114.08071,44.92847],[113.909,44.91444],[113.63821,44.74326],[112.74662,44.86297],[112.4164,45.06858],[111.98695,45.09074],[111.76275,44.98032],[111.40498,44.3461],[111.96289,43.81596],[111.93776,43.68709],[111.79758,43.6637],[111.59087,43.51207],[111.0149,43.3289],[110.4327,42.78293],[110.08401,42.6411],[109.89402,42.63111],[109.452,42.44842],[109.00679,42.45302],[108.84489,42.40246],[108.23156,42.45532],[107.57258,42.40898],[107.49681,42.46221],[107.29755,42.41395],[107.24774,42.36107],[106.76517,42.28741],[105.24708,41.7442],[105.01119,41.58382],[104.91272,41.64619],[104.51667,41.66113],[104.52258,41.8706],[103.92804,41.78246],[103.3685,41.89696],[102.72403,42.14675],[102.42826,42.15137],[102.07645,42.22519],[101.80515,42.50074],[101.28833,42.58524],[100.84979,42.67087],[100.33297,42.68231],[99.50671,42.56535],[97.1777,42.7964],[96.37926,42.72055],[96.35658,42.90363],[95.89543,43.2528],[95.52594,43.99353],[95.32891,44.02407],[95.39772,44.2805],[95.01191,44.25274],[94.71959,44.35284],[94.10003,44.71016],[93.51161,44.95964],[91.64048,45.07408],[90.89169,45.19667],[90.65114,45.49314],[90.70907,45.73437],[91.03026,46.04194],[90.99672,46.14207],[90.89639,46.30711],[91.07696,46.57315],[91.0147,46.58171],[91.03649,46.72916],[90.84035,46.99525],[90.76108,46.99399],[90.48542,47.30438],[90.48854,47.41826],[90.33598,47.68303],[90.10871,47.7375],[90.06512,47.88177],[89.76624,47.82745],[89.55453,48.0423],[89.0711,47.98528],[88.93186,48.10263],[88.8011,48.11302],[88.58316,48.21893],[88.58939,48.34531],[87.96361,48.58478],[88.0788,48.71436],[87.73822,48.89582],[87.88171,48.95853],[87.81333,49.17354],[87.48983,49.13794],[87.478,49.07403],[87.28386,49.11626],[86.87238,49.12432],[86.73568,48.99918],[86.75343,48.70331],[86.38069,48.46064],[85.73581,48.3939],[85.5169,48.05493],[85.61067,47.49753],[85.69696,47.2898],[85.54294,47.06171],[85.22443,47.04816],[84.93995,46.87399],[84.73077,47.01394],[83.92184,46.98912],[83.04622,47.19053],[82.21792,45.56619],[82.58474,45.40027],[82.51374,45.1755],[81.73278,45.3504],[80.11169,45.03352],[79.8987,44.89957],[80.38384,44.63073],[80.40229,44.23319],[80.40031,44.10986],[80.75156,43.44948],[80.69718,43.32589],[80.77771,43.30065],[80.78817,43.14235],[80.62913,43.141],[80.3735,43.01557],[80.58999,42.9011],[80.38169,42.83142],[80.26886,42.8366],[80.16892,42.61137],[80.26841,42.23797],[80.17807,42.21166],[80.17842,42.03211],[79.92977,42.04113],[78.3732,41.39603],[78.15757,41.38565],[78.12873,41.23091],[77.81287,41.14307],[77.76206,41.01574],[77.52723,41.00227],[77.3693,41.0375],[77.28004,41.0033],[76.99302,41.0696],[76.75681,40.95354],[76.5261,40.46114],[76.33659,40.3482],[75.96168,40.38064],[75.91361,40.2948],[75.69663,40.28642],[75.5854,40.66874],[75.22834,40.45382],[75.08243,40.43945],[74.82013,40.52197],[74.78168,40.44886],[74.85996,40.32857],[74.69875,40.34668],[74.35063,40.09742],[74.25533,40.13191],[73.97049,40.04378],[73.83006,39.76136],[73.9051,39.75073],[73.92354,39.69565],[73.94683,39.60733],[73.87018,39.47879],[73.59831,39.46425],[73.59241,39.40843],[73.5004,39.38402]]]}},{"type":"Feature","properties":{"id":"CL"},"geometry":{"type":"Polygon","coordinates":[[[-113.52687,-26.52828],[-68.11646,-58.14883],[-66.07313,-55.19618],[-67.11046,-54.94199],[-67.46182,-54.92205],[-68.01394,-54.8753],[-68.60733,-54.9125],[-68.60702,-52.65781],[-68.41683,-52.33516],[-69.97824,-52.00845],[-71.99889,-51.98018],[-72.33873,-51.59954],[-72.31343,-50.58411],[-73.15765,-50.78337],[-73.55259,-49.92488],[-73.45156,-49.79461],[-73.09655,-49.14342],[-72.56894,-48.81116],[-72.54042,-48.52392],[-72.27662,-48.28727],[-72.50478,-47.80586],[-71.94152,-47.13595],[-71.68577,-46.55385],[-71.75614,-45.61611],[-71.35687,-45.22075],[-72.06985,-44.81756],[-71.26418,-44.75684],[-71.16436,-44.46244],[-71.81318,-44.38097],[-71.64206,-43.64774],[-72.14828,-42.85321],[-72.15541,-42.15941],[-71.74901,-42.11711],[-71.92726,-40.72714],[-71.37826,-38.91474],[-70.89532,-38.6923],[-71.24279,-37.20264],[-70.95047,-36.4321],[-70.38008,-36.02375],[-70.49416,-35.24145],[-69.87386,-34.13344],[-69.88099,-33.34489],[-70.55832,-31.51559],[-70.14479,-30.36595],[-69.8596,-30.26131],[-69.99507,-29.28351],[-69.80969,-29.07185],[-69.66709,-28.44055],[-69.22504,-27.95042],[-68.77586,-27.16029],[-68.43363,-27.08414],[-68.27677,-26.90626],[-68.59048,-26.49861],[-68.56909,-26.28146],[-68.38372,-26.15353],[-68.57622,-25.32505],[-68.38372,-25.08636],[-68.56909,-24.69831],[-68.24825,-24.42596],[-67.33563,-24.04237],[-66.99632,-22.99839],[-67.18382,-22.81525],[-67.54284,-22.89771],[-67.85114,-22.87076],[-68.18816,-21.28614],[-68.40403,-20.94562],[-68.53957,-20.91542],[-68.55383,-20.7355],[-68.44023,-20.62701],[-68.7276,-20.46178],[-68.74273,-20.08817],[-68.57132,-20.03134],[-68.54611,-19.84651],[-68.66761,-19.72118],[-68.41218,-19.40499],[-68.61989,-19.27584],[-68.80602,-19.08355],[-68.87082,-19.06003],[-68.94987,-18.93302],[-69.07432,-18.28259],[-69.14807,-18.16893],[-69.07496,-18.03715],[-69.28671,-17.94844],[-69.34126,-17.72753],[-69.46623,-17.60518],[-69.46897,-17.4988],[-69.66483,-17.65083],[-69.79087,-17.65563],[-69.82868,-17.72048],[-69.75305,-17.94605],[-69.81607,-18.12582],[-69.96732,-18.25992],[-70.16394,-18.31737],[-70.31267,-18.31258],[-70.378,-18.3495],[-70.59118,-18.35072],[-73.98689,-20.10822],[-113.52687,-26.52828]]]}},{"type":"Feature","properties":{"id":"CI"},"geometry":{"type":"Polygon","coordinates":[[[-8.59456,6.50612],[-8.48652,6.43797],[-8.45666,6.49977],[-8.38453,6.35887],[-8.3298,6.36381],[-8.17557,6.28222],[-8.00642,6.31684],[-7.90692,6.27728],[-7.83478,6.20309],[-7.8497,6.08932],[-7.79747,6.07696],[-7.78254,5.99037],[-7.70294,5.90625],[-7.67309,5.94337],[-7.48155,5.80974],[-7.46165,5.84934],[-7.43677,5.84687],[-7.43926,5.74787],[-7.37209,5.61173],[-7.43428,5.42355],[-7.36463,5.32944],[-7.46165,5.26256],[-7.48901,5.14118],[-7.55369,5.08667],[-7.53876,4.94294],[-7.59349,4.8909],[-7.53259,4.35145],[-7.52774,3.7105],[-3.34019,4.17519],[-3.10675,5.08515],[-3.11073,5.12675],[-3.063,5.13665],[-2.96554,5.10397],[-2.95261,5.12477],[-2.75502,5.10657],[-2.73074,5.1364],[-2.77625,5.34621],[-2.72737,5.34789],[-2.76614,5.60963],[-2.85378,5.65156],[-2.93132,5.62137],[-2.96671,5.6415],[-2.95323,5.71865],[-3.01896,5.71697],[-3.25999,6.62521],[-3.21954,6.74407],[-3.23327,6.81744],[-2.95438,7.23737],[-2.97822,7.27165],[-2.92339,7.60847],[-2.79467,7.86002],[-2.78395,7.94974],[-2.74819,7.92613],[-2.67787,8.02055],[-2.61232,8.02645],[-2.62901,8.11495],[-2.49037,8.20872],[-2.58243,8.7789],[-2.66357,9.01771],[-2.77799,9.04949],[-2.69814,9.22717],[-2.68802,9.49343],[-2.76494,9.40778],[-2.93012,9.57403],[-3.00765,9.74019],[-3.16609,9.85147],[-3.19306,9.93781],[-3.27228,9.84981],[-3.31779,9.91125],[-3.69703,9.94279],[-4.25999,9.76012],[-4.31392,9.60062],[-4.6426,9.70696],[-4.96621,9.89132],[-4.96453,9.99923],[-5.12465,10.29788],[-5.39602,10.2929],[-5.51058,10.43177],[-5.65135,10.46767],[-5.78124,10.43952],[-5.99478,10.19694],[-6.18851,10.24244],[-6.1731,10.46983],[-6.24795,10.74248],[-6.325,10.68624],[-6.40646,10.69922],[-6.42847,10.5694],[-6.52974,10.59104],[-6.63541,10.66893],[-6.68164,10.35074],[-6.93921,10.35291],[-7.01186,10.25111],[-6.97444,10.21644],[-7.00966,10.15794],[-7.0603,10.14711],[-7.13331,10.24877],[-7.3707,10.24677],[-7.44555,10.44602],[-7.52261,10.4655],[-7.54462,10.40921],[-7.63048,10.46334],[-7.92107,10.15577],[-7.97971,10.17117],[-8.01225,10.1021],[-8.11921,10.04577],[-8.15652,9.94288],[-8.09434,9.86936],[-8.14657,9.55062],[-8.03463,9.39604],[-7.85056,9.41812],[-7.90777,9.20456],[-7.73862,9.08422],[-7.92518,8.99332],[-7.95503,8.81146],[-7.69882,8.66148],[-7.65653,8.36873],[-7.92518,8.50652],[-8.22991,8.48438],[-8.2411,8.24196],[-8.062,8.16071],[-7.98675,8.20134],[-7.99919,8.11023],[-7.94695,8.00925],[-8.06449,8.04989],[-8.13414,7.87991],[-8.09931,7.78626],[-8.21374,7.54466],[-8.4003,7.6285],[-8.47114,7.55676],[-8.41935,7.51203],[-8.37458,7.25794],[-8.29249,7.1691],[-8.31736,6.82837],[-8.59456,6.50612]]]}},{"type":"Feature","properties":{"id":"CM"},"geometry":{"type":"Polygon","coordinates":[[[8.34397,4.30689],[8.6479,4.06346],[9.22018,3.72052],[9.6225,2.44901],[9.81162,2.33797],[9.82123,2.35097],[9.83754,2.32428],[9.83238,2.29079],[9.84716,2.24676],[9.89012,2.20457],[9.90749,2.20049],[9.991,2.16561],[11.3561,2.17217],[11.37116,2.29975],[13.28534,2.25716],[13.29457,2.16106],[14.61145,2.17866],[15.00996,1.98887],[15.22634,2.03243],[15.34776,1.91264],[15.48942,1.98265],[16.02959,1.76483],[16.02647,1.65591],[16.14634,1.70259],[16.05294,1.9811],[16.08563,2.19733],[16.15568,2.18955],[16.19357,2.21537],[16.08252,2.45708],[16.05449,3.02306],[15.77725,3.26835],[15.73522,3.24348],[15.07686,4.01805],[15.17482,4.05131],[15.10644,4.1362],[15.08609,4.30282],[15.00825,4.41458],[14.73383,4.6135],[14.65489,5.21343],[14.57083,5.23979],[14.52724,5.28319],[14.62531,5.51411],[14.58951,5.59777],[14.62375,5.70466],[14.60974,5.91838],[14.49455,5.91683],[14.42917,6.00508],[14.43073,6.08867],[14.56149,6.18928],[14.74206,6.26356],[14.80122,6.34866],[14.79966,6.39043],[14.96311,6.75693],[15.04717,6.77085],[15.23397,7.25135],[15.49743,7.52179],[15.56964,7.58936],[15.59272,7.7696],[15.50743,7.79302],[15.20426,8.50892],[15.09484,8.65982],[14.83566,8.80557],[14.35707,9.19611],[14.37094,9.2954],[13.97544,9.6365],[14.01793,9.73169],[14.1317,9.82413],[14.20411,10.00055],[14.4673,10.00264],[14.80082,9.93818],[14.95722,9.97926],[15.05999,9.94845],[15.14043,9.99246],[15.24618,9.99246],[15.41408,9.92876],[15.68761,9.99344],[15.50535,10.1098],[15.30874,10.31063],[15.23724,10.47764],[15.14936,10.53915],[15.15532,10.62846],[15.06737,10.80921],[15.09127,10.87431],[15.04957,11.02347],[15.10021,11.04101],[15.0585,11.40481],[15.13149,11.5537],[15.06595,11.71126],[15.11579,11.79313],[15.04808,11.8731],[15.05786,12.0608],[15.0349,12.10698],[15.00146,12.1223],[14.96952,12.0925],[14.89019,12.16593],[14.90827,12.3269],[14.83314,12.62963],[14.55058,12.78256],[14.56101,12.91036],[14.46881,13.08259],[14.08251,13.0797],[14.20204,12.53405],[14.17523,12.41916],[14.22215,12.36533],[14.4843,12.35223],[14.6474,12.17466],[14.61612,11.7798],[14.55207,11.72001],[14.64591,11.66166],[14.6124,11.51283],[14.17821,11.23831],[13.97489,11.30258],[13.78945,11.00154],[13.7403,11.00593],[13.70753,10.94451],[13.73434,10.9255],[13.54964,10.61236],[13.5705,10.53183],[13.43644,10.13326],[13.34111,10.12299],[13.25025,10.03647],[13.25323,10.00127],[13.286,9.9822],[13.27409,9.93232],[13.24132,9.91031],[13.25025,9.86042],[13.29941,9.8296],[13.25472,9.76795],[13.22642,9.57266],[13.02385,9.49334],[12.85628,9.36698],[12.91958,9.33905],[12.90022,9.11411],[12.81085,8.91992],[12.79,8.75361],[12.71701,8.7595],[12.68722,8.65938],[12.44146,8.6152],[12.4489,8.52536],[12.26123,8.43696],[12.24782,8.17904],[12.19271,8.10826],[12.20909,7.97553],[11.99908,7.67302],[12.01844,7.52981],[11.93205,7.47812],[11.84864,7.26098],[11.87396,7.09398],[11.63117,6.9905],[11.55818,6.86186],[11.57755,6.74059],[11.51499,6.60892],[11.42264,6.5882],[11.42041,6.53789],[11.09495,6.51717],[11.09644,6.68437],[10.94302,6.69325],[10.8179,6.83377],[10.83727,6.9358],[10.60789,7.06885],[10.59746,7.14719],[10.57214,7.16345],[10.53639,6.93432],[10.21466,6.88996],[10.15135,7.03781],[9.86314,6.77756],[9.77824,6.79088],[9.70674,6.51717],[9.51757,6.43874],[8.84209,5.82562],[8.88156,5.78857],[8.83687,5.68483],[8.92029,5.58403],[8.78027,5.1243],[8.60302,4.87353],[8.34397,4.30689]]]}},{"type":"Feature","properties":{"id":"IN-TG"},"geometry":{"type":"Polygon","coordinates":[[[77.2344,16.47658],[77.28847,16.40595],[77.48451,16.38223],[77.59523,16.34336],[77.60364,16.29657],[77.49893,16.26906],[77.51197,15.92864],[77.65754,15.88869],[78.03108,15.90421],[78.12,15.82892],[78.41766,16.08012],[78.68408,16.04581],[79.21623,16.21665],[79.21485,16.48251],[79.31304,16.57302],[79.79507,16.72137],[79.94476,16.62731],[80.02544,16.71249],[80.0735,16.81242],[79.99248,16.8604],[80.04432,16.96256],[80.18199,17.04628],[80.26027,17.0082],[80.31864,16.87387],[80.40138,16.85613],[80.45391,16.81702],[80.45871,16.7881],[80.58711,16.772],[80.57544,16.91855],[80.36189,16.96683],[80.38867,17.08139],[80.4467,17.01772],[80.50369,17.1083],[80.61733,17.13226],[80.68771,17.06794],[80.83671,17.02494],[80.91499,17.20081],[81.40594,17.3585],[81.77398,17.88596],[81.39221,17.81014],[81.05026,17.77615],[80.51055,18.62802],[80.34782,18.59158],[80.27503,18.72104],[80.11196,18.6869],[79.9094,18.82474],[79.96261,18.86145],[79.97051,19.35358],[79.93858,19.47792],[79.86991,19.5009],[79.804,19.60054],[79.63165,19.57887],[79.47578,19.49928],[79.23408,19.61219],[79.19048,19.46044],[78.94432,19.54943],[78.95839,19.66037],[78.84613,19.65778],[78.82793,19.75749],[78.27449,19.90476],[78.35861,19.75604],[78.26694,19.69544],[78.3011,19.46885],[78.19141,19.42903],[78.14695,19.22898],[78.00653,19.30158],[77.86422,19.3207],[77.84379,19.18359],[77.74251,19.02577],[77.94353,18.82604],[77.85684,18.81905],[77.74251,18.68267],[77.73994,18.55204],[77.60965,18.5522],[77.56785,18.28849],[77.61377,18.10033],[77.56296,18.04925],[77.66166,17.9686],[77.50837,17.79298],[77.57823,17.74378],[77.45841,17.70568],[77.44005,17.57693],[77.52571,17.57693],[77.67608,17.52751],[77.62716,17.44335],[77.53583,17.44007],[77.52244,17.35178],[77.45155,17.3721],[77.46202,17.28607],[77.36623,17.15883],[77.46356,17.11454],[77.50099,17.01657],[77.45532,16.92068],[77.47489,16.77956],[77.44279,16.78712],[77.427,16.72252],[77.47095,16.71216],[77.47198,16.587],[77.37636,16.48481],[77.32366,16.48942],[77.2344,16.47658]]]}},{"type":"Feature","properties":{"id":"CD"},"geometry":{"type":"Polygon","coordinates":[[[11.95767,-5.94705],[12.42245,-6.07585],[13.04371,-5.87078],[16.55507,-5.85631],[16.96282,-7.21787],[17.5828,-8.13784],[18.33635,-8.00126],[19.33698,-7.99743],[19.5469,-7.00195],[20.30218,-6.98955],[20.31846,-6.91953],[20.61689,-6.90876],[20.56263,-7.28566],[21.79824,-7.29628],[21.84856,-9.59871],[22.19039,-9.94628],[22.32604,-10.76291],[22.17954,-10.85884],[22.25951,-11.24911],[22.54205,-11.05784],[23.16602,-11.10577],[23.45631,-10.946],[23.86868,-11.02856],[24.00027,-10.89356],[24.34528,-11.06816],[24.42612,-11.44975],[25.34069,-11.19707],[25.33058,-11.65767],[26.01777,-11.91488],[26.88687,-12.01868],[27.04351,-11.61312],[27.22541,-11.60323],[27.21025,-11.76157],[27.59932,-12.22123],[28.33199,-12.41375],[29.01918,-13.41353],[29.60531,-13.21685],[29.65078,-13.41844],[29.81551,-13.44683],[29.8139,-12.14898],[29.48404,-12.23604],[29.4992,-12.43843],[29.18592,-12.37921],[28.48357,-11.87532],[28.37241,-11.57848],[28.65032,-10.65133],[28.62795,-9.92942],[28.68532,-9.78],[28.56208,-9.49122],[28.51627,-9.44726],[28.52636,-9.35379],[28.36562,-9.30091],[28.38526,-9.23393],[28.9711,-8.66935],[28.88917,-8.4831],[30.79243,-8.27382],[30.2567,-7.14121],[29.52552,-6.2731],[29.43673,-4.44845],[29.23708,-3.75856],[29.21463,-3.3514],[29.25633,-3.05471],[29.17258,-2.99385],[29.16037,-2.95457],[29.09797,-2.91935],[29.09119,-2.87871],[29.0505,-2.81774],[29.00404,-2.81978],[29.00167,-2.78523],[29.04081,-2.7416],[29.00357,-2.70596],[28.94346,-2.69124],[28.89793,-2.66111],[28.90226,-2.62385],[28.89288,-2.55848],[28.87943,-2.55165],[28.86193,-2.53185],[28.86209,-2.5231],[28.87497,-2.50887],[28.88846,-2.50493],[28.89342,-2.49017],[28.89132,-2.47557],[28.86846,-2.44866],[28.86826,-2.41888],[28.89601,-2.37321],[28.95642,-2.37321],[29.00051,-2.29001],[29.105,-2.27043],[29.17562,-2.12278],[29.11847,-1.90576],[29.24458,-1.69663],[29.24323,-1.66826],[29.36322,-1.50887],[29.45038,-1.5054],[29.53062,-1.40499],[29.59061,-1.39016],[29.58388,-0.89821],[29.63006,-0.8997],[29.62708,-0.71055],[29.67176,-0.55714],[29.67474,-0.47969],[29.65091,-0.46777],[29.72687,-0.08051],[29.7224,0.07291],[29.77454,0.16675],[29.81922,0.16824],[29.87284,0.39166],[29.97413,0.52124],[29.95477,0.64486],[29.98307,0.84295],[30.1484,0.89805],[30.22139,0.99635],[30.24671,1.14974],[30.48503,1.21675],[31.30127,2.11006],[31.28042,2.17853],[31.20148,2.2217],[31.1985,2.29462],[31.12104,2.27676],[31.07934,2.30207],[31.06593,2.35862],[30.96911,2.41071],[30.91102,2.33332],[30.83059,2.42559],[30.74271,2.43601],[30.75612,2.5863],[30.8857,2.83923],[30.8574,2.9508],[30.77101,3.04897],[30.84251,3.26908],[30.93486,3.40737],[30.94081,3.50847],[30.85153,3.48867],[30.85997,3.5743],[30.80713,3.60506],[30.78512,3.67097],[30.56277,3.62703],[30.57378,3.74567],[30.55396,3.84451],[30.47691,3.83353],[30.27658,3.95653],[30.22374,3.93896],[30.1621,4.10586],[30.06964,4.13221],[29.79666,4.37809],[29.82087,4.56246],[29.49726,4.7007],[29.43341,4.50101],[29.22207,4.34297],[29.03054,4.48784],[28.8126,4.48784],[28.6651,4.42638],[28.20719,4.35614],[27.79551,4.59976],[27.76469,4.79284],[27.65462,4.89375],[27.56656,4.89375],[27.44012,5.07349],[27.09575,5.22305],[26.93064,5.13535],[26.85579,5.03887],[26.74572,5.10685],[26.48595,5.04984],[26.13371,5.25594],[25.86073,5.19455],[25.53271,5.37431],[25.34558,5.29101],[25.31256,5.03668],[24.71816,4.90509],[24.46719,5.0915],[23.38847,4.60013],[22.94817,4.82392],[22.89094,4.79321],[22.84691,4.69887],[22.78526,4.71423],[22.6928,4.47285],[22.60915,4.48821],[22.5431,4.22041],[22.45504,4.13039],[22.27682,4.11347],[22.10721,4.20723],[21.6405,4.317],[21.55904,4.25553],[21.25744,4.33676],[21.21341,4.29285],[21.11214,4.33895],[21.08793,4.39603],[20.90383,4.44877],[20.60184,4.42394],[18.62755,3.47564],[18.63857,3.19342],[18.10683,2.26876],[18.08034,1.58553],[17.85887,1.04327],[17.86989,0.58873],[17.95255,0.48128],[17.93877,0.32424],[17.81204,0.23884],[17.66051,-0.26535],[17.72112,-0.52707],[17.32438,-0.99265],[16.97999,-1.12762],[16.70724,-1.45815],[16.50336,-1.8795],[16.16173,-2.16586],[16.22785,-2.59528],[16.1755,-3.25014],[16.21407,-3.2969],[15.89448,-3.9513],[15.53081,-4.042],[15.48121,-4.22062],[15.41785,-4.28381],[15.32693,-4.27282],[15.25411,-4.31121],[15.1978,-4.32388],[14.83101,-4.80838],[14.67948,-4.92093],[14.5059,-4.84956],[14.41499,-4.8825],[14.37366,-4.56125],[14.47284,-4.42941],[14.3957,-4.36623],[14.40672,-4.28381],[13.9108,-4.50906],[13.81162,-4.41842],[13.71794,-4.44864],[13.70417,-4.72601],[13.50305,-4.77818],[13.41764,-4.89897],[13.11182,-4.5942],[13.09648,-4.63739],[13.11195,-4.67745],[12.8733,-4.74346],[12.70868,-4.95505],[12.63465,-4.94632],[12.60251,-5.01715],[12.46297,-5.09408],[12.49815,-5.14058],[12.51589,-5.1332],[12.53586,-5.14658],[12.53599,-5.1618],[12.52301,-5.17481],[12.52318,-5.74353],[12.26557,-5.74031],[12.20376,-5.76338],[11.95767,-5.94705]]]}},{"type":"Feature","properties":{"id":"CG"},"geometry":{"type":"Polygon","coordinates":[[[10.75913,-4.39519],[11.50888,-5.33417],[12.00924,-5.02627],[12.16068,-4.90089],[12.20901,-4.75642],[12.25587,-4.79437],[12.32324,-4.78415],[12.40964,-4.60609],[12.64835,-4.55937],[12.76844,-4.38709],[12.87096,-4.40315],[12.91489,-4.47907],[13.09648,-4.63739],[13.11182,-4.5942],[13.41764,-4.89897],[13.50305,-4.77818],[13.70417,-4.72601],[13.71794,-4.44864],[13.81162,-4.41842],[13.9108,-4.50906],[14.40672,-4.28381],[14.3957,-4.36623],[14.47284,-4.42941],[14.37366,-4.56125],[14.41499,-4.8825],[14.5059,-4.84956],[14.67948,-4.92093],[14.83101,-4.80838],[15.1978,-4.32388],[15.25411,-4.31121],[15.32693,-4.27282],[15.41785,-4.28381],[15.48121,-4.22062],[15.53081,-4.042],[15.89448,-3.9513],[16.21407,-3.2969],[16.1755,-3.25014],[16.22785,-2.59528],[16.16173,-2.16586],[16.50336,-1.8795],[16.70724,-1.45815],[16.97999,-1.12762],[17.32438,-0.99265],[17.72112,-0.52707],[17.66051,-0.26535],[17.81204,0.23884],[17.93877,0.32424],[17.95255,0.48128],[17.86989,0.58873],[17.85887,1.04327],[18.08034,1.58553],[18.10683,2.26876],[18.63857,3.19342],[18.62755,3.47564],[18.58711,3.49423],[18.49245,3.63924],[18.39558,3.58212],[18.2723,3.57992],[18.24148,3.50302],[18.17323,3.47665],[18.14902,3.54476],[18.05656,3.56893],[17.85842,3.53378],[17.83421,3.61068],[17.60966,3.63705],[17.46876,3.70515],[17.35649,3.63045],[17.01746,3.55136],[16.68283,3.54257],[16.57598,3.47999],[16.46701,2.92512],[16.50126,2.84739],[16.19357,2.21537],[16.15568,2.18955],[16.08563,2.19733],[16.05294,1.9811],[16.14634,1.70259],[16.02647,1.65591],[16.02959,1.76483],[15.48942,1.98265],[15.34776,1.91264],[15.22634,2.03243],[15.00996,1.98887],[14.61145,2.17866],[13.29457,2.16106],[13.13461,1.57238],[13.25447,1.32339],[13.15519,1.23368],[13.89582,1.4261],[14.25186,1.39842],[14.48179,0.9152],[14.26066,0.57255],[14.10909,0.58563],[13.88648,0.26652],[13.90632,-0.2287],[14.06862,-0.20826],[14.2165,-0.38261],[14.41887,-0.44799],[14.52569,-0.57818],[14.41838,-1.89412],[14.25932,-1.97624],[14.23518,-2.15671],[14.16202,-2.23916],[14.23829,-2.33715],[14.10442,-2.49268],[13.85846,-2.46935],[13.92073,-2.35581],[13.75884,-2.09293],[13.47977,-2.43224],[13.02759,-2.33098],[12.82172,-1.91091],[12.61312,-1.8129],[12.44656,-1.92025],[12.47925,-2.32626],[12.04895,-2.41704],[11.96866,-2.33559],[11.74605,-2.39936],[11.57637,-2.33379],[11.64487,-2.61865],[11.5359,-2.85654],[11.64798,-2.81146],[11.80365,-3.00424],[11.70558,-3.0773],[11.70227,-3.17465],[11.96554,-3.30267],[11.8318,-3.5812],[11.92719,-3.62768],[11.87083,-3.71571],[11.68608,-3.68942],[11.57949,-3.52798],[11.48764,-3.51089],[11.22301,-3.69888],[11.12647,-3.94169],[10.75913,-4.39519]]]}},{"type":"Feature","properties":{"id":"CO"},"geometry":{"type":"Polygon","coordinates":[[[-82.56142,11.91792],[-78.79327,9.93766],[-77.58292,9.22278],[-77.32389,8.81247],[-77.45064,8.49991],[-77.17257,7.97422],[-77.57185,7.51147],[-77.72514,7.72348],[-77.72157,7.47612],[-77.81426,7.48319],[-77.89178,7.22681],[-78.06168,7.07793],[-82.12561,4.00341],[-78.87137,1.47457],[-78.42749,1.15389],[-77.85677,0.80197],[-77.7148,0.85003],[-77.68613,0.83029],[-77.66416,0.81604],[-77.67815,0.73863],[-77.49984,0.64476],[-77.52001,0.40782],[-76.89177,0.24736],[-76.4094,0.24015],[-76.41215,0.38228],[-76.23441,0.42294],[-75.82927,0.09578],[-75.25764,-0.11943],[-75.18513,-0.0308],[-74.42701,-0.50218],[-74.26675,-0.97229],[-73.65312,-1.26222],[-72.92587,-2.44514],[-71.75223,-2.15058],[-70.94377,-2.23142],[-70.04609,-2.73906],[-70.71396,-3.7921],[-70.52393,-3.87553],[-70.3374,-3.79505],[-69.94708,-4.2431],[-69.43395,-1.42219],[-69.4215,-1.01853],[-69.59796,-0.75136],[-69.603,-0.51947],[-70.03658,-0.19681],[-70.04162,0.55437],[-69.47696,0.71065],[-69.20976,0.57958],[-69.14422,0.84172],[-69.26017,1.06856],[-69.82987,1.07864],[-69.83491,1.69353],[-69.53746,1.76408],[-69.38621,1.70865],[-68.18128,1.72881],[-68.26699,1.83463],[-68.18632,2.00091],[-67.9292,1.82455],[-67.40488,2.22258],[-67.299,1.87494],[-67.15784,1.80439],[-67.08222,1.17441],[-66.85795,1.22998],[-67.21967,2.35778],[-67.65696,2.81691],[-67.85862,2.79173],[-67.85862,2.86727],[-67.30945,3.38393],[-67.50067,3.75812],[-67.62671,3.74303],[-67.85358,4.53249],[-67.83341,5.31104],[-67.59141,5.5369],[-67.63914,5.64963],[-67.58558,5.84537],[-67.43513,5.98835],[-67.4625,6.20625],[-67.60654,6.2891],[-69.41843,6.1072],[-70.10716,6.96516],[-70.7596,7.09799],[-71.03941,6.98163],[-71.37234,7.01588],[-71.42212,7.03854],[-71.44118,7.02116],[-71.82441,7.04314],[-72.04895,7.03837],[-72.19437,7.37034],[-72.43132,7.40034],[-72.47415,7.48928],[-72.45321,7.57232],[-72.47827,7.65604],[-72.46763,7.79518],[-72.44454,7.86031],[-72.46183,7.90682],[-72.45806,7.91141],[-72.47042,7.92306],[-72.48183,7.92909],[-72.48801,7.94329],[-72.47213,7.96106],[-72.39137,8.03534],[-72.35163,8.01163],[-72.36987,8.19976],[-72.4042,8.36513],[-72.65474,8.61428],[-72.77415,9.10165],[-72.94052,9.10663],[-73.02119,9.27584],[-73.36905,9.16636],[-72.98085,9.85253],[-72.88002,10.44309],[-72.4767,11.1117],[-72.24983,11.14138],[-71.9675,11.65536],[-71.3275,11.85],[-70.92579,11.96275],[-71.19849,12.65801],[-78.66279,16.62373],[-81.80642,15.86201],[-82.06974,14.49418],[-82.56142,11.91792]]]}},{"type":"Feature","properties":{"id":"CR"},"geometry":{"type":"Polygon","coordinates":[[[-87.41779,5.02401],[-82.94503,7.93865],[-82.89978,8.04083],[-82.89137,8.05755],[-82.88641,8.10219],[-82.9388,8.26634],[-83.05209,8.33394],[-82.93056,8.43465],[-82.8679,8.44042],[-82.8382,8.48117],[-82.83322,8.52464],[-82.83975,8.54755],[-82.82739,8.60153],[-82.8794,8.6981],[-82.92068,8.74832],[-82.91377,8.774],[-82.88253,8.83331],[-82.72126,8.97125],[-82.93516,9.07687],[-82.93516,9.46741],[-82.84871,9.4973],[-82.87919,9.62645],[-82.77206,9.59573],[-82.66667,9.49746],[-82.61345,9.49881],[-82.56507,9.57279],[-82.51044,9.65379],[-83.54024,10.96805],[-83.68276,11.01562],[-83.66597,10.79916],[-83.90838,10.71161],[-84.68197,11.07568],[-84.92439,10.9497],[-85.60529,11.22607],[-85.71223,11.06868],[-86.14524,11.09059],[-87.41779,5.02401]]]}},{"type":"Feature","properties":{"id":"CZ"},"geometry":{"type":"Polygon","coordinates":[[[12.09287,50.25032],[12.19335,50.19997],[12.21484,50.16399],[12.1917,50.13434],[12.2073,50.10315],[12.23709,50.10213],[12.27433,50.0771],[12.26111,50.06331],[12.30798,50.05719],[12.49908,49.97305],[12.47264,49.94222],[12.55197,49.92094],[12.48256,49.83575],[12.46603,49.78882],[12.40489,49.76321],[12.4462,49.70233],[12.52553,49.68415],[12.53544,49.61888],[12.56188,49.6146],[12.60155,49.52887],[12.64782,49.52565],[12.64121,49.47628],[12.669,49.42935],[12.71227,49.42363],[12.75854,49.3989],[12.78168,49.34618],[12.88414,49.33541],[12.88249,49.35479],[12.94859,49.34079],[13.03618,49.30417],[13.02957,49.27399],[13.05883,49.26259],[13.17665,49.16713],[13.17019,49.14339],[13.20405,49.12303],[13.23689,49.11412],[13.28242,49.1228],[13.39479,49.04812],[13.40802,48.98851],[13.50221,48.93752],[13.50552,48.97441],[13.58319,48.96899],[13.61624,48.9462],[13.67739,48.87886],[13.73854,48.88538],[13.76994,48.83537],[13.78977,48.83319],[13.8096,48.77877],[13.84023,48.76988],[14.06151,48.66873],[14.01482,48.63788],[14.09104,48.5943],[14.20691,48.5898],[14.33909,48.55852],[14.43076,48.58855],[14.4587,48.64695],[14.56139,48.60429],[14.60808,48.62881],[14.66762,48.58215],[14.71794,48.59794],[14.72756,48.69502],[14.80584,48.73489],[14.80821,48.77711],[14.81545,48.7874],[14.94773,48.76268],[14.95641,48.75915],[14.9758,48.76857],[14.98112,48.77524],[14.9782,48.7766],[14.98032,48.77959],[14.95072,48.79101],[14.98917,48.90082],[14.97612,48.96983],[14.99878,49.01444],[15.15534,48.99056],[15.16358,48.94278],[15.26177,48.95766],[15.28305,48.98831],[15.34823,48.98444],[15.48027,48.94481],[15.51357,48.91549],[15.61622,48.89541],[15.6921,48.85973],[15.75341,48.8516],[15.78087,48.87644],[15.84404,48.86921],[16.06034,48.75436],[16.37345,48.729],[16.40915,48.74576],[16.46134,48.80865],[16.67008,48.77699],[16.68518,48.7281],[16.71883,48.73806],[16.79779,48.70998],[16.90354,48.71541],[16.93955,48.60371],[17.00215,48.70887],[17.11202,48.82925],[17.19355,48.87602],[17.29054,48.85546],[17.3853,48.80936],[17.45671,48.85004],[17.5295,48.81117],[17.7094,48.86721],[17.73126,48.87885],[17.77944,48.92318],[17.87831,48.92679],[17.91814,49.01784],[18.06885,49.03157],[18.1104,49.08624],[18.15022,49.24518],[18.18456,49.28909],[18.36446,49.3267],[18.4139,49.36517],[18.4084,49.40003],[18.44686,49.39467],[18.54848,49.47059],[18.53063,49.49022],[18.57183,49.51162],[18.6144,49.49824],[18.67757,49.50895],[18.74761,49.492],[18.84521,49.51672],[18.84786,49.5446],[18.80479,49.6815],[18.72838,49.68163],[18.69817,49.70473],[18.62676,49.71983],[18.62943,49.74603],[18.62645,49.75002],[18.61368,49.75426],[18.61278,49.7618],[18.57183,49.83334],[18.60341,49.86256],[18.57045,49.87849],[18.57697,49.91565],[18.54299,49.92537],[18.54495,49.9079],[18.53423,49.89906],[18.41604,49.93498],[18.33562,49.94747],[18.33278,49.92415],[18.31914,49.91565],[18.27794,49.93863],[18.27107,49.96779],[18.21752,49.97309],[18.20241,49.99958],[18.10628,50.00223],[18.07898,50.04535],[18.03212,50.06574],[18.00396,50.04954],[18.04585,50.03311],[18.04585,50.01194],[18.00191,50.01723],[17.86886,49.97452],[17.77669,50.02253],[17.7506,50.07896],[17.6888,50.12037],[17.66683,50.10275],[17.59404,50.16437],[17.70528,50.18812],[17.76296,50.23382],[17.72176,50.25665],[17.74648,50.29966],[17.69292,50.32859],[17.67764,50.28977],[17.58889,50.27837],[17.3702,50.28123],[17.34548,50.2628],[17.34273,50.32947],[17.27681,50.32246],[17.19991,50.3654],[17.19579,50.38817],[17.14498,50.38117],[17.1224,50.39494],[16.89229,50.45117],[16.85933,50.41093],[16.90877,50.38642],[16.94448,50.31281],[16.99803,50.30316],[17.02138,50.27772],[16.99803,50.25753],[17.02825,50.23118],[17.00353,50.21449],[16.98018,50.24172],[16.8456,50.20834],[16.7014,50.09659],[16.63137,50.1142],[16.55446,50.16613],[16.56407,50.21009],[16.42674,50.32509],[16.39379,50.3207],[16.3622,50.34875],[16.36495,50.37679],[16.30289,50.38292],[16.28118,50.36891],[16.22821,50.41054],[16.21585,50.40627],[16.19526,50.43291],[16.31413,50.50274],[16.34572,50.49575],[16.44597,50.58041],[16.33611,50.66579],[16.23174,50.67101],[16.20839,50.63096],[16.10265,50.66405],[16.02437,50.60046],[15.98317,50.61528],[16.0175,50.63009],[15.97219,50.69799],[15.87331,50.67188],[15.81683,50.75666],[15.73186,50.73885],[15.43798,50.80833],[15.3803,50.77187],[15.36656,50.83956],[15.2773,50.8907],[15.27043,50.97724],[15.2361,50.99886],[15.1743,50.9833],[15.16744,51.01959],[15.11937,50.99021],[15.10152,51.01095],[15.06218,51.02269],[15.03895,51.0123],[15.02433,51.0242],[14.96419,50.99108],[15.01088,50.97984],[14.99852,50.86817],[14.82803,50.86966],[14.79139,50.81438],[14.70661,50.84096],[14.61993,50.86049],[14.63434,50.8883],[14.65259,50.90513],[14.64802,50.93241],[14.58024,50.91443],[14.56374,50.922],[14.59702,50.96148],[14.59908,50.98685],[14.58215,50.99306],[14.56432,51.01008],[14.53438,51.00374],[14.53321,51.01679],[14.49873,51.02242],[14.50809,51.0427],[14.49991,51.04692],[14.49154,51.04382],[14.49202,51.02286],[14.45827,51.03712],[14.41335,51.02086],[14.30098,51.05515],[14.25665,50.98935],[14.28776,50.97718],[14.32353,50.98556],[14.32793,50.97379],[14.30251,50.96606],[14.31422,50.95243],[14.39848,50.93866],[14.38691,50.89907],[14.30098,50.88448],[14.27123,50.89386],[14.24314,50.88761],[14.22331,50.86049],[14.02982,50.80662],[13.98864,50.8177],[13.89113,50.78533],[13.89444,50.74142],[13.82942,50.7251],[13.76316,50.73487],[13.70204,50.71771],[13.65977,50.73096],[13.52474,50.70394],[13.53748,50.67654],[13.5226,50.64721],[13.49742,50.63133],[13.46413,50.60102],[13.42189,50.61243],[13.37485,50.64931],[13.37805,50.627],[13.32264,50.60317],[13.32594,50.58009],[13.29454,50.57904],[13.25158,50.59268],[13.19043,50.50237],[13.13424,50.51709],[13.08301,50.50132],[13.0312,50.50944],[13.02038,50.4734],[13.02147,50.44763],[12.98433,50.42016],[12.94058,50.40944],[12.82465,50.45738],[12.73476,50.43237],[12.73044,50.42268],[12.70731,50.39948],[12.67261,50.41949],[12.51356,50.39694],[12.48747,50.37278],[12.49214,50.35228],[12.48256,50.34784],[12.46643,50.35527],[12.43722,50.33774],[12.43371,50.32506],[12.39924,50.32302],[12.40158,50.29521],[12.36594,50.28289],[12.35425,50.23993],[12.33263,50.24367],[12.32445,50.20442],[12.33847,50.19432],[12.32596,50.17146],[12.29232,50.17524],[12.28063,50.19544],[12.28755,50.22429],[12.23943,50.24594],[12.24791,50.25525],[12.26953,50.25189],[12.25119,50.27079],[12.20823,50.2729],[12.18013,50.32146],[12.10907,50.32041],[12.13716,50.27396],[12.09287,50.25032]]]}},{"type":"Feature","properties":{"id":"IN-MZ"},"geometry":{"type":"Polygon","coordinates":[[[92.26541,23.70392],[92.38214,23.28705],[92.37665,22.9435],[92.5181,22.71441],[92.60029,22.1522],[92.56616,22.13554],[92.60949,21.97638],[92.67532,22.03547],[92.70416,22.16017],[92.86208,22.05456],[92.89504,21.95143],[92.93899,22.02656],[92.99804,21.98964],[92.99255,22.05965],[93.04885,22.20595],[93.15734,22.18687],[93.14224,22.24535],[93.19991,22.25425],[93.18206,22.43716],[93.13537,22.45873],[93.11477,22.54374],[93.134,22.59573],[93.09417,22.69459],[93.134,22.92498],[93.12988,23.05772],[93.2878,23.00464],[93.38478,23.13698],[93.36862,23.35426],[93.38781,23.36139],[93.39981,23.38828],[93.38805,23.4728],[93.43475,23.68299],[93.3908,23.7622],[93.3908,23.92925],[93.36059,23.93176],[93.32351,24.04468],[92.98416,24.11354],[93.02329,24.40026],[92.8379,24.39588],[92.76168,24.52088],[92.52685,24.16617],[92.44239,24.14299],[92.42317,24.25635],[92.29819,24.25406],[92.31777,23.86543],[92.26541,23.70392]]]}},{"type":"Feature","properties":{"id":"CN-FJ"},"geometry":{"type":"Polygon","coordinates":[[[115.8625,25.22544],[115.88859,24.94123],[115.96618,24.92193],[116.05201,24.85528],[116.20754,24.84718],[116.29886,24.79857],[116.34761,24.86899],[116.40975,24.84313],[116.37062,24.80231],[116.48735,24.67977],[116.51859,24.60332],[116.81076,24.68352],[116.7517,24.5415],[116.89693,24.40025],[116.93023,24.23256],[116.99512,24.18402],[116.91478,24.09097],[116.97933,24.00099],[116.97589,23.95739],[116.96353,23.90655],[117.05863,23.73884],[117.76968,23.10828],[118.41371,24.06775],[118.179,24.33015],[118.09488,24.38193],[118.28244,24.51231],[118.35291,24.51645],[118.42453,24.54644],[118.56434,24.49266],[120.49232,25.22863],[121.03532,26.8787],[120.43281,27.17219],[120.40603,27.20273],[120.42011,27.26531],[120.25909,27.43089],[120.13275,27.42053],[120.03662,27.34371],[119.76985,27.30741],[119.65999,27.5381],[119.61845,27.67988],[119.25247,27.43425],[119.12132,27.44186],[118.89541,27.47294],[118.89678,27.64643],[118.79722,27.94164],[118.71002,27.98773],[118.79035,28.24572],[118.53973,28.28594],[118.47759,28.23876],[118.42121,28.29239],[118.31245,28.22878],[118.36875,28.19369],[118.35296,28.09409],[118.16413,28.05743],[118.08792,27.99167],[117.85274,27.94891],[117.7518,27.83027],[117.67249,27.82268],[117.56332,27.96408],[117.28523,27.87671],[117.31269,27.76801],[117.01469,27.66163],[117.16918,27.2943],[117.05451,27.1062],[116.60476,26.92513],[116.51412,26.70145],[116.64321,26.49024],[116.38572,26.23368],[116.50039,26.15728],[116.36444,25.971],[116.14265,25.87899],[116.00601,25.32789],[115.8625,25.22544]]]}},{"type":"Feature","properties":{"id":"DJ"},"geometry":{"type":"Polygon","coordinates":[[[41.77727,11.49902],[41.8096,11.33606],[41.80056,10.97127],[42.06302,10.92599],[42.13691,10.97586],[42.42669,10.98493],[42.62989,11.09711],[42.75111,11.06992],[42.79037,10.98493],[42.95776,10.98533],[43.42425,11.70983],[43.90659,12.3823],[43.32909,12.59711],[43.29075,12.79154],[42.86195,12.58747],[42.7996,12.42629],[42.6957,12.36201],[42.46941,12.52661],[42.4037,12.46478],[41.95461,11.81157],[41.82878,11.72361],[41.77727,11.49902]]]}},{"type":"Feature","properties":{"id":"DM"},"geometry":{"type":"Polygon","coordinates":[[[-61.81728,15.58058],[-61.51867,14.96709],[-60.69955,15.22234],[-60.95725,15.70997],[-61.44899,15.79571],[-61.81728,15.58058]]]}},{"type":"Feature","properties":{"id":"DO"},"geometry":{"type":"Polygon","coordinates":[[[-72.29523,17.48026],[-71.87936,17.20162],[-68.20301,17.83927],[-67.99519,18.97186],[-70.39828,20.32236],[-72.17094,20.08703],[-71.77419,19.73128],[-71.75865,19.70231],[-71.7429,19.58445],[-71.71449,19.55364],[-71.71268,19.53374],[-71.6802,19.45008],[-71.69448,19.37866],[-71.77766,19.33823],[-71.73229,19.26686],[-71.62642,19.21212],[-71.65337,19.11759],[-71.69938,19.10916],[-71.71088,19.08353],[-71.74088,19.0437],[-71.88102,18.95007],[-71.77766,18.95007],[-71.72624,18.87802],[-71.71885,18.78423],[-71.82556,18.62551],[-71.95412,18.64939],[-72.00201,18.62312],[-71.88102,18.50125],[-71.90875,18.45821],[-71.69952,18.34101],[-71.78271,18.18302],[-71.75465,18.14405],[-71.74994,18.11115],[-71.73783,18.07177],[-71.75671,18.03456],[-72.29523,17.48026]]]}},{"type":"Feature","properties":{"id":"DZ"},"geometry":{"type":"Polygon","coordinates":[[[-8.6715,28.71194],[-8.66879,27.6666],[-8.66674,27.31569],[-4.83423,24.99935],[1.15698,21.12843],[1.20992,20.73533],[3.24648,19.81703],[3.12501,19.1366],[3.36082,18.9745],[4.26651,19.14224],[5.8153,19.45101],[7.38361,20.79165],[7.48273,20.87258],[11.96886,23.51735],[11.62498,24.26669],[11.41061,24.21456],[10.85323,24.5595],[10.33159,24.5465],[10.02432,24.98124],[10.03146,25.35635],[9.38834,26.19288],[9.51696,26.39148],[9.89569,26.57696],[9.78136,29.40961],[9.3876,30.16738],[9.55544,30.23971],[9.07483,32.07865],[8.35999,32.50101],[8.31895,32.83483],[8.1179,33.05086],[8.11433,33.10175],[7.83028,33.18851],[7.73687,33.42114],[7.54088,33.7726],[7.52851,34.06493],[7.66174,34.20167],[7.74207,34.16492],[7.81242,34.21841],[7.86264,34.3987],[8.20482,34.57575],[8.29655,34.72798],[8.25189,34.92009],[8.30727,34.95378],[8.3555,35.10007],[8.47318,35.23376],[8.30329,35.29884],[8.36086,35.47774],[8.35371,35.66373],[8.26472,35.73669],[8.2626,35.91733],[8.40731,36.42208],[8.18936,36.44939],[8.16167,36.48817],[8.47609,36.66607],[8.46537,36.7706],[8.57613,36.78062],[8.67706,36.8364],[8.62972,36.86499],[8.64044,36.9401],[8.59123,37.14286],[2.46645,37.97429],[-2.27707,35.35051],[-2.21248,35.08532],[-2.21445,35.04378],[-2.04734,34.93218],[-1.97833,34.93218],[-1.97469,34.886],[-1.73707,34.74226],[-1.84569,34.61907],[-1.69788,34.48056],[-1.78042,34.39018],[-1.64666,34.10405],[-1.73494,33.71721],[-1.59508,33.59929],[-1.67067,33.27084],[-1.46249,33.0499],[-1.54244,32.95499],[-1.37794,32.73628],[-0.9912,32.52467],[-1.24998,32.32993],[-1.24453,32.1917],[-1.15735,32.12096],[-1.22829,32.07832],[-2.46166,32.16603],[-2.93873,32.06557],[-2.82784,31.79459],[-3.66314,31.6339],[-3.66386,31.39202],[-3.77647,31.31912],[-3.77103,31.14984],[-3.54944,31.0503],[-3.65418,30.85566],[-3.64735,30.67539],[-4.31774,30.53229],[-4.6058,30.28343],[-5.21671,29.95253],[-5.58831,29.48103],[-5.72121,29.52322],[-5.75616,29.61407],[-6.69965,29.51623],[-6.78351,29.44634],[-6.95824,29.50924],[-7.61585,29.36252],[-8.6715,28.71194]]]}},{"type":"Feature","properties":{"id":"CN-TJ"},"geometry":{"type":"Polygon","coordinates":[[[116.70364,38.93751],[116.75514,38.74176],[116.85539,38.74658],[116.87187,38.68658],[117.02567,38.69837],[117.09297,38.58682],[117.21931,38.63189],[117.24128,38.56373],[117.42736,38.61204],[117.59559,38.61472],[118.33648,38.49229],[118.35983,38.73266],[118.02577,39.21789],[118.06079,39.25166],[117.96363,39.31331],[117.84072,39.32712],[117.84656,39.35421],[117.79197,39.36668],[117.85274,39.38685],[117.92861,39.57499],[117.76245,39.59828],[117.71026,39.52787],[117.65945,39.63848],[117.58872,39.73993],[117.54753,39.7584],[117.50427,39.88971],[117.53517,39.98711],[117.78648,39.96659],[117.75558,40.05389],[117.5537,40.22607],[117.34291,40.23131],[117.40608,40.17362],[117.19425,40.07281],[117.13897,39.8797],[117.26154,39.83385],[117.14755,39.81723],[117.19493,39.75999],[117.14137,39.61203],[116.95083,39.65434],[116.89075,39.69714],[116.80732,39.61415],[116.77848,39.46005],[116.87049,39.43354],[116.81899,39.34491],[116.87942,39.34385],[116.85539,39.16467],[116.91581,39.13112],[116.85882,39.05598],[116.75926,39.04372],[116.70364,38.93751]]]}},{"type":"Feature","properties":{"id":"EC"},"geometry":{"type":"Polygon","coordinates":[[[-93.12365,2.64343],[-92.46744,-2.52874],[-84.52388,-3.36941],[-80.30602,-3.39149],[-80.20647,-3.431],[-80.24123,-3.46124],[-80.24475,-3.47846],[-80.24586,-3.48677],[-80.23651,-3.48652],[-80.22629,-3.501],[-80.20535,-3.51667],[-80.21642,-3.5888],[-80.19848,-3.59249],[-80.18741,-3.63994],[-80.19926,-3.68894],[-80.13232,-3.90317],[-80.46386,-4.01342],[-80.4822,-4.05477],[-80.45023,-4.20938],[-80.32114,-4.21323],[-80.46386,-4.41516],[-80.39256,-4.48269],[-80.13945,-4.29786],[-79.79722,-4.47558],[-79.59402,-4.46848],[-79.26248,-4.95167],[-79.1162,-4.97774],[-79.01659,-5.01481],[-78.85149,-4.66795],[-78.68394,-4.60754],[-78.34362,-3.38633],[-78.24589,-3.39907],[-78.22642,-3.51113],[-78.14324,-3.47653],[-78.19369,-3.36431],[-77.94147,-3.05454],[-76.6324,-2.58397],[-76.05203,-2.12179],[-75.57429,-1.55961],[-75.3872,-0.9374],[-75.22862,-0.95588],[-75.22862,-0.60048],[-75.53615,-0.19213],[-75.60169,-0.18708],[-75.61997,-0.10012],[-75.40192,-0.17196],[-75.25764,-0.11943],[-75.82927,0.09578],[-76.23441,0.42294],[-76.41215,0.38228],[-76.4094,0.24015],[-76.89177,0.24736],[-77.52001,0.40782],[-77.49984,0.64476],[-77.67815,0.73863],[-77.66416,0.81604],[-77.68613,0.83029],[-77.7148,0.85003],[-77.85677,0.80197],[-78.42749,1.15389],[-78.87137,1.47457],[-93.12365,2.64343]]]}},{"type":"Feature","properties":{"id":"EG"},"geometry":{"type":"Polygon","coordinates":[[[24.71117,30.17441],[24.99968,29.24574],[24.99885,21.99535],[33.17563,22.00405],[34.0765,22.00501],[37.8565,22.00903],[34.51305,27.70027],[34.46254,27.99552],[34.88293,29.37455],[34.92298,29.45305],[34.26742,31.21998],[34.24012,31.29591],[34.23572,31.2966],[34.21853,31.32363],[34.052,31.46619],[33.62659,31.82938],[25.63787,31.9359],[25.14001,31.67534],[25.06041,31.57937],[24.83101,31.31921],[25.01077,30.73861],[24.71117,30.17441]]]}},{"type":"Feature","properties":{"id":"CN-JL"},"geometry":{"type":"Polygon","coordinates":[[[121.64337,45.73877],[121.74568,45.68267],[121.95098,45.71097],[121.99836,45.6366],[122.01965,45.48324],[122.16522,45.41484],[122.1453,45.2971],[122.08213,44.91327],[122.11715,44.57237],[122.33001,44.22256],[123.143,44.52294],[123.1327,44.34938],[123.37715,44.15215],[123.3229,44.06045],[123.53301,43.64203],[123.32153,43.48979],[123.68682,43.3756],[123.79806,43.49627],[124.14619,43.2412],[124.28077,43.21268],[124.28832,43.14608],[124.41261,43.06738],[124.35836,42.88854],[124.45793,42.81907],[124.85961,43.17563],[124.84863,42.79086],[124.97909,42.77574],[125.18096,42.29813],[125.25443,42.31387],[125.41854,42.09159],[125.28671,41.9554],[125.32241,41.67034],[125.44738,41.67393],[125.49167,41.53222],[125.54283,41.39767],[125.57544,41.39174],[125.63449,41.33325],[125.63724,41.26877],[125.75225,41.23005],[125.78487,41.16185],[125.63552,40.95086],[125.56892,40.89327],[125.66574,40.91403],[125.71172,40.85223],[125.76869,40.87908],[126.00335,40.92835],[126.242,41.15454],[126.53189,41.35206],[126.60631,41.65565],[126.90729,41.79955],[127.17841,41.59714],[127.29712,41.49473],[127.92943,41.44291],[128.02633,41.42103],[128.03311,41.39232],[128.12967,41.37931],[128.18546,41.41279],[128.20061,41.40895],[128.30716,41.60322],[128.15119,41.74568],[128.04487,42.01769],[128.94007,42.03537],[128.96068,42.06657],[129.15178,42.17224],[129.22285,42.26491],[129.22423,42.3553],[129.28541,42.41574],[129.42882,42.44702],[129.54701,42.37254],[129.60482,42.44461],[129.72541,42.43739],[129.75294,42.59409],[129.77183,42.69435],[129.7835,42.76521],[129.80719,42.79218],[129.83277,42.86746],[129.85261,42.96494],[129.8865,43.00395],[129.95082,43.01051],[129.96409,42.97306],[130.12957,42.98361],[130.09764,42.91425],[130.26095,42.9027],[130.23068,42.80125],[130.2385,42.71127],[130.41826,42.6011],[130.44361,42.54849],[130.50123,42.61636],[130.55143,42.52158],[130.62107,42.58413],[130.56576,42.68925],[130.40213,42.70788],[130.44361,42.76205],[130.66524,42.84753],[131.02438,42.86518],[131.02668,42.91246],[131.135,42.94114],[131.10274,43.04734],[131.20414,43.13654],[131.19031,43.21385],[131.30324,43.39498],[131.29402,43.46695],[130.44616,43.63905],[130.38574,44.03824],[130.07537,43.8048],[129.94903,44.06193],[128.88198,43.50374],[128.43429,44.50825],[127.71331,44.03429],[127.53753,44.55525],[127.03765,44.59242],[127.08846,44.93369],[126.65313,45.23621],[126.00768,45.12296],[125.68771,45.50346],[124.55612,45.41002],[124.13452,45.61692],[123.90655,46.28812],[123.17046,46.2283],[122.79418,45.94064],[122.72003,45.70474],[122.52433,45.7771],[122.39868,45.9139],[122.2586,45.79434],[121.8727,46.04083],[121.75735,45.99505],[121.82121,45.8728],[121.64337,45.73877]]]}},{"type":"Feature","properties":{"id":"ER"},"geometry":{"type":"Polygon","coordinates":[[[36.44337,15.14963],[36.54376,14.25597],[36.56536,14.26177],[36.55659,14.28237],[36.63364,14.31172],[36.85787,14.32201],[37.01622,14.2561],[37.09486,14.27155],[37.13206,14.40746],[37.3106,14.44657],[37.47319,14.2149],[37.528,14.18413],[37.91287,14.89447],[38.0364,14.72745],[38.25562,14.67287],[38.3533,14.51323],[38.45748,14.41445],[38.78306,14.4754],[38.98058,14.54895],[39.02834,14.63717],[39.16074,14.65187],[39.14772,14.61827],[39.19547,14.56996],[39.23888,14.56365],[39.26927,14.48801],[39.2302,14.44598],[39.2519,14.40393],[39.37685,14.54402],[39.52756,14.49011],[39.50585,14.55735],[39.58182,14.60987],[39.76632,14.54264],[39.9443,14.41024],[40.07236,14.54264],[40.14649,14.53969],[40.21128,14.39342],[40.25686,14.41445],[40.9167,14.11152],[41.25097,13.60787],[41.62864,13.38626],[42.05841,12.80912],[42.21469,12.75832],[42.2798,12.6355],[42.4037,12.46478],[42.46941,12.52661],[42.6957,12.36201],[42.7996,12.42629],[42.86195,12.58747],[43.29075,12.79154],[42.63806,13.58268],[41.29956,15.565],[41.37609,16.19728],[39.63762,18.37348],[38.57727,17.98125],[38.45916,17.87167],[38.37133,17.66269],[38.13362,17.53906],[37.50967,17.32199],[37.42694,17.04041],[36.99777,17.07172],[36.92193,16.23451],[36.76371,15.80831],[36.69761,15.75323],[36.54276,15.23478],[36.44337,15.14963]]]}},{"type":"Feature","properties":{"id":"EE"},"geometry":{"type":"Polygon","coordinates":[[[19.84909,57.57876],[22.80496,57.87798],[23.20055,57.56697],[24.26221,57.91787],[24.3579,57.87471],[25.19484,58.0831],[25.28237,57.98539],[25.29581,58.08288],[25.73499,57.90193],[26.05949,57.84744],[26.0324,57.79037],[26.02456,57.78342],[26.027,57.78158],[26.0266,57.77441],[26.02069,57.77169],[26.02415,57.76865],[26.03332,57.7718],[26.0543,57.76105],[26.08098,57.76619],[26.2029,57.7206],[26.1866,57.6849],[26.29253,57.59244],[26.46527,57.56885],[26.54675,57.51813],[26.90364,57.62823],[27.34698,57.52242],[27.31919,57.57672],[27.40393,57.62125],[27.3746,57.66834],[27.52615,57.72843],[27.50171,57.78842],[27.56689,57.83356],[27.78526,57.83963],[27.81841,57.89244],[27.67282,57.92627],[27.62393,58.09462],[27.48541,58.22615],[27.55489,58.39525],[27.36366,58.78381],[27.74429,58.98351],[27.80482,59.1116],[27.87978,59.18097],[27.90911,59.24353],[28.00689,59.28351],[28.14215,59.28934],[28.19284,59.35791],[28.20537,59.36491],[28.21137,59.38058],[28.19061,59.39962],[28.04187,59.47017],[27.85643,59.58538],[26.90044,59.63819],[26.32936,60.00121],[20.5104,59.15546],[19.84909,57.57876]]]}},{"type":"Feature","properties":{"id":"ET"},"geometry":{"type":"Polygon","coordinates":[[[33.0006,7.90333],[33.04944,7.78989],[33.24637,7.77939],[33.32531,7.71297],[33.44745,7.7543],[33.71407,7.65983],[33.87642,7.5491],[34.02984,7.36449],[34.03878,7.27437],[34.01495,7.25664],[34.19369,7.12807],[34.19369,7.04382],[34.35753,6.91963],[34.47669,6.91076],[34.53925,6.82794],[34.53776,6.74808],[34.65096,6.72589],[34.77459,6.5957],[34.87736,6.60161],[35.01738,6.46991],[34.96227,6.26415],[35.00546,5.89387],[35.12611,5.68937],[35.13058,5.62118],[35.31188,5.50106],[35.29938,5.34042],[35.50792,5.42431],[35.8576,5.33413],[35.81968,5.10757],[35.82118,4.77382],[35.9419,4.61933],[35.95449,4.53244],[36.03924,4.44406],[36.84474,4.44518],[37.07724,4.33503],[38.14168,3.62487],[38.45812,3.60445],[38.52336,3.62551],[38.91938,3.51198],[39.07736,3.5267],[39.19954,3.47834],[39.49444,3.45521],[39.51551,3.40895],[39.55132,3.39634],[39.58339,3.47434],[39.76808,3.67058],[39.86043,3.86974],[40.77498,4.27683],[41.1754,3.94079],[41.89488,3.97375],[42.07619,4.17667],[42.55853,4.20518],[42.84526,4.28357],[42.97746,4.44032],[43.04177,4.57923],[43.40263,4.79289],[44.02436,4.9451],[44.98104,4.91821],[47.97917,8.00124],[47.92477,8.00111],[46.99339,7.9989],[44.19222,8.93028],[43.32613,9.59205],[43.23518,9.84605],[43.0937,9.90579],[42.87643,10.18441],[42.69452,10.62672],[42.95776,10.98533],[42.79037,10.98493],[42.75111,11.06992],[42.62989,11.09711],[42.42669,10.98493],[42.13691,10.97586],[42.06302,10.92599],[41.80056,10.97127],[41.8096,11.33606],[41.77727,11.49902],[41.82878,11.72361],[41.95461,11.81157],[42.4037,12.46478],[42.2798,12.6355],[42.21469,12.75832],[42.05841,12.80912],[41.62864,13.38626],[41.25097,13.60787],[40.9167,14.11152],[40.25686,14.41445],[40.21128,14.39342],[40.14649,14.53969],[40.07236,14.54264],[39.9443,14.41024],[39.76632,14.54264],[39.58182,14.60987],[39.50585,14.55735],[39.52756,14.49011],[39.37685,14.54402],[39.2519,14.40393],[39.2302,14.44598],[39.26927,14.48801],[39.23888,14.56365],[39.19547,14.56996],[39.14772,14.61827],[39.16074,14.65187],[39.02834,14.63717],[38.98058,14.54895],[38.78306,14.4754],[38.45748,14.41445],[38.3533,14.51323],[38.25562,14.67287],[38.0364,14.72745],[37.91287,14.89447],[37.528,14.18413],[37.47319,14.2149],[37.3106,14.44657],[37.13206,14.40746],[37.09486,14.27155],[37.01622,14.2561],[36.85787,14.32201],[36.63364,14.31172],[36.55659,14.28237],[36.56536,14.26177],[36.54376,14.25597],[36.44653,13.95666],[36.48824,13.83954],[36.38993,13.56459],[36.24545,13.36759],[36.13374,12.92665],[36.16651,12.88019],[36.14268,12.70879],[36.01458,12.72478],[35.70476,12.67101],[35.24302,11.91132],[35.11492,11.85156],[35.05832,11.71158],[35.09556,11.56278],[34.95704,11.24448],[35.01215,11.19626],[34.93172,10.95946],[34.97789,10.91559],[34.97491,10.86147],[34.86916,10.78832],[34.86618,10.74588],[34.77532,10.69027],[34.77383,10.74588],[34.59062,10.89072],[34.4372,10.781],[34.2823,10.53508],[34.34783,10.23914],[34.32102,10.11599],[34.22718,10.02506],[34.20484,9.9033],[34.13186,9.7492],[34.08717,9.55243],[34.10229,9.50238],[34.14304,9.04654],[34.14453,8.60204],[34.01346,8.50041],[33.89579,8.4842],[33.87195,8.41938],[33.71407,8.3678],[33.66938,8.44442],[33.54575,8.47094],[33.3119,8.45474],[33.19721,8.40317],[33.1853,8.29264],[33.18083,8.13047],[33.08401,8.05822],[33.0006,7.90333]]]}},{"type":"Feature","properties":{"id":"FI"},"geometry":{"type":"Polygon","coordinates":[[[19.08191,60.19152],[20.5104,59.15546],[26.32936,60.00121],[27.44953,60.22766],[27.71177,60.3893],[27.77352,60.52722],[28.47974,60.93365],[28.82816,61.1233],[29.01829,61.17448],[31.10136,62.43042],[31.38369,62.66284],[31.58535,62.91642],[31.29294,63.09035],[31.23244,63.22239],[30.49637,63.46666],[29.98213,63.75795],[30.25437,63.83364],[30.55687,64.09036],[30.4762,64.25728],[30.06279,64.35782],[30.01238,64.57513],[30.12329,64.64862],[30.05271,64.79072],[29.68972,64.80789],[29.61914,65.05993],[29.84096,65.1109],[29.8813,65.22101],[29.61914,65.23791],[29.68972,65.31803],[29.84096,65.56945],[29.74013,65.64025],[29.97205,65.70256],[30.16363,65.66935],[29.91155,66.13863],[28.9839,66.94139],[29.91155,67.51507],[30.02041,67.67523],[29.66955,67.79872],[29.34179,68.06655],[28.62982,68.19816],[28.43941,68.53366],[28.78224,68.86696],[28.45957,68.91417],[28.91738,69.04774],[28.81248,69.11997],[28.8629,69.22395],[29.31664,69.47994],[29.12697,69.69193],[28.36883,69.81658],[28.32849,69.88605],[27.97558,69.99671],[27.95542,70.0965],[27.57226,70.06215],[27.05802,69.92069],[26.64461,69.96565],[26.40261,69.91377],[25.96904,69.68397],[25.69679,69.27039],[25.75729,68.99383],[25.61613,68.89602],[25.42455,68.90328],[25.12206,68.78684],[25.10189,68.63307],[24.93048,68.61102],[24.90023,68.55579],[24.74898,68.65143],[24.18432,68.73936],[24.02299,68.81601],[23.781,68.84514],[23.68017,68.70276],[23.13064,68.64684],[22.53321,68.74393],[22.38367,68.71561],[22.27276,68.89514],[21.63833,69.27485],[21.27827,69.31281],[21.00732,69.22755],[20.98641,69.18809],[21.11099,69.10291],[21.05775,69.0356],[20.72171,69.11874],[20.55258,69.06069],[20.78802,69.03087],[20.91658,68.96764],[20.85104,68.93142],[20.90649,68.89696],[21.03001,68.88969],[22.00429,68.50692],[22.73028,68.40881],[23.10336,68.26551],[23.15377,68.14759],[23.26469,68.15134],[23.40081,68.05545],[23.65793,67.9497],[23.45627,67.85297],[23.54701,67.59306],[23.39577,67.46974],[23.75372,67.43688],[23.75372,67.29914],[23.54701,67.25435],[23.58735,67.20752],[23.56214,67.17038],[23.98563,66.84149],[23.98059,66.79585],[23.89488,66.772],[23.85959,66.56434],[23.63776,66.43568],[23.67591,66.3862],[23.64982,66.30603],[23.71339,66.21299],[23.90497,66.15802],[24.15791,65.85385],[24.14798,65.83466],[24.15107,65.81427],[24.14112,65.39731],[20.15877,63.06556],[19.23413,60.61414],[19.08191,60.19152]]]}},{"type":"Feature","properties":{"id":"NC"},"geometry":{"type":"Polygon","coordinates":[[[157.46481,-18.93777],[158.4748,-21.86428],[166.93331,-23.49588],[173.07304,-22.54607],[162.93363,-17.28904],[157.46481,-18.93777]]]}},{"type":"Feature","properties":{"id":"GF"},"geometry":{"type":"Polygon","coordinates":[[[-54.6084,2.32856],[-54.16286,2.10779],[-53.78743,2.34412],[-52.96539,2.1881],[-52.6906,2.37298],[-52.31787,3.17896],[-51.85573,3.83427],[-51.82312,3.85825],[-51.79599,3.89336],[-51.61983,4.14596],[-51.63798,4.51394],[-51.35485,4.8383],[-53.7094,6.2264],[-54.01074,5.68785],[-54.01877,5.52789],[-54.26916,5.26909],[-54.4717,4.91964],[-54.38444,4.13222],[-54.19367,3.84387],[-54.05128,3.63557],[-53.98914,3.627],[-53.9849,3.58697],[-54.28534,2.67798],[-54.42864,2.42442],[-54.6084,2.32856]]]}},{"type":"Feature","properties":{"id":"MQ"},"geometry":{"type":"Polygon","coordinates":[[[-61.51867,14.96709],[-61.26561,14.25664],[-60.5958,14.23076],[-60.69955,15.22234],[-61.51867,14.96709]]]}},{"type":"Feature","properties":{"id":"GP"},"geometry":{"type":"Polygon","coordinates":[[[-62.17275,16.35721],[-61.81728,15.58058],[-61.44899,15.79571],[-60.95725,15.70997],[-60.71337,16.48911],[-61.44461,16.81958],[-61.83929,16.66647],[-62.17275,16.35721]]]}},{"type":"Feature","properties":{"id":"FX"},"geometry":{"type":"Polygon","coordinates":[[[-5.81385,48.52441],[-1.81005,43.59738],[-1.77289,43.38957],[-1.79319,43.37497],[-1.78332,43.36399],[-1.78714,43.35476],[-1.77068,43.34396],[-1.75334,43.34107],[-1.75079,43.3317],[-1.7397,43.32979],[-1.73074,43.29481],[-1.69407,43.31378],[-1.62481,43.30726],[-1.63052,43.28591],[-1.61341,43.25269],[-1.57674,43.25269],[-1.55963,43.28828],[-1.50992,43.29481],[-1.45289,43.27049],[-1.40942,43.27272],[-1.3758,43.24511],[-1.41562,43.12815],[-1.47555,43.08372],[-1.44067,43.047],[-1.35272,43.02658],[-1.34419,43.09665],[-1.32209,43.1127],[-1.27118,43.11961],[-1.30052,43.09581],[-1.30531,43.06859],[-1.25244,43.04164],[-1.22881,43.05534],[-1.10333,43.0059],[-1.00963,42.99279],[-0.97133,42.96239],[-0.81652,42.95166],[-0.75478,42.96916],[-0.72037,42.92541],[-0.73422,42.91228],[-0.72608,42.89318],[-0.69837,42.87945],[-0.67637,42.88303],[-0.55497,42.77846],[-0.50863,42.82713],[-0.44334,42.79939],[-0.41319,42.80776],[-0.38833,42.80132],[-0.3122,42.84788],[-0.17939,42.78974],[-0.16141,42.79535],[-0.10519,42.72761],[-0.02468,42.68513],[0.17569,42.73424],[0.25336,42.7174],[0.29407,42.67431],[0.36251,42.72282],[0.40214,42.69779],[0.67873,42.69458],[0.65421,42.75872],[0.66121,42.84021],[0.711,42.86372],[0.93089,42.79154],[0.96166,42.80629],[0.98292,42.78754],[1.0804,42.78569],[1.15928,42.71407],[1.35562,42.71944],[1.44197,42.60217],[1.47986,42.61346],[1.46718,42.63296],[1.48043,42.65203],[1.50867,42.64483],[1.55418,42.65669],[1.60085,42.62703],[1.63485,42.62957],[1.6625,42.61982],[1.68267,42.62533],[1.73452,42.61515],[1.72588,42.59098],[1.7858,42.57698],[1.73683,42.55492],[1.72515,42.50338],[1.76335,42.48863],[1.83037,42.48395],[1.88853,42.4501],[1.93663,42.45439],[1.94292,42.44316],[1.94061,42.43333],[1.94084,42.43039],[1.9574,42.42401],[1.96482,42.37787],[2.00488,42.35399],[2.06241,42.35906],[2.11621,42.38393],[2.12789,42.41291],[2.16599,42.42314],[2.20578,42.41633],[2.25551,42.43757],[2.38504,42.39977],[2.43299,42.39423],[2.43508,42.37568],[2.48457,42.33933],[2.54382,42.33406],[2.55516,42.35351],[2.57934,42.35808],[2.6747,42.33974],[2.65311,42.38771],[2.72056,42.42298],[2.75497,42.42578],[2.77464,42.41046],[2.84335,42.45724],[2.85675,42.45444],[2.86983,42.46843],[2.88413,42.45938],[2.92107,42.4573],[2.94283,42.48174],[2.96518,42.46692],[3.03734,42.47363],[3.08167,42.42748],[3.10027,42.42621],[3.11379,42.43646],[3.17156,42.43545],[3.4481,42.4358],[7.52234,41.54558],[8.80584,41.26173],[9.28609,41.32097],[9.62656,41.44198],[9.86526,42.21008],[9.56115,43.20816],[7.50102,43.51859],[7.41855,43.72479],[7.40903,43.7296],[7.41113,43.73156],[7.41291,43.73168],[7.41298,43.73311],[7.41233,43.73439],[7.42062,43.73977],[7.42299,43.74176],[7.42443,43.74087],[7.42809,43.74396],[7.43013,43.74895],[7.43624,43.75014],[7.43708,43.75197],[7.4389,43.75151],[7.4379,43.74963],[7.45448,43.7432],[7.53358,43.53609],[7.63035,43.57419],[7.5289,43.78887],[7.50423,43.84345],[7.49355,43.86551],[7.51162,43.88301],[7.56075,43.89932],[7.56858,43.94506],[7.60771,43.95772],[7.65266,43.9763],[7.66848,43.99943],[7.6597,44.03009],[7.72508,44.07578],[7.66878,44.12795],[7.68694,44.17487],[7.63245,44.17877],[7.62155,44.14881],[7.36364,44.11882],[7.34547,44.14359],[7.27827,44.1462],[7.16929,44.20352],[7.00764,44.23736],[6.98221,44.28289],[6.89171,44.36637],[6.88784,44.42043],[6.94504,44.43112],[6.86233,44.49834],[6.85507,44.53072],[6.96042,44.62129],[6.95133,44.66264],[7.00582,44.69364],[7.07484,44.68073],[7.00401,44.78782],[7.02217,44.82519],[6.93499,44.8664],[6.90774,44.84322],[6.75518,44.89915],[6.74519,44.93661],[6.74791,45.01939],[6.66981,45.02324],[6.62803,45.11175],[6.7697,45.16044],[6.85144,45.13226],[6.96706,45.20841],[7.07074,45.21228],[7.13115,45.25386],[7.10572,45.32924],[7.18019,45.40071],[7.00037,45.509],[6.98948,45.63869],[6.80785,45.71864],[6.80785,45.83265],[6.95315,45.85163],[7.04151,45.92435],[7.00946,45.9944],[6.93862,46.06502],[6.87868,46.03855],[6.89321,46.12548],[6.78968,46.14058],[6.86052,46.28512],[6.77152,46.34784],[6.8024,46.39171],[6.82312,46.42661],[6.53358,46.45431],[6.25432,46.3632],[6.21981,46.31304],[6.24826,46.30175],[6.25137,46.29014],[6.23775,46.27822],[6.24952,46.26255],[6.26749,46.24745],[6.29474,46.26221],[6.31041,46.24417],[6.29663,46.22688],[6.27694,46.21566],[6.26007,46.21165],[6.24821,46.20531],[6.23913,46.20511],[6.23544,46.20714],[6.22175,46.20045],[6.22222,46.19888],[6.21844,46.19837],[6.21603,46.19507],[6.21273,46.19409],[6.21114,46.1927],[6.20539,46.19163],[6.19807,46.18369],[6.19552,46.18401],[6.18707,46.17999],[6.18871,46.16644],[6.18116,46.16187],[6.15305,46.15194],[6.13397,46.1406],[6.09926,46.14373],[6.09199,46.15191],[6.07491,46.14879],[6.05203,46.15191],[6.04564,46.14031],[6.03614,46.13712],[6.01791,46.14228],[5.9871,46.14499],[5.97893,46.13303],[5.95781,46.12925],[5.9641,46.14412],[5.97508,46.15863],[5.98188,46.17392],[5.98846,46.17046],[5.99573,46.18587],[5.96515,46.19638],[5.97542,46.21525],[6.02461,46.23313],[6.03342,46.2383],[6.04602,46.23127],[6.05029,46.23518],[6.0633,46.24583],[6.07072,46.24085],[6.08563,46.24651],[6.10071,46.23772],[6.12446,46.25059],[6.11926,46.2634],[6.1013,46.28512],[6.11697,46.29547],[6.1198,46.31157],[6.13876,46.33844],[6.15738,46.3491],[6.16987,46.36759],[6.15985,46.37721],[6.15016,46.3778],[6.09926,46.40768],[6.06407,46.41676],[6.08427,46.44305],[6.07269,46.46244],[6.1567,46.54402],[6.11084,46.57649],[6.27135,46.68251],[6.38351,46.73171],[6.45209,46.77502],[6.43216,46.80336],[6.46456,46.88865],[6.43341,46.92703],[6.71531,47.0494],[6.68823,47.06616],[6.76788,47.1208],[6.8489,47.15933],[6.9508,47.24338],[6.95108,47.26428],[6.94316,47.28747],[7.05305,47.33304],[7.0564,47.35134],[7.03125,47.36996],[6.87959,47.35335],[6.88542,47.37262],[6.93744,47.40714],[6.93953,47.43388],[7.0024,47.45264],[6.98425,47.49432],[7.0231,47.50522],[7.07425,47.48863],[7.12781,47.50371],[7.16249,47.49025],[7.19583,47.49455],[7.17026,47.44312],[7.24669,47.4205],[7.33526,47.44186],[7.35603,47.43432],[7.40308,47.43638],[7.43088,47.45846],[7.4462,47.46264],[7.4583,47.47216],[7.42923,47.48628],[7.43356,47.49712],[7.47534,47.47932],[7.51076,47.49651],[7.49804,47.51798],[7.5229,47.51644],[7.53199,47.5284],[7.51904,47.53515],[7.50588,47.52856],[7.49691,47.53821],[7.50873,47.54546],[7.51723,47.54578],[7.52831,47.55347],[7.53634,47.55553],[7.55652,47.56779],[7.55689,47.57232],[7.56548,47.57617],[7.56684,47.57785],[7.58386,47.57536],[7.58945,47.59017],[7.59301,47.60058],[7.58851,47.60794],[7.57423,47.61628],[7.5591,47.63849],[7.53384,47.65115],[7.52067,47.66437],[7.51915,47.68335],[7.51266,47.70197],[7.53722,47.71635],[7.54761,47.72912],[7.52921,47.77747],[7.55673,47.87371],[7.62302,47.97898],[7.56966,48.03265],[7.57137,48.12292],[7.6648,48.22219],[7.69022,48.30018],[7.74562,48.32736],[7.73109,48.39192],[7.76833,48.48945],[7.80647,48.51239],[7.80167,48.54758],[7.80057,48.5857],[7.84098,48.64217],[7.89002,48.66317],[7.96812,48.72491],[7.96994,48.75606],[8.01534,48.76085],[8.0326,48.79017],[8.06802,48.78957],[8.10253,48.81829],[8.12813,48.87985],[8.19989,48.95825],[8.20031,48.95856],[8.22604,48.97352],[8.14189,48.97833],[7.97783,49.03161],[7.93641,49.05544],[7.86386,49.03499],[7.79557,49.06583],[7.75948,49.04562],[7.63618,49.05428],[7.62575,49.07654],[7.56416,49.08136],[7.53012,49.09818],[7.49172,49.13915],[7.49473,49.17],[7.44455,49.16765],[7.44052,49.18354],[7.3662,49.17308],[7.35995,49.14399],[7.3195,49.14231],[7.29514,49.11426],[7.23473,49.12971],[7.1593,49.1204],[7.1358,49.1282],[7.12504,49.14253],[7.10384,49.13787],[7.10715,49.15631],[7.07859,49.15031],[7.09007,49.13094],[7.07162,49.1255],[7.06642,49.11415],[7.05548,49.11185],[7.04843,49.11422],[7.04409,49.12123],[7.04662,49.13724],[7.03178,49.15734],[7.0274,49.17042],[7.03459,49.19096],[7.01318,49.19018],[6.97273,49.2099],[6.95963,49.203],[6.94028,49.21641],[6.93831,49.2223],[6.91875,49.22261],[6.89298,49.20863],[6.85939,49.22376],[6.83555,49.21249],[6.85119,49.20038],[6.85016,49.19354],[6.86225,49.18185],[6.84703,49.15734],[6.83385,49.15162],[6.78265,49.16793],[6.73765,49.16375],[6.71137,49.18808],[6.73256,49.20486],[6.71843,49.2208],[6.69274,49.21661],[6.66583,49.28065],[6.60186,49.31055],[6.572,49.35027],[6.58807,49.35358],[6.60091,49.36864],[6.533,49.40748],[6.55404,49.42464],[6.42432,49.47683],[6.40274,49.46546],[6.39168,49.4667],[6.38352,49.46463],[6.36778,49.46937],[6.3687,49.4593],[6.28818,49.48465],[6.27875,49.503],[6.25029,49.50609],[6.2409,49.51408],[6.19543,49.50536],[6.17386,49.50934],[6.15366,49.50226],[6.16115,49.49297],[6.14321,49.48796],[6.12814,49.49365],[6.12346,49.4735],[6.10325,49.4707],[6.09845,49.46351],[6.10072,49.45268],[6.08373,49.45594],[6.07887,49.46399],[6.05553,49.46663],[6.04176,49.44801],[6.02743,49.44845],[6.02648,49.45451],[5.97693,49.45513],[5.96876,49.49053],[5.94224,49.49608],[5.94128,49.50034],[5.86571,49.50015],[5.83389,49.52152],[5.83467,49.52717],[5.84466,49.53027],[5.83648,49.5425],[5.81664,49.53775],[5.80871,49.5425],[5.81838,49.54777],[5.79195,49.55228],[5.77435,49.56298],[5.7577,49.55915],[5.75649,49.54321],[5.64505,49.55146],[5.60909,49.51228],[5.55001,49.52729],[5.46541,49.49825],[5.46734,49.52648],[5.43713,49.5707],[5.3974,49.61596],[5.34837,49.62889],[5.33851,49.61599],[5.3137,49.61225],[5.30214,49.63055],[5.33039,49.6555],[5.31465,49.66846],[5.26232,49.69456],[5.14545,49.70287],[5.09249,49.76193],[4.96714,49.79872],[4.85464,49.78995],[4.86965,49.82271],[4.85134,49.86457],[4.88529,49.9236],[4.78827,49.95609],[4.8382,50.06738],[4.88602,50.15182],[4.83279,50.15331],[4.82438,50.16878],[4.75237,50.11314],[4.70064,50.09384],[4.68695,49.99685],[4.5414,49.96911],[4.51098,49.94659],[4.43488,49.94122],[4.35051,49.95315],[4.31963,49.97043],[4.20532,49.95803],[4.14239,49.98034],[4.13508,50.01976],[4.16294,50.04719],[4.23101,50.06945],[4.20147,50.13535],[4.13561,50.13078],[4.16014,50.19239],[4.15524,50.21103],[4.21945,50.25539],[4.20651,50.27333],[4.17861,50.27443],[4.17347,50.28838],[4.15524,50.2833],[4.16808,50.25786],[4.13665,50.25609],[4.11954,50.30425],[4.10957,50.30234],[4.10237,50.31247],[4.0689,50.3254],[4.0268,50.35793],[3.96771,50.34989],[3.90781,50.32814],[3.84314,50.35219],[3.73911,50.34809],[3.70987,50.3191],[3.71009,50.30305],[3.66976,50.34563],[3.65709,50.36873],[3.67262,50.38663],[3.67494,50.40239],[3.66153,50.45165],[3.64426,50.46275],[3.61014,50.49568],[3.58361,50.49049],[3.5683,50.50192],[3.49509,50.48885],[3.51564,50.5256],[3.47385,50.53397],[3.44629,50.51009],[3.37693,50.49538],[3.28575,50.52724],[3.2729,50.60718],[3.23951,50.6585],[3.264,50.67668],[3.2536,50.68977],[3.26141,50.69151],[3.26063,50.70086],[3.24593,50.71389],[3.22042,50.71019],[3.20845,50.71662],[3.19017,50.72569],[3.20064,50.73547],[3.18811,50.74025],[3.18339,50.74981],[3.16476,50.76843],[3.15017,50.79031],[3.1257,50.78603],[3.11987,50.79188],[3.11206,50.79416],[3.10614,50.78303],[3.09163,50.77717],[3.04314,50.77674],[3.00537,50.76588],[2.96778,50.75242],[2.95019,50.75138],[2.90873,50.702],[2.91036,50.6939],[2.90069,50.69263],[2.88504,50.70656],[2.87937,50.70298],[2.86985,50.7033],[2.8483,50.72276],[2.81056,50.71773],[2.71165,50.81295],[2.63331,50.81457],[2.59093,50.91751],[2.63074,50.94746],[2.57551,51.00326],[2.55904,51.07014],[2.18458,51.52087],[1.17405,50.74239],[-2.02963,49.91866],[-2.09454,49.46288],[-1.83944,49.23037],[-2.00491,48.86706],[-2.5234,48.91595],[-2.56423,49.22209],[-2.9511,49.31141],[-5.81385,48.52441]]]}},{"type":"Feature","properties":{"id":"GA"},"geometry":{"type":"Polygon","coordinates":[[[7.24416,-0.64092],[10.75913,-4.39519],[11.12647,-3.94169],[11.22301,-3.69888],[11.48764,-3.51089],[11.57949,-3.52798],[11.68608,-3.68942],[11.87083,-3.71571],[11.92719,-3.62768],[11.8318,-3.5812],[11.96554,-3.30267],[11.70227,-3.17465],[11.70558,-3.0773],[11.80365,-3.00424],[11.64798,-2.81146],[11.5359,-2.85654],[11.64487,-2.61865],[11.57637,-2.33379],[11.74605,-2.39936],[11.96866,-2.33559],[12.04895,-2.41704],[12.47925,-2.32626],[12.44656,-1.92025],[12.61312,-1.8129],[12.82172,-1.91091],[13.02759,-2.33098],[13.47977,-2.43224],[13.75884,-2.09293],[13.92073,-2.35581],[13.85846,-2.46935],[14.10442,-2.49268],[14.23829,-2.33715],[14.16202,-2.23916],[14.23518,-2.15671],[14.25932,-1.97624],[14.41838,-1.89412],[14.52569,-0.57818],[14.41887,-0.44799],[14.2165,-0.38261],[14.06862,-0.20826],[13.90632,-0.2287],[13.88648,0.26652],[14.10909,0.58563],[14.26066,0.57255],[14.48179,0.9152],[14.25186,1.39842],[13.89582,1.4261],[13.15519,1.23368],[13.25447,1.32339],[13.13461,1.57238],[13.29457,2.16106],[13.28534,2.25716],[11.37116,2.29975],[11.3561,2.17217],[11.35307,1.00251],[9.79648,1.0019],[9.78058,1.03996],[9.76085,1.05949],[9.73014,1.06721],[9.68638,1.06836],[9.66092,1.05865],[9.62096,1.03039],[9.54793,1.0185],[9.51998,0.96418],[9.35563,0.84865],[9.00916,0.69445],[7.24416,-0.64092]]]}},{"type":"Feature","properties":{"id":"MS"},"geometry":{"type":"Polygon","coordinates":[[[-62.52079,16.69392],[-62.17275,16.35721],[-61.83929,16.66647],[-62.14123,17.02632],[-62.52079,16.69392]]]}},{"type":"Feature","properties":{"id":"BM"},"geometry":{"type":"Polygon","coordinates":[[[-65.23529,32.66274],[-65.22652,31.98296],[-64.37503,31.99084],[-64.3838,32.67056],[-65.23529,32.66274]]]}},{"type":"Feature","properties":{"id":"GI"},"geometry":{"type":"Polygon","coordinates":[[[-5.40134,36.14896],[-5.39074,36.10278],[-5.36503,36.06205],[-5.32837,36.05935],[-5.3004,36.07439],[-5.28217,36.09907],[-5.27801,36.14942],[-5.33822,36.15272],[-5.34536,36.15501],[-5.36494,36.15496],[-5.38545,36.15481],[-5.40134,36.14896]]]}},{"type":"Feature","properties":{"id":"GE"},"geometry":{"type":"Polygon","coordinates":[[[39.81147,43.06294],[40.89217,41.72528],[41.54366,41.52185],[41.7148,41.4932],[41.7124,41.47417],[41.81939,41.43621],[41.95134,41.52466],[42.26387,41.49346],[42.51772,41.43606],[42.59202,41.58183],[42.72794,41.59714],[42.84471,41.58912],[42.78995,41.50126],[42.84899,41.47265],[42.8785,41.50516],[43.02956,41.37891],[43.21707,41.30331],[43.13373,41.25503],[43.1945,41.25242],[43.23096,41.17536],[43.36118,41.2028],[43.44973,41.17666],[43.4717,41.12611],[43.67712,41.13398],[43.74717,41.1117],[43.84835,41.16329],[44.16591,41.19141],[44.18148,41.24644],[44.32139,41.2079],[44.34337,41.20312],[44.34417,41.2382],[44.46791,41.18204],[44.59322,41.1933],[44.61462,41.24018],[44.72814,41.20338],[44.82084,41.21513],[44.87887,41.20195],[44.89911,41.21366],[44.84358,41.23088],[44.81749,41.23488],[44.80053,41.25949],[44.81437,41.30371],[44.93493,41.25685],[45.0133,41.29747],[45.09867,41.34065],[45.1797,41.42231],[45.26285,41.46433],[45.31352,41.47168],[45.4006,41.42402],[45.45973,41.45898],[45.68389,41.3539],[45.71035,41.36208],[45.75705,41.35157],[45.69946,41.29545],[45.80842,41.2229],[45.95786,41.17956],[46.13221,41.19479],[46.27698,41.19011],[46.37661,41.10805],[46.456,41.09984],[46.48558,41.0576],[46.55096,41.1104],[46.63969,41.09515],[46.66148,41.20533],[46.72375,41.28609],[46.63658,41.37727],[46.4669,41.43331],[46.40307,41.48464],[46.33925,41.4963],[46.29794,41.5724],[46.34126,41.57454],[46.34039,41.5947],[46.3253,41.60912],[46.28182,41.60089],[46.26531,41.63339],[46.24429,41.59883],[46.19759,41.62327],[46.17891,41.72094],[46.20538,41.77205],[46.23962,41.75811],[46.30863,41.79133],[46.3984,41.84399],[46.42738,41.91323],[45.61676,42.20768],[45.78692,42.48358],[45.36501,42.55268],[45.15318,42.70598],[44.88754,42.74934],[44.80941,42.61277],[44.70002,42.74679],[44.54202,42.75699],[43.95517,42.55396],[43.73119,42.62043],[43.81453,42.74297],[43.0419,43.02413],[43.03322,43.08883],[42.75889,43.19651],[42.66667,43.13917],[42.40563,43.23226],[41.64935,43.22331],[40.65957,43.56212],[40.10657,43.57344],[40.04445,43.47776],[40.03312,43.44262],[40.01007,43.42411],[40.01552,43.42025],[40.00853,43.40578],[40.0078,43.38551],[39.81147,43.06294]]]}},{"type":"Feature","properties":{"id":"GH"},"geometry":{"type":"Polygon","coordinates":[[[-3.34019,4.17519],[1.07031,5.15655],[1.27574,5.93551],[1.19771,6.11522],[1.19966,6.17069],[1.09187,6.17074],[1.05969,6.22998],[1.03108,6.24064],[0.99652,6.33779],[0.89283,6.33779],[0.71048,6.53083],[0.74862,6.56517],[0.63659,6.63857],[0.6497,6.73682],[0.58176,6.76049],[0.57406,6.80348],[0.52853,6.82921],[0.56508,6.92971],[0.52098,6.94391],[0.52217,6.9723],[0.59606,7.01252],[0.65327,7.31643],[0.62943,7.41099],[0.57223,7.39326],[0.52455,7.45354],[0.51979,7.58706],[0.58295,7.62368],[0.62943,7.85751],[0.58891,8.12779],[0.6056,8.13959],[0.61156,8.18324],[0.5913,8.19622],[0.63897,8.25873],[0.73432,8.29529],[0.64731,8.48866],[0.47211,8.59945],[0.37319,8.75262],[0.52455,8.87746],[0.45424,9.04581],[0.56388,9.40697],[0.49118,9.48339],[0.36485,9.49749],[0.33148,9.44812],[0.25758,9.42696],[0.2254,9.47869],[0.31241,9.50337],[0.30406,9.521],[0.2409,9.52335],[0.23851,9.57389],[0.38153,9.58682],[0.36008,9.6256],[0.29334,9.59387],[0.26712,9.66437],[0.28261,9.69022],[0.32313,9.6491],[0.34816,9.66907],[0.34816,9.71607],[0.32075,9.72781],[0.36366,10.03309],[0.41252,10.02018],[0.41371,10.06361],[0.35293,10.09412],[0.39584,10.31112],[0.33028,10.30408],[0.29453,10.41546],[0.18846,10.4096],[0.12886,10.53149],[-0.05945,10.63458],[-0.09141,10.7147],[-0.07327,10.71845],[-0.07183,10.76794],[-0.0228,10.81916],[-0.02685,10.8783],[-0.00908,10.91644],[-0.0063,10.96417],[0.03355,10.9807],[0.02395,11.06229],[0.00342,11.08317],[-0.00514,11.10763],[-0.0275,11.11202],[-0.05733,11.08628],[-0.14462,11.10811],[-0.13493,11.14075],[-0.27374,11.17157],[-0.28566,11.12713],[-0.35955,11.07801],[-0.38219,11.12596],[-0.42391,11.11661],[-0.44298,11.04292],[-0.61937,10.91305],[-0.67143,10.99811],[-2.83373,11.0067],[-2.94232,10.64281],[-2.83108,10.40252],[-2.74174,9.83172],[-2.76534,9.56589],[-2.68802,9.49343],[-2.69814,9.22717],[-2.77799,9.04949],[-2.66357,9.01771],[-2.58243,8.7789],[-2.49037,8.20872],[-2.62901,8.11495],[-2.61232,8.02645],[-2.67787,8.02055],[-2.74819,7.92613],[-2.78395,7.94974],[-2.79467,7.86002],[-2.92339,7.60847],[-2.97822,7.27165],[-2.95438,7.23737],[-3.23327,6.81744],[-3.21954,6.74407],[-3.25999,6.62521],[-3.01896,5.71697],[-2.95323,5.71865],[-2.96671,5.6415],[-2.93132,5.62137],[-2.85378,5.65156],[-2.76614,5.60963],[-2.72737,5.34789],[-2.77625,5.34621],[-2.73074,5.1364],[-2.75502,5.10657],[-2.95261,5.12477],[-2.96554,5.10397],[-3.063,5.13665],[-3.11073,5.12675],[-3.10675,5.08515],[-3.34019,4.17519]]]}},{"type":"Feature","properties":{"id":"GN"},"geometry":{"type":"Polygon","coordinates":[[[-15.96748,10.162],[-14.36218,8.64107],[-13.29911,9.04245],[-13.18586,9.0925],[-13.08953,9.0409],[-12.94095,9.26335],[-12.76788,9.3133],[-12.47254,9.86834],[-12.24262,9.92386],[-12.12634,9.87203],[-11.91023,9.93927],[-11.89624,9.99763],[-11.2118,10.00098],[-10.6534,9.29919],[-10.74484,9.07998],[-10.5783,9.06386],[-10.56197,8.81225],[-10.47707,8.67669],[-10.61422,8.5314],[-10.70565,8.29235],[-10.63934,8.35326],[-10.54891,8.31174],[-10.37257,8.48941],[-10.27575,8.48711],[-10.203,8.47991],[-10.14579,8.52665],[-10.05375,8.50697],[-10.05873,8.42578],[-9.77763,8.54633],[-9.47415,8.35195],[-9.50898,8.18455],[-9.41445,8.02448],[-9.44928,7.9284],[-9.35724,7.74111],[-9.37465,7.62032],[-9.48161,7.37122],[-9.41943,7.41809],[-9.305,7.42056],[-9.20798,7.38109],[-9.18311,7.30461],[-9.09107,7.1985],[-8.93435,7.2824],[-8.85724,7.26019],[-8.8448,7.35149],[-8.72789,7.51429],[-8.67814,7.69428],[-8.55874,7.70167],[-8.55874,7.62525],[-8.47114,7.55676],[-8.4003,7.6285],[-8.21374,7.54466],[-8.09931,7.78626],[-8.13414,7.87991],[-8.06449,8.04989],[-7.94695,8.00925],[-7.99919,8.11023],[-7.98675,8.20134],[-8.062,8.16071],[-8.2411,8.24196],[-8.22991,8.48438],[-7.92518,8.50652],[-7.65653,8.36873],[-7.69882,8.66148],[-7.95503,8.81146],[-7.92518,8.99332],[-7.73862,9.08422],[-7.90777,9.20456],[-7.85056,9.41812],[-8.03463,9.39604],[-8.14657,9.55062],[-8.09434,9.86936],[-8.15652,9.94288],[-8.11921,10.04577],[-8.01225,10.1021],[-7.97971,10.17117],[-7.9578,10.2703],[-8.10207,10.44649],[-8.22711,10.41722],[-8.32614,10.69273],[-8.2667,10.91762],[-8.35083,11.06234],[-8.66923,10.99397],[-8.40058,11.37466],[-8.80854,11.66715],[-8.94784,12.34842],[-9.13689,12.50875],[-9.38067,12.48446],[-9.32097,12.29009],[-9.63938,12.18312],[-9.714,12.0226],[-10.30604,12.24634],[-10.71897,11.91552],[-10.80355,12.1053],[-10.99758,12.24634],[-11.24136,12.01286],[-11.50006,12.17826],[-11.37536,12.40788],[-11.46267,12.44559],[-11.91331,12.42008],[-12.35415,12.32758],[-12.87336,12.51892],[-13.06603,12.49342],[-13.05296,12.64003],[-13.70523,12.68013],[-13.7039,12.60313],[-13.65089,12.49515],[-13.64168,12.42764],[-13.70851,12.24978],[-13.92745,12.24077],[-13.94589,12.16869],[-13.7039,12.00869],[-13.7039,11.70195],[-14.09799,11.63649],[-14.26623,11.67486],[-14.31513,11.60713],[-14.51173,11.49708],[-14.66677,11.51188],[-14.77786,11.36323],[-14.95993,10.99244],[-15.07174,10.89557],[-15.96748,10.162]]]}},{"type":"Feature","properties":{"id":"GM"},"geometry":{"type":"Polygon","coordinates":[[[-17.43966,13.04579],[-16.74676,13.06025],[-16.69343,13.16791],[-15.80355,13.16729],[-15.80478,13.34832],[-15.26908,13.37768],[-15.14917,13.57989],[-14.36795,13.23033],[-13.79409,13.34472],[-13.8955,13.59126],[-14.34721,13.46578],[-14.93719,13.80173],[-15.36504,13.79313],[-15.47902,13.58758],[-17.43598,13.59273],[-17.43966,13.04579]]]}},{"type":"Feature","properties":{"id":"GW"},"geometry":{"type":"Polygon","coordinates":[[[-17.4623,11.92379],[-15.96748,10.162],[-15.07174,10.89557],[-14.95993,10.99244],[-14.77786,11.36323],[-14.66677,11.51188],[-14.51173,11.49708],[-14.31513,11.60713],[-14.26623,11.67486],[-14.09799,11.63649],[-13.7039,11.70195],[-13.7039,12.00869],[-13.94589,12.16869],[-13.92745,12.24077],[-13.70851,12.24978],[-13.64168,12.42764],[-13.65089,12.49515],[-13.7039,12.60313],[-13.70523,12.68013],[-15.17582,12.6847],[-15.67302,12.42974],[-16.20591,12.46157],[-16.38191,12.36449],[-16.70562,12.34803],[-17.4623,11.92379]]]}},{"type":"Feature","properties":{"id":"IN-UP"},"geometry":{"type":"Polygon","coordinates":[[[77.10411,29.50415],[77.14187,29.09577],[77.22358,28.89939],[77.21157,28.8573],[77.2229,28.82091],[77.20985,28.81429],[77.20418,28.80527],[77.20659,28.78451],[77.23839,28.75908],[77.24886,28.75524],[77.25512,28.7558],[77.26006,28.75039],[77.25658,28.7444],[77.25547,28.73861],[77.26057,28.73564],[77.27667,28.73564],[77.28688,28.7248],[77.29083,28.72273],[77.2865,28.7143],[77.29036,28.70602],[77.29628,28.70526],[77.29971,28.71008],[77.3134,28.71366],[77.33207,28.71317],[77.32409,28.69864],[77.33345,28.68147],[77.32997,28.67861],[77.32551,28.67827],[77.32027,28.66234],[77.31988,28.65188],[77.31594,28.64152],[77.34087,28.62299],[77.3419,28.60524],[77.33645,28.60174],[77.33066,28.60098],[77.3246,28.59789],[77.31332,28.59661],[77.31049,28.59085],[77.30422,28.58587],[77.29916,28.58772],[77.29293,28.57634],[77.29886,28.55723],[77.34615,28.51651],[77.37447,28.47035],[77.38752,28.46506],[77.41447,28.47465],[77.42477,28.46122],[77.41584,28.44039],[77.43086,28.4259],[77.45704,28.43586],[77.47361,28.41918],[77.46811,28.3997],[77.4979,28.40891],[77.48828,28.35515],[77.46528,28.30831],[77.53532,28.23725],[77.48794,28.19792],[77.54699,28.17613],[77.47283,28.08409],[77.53635,27.99167],[77.52468,27.9204],[77.28126,27.80689],[77.44331,27.3931],[77.6493,27.24303],[77.67127,27.17341],[77.49412,27.08297],[77.75848,27.00469],[77.41722,26.85776],[77.45704,26.74315],[77.78045,26.92819],[78.04275,26.87001],[78.14575,26.94961],[78.26042,26.92941],[78.21029,26.82407],[78.74999,26.77994],[79.01779,26.63518],[79.12902,26.32665],[78.88458,25.90864],[78.74914,25.73589],[78.82003,25.6375],[78.52752,25.57031],[78.44066,25.56133],[78.30642,25.3707],[78.44306,25.12787],[78.34178,25.08155],[78.30642,24.97454],[78.16635,24.87647],[78.28033,24.5671],[78.2666,24.45277],[78.38882,24.26511],[78.51516,24.39025],[78.80767,24.15677],[78.9759,24.35397],[78.98483,24.44527],[78.87634,24.64483],[78.75686,24.60519],[78.77471,24.86027],[78.65558,24.91197],[78.63395,25.0887],[78.55464,25.26984],[78.42109,25.28164],[78.5464,25.3133],[78.52306,25.36419],[78.57868,25.34961],[78.56975,25.39676],[78.71051,25.45102],[78.66588,25.38807],[78.75789,25.33968],[78.81214,25.43056],[78.73146,25.47086],[78.92681,25.56753],[79.04182,25.1459],[79.31373,25.14404],[79.2794,25.35395],[79.47303,25.27512],[79.39269,25.11731],[79.86442,25.1086],[79.86854,25.23786],[80.29014,25.42281],[80.41648,25.1633],[80.25649,25.02401],[80.61561,25.10425],[80.77972,25.05823],[80.71723,25.14342],[80.88958,25.19375],[80.84426,24.99788],[80.80375,24.94154],[81.22741,24.95431],[81.27822,25.16703],[81.4904,25.07938],[81.56112,25.19748],[81.69605,25.03863],[81.73587,25.05574],[81.79389,25.00783],[81.90376,24.99943],[81.90101,24.88768],[81.95869,24.83301],[82.20691,24.78392],[82.30854,24.60831],[82.42561,24.59458],[82.41634,24.70504],[82.55195,24.65575],[82.69374,24.69755],[82.80361,24.55274],[82.71846,24.52713],[82.71606,24.37305],[82.76618,24.3754],[82.77854,24.29312],[82.71915,24.13876],[82.6752,24.16695],[82.66216,24.12513],[82.70267,24.09693],[82.79708,24.00319],[82.80876,23.96492],[82.95226,23.87642],[83.15963,23.90467],[83.32134,24.10131],[83.4027,24.26793],[83.37387,24.3155],[83.46347,24.36992],[83.39275,24.50027],[83.49883,24.52651],[83.5033,24.73747],[83.39824,24.78735],[83.34125,25.0125],[83.34897,25.17744],[83.41335,25.24966],[83.4621,25.25152],[83.49077,25.28614],[83.64852,25.34464],[83.65917,25.36745],[83.74242,25.40792],[83.76422,25.3859],[83.84593,25.43645],[83.81452,25.45459],[83.871,25.49333],[83.88061,25.51765],[84.05845,25.64833],[84.0921,25.72908],[84.32899,25.70588],[84.38804,25.76959],[84.4749,25.68485],[84.66613,25.74022],[84.54082,25.85737],[84.27955,25.94538],[84.15183,26.03334],[84.02309,26.13848],[84.01245,26.23676],[84.17106,26.26139],[84.17243,26.37495],[83.90258,26.44905],[83.87992,26.5225],[84.05296,26.54891],[84.1254,26.6318],[84.39594,26.61554],[84.30599,26.75082],[84.23973,26.86511],[84.02687,27.08847],[83.83048,27.29552],[83.85595,27.35797],[83.61288,27.47013],[83.39495,27.4798],[83.38872,27.39276],[83.35136,27.33885],[83.29999,27.32778],[83.2673,27.36235],[83.27197,27.38309],[83.19413,27.45632],[82.94938,27.46036],[82.93261,27.50328],[82.74119,27.49838],[82.70378,27.72122],[82.46405,27.6716],[82.06554,27.92222],[81.97214,27.93322],[81.91223,27.84995],[81.47867,28.08303],[81.48179,28.12148],[81.38683,28.17638],[81.32923,28.13521],[81.19847,28.36284],[81.08507,28.38346],[80.89648,28.47237],[80.55142,28.69182],[80.50575,28.6706],[80.52443,28.54897],[80.44504,28.63098],[80.37188,28.63371],[80.12125,28.82346],[80.06957,28.82763],[79.96673,28.70233],[79.79026,28.88736],[79.66529,28.85369],[79.41089,28.85339],[79.40711,28.92854],[79.29416,28.95858],[79.0686,29.15276],[79.00268,29.12127],[78.71429,29.32053],[78.91067,29.45335],[78.52683,29.6248],[78.49044,29.73874],[78.33732,29.79536],[77.98507,29.5418],[77.94181,29.71489],[77.80792,29.67075],[77.70629,29.8722],[77.92945,30.24661],[77.5542,30.40278],[77.58613,30.31006],[77.34443,30.06315],[77.12882,29.75305],[77.10411,29.50415]]]}},{"type":"Feature","properties":{"id":"GQ"},"geometry":{"type":"Polygon","coordinates":[[[5.37613,-1.68343],[5.85762,-1.69667],[7.24416,-0.64092],[9.00916,0.69445],[9.35563,0.84865],[9.51998,0.96418],[9.54793,1.0185],[9.62096,1.03039],[9.66092,1.05865],[9.68638,1.06836],[9.73014,1.06721],[9.76085,1.05949],[9.78058,1.03996],[9.79648,1.0019],[11.35307,1.00251],[11.3561,2.17217],[9.991,2.16561],[9.90749,2.20049],[9.89012,2.20457],[9.84716,2.24676],[9.83238,2.29079],[9.83754,2.32428],[9.82123,2.35097],[9.81162,2.33797],[9.6225,2.44901],[9.22018,3.72052],[8.6479,4.06346],[8.05799,3.48284],[8.0168,1.79377],[6.69416,-0.53945],[5.87114,-1.20569],[5.38965,-1.19244],[5.37613,-1.68343]]]}},{"type":"Feature","properties":{"id":"GT"},"geometry":{"type":"Polygon","coordinates":[[[-92.37213,14.39277],[-90.55276,12.8866],[-90.11344,13.73679],[-90.10505,13.85104],[-89.88937,14.0396],[-89.81807,14.07073],[-89.76103,14.02923],[-89.73251,14.04133],[-89.75569,14.07073],[-89.70756,14.1537],[-89.61844,14.21937],[-89.52397,14.22628],[-89.50614,14.26084],[-89.58814,14.33165],[-89.57441,14.41637],[-89.39028,14.44561],[-89.34776,14.43013],[-89.35189,14.47553],[-89.23719,14.58046],[-89.15653,14.57802],[-89.13132,14.71582],[-89.23467,14.85596],[-89.15149,14.97775],[-89.18048,14.99967],[-89.15149,15.07392],[-88.97343,15.14039],[-88.32467,15.63665],[-88.31459,15.66942],[-88.24022,15.69247],[-88.22552,15.72294],[-88.20359,16.03858],[-88.40779,16.09624],[-88.95358,15.88698],[-89.02415,15.9063],[-89.17418,15.90898],[-89.22683,15.88619],[-89.15025,17.04813],[-89.14985,17.81563],[-90.98678,17.81655],[-90.99199,17.25192],[-91.43809,17.25373],[-91.04436,16.92175],[-90.69064,16.70697],[-90.61212,16.49832],[-90.40499,16.40524],[-90.44567,16.07573],[-91.73182,16.07371],[-92.20983,15.26077],[-92.0621,15.07406],[-92.1454,14.98143],[-92.1423,14.88647],[-92.18161,14.84147],[-92.1454,14.6804],[-92.2261,14.53423],[-92.37213,14.39277]]]}},{"type":"Feature","properties":{"id":"GY"},"geometry":{"type":"Polygon","coordinates":[[[-61.4041,5.95304],[-60.73204,5.20931],[-60.32352,5.21299],[-60.20944,5.28754],[-59.98129,5.07097],[-60.04189,4.69801],[-60.15953,4.53456],[-59.78878,4.45637],[-59.69361,4.34069],[-59.73353,4.20399],[-59.51963,3.91951],[-59.86899,3.57089],[-59.79769,3.37162],[-59.99733,2.92312],[-59.91177,2.36759],[-59.7264,2.27497],[-59.74066,1.87596],[-59.25583,1.40559],[-58.92072,1.31293],[-58.84229,1.17749],[-58.53571,1.29154],[-58.4858,1.48399],[-58.33887,1.58014],[-58.01873,1.51966],[-57.97336,1.64566],[-57.77281,1.73344],[-57.55743,1.69605],[-57.35073,1.98327],[-57.23981,1.95808],[-57.09109,2.01854],[-57.07092,1.95304],[-56.7659,1.89509],[-56.47045,1.95135],[-56.55439,2.02003],[-56.70519,2.02964],[-57.35891,3.32121],[-58.0307,3.95513],[-57.8699,4.89394],[-57.37442,5.0208],[-57.22536,5.15605],[-57.31629,5.33714],[-56.84822,6.73257],[-59.54058,8.6862],[-59.98508,8.53046],[-59.85562,8.35213],[-59.80661,8.28906],[-59.83156,8.23261],[-59.97059,8.20791],[-60.02407,8.04557],[-60.38056,7.8302],[-60.51959,7.83373],[-60.64793,7.56877],[-60.71923,7.55817],[-60.59802,7.33194],[-60.63367,7.25061],[-60.54098,7.14804],[-60.44116,7.20817],[-60.28074,7.1162],[-60.39419,6.94847],[-60.54873,6.8631],[-61.13632,6.70922],[-61.20762,6.58174],[-61.15058,6.19558],[-61.4041,5.95304]]]}},{"type":"Feature","properties":{"id":"HN"},"geometry":{"type":"Polygon","coordinates":[[[-89.35189,14.47553],[-89.34776,14.43013],[-89.04187,14.33644],[-88.94608,14.20207],[-88.85785,14.17763],[-88.815,14.11652],[-88.73182,14.10919],[-88.70661,14.04317],[-88.49738,13.97224],[-88.48982,13.86458],[-88.25791,13.91108],[-88.23018,13.99915],[-88.07641,13.98447],[-88.00331,13.86948],[-87.7966,13.91353],[-87.68821,13.80829],[-87.73106,13.75443],[-87.78148,13.52906],[-87.71657,13.50577],[-87.72115,13.46083],[-87.73841,13.44169],[-87.77354,13.45767],[-87.83467,13.44655],[-87.84675,13.41078],[-87.80177,13.35689],[-87.73714,13.32715],[-87.69751,13.25228],[-87.55124,13.12523],[-87.37107,12.98646],[-87.06306,13.00892],[-87.03785,12.98682],[-86.93197,13.05313],[-86.93383,13.18677],[-86.87066,13.30641],[-86.71267,13.30348],[-86.76812,13.79605],[-86.35219,13.77157],[-86.14801,14.04317],[-86.00685,14.08474],[-86.03458,13.99181],[-85.75477,13.8499],[-85.73964,13.9698],[-85.45762,14.11304],[-85.32149,14.2562],[-85.18602,14.24929],[-85.1575,14.53934],[-84.90082,14.80489],[-84.82596,14.82212],[-84.70119,14.68078],[-84.48373,14.63249],[-84.10584,14.76353],[-83.89551,14.76697],[-83.62101,14.89448],[-83.49268,15.01158],[-83.13724,15.00002],[-83.04763,15.03256],[-82.06974,14.49418],[-81.80642,15.86201],[-83.86109,17.73736],[-88.20359,16.03858],[-88.22552,15.72294],[-88.24022,15.69247],[-88.31459,15.66942],[-88.32467,15.63665],[-88.97343,15.14039],[-89.15149,15.07392],[-89.18048,14.99967],[-89.15149,14.97775],[-89.23467,14.85596],[-89.13132,14.71582],[-89.15653,14.57802],[-89.23719,14.58046],[-89.35189,14.47553]]]}},{"type":"Feature","properties":{"id":"HR"},"geometry":{"type":"Polygon","coordinates":[[[13.05142,45.33128],[13.12821,44.48877],[16.15283,42.18525],[18.45131,42.21682],[18.54128,42.39171],[18.52152,42.42302],[18.43588,42.48556],[18.44307,42.51077],[18.43735,42.55921],[18.36197,42.61423],[18.24318,42.6112],[17.88201,42.83668],[17.80854,42.9182],[17.7948,42.89556],[17.68151,42.92725],[17.6444,42.88641],[17.5392,42.92787],[17.70879,42.97223],[17.64268,43.08595],[17.46986,43.16559],[17.286,43.33065],[17.25579,43.40353],[17.29699,43.44542],[17.24411,43.49376],[17.15828,43.49376],[17.00585,43.58037],[16.80736,43.76011],[16.75316,43.77157],[16.70922,43.84887],[16.55472,43.95326],[16.50528,44.0244],[16.43629,44.02826],[16.43662,44.07523],[16.36864,44.08263],[16.18688,44.27012],[16.21346,44.35231],[16.12969,44.38275],[16.16814,44.40679],[16.10566,44.52586],[16.03012,44.55572],[16.00884,44.58605],[16.05828,44.61538],[15.89348,44.74964],[15.8255,44.71501],[15.72584,44.82334],[15.79472,44.8455],[15.76096,44.87045],[15.74723,44.96818],[15.78568,44.97401],[15.74585,45.0638],[15.78842,45.11519],[15.76371,45.16508],[15.83512,45.22459],[15.98412,45.23088],[16.12153,45.09616],[16.29036,44.99732],[16.35404,45.00241],[16.35863,45.03529],[16.3749,45.05206],[16.38219,45.05139],[16.38309,45.05955],[16.40023,45.1147],[16.4634,45.14522],[16.49155,45.21153],[16.52982,45.22713],[16.5501,45.2212],[16.56559,45.22307],[16.60194,45.23042],[16.64962,45.20714],[16.74845,45.20393],[16.78219,45.19002],[16.81137,45.18434],[16.83804,45.18951],[16.92405,45.27607],[16.9385,45.22742],[17.0415,45.20759],[17.18438,45.14764],[17.24325,45.146],[17.25131,45.14957],[17.26815,45.18444],[17.32092,45.16246],[17.33573,45.14521],[17.41229,45.13335],[17.4498,45.16119],[17.45615,45.12523],[17.47589,45.12656],[17.51469,45.10791],[17.59104,45.10816],[17.66571,45.13408],[17.84826,45.04489],[17.87148,45.04645],[17.93706,45.08016],[17.97336,45.12245],[17.97834,45.13831],[17.99479,45.14958],[18.01594,45.15163],[18.03121,45.12632],[18.1624,45.07654],[18.24387,45.13699],[18.32077,45.1021],[18.41896,45.11083],[18.47939,45.05871],[18.65723,45.07544],[18.78357,44.97741],[18.80661,44.93561],[18.76369,44.93707],[18.76347,44.90669],[18.8704,44.85097],[19.01994,44.85493],[18.98957,44.90645],[19.02871,44.92541],[19.06853,44.89915],[19.15573,44.95409],[19.05205,44.97692],[19.1011,45.01191],[19.07952,45.14668],[19.14063,45.12972],[19.19144,45.17863],[19.43589,45.17137],[19.41941,45.23475],[19.28208,45.23813],[19.10774,45.29547],[18.97446,45.37528],[18.99918,45.49333],[19.08364,45.48804],[19.07471,45.53086],[18.94562,45.53712],[18.88776,45.57253],[18.96691,45.66731],[18.90305,45.71863],[18.85783,45.85493],[18.81394,45.91329],[18.80211,45.87995],[18.6792,45.92057],[18.57483,45.80772],[18.44368,45.73972],[18.12439,45.78905],[18.08869,45.76511],[17.99805,45.79671],[17.87377,45.78522],[17.66545,45.84207],[17.56821,45.93728],[17.35672,45.95209],[17.14592,46.16697],[16.8903,46.28122],[16.8541,46.36255],[16.7154,46.39523],[16.6639,46.45203],[16.59527,46.47524],[16.52604,46.47831],[16.5007,46.49644],[16.44036,46.5171],[16.38771,46.53608],[16.37193,46.55008],[16.29793,46.5121],[16.26733,46.51505],[16.26759,46.50566],[16.23961,46.49653],[16.25124,46.48067],[16.27398,46.42875],[16.27329,46.41467],[16.30162,46.40437],[16.30233,46.37837],[16.18824,46.38282],[16.14859,46.40547],[16.05281,46.39141],[16.05065,46.3833],[16.07314,46.36458],[16.07616,46.3463],[15.97965,46.30652],[15.79284,46.25811],[15.78817,46.21719],[15.75479,46.20336],[15.75436,46.21969],[15.67395,46.22478],[15.6434,46.21396],[15.64904,46.19229],[15.59909,46.14761],[15.6083,46.11992],[15.62317,46.09103],[15.72977,46.04682],[15.71246,46.01196],[15.70327,46.00015],[15.70636,45.92116],[15.67967,45.90455],[15.68383,45.88867],[15.68232,45.86819],[15.70411,45.8465],[15.66662,45.84085],[15.64185,45.82915],[15.57952,45.84953],[15.52234,45.82195],[15.47325,45.8253],[15.47531,45.79802],[15.40836,45.79491],[15.25423,45.72275],[15.30872,45.69014],[15.34919,45.71623],[15.4057,45.64727],[15.38952,45.63682],[15.34214,45.64702],[15.34695,45.63382],[15.31027,45.6303],[15.27747,45.60504],[15.29837,45.5841],[15.30249,45.53224],[15.38188,45.48752],[15.33051,45.45258],[15.27758,45.46678],[15.16862,45.42309],[15.05187,45.49079],[15.02385,45.48533],[14.92266,45.52788],[14.90554,45.47769],[14.81992,45.45913],[14.80124,45.49515],[14.71718,45.53442],[14.68605,45.53006],[14.69694,45.57366],[14.59576,45.62812],[14.60977,45.66403],[14.57397,45.67165],[14.53816,45.6205],[14.5008,45.60852],[14.49769,45.54424],[14.36693,45.48642],[14.32487,45.47142],[14.27681,45.4902],[14.26611,45.48239],[14.24239,45.50607],[14.22371,45.50388],[14.20348,45.46896],[14.07116,45.48752],[14.00578,45.52352],[13.96063,45.50825],[13.99488,45.47551],[13.97309,45.45258],[13.90771,45.45149],[13.88124,45.42637],[13.81742,45.43729],[13.7785,45.46787],[13.67398,45.4436],[13.62902,45.45898],[13.56979,45.4895],[13.45644,45.59464],[13.05142,45.33128]]]}},{"type":"Feature","properties":{"id":"HU"},"geometry":{"type":"Polygon","coordinates":[[[16.10983,46.867],[16.14365,46.8547],[16.15711,46.85434],[16.21892,46.86961],[16.2365,46.87775],[16.2941,46.87137],[16.34547,46.83836],[16.3408,46.80641],[16.31303,46.79838],[16.30966,46.7787],[16.37816,46.69975],[16.42641,46.69228],[16.41863,46.66238],[16.38594,46.6549],[16.39217,46.63673],[16.50139,46.56684],[16.52885,46.53303],[16.52604,46.5051],[16.59527,46.47524],[16.6639,46.45203],[16.7154,46.39523],[16.8541,46.36255],[16.8903,46.28122],[17.14592,46.16697],[17.35672,45.95209],[17.56821,45.93728],[17.66545,45.84207],[17.87377,45.78522],[17.99805,45.79671],[18.08869,45.76511],[18.12439,45.78905],[18.44368,45.73972],[18.57483,45.80772],[18.6792,45.92057],[18.80211,45.87995],[18.81394,45.91329],[18.99712,45.93537],[19.01284,45.96529],[19.0791,45.96458],[19.10388,46.04015],[19.14543,45.9998],[19.28826,45.99694],[19.52473,46.1171],[19.56113,46.16824],[19.66007,46.19005],[19.81491,46.1313],[19.93508,46.17553],[20.01816,46.17696],[20.03533,46.14509],[20.09713,46.17315],[20.26068,46.12332],[20.28324,46.1438],[20.35573,46.16629],[20.45377,46.14405],[20.49718,46.18721],[20.63863,46.12728],[20.76085,46.21002],[20.74574,46.25467],[20.86797,46.28884],[21.06572,46.24897],[21.16872,46.30118],[21.28061,46.44941],[21.26929,46.4993],[21.33214,46.63035],[21.43926,46.65109],[21.5151,46.72147],[21.48935,46.7577],[21.52028,46.84118],[21.59307,46.86935],[21.59581,46.91628],[21.68645,46.99595],[21.648,47.03902],[21.78395,47.11104],[21.94463,47.38046],[22.01055,47.37767],[22.03389,47.42508],[22.00917,47.50492],[22.31816,47.76126],[22.41979,47.7391],[22.46559,47.76583],[22.67247,47.7871],[22.76617,47.8417],[22.77991,47.87211],[22.89849,47.95851],[22.84276,47.98602],[22.87847,48.04665],[22.81804,48.11363],[22.73427,48.12005],[22.66835,48.09162],[22.58733,48.10813],[22.59007,48.15121],[22.49806,48.25189],[22.38133,48.23726],[22.2083,48.42534],[22.14689,48.4005],[21.83339,48.36242],[21.8279,48.33321],[21.72525,48.34628],[21.67134,48.3989],[21.6068,48.50365],[21.44063,48.58456],[21.11516,48.49546],[20.83248,48.5824],[20.5215,48.53336],[20.29943,48.26104],[20.24312,48.2784],[19.92452,48.1283],[19.63338,48.25006],[19.52489,48.19791],[19.47957,48.09437],[19.28182,48.08336],[19.23924,48.0595],[19.01952,48.07052],[18.82176,48.04206],[18.76134,47.97499],[18.76821,47.87469],[18.8506,47.82308],[18.74074,47.8157],[18.66521,47.76772],[18.56496,47.76588],[18.29305,47.73541],[18.02938,47.75665],[17.71215,47.7548],[17.23699,48.02094],[17.16001,48.00636],[17.09786,47.97336],[17.11022,47.92461],[17.08275,47.87719],[17.00997,47.86245],[17.07039,47.81129],[17.05048,47.79377],[17.08893,47.70928],[16.87538,47.68895],[16.86509,47.72268],[16.82938,47.68432],[16.7511,47.67878],[16.72089,47.73469],[16.65679,47.74197],[16.61183,47.76171],[16.54779,47.75074],[16.53514,47.73837],[16.55129,47.72268],[16.4222,47.66537],[16.58699,47.61772],[16.64193,47.63114],[16.71059,47.52692],[16.64821,47.50155],[16.6718,47.46139],[16.57152,47.40868],[16.52414,47.41007],[16.49908,47.39416],[16.45104,47.41181],[16.47782,47.25918],[16.44142,47.25079],[16.43663,47.21127],[16.41739,47.20649],[16.42801,47.18422],[16.4523,47.18812],[16.46442,47.16845],[16.44932,47.14418],[16.52863,47.13974],[16.46134,47.09395],[16.52176,47.05747],[16.43936,47.03548],[16.51369,47.00084],[16.28202,47.00159],[16.27594,46.9643],[16.22403,46.939],[16.19904,46.94134],[16.10983,46.867]]]}},{"type":"Feature","properties":{"id":"IN"},"geometry":{"type":"Polygon","coordinates":[[[68.11329,23.53945],[68.83233,21.42207],[71.96044,11.88348],[72.15131,7.6285],[74.03744,7.70688],[76.72283,7.82138],[77.66782,7.85769],[79.37385,8.98767],[79.45362,9.159],[79.42124,9.80115],[80.48418,10.20786],[93.82619,5.95573],[94.98735,6.60903],[94.6395,14.00732],[93.69443,13.6468],[92.61282,13.95915],[89.13606,21.42955],[89.13927,21.60785],[89.03553,21.77397],[89.07114,22.15335],[88.9367,22.58527],[88.94614,22.66941],[88.9151,22.75228],[88.96713,22.83346],[88.87063,22.95235],[88.88327,23.03885],[88.86377,23.08759],[88.99148,23.21134],[88.71133,23.2492],[88.79254,23.46028],[88.79351,23.50535],[88.74841,23.47361],[88.56507,23.64044],[88.58087,23.87105],[88.66189,23.87607],[88.73743,23.91751],[88.6976,24.14703],[88.74841,24.1959],[88.68801,24.31464],[88.50934,24.32474],[88.12296,24.51301],[88.08786,24.63232],[88.00683,24.66477],[88.15515,24.85806],[88.14004,24.93529],[88.21832,24.96642],[88.27325,24.88796],[88.33917,24.86803],[88.46277,25.07468],[88.44766,25.20149],[88.94067,25.18534],[89.00463,25.26583],[89.01105,25.30303],[88.85278,25.34679],[88.81296,25.51546],[88.677,25.46959],[88.4559,25.59227],[88.45103,25.66245],[88.242,25.80811],[88.13138,25.78773],[88.08804,25.91334],[88.16581,26.0238],[88.1844,26.14417],[88.34757,26.22216],[88.35153,26.29123],[88.51649,26.35923],[88.48749,26.45855],[88.36938,26.48683],[88.35153,26.45241],[88.33093,26.48929],[88.41196,26.63837],[88.4298,26.54489],[88.62144,26.46783],[88.69485,26.38353],[88.67837,26.26291],[88.78961,26.31093],[88.85004,26.23211],[89.05328,26.2469],[88.91321,26.37984],[88.92357,26.40711],[88.95612,26.4564],[89.08899,26.38845],[89.15869,26.13708],[89.35953,26.0077],[89.53515,26.00382],[89.57101,25.9682],[89.63968,26.22595],[89.70201,26.15138],[89.73581,26.15818],[89.77865,26.08387],[89.77728,26.04254],[89.86592,25.93115],[89.80585,25.82489],[89.84388,25.70042],[89.86129,25.61714],[89.81208,25.37244],[89.84086,25.31854],[89.83371,25.29548],[89.87629,25.28337],[89.90478,25.31038],[90.1155,25.22686],[90.40034,25.1534],[90.65042,25.17788],[90.87427,25.15799],[91.25517,25.20677],[91.63648,25.12846],[92.0316,25.1834],[92.33957,25.07593],[92.39147,25.01471],[92.49887,24.88796],[92.38626,24.86055],[92.25854,24.9191],[92.15796,24.54435],[92.11662,24.38997],[91.96603,24.3799],[91.89258,24.14674],[91.82596,24.22345],[91.76004,24.23848],[91.73257,24.14703],[91.65292,24.22095],[91.63782,24.1132],[91.55542,24.08687],[91.37414,24.10693],[91.35741,23.99072],[91.29587,24.0041],[91.22308,23.89616],[91.25192,23.83463],[91.15579,23.6599],[91.28293,23.37538],[91.36453,23.06612],[91.40848,23.07117],[91.4035,23.27522],[91.46615,23.2328],[91.54993,23.01051],[91.61571,22.93929],[91.7324,23.00043],[91.81634,23.08001],[91.76417,23.26619],[91.84789,23.42235],[91.95642,23.47361],[91.95093,23.73284],[92.04706,23.64229],[92.15417,23.73409],[92.26541,23.70392],[92.38214,23.28705],[92.37665,22.9435],[92.5181,22.71441],[92.60029,22.1522],[92.56616,22.13554],[92.60949,21.97638],[92.67532,22.03547],[92.70416,22.16017],[92.86208,22.05456],[92.89504,21.95143],[92.93899,22.02656],[92.99804,21.98964],[92.99255,22.05965],[93.04885,22.20595],[93.15734,22.18687],[93.14224,22.24535],[93.19991,22.25425],[93.18206,22.43716],[93.13537,22.45873],[93.11477,22.54374],[93.134,22.59573],[93.09417,22.69459],[93.134,22.92498],[93.12988,23.05772],[93.2878,23.00464],[93.38478,23.13698],[93.36862,23.35426],[93.38781,23.36139],[93.39981,23.38828],[93.38805,23.4728],[93.43475,23.68299],[93.3908,23.7622],[93.3908,23.92925],[93.36059,23.93176],[93.32351,24.04468],[93.34735,24.10151],[93.41415,24.07854],[93.46633,23.97067],[93.50616,23.94432],[93.62871,24.00922],[93.75952,24.0003],[93.80279,23.92549],[93.92089,23.95812],[94.14081,23.83333],[94.30215,24.23752],[94.32362,24.27692],[94.45279,24.56656],[94.50729,24.59281],[94.5526,24.70764],[94.60204,24.70889],[94.73937,25.00545],[94.74212,25.13606],[94.57458,25.20318],[94.68032,25.47003],[94.80117,25.49359],[95.18556,26.07338],[95.11428,26.1019],[95.12801,26.38397],[95.05798,26.45408],[95.23513,26.68499],[95.30339,26.65372],[95.437,26.7083],[95.81603,27.01335],[95.93002,27.04149],[96.04949,27.19428],[96.15591,27.24572],[96.40779,27.29818],[96.55761,27.29928],[96.73888,27.36638],[96.88445,27.25046],[96.85287,27.2065],[96.89132,27.17474],[97.14675,27.09041],[97.17422,27.14052],[96.91431,27.45752],[96.90112,27.62149],[97.29919,27.92233],[97.35824,27.87256],[97.38845,28.01329],[97.35412,28.06663],[97.31292,28.06784],[97.34547,28.21385],[97.1289,28.3619],[96.98882,28.32564],[96.88445,28.39452],[96.85561,28.4875],[96.6455,28.61657],[96.48895,28.42955],[96.40929,28.51526],[96.61391,28.72742],[96.3626,29.10607],[96.20467,29.02325],[96.18682,29.11087],[96.31316,29.18643],[96.05361,29.38167],[95.84899,29.31464],[95.75149,29.32063],[95.72086,29.20797],[95.50842,29.13487],[95.41091,29.13007],[95.3038,29.13847],[95.26122,29.07727],[95.2214,29.10727],[95.11291,29.09527],[95.0978,29.14446],[94.81353,29.17804],[94.69318,29.31739],[94.2752,29.11687],[94.35897,29.01965],[93.72797,28.68821],[93.44621,28.67189],[93.18069,28.50319],[93.14635,28.37035],[92.93075,28.25671],[92.67486,28.15018],[92.65472,28.07632],[92.73025,28.05814],[92.7275,27.98662],[92.42538,27.80092],[92.32101,27.79363],[92.27432,27.89077],[91.87057,27.7195],[91.84722,27.76325],[91.6469,27.76358],[91.55819,27.6144],[91.65007,27.48287],[92.01132,27.47352],[92.12019,27.27829],[92.04702,27.26861],[92.03457,27.07334],[92.11863,26.893],[92.05523,26.8692],[91.83181,26.87318],[91.50067,26.79223],[90.67715,26.77215],[90.48504,26.8594],[90.39271,26.90704],[90.30402,26.85098],[90.04535,26.72422],[89.86124,26.73307],[89.63369,26.74402],[89.42349,26.83727],[89.3901,26.84225],[89.38319,26.85963],[89.37913,26.86224],[89.1926,26.81329],[89.12825,26.81661],[89.09554,26.89089],[88.95807,26.92668],[88.92301,26.99286],[88.8714,26.97488],[88.86984,27.10937],[88.74219,27.144],[88.91901,27.32483],[88.82981,27.38814],[88.77517,27.45415],[88.88091,27.85192],[88.83559,28.01936],[88.63235,28.12356],[88.54858,28.06057],[88.25332,27.9478],[88.1278,27.95417],[88.13378,27.88015],[88.1973,27.85067],[88.19107,27.79285],[88.04008,27.49223],[88.07277,27.43007],[88.01646,27.21612],[88.01587,27.21388],[87.9887,27.11045],[88.11719,26.98758],[88.13422,26.98705],[88.12302,26.95324],[88.19107,26.75516],[88.1659,26.68177],[88.16452,26.64111],[88.09963,26.54195],[88.09414,26.43732],[88.00895,26.36029],[87.90115,26.44923],[87.89085,26.48565],[87.84193,26.43663],[87.7918,26.46737],[87.76004,26.40711],[87.67893,26.43501],[87.66803,26.40294],[87.59175,26.38342],[87.55274,26.40596],[87.51571,26.43106],[87.46566,26.44058],[87.37314,26.40815],[87.34568,26.34787],[87.26568,26.37294],[87.26587,26.40592],[87.24682,26.4143],[87.18863,26.40558],[87.14751,26.40542],[87.09147,26.45039],[87.0707,26.58571],[87.04691,26.58685],[87.01559,26.53228],[86.95912,26.52076],[86.94543,26.52076],[86.82898,26.43919],[86.76797,26.45892],[86.74025,26.42386],[86.69124,26.45169],[86.62686,26.46891],[86.61313,26.48658],[86.57073,26.49825],[86.54258,26.53819],[86.49726,26.54218],[86.31564,26.61925],[86.26235,26.61886],[86.22513,26.58863],[86.13596,26.60651],[86.02729,26.66756],[85.8492,26.56667],[85.85126,26.60866],[85.83126,26.61134],[85.76907,26.63076],[85.72315,26.67471],[85.73483,26.79613],[85.66239,26.84822],[85.61621,26.86721],[85.59461,26.85161],[85.5757,26.85955],[85.56471,26.84133],[85.47752,26.79292],[85.34302,26.74954],[85.21159,26.75933],[85.18046,26.80519],[85.19291,26.86909],[85.15883,26.86966],[85.02635,26.85381],[85.05592,26.88991],[85.00536,26.89523],[84.97186,26.9149],[84.96687,26.95599],[84.85754,26.98984],[84.82913,27.01989],[84.793,26.9968],[84.64496,27.04669],[84.69166,27.21294],[84.62161,27.33885],[84.29315,27.39],[84.25735,27.44941],[84.21376,27.45218],[84.10791,27.52399],[84.02229,27.43836],[83.93306,27.44939],[83.86182,27.4241],[83.85595,27.35797],[83.61288,27.47013],[83.39495,27.4798],[83.38872,27.39276],[83.35136,27.33885],[83.29999,27.32778],[83.2673,27.36235],[83.27197,27.38309],[83.19413,27.45632],[82.94938,27.46036],[82.93261,27.50328],[82.74119,27.49838],[82.70378,27.72122],[82.46405,27.6716],[82.06554,27.92222],[81.97214,27.93322],[81.91223,27.84995],[81.47867,28.08303],[81.48179,28.12148],[81.38683,28.17638],[81.32923,28.13521],[81.19847,28.36284],[81.08507,28.38346],[80.89648,28.47237],[80.55142,28.69182],[80.50575,28.6706],[80.52443,28.54897],[80.44504,28.63098],[80.37188,28.63371],[80.12125,28.82346],[80.06957,28.82763],[80.05743,28.91479],[80.18085,29.13649],[80.23178,29.11626],[80.26602,29.13938],[80.24112,29.21414],[80.28626,29.20327],[80.31428,29.30784],[80.24322,29.44299],[80.37939,29.57098],[80.41858,29.63581],[80.38428,29.68513],[80.36803,29.73865],[80.41554,29.79451],[80.43458,29.80466],[80.48997,29.79566],[80.56247,29.86661],[80.56957,29.88176],[80.60226,29.95732],[80.67076,29.95732],[80.8778,30.13384],[80.93695,30.18229],[81.03953,30.20059],[80.83343,30.32023],[80.54504,30.44936],[80.20721,30.58541],[79.93255,30.88288],[79.59884,30.93943],[79.22805,31.34963],[79.14016,31.43403],[79.01931,31.42817],[78.77898,31.31209],[78.71032,31.50197],[78.84516,31.60631],[78.69933,31.78723],[78.78036,31.99478],[78.74404,32.00384],[78.68754,32.10256],[78.49609,32.2762],[78.4645,32.45367],[78.38897,32.53938],[78.73916,32.69438],[78.7831,32.46873],[78.96713,32.33655],[78.99322,32.37948],[79.0979,32.38051],[79.13174,32.47766],[79.26768,32.53277],[79.46562,32.69668],[79.14016,33.02545],[79.15252,33.17156],[78.73636,33.56521],[78.67599,33.66445],[78.77349,33.73871],[78.73367,34.01121],[78.65657,34.03195],[78.66225,34.08858],[78.91769,34.15452],[78.99802,34.3027],[79.05364,34.32482],[78.74465,34.45174],[78.56475,34.50835],[78.54964,34.57283],[78.27781,34.61484],[78.18435,34.7998],[78.22692,34.88771],[78.00033,35.23954],[78.03466,35.3785],[78.11664,35.48022],[77.80532,35.52058],[77.70232,35.46244],[77.44277,35.46132],[76.96624,35.5932],[76.84539,35.67356],[76.77323,35.66062],[76.75475,35.52617],[76.85088,35.39754],[76.93465,35.39866],[77.11796,35.05419],[76.99251,34.93349],[76.87193,34.96906],[76.74514,34.92488],[76.74377,34.84039],[76.67648,34.76371],[76.47186,34.78965],[76.15463,34.6429],[76.04614,34.67566],[75.75438,34.51827],[75.38009,34.55021],[75.01479,34.64629],[74.6663,34.703],[74.58083,34.77386],[74.31239,34.79626],[74.12897,34.70073],[73.96423,34.68244],[73.93401,34.63386],[73.93951,34.57169],[73.89419,34.54568],[73.88732,34.48911],[73.74999,34.3781],[73.74862,34.34183],[73.8475,34.32935],[73.90517,34.35317],[73.98208,34.2522],[73.90677,34.10504],[73.88732,34.05105],[73.91341,34.01235],[74.21554,34.03853],[74.25262,34.01577],[74.26086,33.92237],[74.14001,33.83002],[74.05898,33.82089],[74.00891,33.75437],[73.96423,33.73071],[73.98968,33.66155],[73.97367,33.64061],[74.03576,33.56718],[74.10115,33.56392],[74.18121,33.4745],[74.17983,33.3679],[74.08782,33.26232],[74.01366,33.25199],[74.02144,33.18908],[74.15374,33.13477],[74.17571,33.07495],[74.31854,33.02891],[74.34875,32.97823],[74.31227,32.92795],[74.41467,32.90563],[74.45312,32.77755],[74.6289,32.75561],[74.64675,32.82604],[74.7113,32.84219],[74.65345,32.71225],[74.69542,32.66792],[74.64424,32.60985],[74.65251,32.56416],[74.67431,32.56676],[74.68362,32.49298],[74.84725,32.49075],[74.97634,32.45367],[75.03265,32.49538],[75.28259,32.36556],[75.38046,32.26836],[75.25649,32.10187],[75.00793,32.03786],[74.9269,32.0658],[74.86236,32.04485],[74.79919,31.95983],[74.58907,31.87824],[74.47771,31.72227],[74.57498,31.60382],[74.61517,31.55698],[74.59319,31.50197],[74.64713,31.45605],[74.59773,31.4136],[74.53223,31.30321],[74.51629,31.13829],[74.56023,31.08303],[74.60281,31.10419],[74.60006,31.13711],[74.6852,31.12771],[74.67971,31.05479],[74.5616,31.04153],[73.88993,30.36305],[73.95736,30.28466],[73.97225,30.19829],[73.80299,30.06969],[73.58665,30.01848],[73.3962,29.94707],[73.28094,29.56646],[73.05886,29.1878],[73.01337,29.16422],[72.94272,29.02487],[72.40402,28.78283],[72.29495,28.66367],[72.20329,28.3869],[71.9244,28.11555],[71.89921,27.96035],[70.79054,27.68423],[70.60927,28.02178],[70.37307,28.01208],[70.12502,27.8057],[70.03136,27.56627],[69.58519,27.18109],[69.50904,26.74892],[69.88555,26.56836],[70.05584,26.60398],[70.17532,26.55362],[70.17532,26.24118],[70.08193,26.08094],[70.0985,25.93238],[70.2687,25.71156],[70.37444,25.67443],[70.53649,25.68928],[70.60378,25.71898],[70.67382,25.68186],[70.66695,25.39314],[70.89148,25.15064],[70.94002,24.92843],[71.09405,24.69017],[70.97594,24.60904],[71.00341,24.46038],[71.12838,24.42662],[71.04461,24.34657],[70.94985,24.3791],[70.85784,24.30903],[70.88393,24.27398],[70.71502,24.23517],[70.57906,24.27774],[70.5667,24.43787],[70.11712,24.30915],[70.03428,24.172],[69.73335,24.17007],[69.59579,24.29777],[69.29778,24.28712],[69.19341,24.25646],[69.07806,24.29777],[68.97781,24.26021],[68.90914,24.33156],[68.7416,24.31904],[68.74643,23.97027],[68.39339,23.96838],[68.20763,23.85849],[68.11329,23.53945]]]}},{"type":"Feature","properties":{"id":"IR"},"geometry":{"type":"Polygon","coordinates":[[[44.03667,39.39223],[44.1043,39.19842],[44.20946,39.13975],[44.18863,38.93881],[44.30322,38.81581],[44.26155,38.71427],[44.28065,38.6465],[44.32058,38.62752],[44.3207,38.49799],[44.3119,38.37887],[44.38309,38.36117],[44.44386,38.38295],[44.50115,38.33939],[44.42476,38.25763],[44.22509,37.88859],[44.3883,37.85433],[44.45948,37.77065],[44.55498,37.783],[44.62096,37.71985],[44.56887,37.6429],[44.61401,37.60165],[44.58449,37.45018],[44.81021,37.2915],[44.75986,37.21549],[44.7868,37.16644],[44.78319,37.1431],[44.75229,37.11958],[44.81611,37.04383],[44.89862,37.01897],[44.91199,36.91468],[44.90173,36.86096],[44.83479,36.81362],[44.84725,36.77622],[45.01537,36.75128],[45.06985,36.6814],[45.06985,36.62645],[45.00759,36.5402],[45.11811,36.40751],[45.23953,36.43257],[45.27394,36.35846],[45.26261,36.3001],[45.30038,36.27769],[45.32235,36.17383],[45.37312,36.09917],[45.37652,36.06222],[45.33916,35.99424],[45.38275,35.97156],[45.46594,36.00042],[45.55245,35.99943],[45.60018,35.96069],[45.6645,35.92872],[45.76145,35.79898],[45.81442,35.82107],[45.89784,35.83708],[45.94711,35.82218],[46.08325,35.8581],[46.17198,35.8013],[46.32921,35.82655],[46.34166,35.78363],[46.23736,35.71414],[46.01631,35.69139],[46.0117,35.65059],[45.99452,35.63574],[46.0165,35.61501],[46.01307,35.59756],[46.03028,35.57416],[45.97584,35.58132],[46.01518,35.52012],[45.98453,35.49848],[46.05358,35.38568],[46.13152,35.32548],[46.15474,35.2883],[46.11367,35.23729],[46.18457,35.22561],[46.19738,35.18536],[46.16229,35.16984],[46.15642,35.1268],[46.19116,35.11097],[46.11763,35.07551],[46.07747,35.0838],[46.06508,35.03699],[45.94756,35.09188],[45.93108,35.08148],[45.92203,35.09538],[45.92173,35.0465],[45.87864,35.03441],[45.89477,34.95805],[45.86532,34.89858],[45.78904,34.91135],[45.79682,34.85133],[45.73641,34.83975],[45.70031,34.82322],[45.68284,34.76624],[45.65672,34.7222],[45.70031,34.69277],[45.73923,34.54416],[45.60224,34.55057],[45.59074,34.55558],[45.53219,34.60441],[45.51883,34.47692],[45.43879,34.45949],[45.46697,34.38221],[45.49171,34.3439],[45.53552,34.35148],[45.58667,34.30147],[45.56176,34.15088],[45.47264,34.03099],[45.41077,33.97421],[45.42789,33.9458],[45.50261,33.94968],[45.77814,33.60938],[45.89801,33.63661],[45.96183,33.55751],[45.86687,33.49263],[45.99919,33.5082],[46.20623,33.20395],[46.11905,33.11924],[46.05367,33.13097],[46.03966,33.09577],[46.15175,33.07229],[46.09103,32.98354],[46.17198,32.95612],[46.32298,32.9731],[46.46788,32.91992],[47.17218,32.45393],[47.37529,32.47808],[47.57144,32.20583],[47.52474,32.15972],[47.64771,32.07666],[47.86337,31.78422],[47.6804,31.39086],[47.68219,31.00004],[48.03221,30.9967],[48.02443,30.4789],[48.14585,30.44133],[48.18321,30.39703],[48.19425,30.32796],[48.21279,30.31644],[48.24385,30.33846],[48.26393,30.3408],[48.41117,30.19846],[48.41671,30.17254],[48.38714,30.13485],[48.38869,30.11062],[48.43384,30.08233],[48.4494,30.04456],[48.44785,30.00148],[48.51011,29.96238],[48.61441,29.93675],[48.83867,29.78572],[49.98877,27.87827],[50.37726,27.89227],[54.39838,25.68383],[55.14145,25.62624],[55.81777,26.18798],[56.2644,26.58649],[56.68954,26.76645],[56.79239,26.41236],[56.82555,25.7713],[56.86325,25.03856],[61.5251,24.57287],[61.57592,25.0492],[61.6433,25.27541],[61.683,25.66638],[61.83968,25.7538],[61.83831,26.07249],[61.89391,26.26251],[62.05117,26.31647],[62.21304,26.26601],[62.31484,26.528],[62.77352,26.64099],[63.1889,26.65072],[63.18688,26.83844],[63.25005,26.84212],[63.25005,27.08692],[63.32283,27.14437],[63.19649,27.25674],[62.80604,27.22412],[62.79684,27.34381],[62.84905,27.47627],[62.7638,28.02992],[62.79412,28.28108],[62.59499,28.24842],[62.40259,28.42703],[61.93581,28.55284],[61.65978,28.77937],[61.53765,29.00507],[61.31508,29.38903],[60.87231,29.86514],[61.80829,30.84224],[61.78268,30.92724],[61.8335,30.97669],[61.83257,31.0452],[61.80957,31.12576],[61.80569,31.16167],[61.70929,31.37391],[60.84541,31.49561],[60.86191,32.22565],[60.56485,33.12944],[60.88908,33.50219],[60.91133,33.55596],[60.69573,33.56054],[60.57762,33.59772],[60.5485,33.73422],[60.5838,33.80793],[60.50209,34.13992],[60.66502,34.31539],[60.91321,34.30411],[60.72316,34.52857],[60.99922,34.63064],[61.00197,34.70631],[61.06926,34.82139],[61.12831,35.09938],[61.0991,35.27845],[61.18187,35.30249],[61.27371,35.61482],[61.22719,35.67038],[61.26152,35.80749],[61.22444,35.92879],[61.12007,35.95992],[61.22719,36.12759],[61.1393,36.38782],[61.18187,36.55348],[61.14516,36.64644],[60.34767,36.63214],[60.00768,37.04102],[59.74678,37.12499],[59.55178,37.13594],[59.39385,37.34257],[59.39797,37.47892],[59.33507,37.53146],[59.22905,37.51161],[58.9338,37.67374],[58.6921,37.64548],[58.5479,37.70526],[58.47786,37.6433],[58.39959,37.63134],[58.22999,37.6856],[58.21399,37.77281],[57.79534,37.89299],[57.35042,37.98546],[57.37236,38.09321],[57.21169,38.28965],[57.03453,38.18717],[56.73928,38.27887],[56.62255,38.24005],[56.43303,38.26054],[56.32454,38.18502],[56.33278,38.08132],[55.97847,38.08024],[55.76561,38.12238],[55.44152,38.08564],[55.13412,37.94705],[54.851,37.75739],[54.77684,37.62264],[54.81804,37.61285],[54.77822,37.51597],[54.67247,37.43532],[54.58664,37.45809],[54.36211,37.34912],[54.24565,37.32047],[53.89734,37.3464],[49.20805,38.40869],[48.88288,38.43975],[48.84969,38.45015],[48.81072,38.44853],[48.78979,38.45026],[48.70001,38.40564],[48.62217,38.40198],[48.58793,38.45076],[48.45084,38.61013],[48.3146,38.59958],[48.24773,38.71883],[48.02581,38.82705],[48.01409,38.90333],[48.07734,38.91616],[48.08627,38.94434],[48.28437,38.97186],[48.33884,39.03022],[48.31239,39.09278],[48.15361,39.19419],[48.12404,39.25208],[48.15984,39.30028],[48.37385,39.37584],[48.34264,39.42935],[47.98977,39.70999],[47.84774,39.66285],[47.50099,39.49615],[47.38978,39.45999],[47.31301,39.37492],[47.05927,39.24846],[47.05771,39.20143],[46.95341,39.13505],[46.92539,39.16644],[46.83822,39.13143],[46.75752,39.03231],[46.53497,38.86548],[46.34059,38.92076],[46.20601,38.85262],[46.14785,38.84206],[46.06766,38.87861],[46.00228,38.87376],[45.94624,38.89072],[45.90266,38.87739],[45.83883,38.90768],[45.65172,38.95199],[45.6155,38.94304],[45.6131,38.964],[45.44966,38.99243],[45.44811,39.04927],[45.40452,39.07224],[45.40148,39.09007],[45.30489,39.18333],[45.16168,39.21952],[45.08751,39.35052],[45.05932,39.36435],[44.96746,39.42998],[44.88916,39.59653],[44.81043,39.62677],[44.71806,39.71124],[44.65422,39.72163],[44.6137,39.78393],[44.47298,39.68788],[44.48111,39.61579],[44.41849,39.56659],[44.42832,39.4131],[44.37921,39.4131],[44.29818,39.378],[44.22452,39.4169],[44.03667,39.39223]]]}},{"type":"Feature","properties":{"id":"IQ"},"geometry":{"type":"Polygon","coordinates":[[[38.79171,33.37328],[39.08202,32.50304],[38.98762,32.47694],[39.04251,32.30203],[39.26157,32.35555],[39.29903,32.23259],[40.01521,32.05667],[42.97601,30.72204],[42.97796,30.48295],[44.72255,29.19736],[46.42415,29.05947],[46.5527,29.10283],[46.89695,29.50584],[47.15166,30.01044],[47.37192,30.10421],[47.7095,30.10453],[48.01114,29.98906],[48.06782,30.02906],[48.17332,30.02448],[48.40479,29.85763],[48.59531,29.66815],[48.83867,29.78572],[48.61441,29.93675],[48.51011,29.96238],[48.44785,30.00148],[48.4494,30.04456],[48.43384,30.08233],[48.38869,30.11062],[48.38714,30.13485],[48.41671,30.17254],[48.41117,30.19846],[48.26393,30.3408],[48.24385,30.33846],[48.21279,30.31644],[48.19425,30.32796],[48.18321,30.39703],[48.14585,30.44133],[48.02443,30.4789],[48.03221,30.9967],[47.68219,31.00004],[47.6804,31.39086],[47.86337,31.78422],[47.64771,32.07666],[47.52474,32.15972],[47.57144,32.20583],[47.37529,32.47808],[47.17218,32.45393],[46.46788,32.91992],[46.32298,32.9731],[46.17198,32.95612],[46.09103,32.98354],[46.15175,33.07229],[46.03966,33.09577],[46.05367,33.13097],[46.11905,33.11924],[46.20623,33.20395],[45.99919,33.5082],[45.86687,33.49263],[45.96183,33.55751],[45.89801,33.63661],[45.77814,33.60938],[45.50261,33.94968],[45.42789,33.9458],[45.41077,33.97421],[45.47264,34.03099],[45.56176,34.15088],[45.58667,34.30147],[45.53552,34.35148],[45.49171,34.3439],[45.46697,34.38221],[45.43879,34.45949],[45.51883,34.47692],[45.53219,34.60441],[45.59074,34.55558],[45.60224,34.55057],[45.73923,34.54416],[45.70031,34.69277],[45.65672,34.7222],[45.68284,34.76624],[45.70031,34.82322],[45.73641,34.83975],[45.79682,34.85133],[45.78904,34.91135],[45.86532,34.89858],[45.89477,34.95805],[45.87864,35.03441],[45.92173,35.0465],[45.92203,35.09538],[45.93108,35.08148],[45.94756,35.09188],[46.06508,35.03699],[46.07747,35.0838],[46.11763,35.07551],[46.19116,35.11097],[46.15642,35.1268],[46.16229,35.16984],[46.19738,35.18536],[46.18457,35.22561],[46.11367,35.23729],[46.15474,35.2883],[46.13152,35.32548],[46.05358,35.38568],[45.98453,35.49848],[46.01518,35.52012],[45.97584,35.58132],[46.03028,35.57416],[46.01307,35.59756],[46.0165,35.61501],[45.99452,35.63574],[46.0117,35.65059],[46.01631,35.69139],[46.23736,35.71414],[46.34166,35.78363],[46.32921,35.82655],[46.17198,35.8013],[46.08325,35.8581],[45.94711,35.82218],[45.89784,35.83708],[45.81442,35.82107],[45.76145,35.79898],[45.6645,35.92872],[45.60018,35.96069],[45.55245,35.99943],[45.46594,36.00042],[45.38275,35.97156],[45.33916,35.99424],[45.37652,36.06222],[45.37312,36.09917],[45.32235,36.17383],[45.30038,36.27769],[45.26261,36.3001],[45.27394,36.35846],[45.23953,36.43257],[45.11811,36.40751],[45.00759,36.5402],[45.06985,36.62645],[45.06985,36.6814],[45.01537,36.75128],[44.84725,36.77622],[44.83479,36.81362],[44.90173,36.86096],[44.91199,36.91468],[44.89862,37.01897],[44.81611,37.04383],[44.75229,37.11958],[44.78319,37.1431],[44.76698,37.16162],[44.63179,37.19229],[44.42631,37.05825],[44.38117,37.05825],[44.35315,37.04955],[44.35937,37.02843],[44.30645,36.97373],[44.25975,36.98119],[44.18503,37.09551],[44.22239,37.15756],[44.27998,37.16501],[44.2613,37.25055],[44.13521,37.32486],[44.02002,37.33229],[43.90949,37.22453],[43.84878,37.22205],[43.82699,37.19477],[43.8052,37.22825],[43.7009,37.23692],[43.63085,37.21957],[43.56702,37.25675],[43.50787,37.24436],[43.33508,37.33105],[43.30083,37.30629],[43.11403,37.37436],[42.93705,37.32015],[42.78887,37.38615],[42.56725,37.14878],[42.35724,37.10998],[42.36697,37.0627],[41.81736,36.58782],[41.40058,36.52502],[41.28864,36.35368],[41.2564,36.06012],[41.37027,35.84095],[41.38184,35.62502],[41.26569,35.42708],[41.21654,35.1508],[41.2345,34.80049],[41.12388,34.65742],[40.97676,34.39788],[40.64314,34.31604],[38.79171,33.37328]]]}},{"type":"Feature","properties":{"id":"IL"},"geometry":{"type":"Polygon","coordinates":[[[33.62659,31.82938],[34.052,31.46619],[34.29262,31.70393],[34.48681,31.59711],[34.56797,31.54197],[34.48892,31.48365],[34.40077,31.40926],[34.36505,31.36404],[34.37381,31.30598],[34.36523,31.28963],[34.29417,31.24194],[34.26742,31.21998],[34.92298,29.45305],[34.97718,29.54294],[34.98207,29.58147],[35.02147,29.66343],[35.14108,30.07374],[35.19183,30.34636],[35.16218,30.43535],[35.19595,30.50297],[35.21379,30.60401],[35.29311,30.71365],[35.33456,30.81224],[35.33984,30.8802],[35.41371,30.95565],[35.43658,31.12444],[35.40316,31.25535],[35.47672,31.49578],[35.39675,31.49572],[35.22921,31.37445],[35.13033,31.3551],[35.02459,31.35979],[34.92571,31.34337],[34.88932,31.37093],[34.87833,31.39321],[34.89756,31.43891],[34.93258,31.47816],[34.94356,31.50743],[34.9415,31.55601],[34.95249,31.59813],[35.00879,31.65426],[35.08226,31.69107],[35.10782,31.71594],[35.11895,31.71454],[35.12933,31.7325],[35.13931,31.73012],[35.15119,31.73634],[35.15474,31.73352],[35.16478,31.73242],[35.18023,31.72067],[35.20538,31.72388],[35.21937,31.71578],[35.22392,31.71899],[35.23972,31.70896],[35.24315,31.71244],[35.2438,31.7201],[35.24981,31.72543],[35.25182,31.73945],[35.26319,31.74846],[35.25225,31.7678],[35.26058,31.79064],[35.25573,31.81362],[35.26404,31.82567],[35.251,31.83085],[35.25753,31.8387],[35.24816,31.8458],[35.2304,31.84222],[35.2249,31.85433],[35.22817,31.8638],[35.22567,31.86745],[35.22294,31.87889],[35.22014,31.88264],[35.2136,31.88241],[35.21276,31.88153],[35.21016,31.88237],[35.20945,31.8815],[35.20791,31.8821],[35.20673,31.88151],[35.20381,31.86716],[35.21128,31.863],[35.216,31.83894],[35.21469,31.81835],[35.19461,31.82687],[35.18169,31.82542],[35.18603,31.80901],[35.14174,31.81325],[35.07677,31.85627],[35.05617,31.85685],[35.01978,31.82944],[34.9724,31.83352],[34.99712,31.85569],[35.03489,31.85919],[35.03978,31.89276],[35.03489,31.92448],[35.00124,31.93264],[34.98682,31.96935],[35.00261,32.027],[34.9863,32.09551],[34.99437,32.10962],[34.98507,32.12606],[34.99039,32.14626],[34.96009,32.17503],[34.95703,32.19522],[34.98885,32.20758],[35.01841,32.23981],[35.02939,32.2671],[35.01119,32.28684],[35.01772,32.33863],[35.04243,32.35008],[35.05142,32.3667],[35.0421,32.38242],[35.05311,32.4024],[35.05423,32.41754],[35.07059,32.4585],[35.08564,32.46948],[35.09236,32.47614],[35.10024,32.47856],[35.10882,32.4757],[35.15937,32.50466],[35.2244,32.55289],[35.25049,32.52453],[35.29306,32.50947],[35.30685,32.51024],[35.35212,32.52047],[35.40224,32.50136],[35.42034,32.46009],[35.41598,32.45593],[35.41048,32.43706],[35.42078,32.41562],[35.55807,32.38674],[35.55494,32.42687],[35.57485,32.48669],[35.56614,32.64393],[35.59813,32.65159],[35.61669,32.67999],[35.66527,32.681],[35.68467,32.70715],[35.75983,32.74803],[35.78745,32.77938],[35.83758,32.82817],[35.84021,32.8725],[35.87012,32.91976],[35.89298,32.9456],[35.87188,32.98028],[35.84802,33.1031],[35.81911,33.11077],[35.81911,33.1336],[35.84285,33.16673],[35.83846,33.19397],[35.81647,33.2028],[35.81295,33.24841],[35.77513,33.27342],[35.813,33.3172],[35.77477,33.33609],[35.62019,33.27278],[35.62283,33.24226],[35.58502,33.26653],[35.58326,33.28381],[35.56523,33.28969],[35.55555,33.25844],[35.54544,33.25513],[35.54808,33.236],[35.5362,33.23196],[35.54228,33.19865],[35.52573,33.11921],[35.50335,33.114],[35.50272,33.09056],[35.448,33.09264],[35.43059,33.06659],[35.35223,33.05617],[35.31429,33.10515],[35.1924,33.08743],[35.10645,33.09318],[34.78515,33.20368],[33.62659,31.82938]]]}},{"type":"Feature","properties":{"id":"JM"},"geometry":{"type":"Polygon","coordinates":[[[-78.75694,18.78765],[-78.34606,16.57862],[-75.50728,17.08879],[-76.34192,18.86145],[-78.75694,18.78765]]]}},{"type":"Feature","properties":{"id":"CN-SN"},"geometry":{"type":"Polygon","coordinates":[[[105.47878,32.89406],[105.62461,32.70526],[106.04484,32.86805],[106.11007,32.72144],[106.43073,32.6307],[106.85851,32.71855],[107.1009,32.67174],[107.1215,32.48543],[107.25677,32.40779],[107.42362,32.55433],[107.97569,32.13782],[108.25309,32.28365],[108.50234,32.20641],[109.20066,31.85248],[109.27619,31.71823],[109.58381,31.72933],[109.62364,32.10177],[109.49901,32.3028],[109.55703,32.48543],[109.71393,32.61508],[110.04524,32.55144],[110.19218,32.62029],[110.13725,32.81238],[110.03391,32.86041],[110.02481,32.87482],[109.86259,32.911],[109.79049,32.87929],[109.75925,32.91273],[109.79324,33.0691],[109.42794,33.15479],[109.61299,33.2783],[110.03974,33.19158],[110.16197,33.20996],[110.22926,33.15882],[110.46958,33.17721],[110.55713,33.26653],[110.7003,33.09384],[110.9801,33.2605],[111.0189,33.56771],[110.84106,33.67978],[110.587,33.89093],[110.6385,34.18056],[110.35388,34.519],[110.41122,34.58432],[110.23921,34.62784],[110.2272,34.90733],[110.36041,35.139],[110.40572,35.30728],[110.61035,35.64948],[110.43594,36.1606],[110.4895,36.56039],[110.39474,36.99816],[110.74665,37.45169],[110.77377,37.62946],[110.58357,37.92578],[110.49636,38.02862],[110.5149,38.20905],[110.80192,38.44713],[110.87333,38.45842],[110.88775,38.65522],[110.95745,38.75836],[111.00963,38.90706],[110.97495,38.97836],[111.04637,39.02158],[111.09134,39.02985],[111.1576,39.10741],[111.23897,39.30003],[111.19228,39.30508],[111.11881,39.36403],[111.09289,39.35859],[111.04808,39.43022],[111.15074,39.58478],[110.88363,39.50854],[110.68759,39.26522],[110.59661,39.27744],[110.52005,39.3834],[110.43662,39.38261],[110.38135,39.30826],[110.23063,39.4566],[110.10944,39.42876],[110.20866,39.28488],[109.89795,39.14683],[109.70809,39.05011],[109.55428,38.80119],[108.9624,38.35673],[108.93356,38.17883],[109.18521,38.03592],[109.02831,38.01618],[108.93836,37.9182],[108.83193,38.0662],[108.78936,37.68436],[108.01174,37.66561],[107.96607,37.79269],[107.66139,37.87999],[107.2705,37.47921],[107.30346,37.0979],[107.34878,36.90378],[108.6589,36.41023],[108.64654,35.95021],[108.58886,35.31176],[107.84248,35.26524],[107.7079,35.30896],[107.8466,34.97487],[107.18604,34.9062],[107.05833,35.02887],[106.76788,35.09238],[106.48635,35.05754],[106.5612,34.74443],[106.33186,34.55972],[106.3322,34.51532],[106.47399,34.52183],[106.6175,34.44797],[106.64188,34.38651],[106.71295,34.37092],[106.41357,33.89777],[106.58523,33.57],[106.51519,33.50246],[106.36688,33.61347],[105.95764,33.61061],[105.72624,33.36322],[105.96244,33.15652],[105.85945,32.93896],[105.47878,32.89406]]]}},{"type":"Feature","properties":{"id":"JO"},"geometry":{"type":"Polygon","coordinates":[[[34.88293,29.37455],[34.95987,29.35727],[36.07081,29.18469],[36.50005,29.49696],[36.75083,29.86903],[37.4971,29.99949],[37.66395,30.33245],[37.99354,30.49998],[36.99791,31.50081],[38.99233,31.99721],[39.29903,32.23259],[39.26157,32.35555],[39.04251,32.30203],[38.98762,32.47694],[39.08202,32.50304],[38.79171,33.37328],[36.83946,32.31293],[36.40959,32.37908],[36.23948,32.50108],[36.20875,32.49529],[36.20379,32.52751],[36.08074,32.51463],[36.02239,32.65911],[35.96633,32.66237],[35.93307,32.71966],[35.88405,32.71321],[35.75983,32.74803],[35.68467,32.70715],[35.66527,32.681],[35.61669,32.67999],[35.59813,32.65159],[35.56614,32.64393],[35.57485,32.48669],[35.55494,32.42687],[35.55807,32.38674],[35.57111,32.21877],[35.52012,32.04076],[35.54375,31.96587],[35.52758,31.9131],[35.55941,31.76535],[35.47672,31.49578],[35.40316,31.25535],[35.43658,31.12444],[35.41371,30.95565],[35.33984,30.8802],[35.33456,30.81224],[35.29311,30.71365],[35.21379,30.60401],[35.19595,30.50297],[35.16218,30.43535],[35.19183,30.34636],[35.14108,30.07374],[35.02147,29.66343],[34.98207,29.58147],[34.97718,29.54294],[34.92298,29.45305],[34.88293,29.37455]]]}},{"type":"Feature","properties":{"id":"CN-BJ"},"geometry":{"type":"Polygon","coordinates":[[[115.41755,39.77925],[115.47042,39.74177],[115.51574,39.6041],[115.66268,39.60833],[115.74851,39.51251],[115.81031,39.50933],[115.91365,39.57552],[116.22058,39.5787],[116.23809,39.51649],[116.32942,39.4566],[116.43722,39.44494],[116.46366,39.52946],[116.52065,39.59193],[116.80732,39.61415],[116.89075,39.69714],[116.95083,39.65434],[117.14137,39.61203],[117.19493,39.75999],[117.14755,39.81723],[117.26154,39.83385],[117.13897,39.8797],[117.19425,40.07281],[117.40608,40.17362],[117.34291,40.23131],[117.32814,40.2879],[117.29587,40.27612],[117.21811,40.36616],[117.22824,40.41245],[117.25913,40.43701],[117.20626,40.50126],[117.25227,40.50857],[117.24781,40.54902],[117.3072,40.57719],[117.40882,40.56206],[117.41432,40.63701],[117.42977,40.61851],[117.44419,40.65042],[117.47749,40.63167],[117.51663,40.65069],[117.43972,40.68532],[117.30789,40.65199],[117.21794,40.69938],[116.98379,40.68896],[116.62605,41.06485],[116.6209,40.97989],[116.44306,40.98145],[116.47602,40.89586],[116.31465,40.93037],[116.46537,40.7652],[116.24565,40.79067],[116.11278,40.62646],[115.82267,40.5871],[115.81615,40.5575],[115.77907,40.56128],[115.73272,40.51145],[115.77632,40.46196],[115.76568,40.44668],[115.857,40.36145],[115.90541,40.35544],[115.95382,40.27481],[115.8467,40.14633],[115.76808,40.15736],[115.50338,40.07649],[115.42098,39.96449],[115.56518,39.81011],[115.41755,39.77925]]]}},{"type":"Feature","properties":{"id":"KZ"},"geometry":{"type":"Polygon","coordinates":[[[46.49011,48.43019],[47.11516,48.27188],[47.12107,47.83687],[47.38731,47.68176],[47.41689,47.83687],[47.64973,47.76559],[48.15348,47.74545],[48.45173,47.40818],[48.52326,47.4102],[49.01136,46.72716],[48.51142,46.69268],[48.54988,46.56267],[49.16518,46.38542],[49.32259,46.26944],[49.88945,46.04554],[49.2134,44.84989],[52.26048,41.69249],[52.47884,41.78034],[52.97575,42.1308],[54.20635,42.38477],[54.95182,41.92424],[55.45471,41.25609],[56.00314,41.32584],[55.97584,44.99322],[55.97584,44.99328],[55.97584,44.99338],[55.97584,44.99343],[55.97584,44.99348],[55.97584,44.99353],[55.97584,44.99359],[55.97584,44.99369],[55.97584,44.99374],[55.97584,44.99384],[55.97584,44.9939],[55.97584,44.994],[55.97584,44.99405],[55.97584,44.99415],[55.97584,44.99421],[55.97584,44.99426],[55.97584,44.99431],[55.97584,44.99436],[55.97584,44.99441],[55.97594,44.99446],[55.97605,44.99452],[55.97605,44.99457],[55.97605,44.99462],[55.97605,44.99467],[55.97605,44.99477],[55.97615,44.99477],[55.97615,44.99483],[55.97615,44.99493],[55.97615,44.99498],[55.97615,44.99503],[55.97615,44.99508],[55.97625,44.99514],[55.97636,44.99519],[55.97636,44.99524],[55.97646,44.99529],[55.97646,44.99534],[55.97656,44.99539],[55.97667,44.99545],[55.97677,44.9955],[55.97677,44.99555],[55.97677,44.9956],[55.97687,44.9956],[55.97698,44.99565],[55.97698,44.9957],[55.97708,44.99576],[55.97718,44.99581],[55.97729,44.99586],[55.97739,44.99586],[55.97739,44.99591],[55.97749,44.99591],[55.9776,44.99591],[55.9777,44.99596],[55.9777,44.99601],[55.9778,44.99607],[55.97791,44.99607],[55.97801,44.99607],[55.97801,44.99612],[55.97811,44.99617],[55.97822,44.99617],[55.97832,44.99622],[55.97842,44.99622],[58.59711,45.58671],[61.01475,44.41383],[62.01711,43.51008],[63.34656,43.64003],[64.53885,43.56941],[64.96464,43.74748],[65.18666,43.48835],[65.53277,43.31856],[65.85194,42.85481],[66.09482,42.93426],[66.00546,41.94455],[66.53302,41.87388],[66.69129,41.1311],[67.9644,41.14611],[67.98511,41.02794],[68.08273,41.08148],[68.1271,41.0324],[67.96736,40.83798],[68.49983,40.56437],[68.63,40.59358],[68.58444,40.91447],[68.49983,40.99669],[68.62221,41.03019],[68.65662,40.93861],[68.73945,40.96989],[68.7217,41.05025],[69.01308,41.22804],[69.05006,41.36183],[69.15137,41.43078],[69.17701,41.43769],[69.18528,41.45175],[69.20439,41.45391],[69.22671,41.46298],[69.23332,41.45847],[69.25059,41.46693],[69.29778,41.43673],[69.35554,41.47211],[69.37468,41.46555],[69.45081,41.46246],[69.39485,41.51518],[69.45751,41.56863],[69.49545,41.545],[70.94483,42.26238],[70.85973,42.30188],[70.97717,42.50147],[71.15232,42.60486],[71.17807,42.67381],[71.22785,42.69248],[71.2724,42.77853],[71.53272,42.8014],[71.62405,42.76613],[71.88792,42.83578],[73.44393,42.43098],[73.50992,42.82356],[73.55634,43.03071],[74.22489,43.24657],[74.57491,43.13702],[74.64615,43.05881],[74.70331,43.02519],[74.75,42.99029],[74.88756,42.98612],[75.22619,42.85528],[75.29966,42.86183],[75.72174,42.79672],[75.82823,42.94848],[78.48469,42.89649],[78.91502,42.76839],[79.19763,42.804],[79.52921,42.44778],[79.97364,42.42816],[80.17807,42.21166],[80.26841,42.23797],[80.16892,42.61137],[80.26886,42.8366],[80.38169,42.83142],[80.58999,42.9011],[80.3735,43.01557],[80.62913,43.141],[80.78817,43.14235],[80.77771,43.30065],[80.69718,43.32589],[80.75156,43.44948],[80.40031,44.10986],[80.40229,44.23319],[80.38384,44.63073],[79.8987,44.89957],[80.11169,45.03352],[81.73278,45.3504],[82.51374,45.1755],[82.58474,45.40027],[82.21792,45.56619],[83.04622,47.19053],[83.92184,46.98912],[84.73077,47.01394],[84.93995,46.87399],[85.22443,47.04816],[85.54294,47.06171],[85.69696,47.2898],[85.61067,47.49753],[85.5169,48.05493],[85.73581,48.3939],[86.38069,48.46064],[86.75343,48.70331],[86.73568,48.99918],[86.87238,49.12432],[87.28386,49.11626],[87.31465,49.23603],[87.03071,49.25142],[86.82606,49.51796],[86.61307,49.60239],[86.79056,49.74787],[86.63674,49.80136],[86.18709,49.50259],[85.24047,49.60239],[84.99198,50.06793],[84.29385,50.27257],[83.8442,50.87375],[83.14607,51.00796],[82.55443,50.75412],[81.94999,50.79307],[81.46581,50.77658],[81.41248,50.97524],[81.06091,50.94833],[81.16999,51.15662],[80.80318,51.28262],[80.44819,51.20855],[80.4127,50.95581],[80.08138,50.77658],[79.11255,52.01171],[77.90383,53.29807],[76.54243,53.99329],[76.44076,54.16017],[76.82266,54.1798],[76.91052,54.4677],[75.3668,54.07439],[75.43398,53.98652],[75.07405,53.80831],[73.39218,53.44623],[73.25412,53.61532],[73.68921,53.86522],[73.74778,54.07194],[73.37963,53.96132],[72.71026,54.1161],[72.43415,53.92685],[72.17477,54.36303],[71.96141,54.17736],[71.10379,54.13326],[71.08706,54.33376],[71.24185,54.64965],[71.08288,54.71253],[70.96009,55.10558],[70.76493,55.3027],[70.19179,55.1476],[69.74917,55.35545],[69.34224,55.36344],[68.90865,55.38148],[68.19206,55.18823],[68.26661,55.09226],[68.21308,54.98645],[65.20174,54.55216],[65.24663,54.35721],[65.11033,54.33028],[64.97216,54.4212],[63.97686,54.29763],[64.02715,54.22679],[63.91224,54.20013],[63.80604,54.27079],[62.58651,54.05871],[62.56876,53.94047],[62.45931,53.90737],[62.38535,54.03961],[62.00966,54.04134],[62.03913,53.94768],[61.65318,54.02445],[61.56941,53.95703],[61.47603,54.08048],[61.3706,54.08464],[61.26863,53.92797],[60.99796,53.93699],[61.14283,53.90063],[61.22574,53.80268],[60.90626,53.62937],[61.55706,53.57144],[61.57185,53.50112],[61.37957,53.45887],[61.29082,53.50992],[61.14291,53.41481],[61.19024,53.30536],[62.14574,53.09626],[62.12799,52.99133],[62.0422,52.96105],[61.23462,53.03227],[61.05842,52.92217],[60.71989,52.75923],[60.71693,52.66245],[60.84118,52.63912],[60.84709,52.52228],[60.98021,52.50068],[61.05417,52.35096],[60.78201,52.22067],[60.72581,52.15538],[60.48915,52.15175],[60.19925,51.99173],[59.99809,51.98263],[60.09867,51.87135],[60.50986,51.7964],[60.36787,51.66815],[60.5424,51.61675],[60.92401,51.61124],[60.95655,51.48615],[61.50677,51.40687],[61.55114,51.32746],[61.6813,51.25716],[61.56889,51.23679],[61.4431,50.80679],[60.81833,50.6629],[60.31914,50.67705],[60.17262,50.83312],[60.01288,50.8163],[59.81172,50.54451],[59.51886,50.49937],[59.48928,50.64216],[58.87974,50.70852],[58.3208,51.15151],[57.75578,51.13852],[57.74986,50.93017],[57.44221,50.88354],[57.17302,51.11253],[56.17906,50.93204],[56.11398,50.7471],[55.67774,50.54508],[54.72067,51.03261],[54.56685,51.01958],[54.71476,50.61214],[54.55797,50.52006],[54.41894,50.61214],[54.46331,50.85554],[54.12248,51.11542],[53.69299,51.23466],[53.46165,51.49445],[52.54329,51.48444],[52.36119,51.74161],[51.8246,51.67916],[51.77431,51.49536],[51.301,51.48799],[51.26254,51.68466],[50.59695,51.61859],[50.26859,51.28677],[49.97277,51.2405],[49.76866,51.11067],[49.39001,51.09396],[49.41959,50.85927],[49.12673,50.78639],[48.86936,50.61589],[48.57946,50.63278],[48.90782,50.02281],[48.68352,49.89546],[48.42564,49.82283],[48.24519,49.86099],[48.10044,50.09242],[47.58551,50.47867],[47.30448,50.30894],[47.34589,50.09308],[47.18319,49.93721],[46.9078,49.86707],[46.78398,49.34026],[46.98795,49.23531],[47.04416,49.17152],[47.01458,49.07085],[46.91104,48.99715],[46.78392,48.95352],[46.49011,48.43019]]]}},{"type":"Feature","properties":{"id":"KE"},"geometry":{"type":"Polygon","coordinates":[[[33.90936,0.10581],[33.98449,-0.13079],[33.9264,-0.54188],[33.93107,-0.99298],[34.02286,-1.00779],[34.03084,-1.05101],[34.0824,-1.02264],[37.67199,-3.06222],[37.71745,-3.304],[37.5903,-3.42735],[37.63099,-3.50723],[37.75036,-3.54243],[37.81321,-3.69179],[39.21631,-4.67835],[39.44306,-4.93877],[39.62121,-4.68136],[41.75542,-1.85308],[41.56362,-1.66375],[41.56,-1.59812],[41.00099,-0.83068],[40.98767,2.82959],[41.31368,3.14314],[41.89488,3.97375],[41.1754,3.94079],[40.77498,4.27683],[39.86043,3.86974],[39.76808,3.67058],[39.58339,3.47434],[39.55132,3.39634],[39.51551,3.40895],[39.49444,3.45521],[39.19954,3.47834],[39.07736,3.5267],[38.91938,3.51198],[38.52336,3.62551],[38.45812,3.60445],[38.14168,3.62487],[37.07724,4.33503],[36.84474,4.44518],[36.03924,4.44406],[35.95449,4.53244],[35.9419,4.61933],[35.51424,4.61643],[35.42366,4.76969],[35.47843,4.91872],[35.30992,4.90402],[35.34151,5.02364],[34.47601,4.72162],[33.9873,4.23316],[34.06046,4.15235],[34.15429,3.80464],[34.45815,3.67385],[34.44922,3.51627],[34.39112,3.48802],[34.41794,3.44342],[34.40006,3.37949],[34.45815,3.18319],[34.56242,3.11478],[34.60114,2.93034],[34.65774,2.8753],[34.73967,2.85447],[34.78137,2.76223],[34.77244,2.70272],[34.95267,2.47209],[34.90947,2.42447],[34.98692,1.97348],[34.9899,1.6668],[34.92734,1.56109],[34.87819,1.5596],[34.7918,1.36752],[34.82606,1.30944],[34.82606,1.26626],[34.80223,1.22754],[34.67562,1.21265],[34.58029,1.14712],[34.57427,1.09868],[34.52369,1.10692],[34.43349,0.85254],[34.40041,0.80266],[34.31516,0.75693],[34.27345,0.63182],[34.20196,0.62289],[34.13493,0.58118],[34.11408,0.48884],[34.08727,0.44713],[34.10067,0.36372],[33.90936,0.10581]]]}},{"type":"Feature","properties":{"id":"KH"},"geometry":{"type":"Polygon","coordinates":[[[102.33828,13.55613],[102.361,13.50551],[102.35563,13.47307],[102.35692,13.38274],[102.34611,13.35618],[102.36001,13.31142],[102.36146,13.26006],[102.43422,13.09061],[102.46011,13.08057],[102.52275,12.99813],[102.48694,12.97537],[102.49335,12.92711],[102.53053,12.77506],[102.4994,12.71736],[102.51963,12.66117],[102.57567,12.65358],[102.7796,12.43781],[102.78116,12.40284],[102.73134,12.37091],[102.70176,12.1686],[102.77026,12.06815],[102.78427,11.98746],[102.83957,11.8519],[102.90973,11.75613],[102.91449,11.65512],[102.52395,11.25257],[102.47649,9.66162],[103.99198,10.48391],[104.43778,10.42386],[104.47963,10.43046],[104.49869,10.4057],[104.59018,10.53073],[104.87933,10.52833],[104.95094,10.64003],[105.09571,10.72722],[105.02722,10.89236],[105.08326,10.95656],[105.11449,10.96332],[105.34011,10.86179],[105.42884,10.96878],[105.50045,10.94586],[105.77751,11.03671],[105.86376,10.89839],[105.84603,10.85873],[105.93403,10.83853],[105.94535,10.9168],[106.06708,10.8098],[106.18539,10.79451],[106.14301,10.98176],[106.20095,10.97795],[106.1757,11.07301],[106.1527,11.10476],[106.10444,11.07879],[105.86782,11.28343],[105.88962,11.43605],[105.87328,11.55953],[105.81645,11.56876],[105.80867,11.60536],[105.8507,11.66635],[105.88962,11.67854],[105.95188,11.63738],[106.00792,11.7197],[106.02038,11.77457],[106.06708,11.77761],[106.13158,11.73283],[106.18539,11.75171],[106.26478,11.72122],[106.30525,11.67549],[106.37219,11.69836],[106.44691,11.66787],[106.45158,11.68616],[106.41577,11.76999],[106.44535,11.8279],[106.44068,11.86294],[106.4687,11.86751],[106.4111,11.97413],[106.70687,11.96956],[106.79405,12.0807],[106.92325,12.06548],[106.99953,12.08983],[107.15831,12.27547],[107.34511,12.33327],[107.42917,12.24657],[107.4463,12.29373],[107.55059,12.36824],[107.5755,12.52177],[107.55993,12.7982],[107.49611,12.88926],[107.49144,13.01215],[107.62843,13.3668],[107.61909,13.52577],[107.53503,13.73908],[107.45252,13.78897],[107.46498,13.91593],[107.44318,13.99751],[107.38247,13.99147],[107.35757,14.02319],[107.37158,14.07906],[107.33577,14.11832],[107.40427,14.24509],[107.39493,14.32655],[107.44941,14.41552],[107.48521,14.40346],[107.52569,14.54665],[107.52102,14.59034],[107.55371,14.628],[107.54361,14.69092],[107.47238,14.61523],[107.44435,14.52785],[107.37897,14.54443],[107.3276,14.58812],[107.29803,14.58963],[107.26534,14.54292],[107.256,14.48716],[107.21241,14.48716],[107.17038,14.41782],[107.09722,14.3937],[107.03962,14.45099],[107.04585,14.41782],[106.98825,14.36806],[106.9649,14.3198],[106.90574,14.33639],[106.8497,14.29416],[106.80767,14.31226],[106.73762,14.42687],[106.63333,14.44194],[106.59908,14.50977],[106.57106,14.50525],[106.54148,14.59565],[106.50723,14.58963],[106.45898,14.55045],[106.47766,14.50977],[106.43874,14.52032],[106.40916,14.45249],[106.32355,14.44043],[106.25194,14.48415],[106.21302,14.36203],[106.00131,14.36957],[105.99509,14.32734],[106.02311,14.30623],[106.04801,14.20363],[106.10872,14.18401],[106.11962,14.11307],[106.18656,14.06324],[106.16632,14.01794],[106.10094,13.98471],[106.10405,13.9137],[105.90791,13.92881],[105.78182,14.02247],[105.78338,14.08438],[105.5561,14.15684],[105.44869,14.10703],[105.36775,14.09948],[105.2759,14.17496],[105.20894,14.34967],[105.17748,14.34432],[105.14012,14.23873],[105.08408,14.20402],[105.02804,14.23722],[104.97667,14.38806],[104.69335,14.42726],[104.55014,14.36091],[104.27616,14.39861],[103.93836,14.3398],[103.70175,14.38052],[103.71109,14.4348],[103.53518,14.42575],[103.39353,14.35639],[103.16469,14.33075],[102.93275,14.19044],[102.91251,14.01531],[102.77864,13.93374],[102.72727,13.77806],[102.56848,13.69366],[102.5481,13.6589],[102.58635,13.6286],[102.62483,13.60883],[102.57573,13.60461],[102.5358,13.56933],[102.44601,13.5637],[102.36859,13.57488],[102.33828,13.55613]]]}},{"type":"Feature","properties":{"id":"KN"},"geometry":{"type":"Polygon","coordinates":[[[-63.11114,17.23125],[-62.62949,16.82364],[-62.27053,17.22145],[-62.76692,17.64353],[-63.11114,17.23125]]]}},{"type":"Feature","properties":{"id":"KR"},"geometry":{"type":"Polygon","coordinates":[[[122.80525,33.30571],[127.42045,32.33183],[129.2669,34.87122],[133.61399,37.41],[128.65655,38.61914],[128.37487,38.62345],[128.31105,38.58462],[128.27652,38.41657],[128.02917,38.31861],[127.55013,38.32257],[127.49672,38.30647],[127.38727,38.33227],[127.15749,38.30722],[127.04479,38.25518],[126.95338,38.17735],[126.95887,38.1347],[126.88106,38.10246],[126.84961,38.0344],[126.67023,37.95852],[126.68793,37.9175],[126.68793,37.83728],[126.66067,37.7897],[126.59918,37.76364],[126.56709,37.76857],[126.46818,37.80873],[126.43239,37.84095],[126.24402,37.83113],[126.19097,37.81462],[126.18776,37.74728],[126.13074,37.70512],[125.81159,37.72949],[125.37112,37.62643],[125.06408,37.66334],[124.87921,37.80827],[124.84224,37.977],[124.67666,38.05679],[123.85601,37.49093],[122.80525,33.30571]]]}},{"type":"Feature","properties":{"id":"XK"},"geometry":{"type":"Polygon","coordinates":[[[20.02088,42.74789],[20.02915,42.71147],[20.0969,42.65559],[20.07761,42.55582],[20.17127,42.50469],[20.21797,42.41237],[20.24399,42.32168],[20.34479,42.32656],[20.3819,42.3029],[20.48857,42.25444],[20.56955,42.12097],[20.55633,42.08173],[20.59434,42.03879],[20.63069,41.94913],[20.57946,41.91593],[20.59524,41.8818],[20.68523,41.85318],[20.76786,41.91839],[20.75464,42.05229],[21.11491,42.20794],[21.16614,42.19815],[21.22728,42.08909],[21.31983,42.10993],[21.29913,42.13954],[21.30496,42.1418],[21.38428,42.24465],[21.43882,42.23609],[21.43882,42.2789],[21.50823,42.27156],[21.52145,42.24465],[21.58992,42.25915],[21.56772,42.30946],[21.5264,42.33634],[21.53467,42.36809],[21.57021,42.3647],[21.59029,42.38042],[21.62887,42.37664],[21.64209,42.41081],[21.62556,42.45106],[21.7035,42.51899],[21.70522,42.54176],[21.7327,42.55041],[21.75672,42.62695],[21.79413,42.65923],[21.75025,42.70125],[21.6626,42.67813],[21.58755,42.70418],[21.59154,42.72643],[21.47498,42.74695],[21.39045,42.74888],[21.44047,42.87276],[21.36941,42.87397],[21.32974,42.90424],[21.2719,42.8994],[21.23534,42.95523],[21.23877,43.00848],[21.2041,43.02277],[21.16734,42.99694],[21.14465,43.11089],[21.08952,43.13471],[21.05378,43.10707],[21.00749,43.13984],[20.96287,43.12416],[20.83727,43.17842],[20.88685,43.21697],[20.82145,43.26769],[20.73811,43.25068],[20.68688,43.21335],[20.59929,43.20492],[20.69515,43.09641],[20.64557,43.00826],[20.59929,43.01067],[20.48692,42.93208],[20.53484,42.8885],[20.43734,42.83157],[20.40594,42.84853],[20.35692,42.8335],[20.27869,42.81945],[20.2539,42.76245],[20.04898,42.77701],[20.02088,42.74789]]]}},{"type":"Feature","properties":{"id":"KW"},"geometry":{"type":"Polygon","coordinates":[[[46.5527,29.10283],[47.46202,29.0014],[47.58376,28.83382],[47.59863,28.66798],[47.70561,28.5221],[48.42991,28.53628],[49.00421,28.81495],[48.59531,29.66815],[48.40479,29.85763],[48.17332,30.02448],[48.06782,30.02906],[48.01114,29.98906],[47.7095,30.10453],[47.37192,30.10421],[47.15166,30.01044],[46.89695,29.50584],[46.5527,29.10283]]]}},{"type":"Feature","properties":{"id":"IN-JK"},"geometry":{"type":"Polygon","coordinates":[[[73.74862,34.34183],[73.8475,34.32935],[73.90517,34.35317],[73.98208,34.2522],[73.90677,34.10504],[73.88732,34.05105],[73.91341,34.01235],[74.21554,34.03853],[74.25262,34.01577],[74.26086,33.92237],[74.14001,33.83002],[74.05898,33.82089],[74.00891,33.75437],[73.96423,33.73071],[73.98968,33.66155],[73.97367,33.64061],[74.03576,33.56718],[74.10115,33.56392],[74.18121,33.4745],[74.17983,33.3679],[74.08782,33.26232],[74.01366,33.25199],[74.02144,33.18908],[74.15374,33.13477],[74.17571,33.07495],[74.31854,33.02891],[74.34875,32.97823],[74.31227,32.92795],[74.41467,32.90563],[74.45312,32.77755],[74.6289,32.75561],[74.64675,32.82604],[74.7113,32.84219],[74.65345,32.71225],[74.69542,32.66792],[74.64424,32.60985],[74.65251,32.56416],[74.67431,32.56676],[74.68362,32.49298],[74.84725,32.49075],[74.97634,32.45367],[75.03265,32.49538],[75.28259,32.36556],[75.49941,32.28074],[75.57083,32.36836],[75.78506,32.47095],[75.82936,32.52664],[75.92513,32.64689],[75.77888,32.9355],[75.95329,32.88362],[76.31584,33.1341],[76.76902,33.26337],[77.32795,32.82305],[77.66784,32.97007],[77.88345,32.7942],[77.97477,32.58905],[78.32565,32.75263],[78.38897,32.53938],[78.73916,32.69438],[78.7831,32.46873],[78.96713,32.33655],[78.99322,32.37948],[79.0979,32.38051],[79.13174,32.47766],[79.26768,32.53277],[79.46562,32.69668],[79.14016,33.02545],[79.15252,33.17156],[78.73636,33.56521],[78.67599,33.66445],[78.77349,33.73871],[78.73367,34.01121],[78.65657,34.03195],[78.66225,34.08858],[78.91769,34.15452],[78.99802,34.3027],[79.05364,34.32482],[78.74465,34.45174],[78.56475,34.50835],[78.54964,34.57283],[78.27781,34.61484],[78.18435,34.7998],[78.22692,34.88771],[78.00033,35.23954],[78.03466,35.3785],[78.11664,35.48022],[77.80532,35.52058],[77.70232,35.46244],[77.44277,35.46132],[76.96624,35.5932],[76.84539,35.67356],[76.77323,35.66062],[76.75475,35.52617],[76.85088,35.39754],[76.93465,35.39866],[77.11796,35.05419],[76.99251,34.93349],[76.87193,34.96906],[76.74514,34.92488],[76.74377,34.84039],[76.67648,34.76371],[76.47186,34.78965],[76.15463,34.6429],[76.04614,34.67566],[75.75438,34.51827],[75.38009,34.55021],[75.01479,34.64629],[74.6663,34.703],[74.58083,34.77386],[74.31239,34.79626],[74.12897,34.70073],[73.96423,34.68244],[73.93401,34.63386],[73.93951,34.57169],[73.89419,34.54568],[73.88732,34.48911],[73.74999,34.3781],[73.74862,34.34183]]]}},{"type":"Feature","properties":{"id":"LA"},"geometry":{"type":"Polygon","coordinates":[[[100.08404,20.36626],[100.09999,20.31614],[100.09337,20.26293],[100.11785,20.24787],[100.1712,20.24324],[100.16668,20.2986],[100.22076,20.31598],[100.25769,20.3992],[100.33383,20.4028],[100.37439,20.35156],[100.41473,20.25625],[100.44992,20.23644],[100.4537,20.19971],[100.47567,20.19133],[100.51052,20.14928],[100.55218,20.17741],[100.58808,20.15791],[100.5094,19.87904],[100.398,19.75047],[100.49604,19.53504],[100.58219,19.49164],[100.64606,19.55884],[100.77231,19.48324],[100.90302,19.61901],[101.08928,19.59748],[101.26545,19.59242],[101.26991,19.48324],[101.21347,19.46223],[101.20604,19.35296],[101.24911,19.33334],[101.261,19.12717],[101.35606,19.04716],[101.25803,18.89545],[101.22832,18.73377],[101.27585,18.68875],[101.06047,18.43247],[101.18227,18.34367],[101.15108,18.25624],[101.19118,18.2125],[101.1793,18.0544],[101.02185,17.87637],[100.96541,17.57926],[101.15108,17.47586],[101.44667,17.7392],[101.72294,17.92867],[101.78087,18.07559],[101.88485,18.02474],[102.11359,18.21532],[102.45523,17.97106],[102.59234,17.96127],[102.60971,17.95411],[102.61432,17.92273],[102.5896,17.84889],[102.59485,17.83537],[102.68194,17.80151],[102.69946,17.81686],[102.67543,17.84529],[102.68538,17.86653],[102.75954,17.89561],[102.79044,17.93612],[102.81988,17.94233],[102.86323,17.97531],[102.95812,18.0054],[102.9912,17.9949],[103.01998,17.97095],[103.0566,18.00144],[103.07823,18.03833],[103.07343,18.12351],[103.1493,18.17799],[103.14994,18.23172],[103.17093,18.2618],[103.29757,18.30475],[103.23818,18.34875],[103.24779,18.37807],[103.30977,18.4341],[103.41044,18.4486],[103.47773,18.42841],[103.60957,18.40528],[103.699,18.34125],[103.82449,18.33979],[103.85642,18.28666],[103.93916,18.33914],[103.97725,18.33631],[104.06533,18.21656],[104.10927,18.10826],[104.21776,17.99335],[104.2757,17.86139],[104.35432,17.82871],[104.45404,17.66788],[104.69867,17.53038],[104.80061,17.39367],[104.80716,17.19025],[104.73712,17.01404],[104.7373,16.91125],[104.76442,16.84752],[104.7397,16.81005],[104.76099,16.69302],[104.73349,16.565],[104.88057,16.37311],[105.00262,16.25627],[105.06204,16.09792],[105.42001,16.00657],[105.38508,15.987],[105.34115,15.92737],[105.37959,15.84074],[105.42285,15.76971],[105.46573,15.74742],[105.61756,15.68792],[105.60446,15.53301],[105.58191,15.41031],[105.47635,15.3796],[105.4692,15.33709],[105.50662,15.32054],[105.58043,15.32724],[105.46661,15.13132],[105.61162,15.00037],[105.5121,14.80802],[105.53864,14.55731],[105.43783,14.43865],[105.20894,14.34967],[105.2759,14.17496],[105.36775,14.09948],[105.44869,14.10703],[105.5561,14.15684],[105.78338,14.08438],[105.78182,14.02247],[105.90791,13.92881],[106.10405,13.9137],[106.10094,13.98471],[106.16632,14.01794],[106.18656,14.06324],[106.11962,14.11307],[106.10872,14.18401],[106.04801,14.20363],[106.02311,14.30623],[105.99509,14.32734],[106.00131,14.36957],[106.21302,14.36203],[106.25194,14.48415],[106.32355,14.44043],[106.40916,14.45249],[106.43874,14.52032],[106.47766,14.50977],[106.45898,14.55045],[106.50723,14.58963],[106.54148,14.59565],[106.57106,14.50525],[106.59908,14.50977],[106.63333,14.44194],[106.73762,14.42687],[106.80767,14.31226],[106.8497,14.29416],[106.90574,14.33639],[106.9649,14.3198],[106.98825,14.36806],[107.04585,14.41782],[107.03962,14.45099],[107.09722,14.3937],[107.17038,14.41782],[107.21241,14.48716],[107.256,14.48716],[107.26534,14.54292],[107.29803,14.58963],[107.3276,14.58812],[107.37897,14.54443],[107.44435,14.52785],[107.47238,14.61523],[107.54361,14.69092],[107.51579,14.79282],[107.59285,14.87795],[107.48277,14.93751],[107.46516,15.00982],[107.61486,15.0566],[107.61926,15.13949],[107.58844,15.20111],[107.62587,15.2266],[107.60605,15.37524],[107.62367,15.42193],[107.53341,15.40496],[107.50699,15.48771],[107.3815,15.49832],[107.34408,15.62345],[107.27583,15.62769],[107.27143,15.71459],[107.21859,15.74638],[107.21419,15.83747],[107.34188,15.89464],[107.39471,15.88829],[107.46296,16.01106],[107.44975,16.08511],[107.33968,16.05549],[107.25822,16.13587],[107.14595,16.17816],[107.15035,16.26271],[107.09091,16.3092],[107.02597,16.31132],[106.97385,16.30204],[106.96638,16.34938],[106.88067,16.43594],[106.88727,16.52671],[106.84104,16.55415],[106.74418,16.41904],[106.65832,16.47816],[106.66052,16.56892],[106.61477,16.60713],[106.58267,16.6012],[106.59013,16.62259],[106.55485,16.68704],[106.55265,16.86831],[106.52183,16.87884],[106.51963,16.92097],[106.54824,16.92729],[106.55045,17.0031],[106.50862,16.9673],[106.43597,17.01362],[106.31929,17.20509],[106.29287,17.3018],[106.24444,17.24714],[106.18991,17.28227],[106.09019,17.36399],[105.85744,17.63221],[105.76612,17.67147],[105.60381,17.89356],[105.64784,17.96687],[105.46292,18.22008],[105.38366,18.15315],[105.15942,18.38691],[105.10408,18.43533],[105.1327,18.58355],[105.19654,18.64196],[105.12829,18.70453],[104.64617,18.85668],[104.5361,18.97747],[103.87125,19.31854],[104.06058,19.43484],[104.10832,19.51575],[104.05617,19.61743],[104.06498,19.66926],[104.23229,19.70242],[104.41281,19.70035],[104.53169,19.61743],[104.64837,19.62365],[104.68359,19.72729],[104.8355,19.80395],[104.8465,19.91783],[104.9874,20.09573],[104.91695,20.15567],[104.86852,20.14121],[104.61315,20.24452],[104.62195,20.36633],[104.72102,20.40554],[104.66158,20.47774],[104.47886,20.37459],[104.40621,20.3849],[104.38199,20.47155],[104.63957,20.6653],[104.27412,20.91433],[104.11121,20.96779],[103.98024,20.91531],[103.82282,20.8732],[103.73478,20.6669],[103.68633,20.66324],[103.45737,20.82382],[103.38032,20.79501],[103.21497,20.89832],[103.12055,20.89994],[103.03469,21.05821],[102.97745,21.05821],[102.89825,21.24707],[102.80794,21.25736],[102.88939,21.3107],[102.94223,21.46034],[102.86297,21.4255],[102.98846,21.58936],[102.97965,21.74076],[102.86077,21.71213],[102.85637,21.84501],[102.81894,21.83888],[102.82115,21.73667],[102.74189,21.66713],[102.67145,21.65894],[102.62301,21.91447],[102.49092,21.99002],[102.51734,22.02676],[102.18712,22.30403],[102.14099,22.40092],[102.1245,22.43372],[102.03633,22.46164],[101.98487,22.42766],[101.91344,22.44417],[101.90714,22.38688],[101.86828,22.38397],[101.7685,22.50337],[101.68973,22.46843],[101.61306,22.27515],[101.56789,22.28876],[101.53638,22.24794],[101.60675,22.13513],[101.57525,22.13026],[101.62566,21.96574],[101.7791,21.83019],[101.74555,21.72852],[101.83257,21.61562],[101.80001,21.57461],[101.7475,21.5873],[101.7727,21.51794],[101.74224,21.48276],[101.74014,21.30967],[101.84412,21.25291],[101.83887,21.20983],[101.76745,21.21571],[101.79266,21.19025],[101.7622,21.14813],[101.70548,21.14911],[101.66977,21.20004],[101.60886,21.17947],[101.59491,21.18621],[101.6068,21.23329],[101.54563,21.25668],[101.29326,21.17254],[101.2229,21.23271],[101.26912,21.36482],[101.19349,21.41959],[101.2124,21.56422],[101.15156,21.56129],[101.16198,21.52808],[101.00234,21.39612],[100.80173,21.2934],[100.72716,21.31786],[100.63578,21.05639],[100.55281,21.02796],[100.50974,20.88574],[100.64628,20.88279],[100.60112,20.8347],[100.51079,20.82194],[100.36375,20.82783],[100.1957,20.68247],[100.08404,20.36626]]]}},{"type":"Feature","properties":{"id":"LB"},"geometry":{"type":"Polygon","coordinates":[[[34.78515,33.20368],[35.10645,33.09318],[35.1924,33.08743],[35.31429,33.10515],[35.35223,33.05617],[35.43059,33.06659],[35.448,33.09264],[35.50272,33.09056],[35.50335,33.114],[35.52573,33.11921],[35.54228,33.19865],[35.5362,33.23196],[35.54808,33.236],[35.54544,33.25513],[35.55555,33.25844],[35.56523,33.28969],[35.58326,33.28381],[35.58502,33.26653],[35.62283,33.24226],[35.62019,33.27278],[35.77477,33.33609],[35.81324,33.36354],[35.82577,33.40479],[35.88668,33.43183],[35.94816,33.47886],[35.94465,33.52774],[36.05723,33.57904],[35.9341,33.6596],[36.06778,33.82927],[36.14517,33.85118],[36.3967,33.83365],[36.38263,33.86579],[36.28589,33.91981],[36.41078,34.05253],[36.50576,34.05982],[36.5128,34.09916],[36.62537,34.20251],[36.59195,34.2316],[36.58667,34.27667],[36.60778,34.31009],[36.56556,34.31881],[36.53039,34.3798],[36.55853,34.41609],[36.46179,34.46541],[36.4442,34.50165],[36.34745,34.5002],[36.3369,34.52629],[36.39846,34.55672],[36.41429,34.61175],[36.45299,34.59438],[36.46003,34.6378],[36.42941,34.62505],[36.35384,34.65447],[36.35135,34.68516],[36.32399,34.69334],[36.29165,34.62991],[35.98718,34.64977],[35.97386,34.63322],[35.48515,34.70851],[34.78515,33.20368]]]}},{"type":"Feature","properties":{"id":"LR"},"geometry":{"type":"Polygon","coordinates":[[[-12.15048,6.15992],[-7.52774,3.7105],[-7.53259,4.35145],[-7.59349,4.8909],[-7.53876,4.94294],[-7.55369,5.08667],[-7.48901,5.14118],[-7.46165,5.26256],[-7.36463,5.32944],[-7.43428,5.42355],[-7.37209,5.61173],[-7.43926,5.74787],[-7.43677,5.84687],[-7.46165,5.84934],[-7.48155,5.80974],[-7.67309,5.94337],[-7.70294,5.90625],[-7.78254,5.99037],[-7.79747,6.07696],[-7.8497,6.08932],[-7.83478,6.20309],[-7.90692,6.27728],[-8.00642,6.31684],[-8.17557,6.28222],[-8.3298,6.36381],[-8.38453,6.35887],[-8.45666,6.49977],[-8.48652,6.43797],[-8.59456,6.50612],[-8.31736,6.82837],[-8.29249,7.1691],[-8.37458,7.25794],[-8.41935,7.51203],[-8.47114,7.55676],[-8.55874,7.62525],[-8.55874,7.70167],[-8.67814,7.69428],[-8.72789,7.51429],[-8.8448,7.35149],[-8.85724,7.26019],[-8.93435,7.2824],[-9.09107,7.1985],[-9.18311,7.30461],[-9.20798,7.38109],[-9.305,7.42056],[-9.41943,7.41809],[-9.48161,7.37122],[-9.37465,7.62032],[-9.35724,7.74111],[-9.44928,7.9284],[-9.41445,8.02448],[-9.50898,8.18455],[-9.47415,8.35195],[-9.77763,8.54633],[-10.05873,8.42578],[-10.05375,8.50697],[-10.14579,8.52665],[-10.203,8.47991],[-10.27575,8.48711],[-10.30084,8.30008],[-10.31635,8.28554],[-10.29839,8.21283],[-10.35227,8.15223],[-10.45023,8.15627],[-10.51554,8.1393],[-10.57523,8.04829],[-10.60492,8.04072],[-10.60422,7.7739],[-11.29417,7.21576],[-11.4027,6.97746],[-11.50429,6.92704],[-12.15048,6.15992]]]}},{"type":"Feature","properties":{"id":"LY"},"geometry":{"type":"Polygon","coordinates":[[[9.3876,30.16738],[9.78136,29.40961],[9.89569,26.57696],[9.51696,26.39148],[9.38834,26.19288],[10.03146,25.35635],[10.02432,24.98124],[10.33159,24.5465],[10.85323,24.5595],[11.41061,24.21456],[11.62498,24.26669],[11.96886,23.51735],[13.5631,23.16574],[14.22918,22.61719],[14.99751,23.00539],[15.99566,23.49639],[23.99539,19.49944],[23.99715,20.00038],[24.99794,19.99661],[24.99885,21.99535],[24.99968,29.24574],[24.71117,30.17441],[25.01077,30.73861],[24.83101,31.31921],[25.06041,31.57937],[25.14001,31.67534],[25.63787,31.9359],[22.5213,33.45682],[11.66543,33.34642],[11.56255,33.16754],[11.55852,33.1409],[11.51549,33.09826],[11.46037,32.6307],[11.57828,32.48013],[11.53898,32.4138],[11.04234,32.2145],[10.7315,31.97235],[10.62788,31.96629],[10.48497,31.72956],[10.31364,31.72648],[10.12239,31.42098],[10.29516,30.90337],[9.88152,30.34074],[9.76848,30.34366],[9.55544,30.23971],[9.3876,30.16738]]]}},{"type":"Feature","properties":{"id":"LC"},"geometry":{"type":"Polygon","coordinates":[[[-61.43129,13.68336],[-60.70539,13.41452],[-60.5958,14.23076],[-61.26561,14.25664],[-61.43129,13.68336]]]}},{"type":"Feature","properties":{"id":"LI"},"geometry":{"type":"Polygon","coordinates":[[[9.47139,47.06402],[9.47548,47.05257],[9.54041,47.06495],[9.55721,47.04762],[9.60717,47.06091],[9.61216,47.07732],[9.63395,47.08443],[9.62623,47.14685],[9.56539,47.17124],[9.58264,47.20673],[9.56981,47.21926],[9.55176,47.22585],[9.56766,47.24281],[9.53116,47.27029],[9.52406,47.24959],[9.50318,47.22153],[9.4891,47.19346],[9.48774,47.17402],[9.51044,47.13727],[9.52089,47.10019],[9.51362,47.08505],[9.47139,47.06402]]]}},{"type":"Feature","properties":{"id":"CN-HN"},"geometry":{"type":"Polygon","coordinates":[[[108.78936,27.08908],[108.87451,27.00652],[109.13268,27.06462],[109.40734,27.15264],[109.49043,27.06524],[109.51652,26.75726],[109.28581,26.70022],[109.38056,26.57931],[109.28649,26.28664],[109.45129,26.30449],[109.47669,26.03334],[109.72663,26.00001],[109.68749,25.88517],[109.82276,25.88023],[109.81109,26.04259],[109.97486,26.19241],[110.09811,26.01914],[110.31028,25.96915],[110.61172,26.33465],[110.75317,26.25277],[110.9262,26.26694],[110.96328,26.3851],[111.09306,26.31188],[111.29287,26.24662],[111.19125,25.94693],[111.25579,25.85922],[111.48239,25.88208],[111.37596,25.73001],[111.30042,25.70155],[111.31347,25.47613],[110.97015,25.10922],[110.98525,24.9157],[111.28326,25.14528],[111.46179,25.02526],[111.42745,24.6832],[111.52633,24.63952],[111.68666,24.78486],[112.04166,24.77987],[112.15015,24.82662],[112.17143,24.91944],[112.11547,24.96582],[112.13504,25.00535],[112.18963,25.18987],[112.65174,25.13751],[112.70393,25.08622],[112.7798,24.89328],[113.00571,24.93999],[112.96674,25.16361],[113.02854,25.20059],[112.98923,25.24857],[112.8713,25.24857],[112.84984,25.34278],[112.89653,25.31501],[113.01721,25.34976],[113.12725,25.47039],[113.26217,25.51486],[113.56635,25.30802],[113.98315,25.40916],[113.91448,25.69908],[114.00787,25.89258],[114.02606,26.021],[114.23789,26.20042],[113.94058,26.18193],[114.07482,26.40847],[114.104,26.57624],[113.91208,26.61277],[113.86402,26.65513],[113.83895,26.79342],[113.91517,26.94716],[113.77715,27.11781],[113.875,27.38548],[113.62232,27.34859],[113.62232,27.41017],[113.5976,27.42114],[113.59863,27.63365],[113.75656,27.81782],[113.72085,27.8755],[113.74351,27.9477],[114.03945,28.06289],[113.99963,28.15253],[114.25094,28.38233],[114.07653,28.55919],[114.14932,28.77187],[114.01817,28.89758],[113.9447,29.05196],[113.85749,29.04056],[113.81835,29.10837],[113.69132,29.06637],[113.69132,29.2187],[113.59588,29.25914],[113.7569,29.44767],[113.62403,29.52118],[113.7363,29.58928],[113.56704,29.67254],[113.51898,29.82813],[113.15505,29.46112],[112.94769,29.47188],[112.9264,29.69014],[112.8955,29.79328],[112.80796,29.74917],[112.68093,29.59734],[112.46566,29.6433],[112.28713,29.50147],[112.2377,29.65673],[112.10861,29.66001],[112.06706,29.73188],[111.95548,29.82843],[111.79447,29.91209],[111.6053,29.89006],[111.51912,29.93232],[111.40274,29.91268],[111.24481,30.04383],[110.94646,30.06493],[110.75729,30.12523],[110.75386,30.04888],[110.52246,30.06523],[110.4943,29.91923],[110.64742,29.77272],[110.37036,29.63345],[110.14514,29.78374],[109.78637,29.76556],[109.70088,29.60928],[109.53609,29.62331],[109.45678,29.55613],[109.2346,29.11829],[109.31877,29.05827],[109.23208,28.87985],[109.23688,28.78255],[109.29885,28.73018],[109.18556,28.63184],[109.19466,28.60275],[109.29671,28.62913],[109.31576,28.58595],[109.29121,28.57268],[109.27645,28.52202],[109.26727,28.51787],[109.26898,28.50437],[109.26993,28.49849],[109.25302,28.4711],[109.2616,28.39034],[109.28495,28.3772],[109.26881,28.3145],[109.39807,28.27717],[109.29336,28.05531],[109.38056,28.03683],[109.31533,27.9856],[109.33799,27.78198],[109.46708,27.69508],[109.45197,27.5722],[109.2937,27.42541],[109.14642,27.45344],[109.10659,27.3495],[109.04651,27.33578],[109.0472,27.29643],[108.78936,27.08908]]]}},{"type":"Feature","properties":{"id":"LS"},"geometry":{"type":"Polygon","coordinates":[[[27.01016,-29.65439],[27.09489,-29.72796],[27.22719,-30.00718],[27.29603,-30.05473],[27.32555,-30.14785],[27.40778,-30.14577],[27.37293,-30.19401],[27.36649,-30.27246],[27.38108,-30.33456],[27.45452,-30.32239],[27.56901,-30.42504],[27.56781,-30.44562],[27.62137,-30.50509],[27.6521,-30.51707],[27.67819,-30.53437],[27.69467,-30.55862],[27.74814,-30.60635],[28.12073,-30.68072],[28.2319,-30.28476],[28.399,-30.1592],[28.68627,-30.12885],[28.80222,-30.10579],[28.9338,-30.05072],[29.16548,-29.91706],[29.12553,-29.76266],[29.28545,-29.58456],[29.33204,-29.45598],[29.44883,-29.3772],[29.40524,-29.21246],[28.68043,-28.58744],[28.65091,-28.57025],[28.40612,-28.6215],[28.30518,-28.69531],[28.2348,-28.69471],[28.1317,-28.7293],[28.02503,-28.85991],[27.98675,-28.8787],[27.9392,-28.84864],[27.88933,-28.88156],[27.8907,-28.91612],[27.75458,-28.89839],[27.55974,-29.18954],[27.5158,-29.2261],[27.54258,-29.25575],[27.48679,-29.29349],[27.45125,-29.29708],[27.47254,-29.31968],[27.4358,-29.33465],[27.33464,-29.48161],[27.01016,-29.65439]]]}},{"type":"Feature","properties":{"id":"LT"},"geometry":{"type":"Polygon","coordinates":[[[20.60454,55.40986],[20.95181,55.27994],[21.26425,55.24456],[21.35465,55.28427],[21.38446,55.29348],[21.46766,55.21115],[21.51095,55.18507],[21.55605,55.20311],[21.64954,55.1791],[21.85521,55.09493],[21.96505,55.07353],[21.99543,55.08691],[22.03984,55.07888],[22.02582,55.05078],[22.06087,55.02935],[22.11697,55.02131],[22.14267,55.05345],[22.31562,55.0655],[22.47688,55.04408],[22.58907,55.07085],[22.60075,55.01863],[22.65451,54.97037],[22.68723,54.9811],[22.76422,54.92521],[22.85083,54.88711],[22.87317,54.79492],[22.73631,54.72952],[22.73397,54.66604],[22.75467,54.6483],[22.74225,54.64339],[22.7522,54.63525],[22.68021,54.58486],[22.71293,54.56454],[22.67788,54.532],[22.70208,54.45312],[22.7253,54.41732],[22.79705,54.36264],[22.83756,54.40827],[23.00584,54.38514],[22.99649,54.35927],[23.05726,54.34565],[23.04323,54.31567],[23.104,54.29794],[23.13905,54.31567],[23.15526,54.31076],[23.15938,54.29894],[23.24656,54.25701],[23.3494,54.25155],[23.39525,54.21672],[23.42418,54.17911],[23.45223,54.17775],[23.49196,54.14764],[23.52702,54.04622],[23.48261,53.98855],[23.51284,53.95052],[23.61677,53.92691],[23.71726,53.93379],[23.80543,53.89558],[23.81309,53.94205],[23.95098,53.9613],[23.98837,53.92554],[24.19638,53.96405],[24.34128,53.90076],[24.44411,53.90076],[24.62275,54.00217],[24.69652,54.01901],[24.69185,53.96543],[24.74279,53.96663],[24.85311,54.02862],[24.77131,54.11091],[24.96894,54.17589],[24.991,54.14241],[25.0728,54.13419],[25.19199,54.219],[25.22705,54.26271],[25.35559,54.26544],[25.509,54.30267],[25.56823,54.25212],[25.51452,54.17799],[25.54724,54.14925],[25.64875,54.1259],[25.71084,54.16704],[25.78563,54.15747],[25.78553,54.23327],[25.68513,54.31727],[25.55425,54.31591],[25.5376,54.33158],[25.63371,54.42075],[25.62203,54.4656],[25.64813,54.48704],[25.68045,54.5321],[25.75977,54.57252],[25.74122,54.80108],[25.89462,54.93438],[25.99129,54.95705],[26.05907,54.94631],[26.13386,54.98924],[26.20397,54.99729],[26.26941,55.08032],[26.23202,55.10439],[26.30628,55.12536],[26.35121,55.1525],[26.46249,55.12814],[26.51481,55.16051],[26.54753,55.14181],[26.69243,55.16718],[26.68075,55.19787],[26.72983,55.21788],[26.73017,55.24226],[26.835,55.28182],[26.83266,55.30444],[26.80929,55.31642],[26.6714,55.33902],[26.5709,55.32572],[26.44937,55.34832],[26.5522,55.40277],[26.55094,55.5093],[26.63167,55.57887],[26.63231,55.67968],[26.58248,55.6754],[26.46661,55.70375],[26.39561,55.71156],[26.18509,55.86813],[26.03815,55.95884],[25.90047,56.0013],[25.85893,56.00188],[25.81773,56.05444],[25.69246,56.08892],[25.68588,56.14725],[25.53621,56.16663],[25.39751,56.15707],[25.23099,56.19147],[25.09325,56.1878],[25.05762,56.26742],[24.89005,56.46666],[24.83686,56.41565],[24.70022,56.40483],[24.57353,56.31525],[24.58143,56.29125],[24.42746,56.26522],[24.32334,56.30226],[24.13139,56.24881],[24.02657,56.3231],[23.75726,56.37282],[23.49803,56.34307],[23.40486,56.37689],[23.31606,56.3827],[23.17312,56.36795],[23.09531,56.30511],[22.96988,56.41213],[22.83048,56.367],[22.69354,56.36284],[22.56441,56.39305],[22.3361,56.4016],[22.09728,56.42851],[22.00548,56.41508],[21.74558,56.33181],[21.57888,56.31406],[21.49736,56.29106],[21.24644,56.16917],[21.15016,56.07818],[20.68447,56.04073],[20.60454,55.40986]]]}},{"type":"Feature","properties":{"id":"LU"},"geometry":{"type":"Polygon","coordinates":[[[5.73621,49.89796],[5.78415,49.87922],[5.75269,49.8711],[5.75861,49.85631],[5.74567,49.85368],[5.75884,49.84811],[5.74953,49.84709],[5.74975,49.83933],[5.74076,49.83823],[5.7404,49.83452],[5.74844,49.82435],[5.74364,49.82058],[5.74953,49.81428],[5.75409,49.79239],[5.78871,49.7962],[5.82245,49.75048],[5.83149,49.74729],[5.82562,49.72395],[5.84193,49.72161],[5.86503,49.72739],[5.88677,49.70951],[5.86527,49.69291],[5.86175,49.67862],[5.9069,49.66377],[5.90164,49.6511],[5.90599,49.63853],[5.88552,49.63507],[5.88393,49.62802],[5.87609,49.62047],[5.8762,49.60898],[5.84826,49.5969],[5.84971,49.58674],[5.86986,49.58756],[5.87256,49.57539],[5.8424,49.56082],[5.84692,49.55663],[5.84143,49.5533],[5.81838,49.54777],[5.80871,49.5425],[5.81664,49.53775],[5.83648,49.5425],[5.84466,49.53027],[5.83467,49.52717],[5.83389,49.52152],[5.86571,49.50015],[5.94128,49.50034],[5.94224,49.49608],[5.96876,49.49053],[5.97693,49.45513],[6.02648,49.45451],[6.02743,49.44845],[6.04176,49.44801],[6.05553,49.46663],[6.07887,49.46399],[6.08373,49.45594],[6.10072,49.45268],[6.09845,49.46351],[6.10325,49.4707],[6.12346,49.4735],[6.12814,49.49365],[6.14321,49.48796],[6.16115,49.49297],[6.15366,49.50226],[6.17386,49.50934],[6.19543,49.50536],[6.2409,49.51408],[6.25029,49.50609],[6.27875,49.503],[6.28818,49.48465],[6.3687,49.4593],[6.36778,49.46937],[6.36907,49.48931],[6.36788,49.50377],[6.35666,49.52931],[6.38072,49.55171],[6.38228,49.55855],[6.35825,49.57053],[6.36676,49.57813],[6.38024,49.57593],[6.38342,49.5799],[6.37464,49.58886],[6.385,49.59946],[6.39822,49.60081],[6.41861,49.61723],[6.4413,49.65722],[6.43768,49.66021],[6.42726,49.66078],[6.42937,49.66857],[6.44654,49.67799],[6.46048,49.69092],[6.48014,49.69767],[6.49785,49.71118],[6.50647,49.71353],[6.5042,49.71808],[6.49694,49.72205],[6.49535,49.72645],[6.50261,49.72718],[6.51397,49.72058],[6.51805,49.72425],[6.50193,49.73291],[6.50174,49.75292],[6.51646,49.75961],[6.51828,49.76855],[6.51056,49.77515],[6.51669,49.78336],[6.50534,49.78952],[6.52169,49.79787],[6.53122,49.80666],[6.52121,49.81338],[6.51215,49.80124],[6.50647,49.80916],[6.48718,49.81267],[6.47111,49.82263],[6.45425,49.81164],[6.44131,49.81443],[6.42905,49.81091],[6.42521,49.81591],[6.40022,49.82029],[6.36576,49.85032],[6.34267,49.84974],[6.33585,49.83785],[6.32098,49.83728],[6.32303,49.85133],[6.30963,49.87021],[6.29692,49.86685],[6.28874,49.87592],[6.26146,49.88203],[6.23496,49.89972],[6.22926,49.92096],[6.21882,49.92403],[6.22608,49.929],[6.22094,49.94955],[6.19856,49.95053],[6.19089,49.96991],[6.18045,49.96611],[6.18554,49.95622],[6.17872,49.9537],[6.16466,49.97086],[6.1701,49.98518],[6.14147,49.99563],[6.14948,50.00908],[6.13806,50.01056],[6.1295,50.01849],[6.13273,50.02019],[6.13794,50.01466],[6.14666,50.02207],[6.13044,50.02929],[6.13458,50.04141],[6.11274,50.05916],[6.12055,50.09171],[6.1379,50.12964],[6.1137,50.13668],[6.12028,50.16374],[6.08577,50.17246],[6.06406,50.15344],[6.03093,50.16362],[6.02488,50.18283],[5.96453,50.17259],[5.95929,50.13295],[5.89488,50.11476],[5.8857,50.07824],[5.85474,50.06342],[5.86904,50.04614],[5.8551,50.02683],[5.81866,50.01286],[5.82331,49.99662],[5.83968,49.9892],[5.83467,49.97823],[5.81163,49.97142],[5.80833,49.96451],[5.77291,49.96056],[5.77314,49.93646],[5.73621,49.89796]]]}},{"type":"Feature","properties":{"id":"LV"},"geometry":{"type":"Polygon","coordinates":[[[19.64795,57.06466],[20.68447,56.04073],[21.15016,56.07818],[21.24644,56.16917],[21.49736,56.29106],[21.57888,56.31406],[21.74558,56.33181],[22.00548,56.41508],[22.09728,56.42851],[22.3361,56.4016],[22.56441,56.39305],[22.69354,56.36284],[22.83048,56.367],[22.96988,56.41213],[23.09531,56.30511],[23.17312,56.36795],[23.31606,56.3827],[23.40486,56.37689],[23.49803,56.34307],[23.75726,56.37282],[24.02657,56.3231],[24.13139,56.24881],[24.32334,56.30226],[24.42746,56.26522],[24.58143,56.29125],[24.57353,56.31525],[24.70022,56.40483],[24.83686,56.41565],[24.89005,56.46666],[25.05762,56.26742],[25.09325,56.1878],[25.23099,56.19147],[25.39751,56.15707],[25.53621,56.16663],[25.68588,56.14725],[25.69246,56.08892],[25.81773,56.05444],[25.85893,56.00188],[25.90047,56.0013],[26.03815,55.95884],[26.18509,55.86813],[26.39561,55.71156],[26.46661,55.70375],[26.58248,55.6754],[26.63231,55.67968],[26.64888,55.70515],[26.71802,55.70645],[26.76872,55.67658],[26.87448,55.7172],[26.97153,55.8102],[27.1559,55.85032],[27.27804,55.78299],[27.3541,55.8089],[27.61683,55.78558],[27.63065,55.89687],[27.97865,56.11849],[28.15217,56.16964],[28.23716,56.27588],[28.16599,56.37806],[28.19057,56.44637],[28.10069,56.524],[28.13526,56.57989],[28.04768,56.59004],[27.86101,56.88204],[27.66511,56.83921],[27.86101,57.29402],[27.52453,57.42826],[27.56832,57.53728],[27.34698,57.52242],[26.90364,57.62823],[26.54675,57.51813],[26.46527,57.56885],[26.29253,57.59244],[26.1866,57.6849],[26.2029,57.7206],[26.08098,57.76619],[26.0543,57.76105],[26.03332,57.7718],[26.02415,57.76865],[26.02069,57.77169],[26.0266,57.77441],[26.027,57.78158],[26.02456,57.78342],[26.0324,57.79037],[26.05949,57.84744],[25.73499,57.90193],[25.29581,58.08288],[25.28237,57.98539],[25.19484,58.0831],[24.3579,57.87471],[24.26221,57.91787],[23.20055,57.56697],[22.80496,57.87798],[19.84909,57.57876],[19.64795,57.06466]]]}},{"type":"Feature","properties":{"id":"MC"},"geometry":{"type":"Polygon","coordinates":[[[7.40903,43.7296],[7.41855,43.72479],[7.50102,43.51859],[7.53358,43.53609],[7.45448,43.7432],[7.4379,43.74963],[7.4389,43.75151],[7.43708,43.75197],[7.43624,43.75014],[7.43013,43.74895],[7.42809,43.74396],[7.42443,43.74087],[7.42299,43.74176],[7.42062,43.73977],[7.41233,43.73439],[7.41298,43.73311],[7.41291,43.73168],[7.41113,43.73156],[7.40903,43.7296]]]}},{"type":"Feature","properties":{"id":"MD"},"geometry":{"type":"Polygon","coordinates":[[[26.62823,48.25804],[26.81161,48.25049],[26.87708,48.19919],[26.94265,48.1969],[26.98042,48.15752],[26.96119,48.13003],[27.04118,48.12522],[27.02985,48.09083],[27.15622,47.98538],[27.1618,47.92391],[27.29069,47.73722],[27.25519,47.71366],[27.32202,47.64009],[27.3979,47.59473],[27.47942,47.48113],[27.55731,47.46637],[27.60263,47.32507],[27.68706,47.28962],[27.73172,47.29248],[27.81892,47.1381],[28.09095,46.97621],[28.12173,46.82283],[28.24808,46.64305],[28.22281,46.50481],[28.25769,46.43334],[28.18902,46.35283],[28.19864,46.31869],[28.10937,46.22852],[28.13684,46.18099],[28.08612,46.01105],[28.13111,45.92819],[28.16568,45.6421],[28.08927,45.6051],[28.18741,45.47358],[28.21139,45.46895],[28.30201,45.54744],[28.41836,45.51715],[28.43072,45.48538],[28.51449,45.49982],[28.49252,45.56716],[28.54196,45.58062],[28.51587,45.6613],[28.47879,45.66994],[28.52823,45.73803],[28.70401,45.78019],[28.69852,45.81753],[28.78503,45.83475],[28.74383,45.96664],[28.98004,46.00385],[29.00613,46.04962],[28.94643,46.09176],[29.06656,46.19716],[28.94953,46.25852],[28.98478,46.31803],[29.004,46.31495],[28.9306,46.45699],[29.01241,46.46177],[29.02409,46.49582],[29.23547,46.55435],[29.24886,46.37912],[29.35357,46.49505],[29.49914,46.45889],[29.5939,46.35472],[29.6763,46.36041],[29.66359,46.4215],[29.74496,46.45605],[29.88329,46.35851],[29.94114,46.40114],[30.09103,46.38694],[30.16794,46.40967],[30.02511,46.45132],[29.88916,46.54302],[29.94409,46.56002],[29.9743,46.75325],[29.94522,46.80055],[29.98814,46.82358],[29.87405,46.88199],[29.75458,46.8604],[29.72986,46.92234],[29.57056,46.94766],[29.62137,47.05069],[29.61038,47.09932],[29.53044,47.07851],[29.49732,47.12878],[29.57696,47.13581],[29.54996,47.24962],[29.59665,47.25521],[29.5733,47.36508],[29.48678,47.36043],[29.47854,47.30366],[29.39889,47.30179],[29.3261,47.44664],[29.18603,47.43387],[29.11743,47.55001],[29.22414,47.60012],[29.22242,47.73607],[29.27255,47.79953],[29.20663,47.80367],[29.27804,47.88893],[29.19839,47.89261],[29.1723,47.99013],[28.9306,47.96255],[28.8414,48.03392],[28.85232,48.12506],[28.69896,48.13106],[28.53921,48.17453],[28.48428,48.0737],[28.42454,48.12047],[28.43701,48.15832],[28.38712,48.17567],[28.34009,48.13147],[28.30609,48.14018],[28.30586,48.1597],[28.34912,48.1787],[28.36996,48.20543],[28.35519,48.24957],[28.32508,48.23384],[28.2856,48.23202],[28.19314,48.20749],[28.17666,48.25963],[28.07504,48.23494],[28.09873,48.3124],[28.04527,48.32661],[27.95883,48.32368],[27.88391,48.36699],[27.87533,48.4037],[27.81902,48.41874],[27.79225,48.44244],[27.74422,48.45926],[27.6658,48.44034],[27.59027,48.46311],[27.5889,48.49224],[27.46942,48.454],[27.44333,48.41209],[27.37741,48.41026],[27.37604,48.44398],[27.32159,48.4434],[27.27855,48.37534],[27.13434,48.37288],[27.08078,48.43214],[27.0231,48.42485],[27.03821,48.37653],[26.93384,48.36558],[26.85556,48.41095],[26.71274,48.40388],[26.82809,48.31629],[26.79239,48.29071],[26.6839,48.35828],[26.62823,48.25804]]]}},{"type":"Feature","properties":{"id":"MG"},"geometry":{"type":"Polygon","coordinates":[[[40.40841,-23.17181],[42.93867,-25.64228],[47.18248,-26.33102],[51.94557,-12.74579],[48.86266,-10.8109],[47.29063,-12.45583],[43.72277,-16.09877],[40.40841,-23.17181]]]}},{"type":"Feature","properties":{"id":"MK"},"geometry":{"type":"Polygon","coordinates":[[[20.45331,41.51436],[20.49039,41.49277],[20.51301,41.442],[20.55976,41.4087],[20.52119,41.34381],[20.49432,41.33679],[20.51068,41.2323],[20.59715,41.13644],[20.58546,41.11179],[20.59832,41.09066],[20.63454,41.0889],[20.65558,41.08009],[20.71634,40.91781],[20.73504,40.9081],[20.81567,40.89662],[20.83671,40.92752],[20.94305,40.92399],[20.97693,40.90103],[20.97887,40.85475],[21.15262,40.85546],[21.21105,40.8855],[21.25779,40.86165],[21.35595,40.87578],[21.41555,40.9173],[21.53007,40.90759],[21.57448,40.86076],[21.69601,40.9429],[21.7556,40.92525],[21.91102,41.04786],[21.90869,41.09191],[22.06527,41.15617],[22.1424,41.12449],[22.17629,41.15969],[22.26744,41.16409],[22.42285,41.11921],[22.5549,41.13065],[22.58295,41.11568],[22.62852,41.14385],[22.65306,41.18168],[22.71266,41.13945],[22.74538,41.16321],[22.76408,41.32225],[22.81199,41.3398],[22.93334,41.34104],[22.96331,41.35782],[22.95513,41.63265],[23.03342,41.71034],[23.01239,41.76527],[22.96682,41.77137],[22.90254,41.87587],[22.86749,42.02275],[22.67701,42.06614],[22.51224,42.15457],[22.50289,42.19527],[22.47251,42.20393],[22.38136,42.30339],[22.34773,42.31725],[22.29275,42.34913],[22.29605,42.37477],[22.16384,42.32103],[22.02908,42.29848],[21.94405,42.34669],[21.91595,42.30392],[21.84654,42.3247],[21.77176,42.2648],[21.70111,42.23789],[21.58992,42.25915],[21.52145,42.24465],[21.50823,42.27156],[21.43882,42.2789],[21.43882,42.23609],[21.38428,42.24465],[21.30496,42.1418],[21.29913,42.13954],[21.31983,42.10993],[21.22728,42.08909],[21.16614,42.19815],[21.11491,42.20794],[20.75464,42.05229],[20.76786,41.91839],[20.68523,41.85318],[20.59524,41.8818],[20.55976,41.87068],[20.57144,41.7897],[20.53405,41.78099],[20.51301,41.72433],[20.52937,41.69292],[20.51769,41.65975],[20.55508,41.58113],[20.52103,41.56473],[20.45809,41.5549],[20.45331,41.51436]]]}},{"type":"Feature","properties":{"id":"ML"},"geometry":{"type":"Polygon","coordinates":[[[-12.23936,14.76324],[-11.93043,13.84505],[-12.06897,13.71049],[-11.83345,13.33333],[-11.63025,13.39174],[-11.39935,12.97808],[-11.37536,12.40788],[-11.50006,12.17826],[-11.24136,12.01286],[-10.99758,12.24634],[-10.80355,12.1053],[-10.71897,11.91552],[-10.30604,12.24634],[-9.714,12.0226],[-9.63938,12.18312],[-9.32097,12.29009],[-9.38067,12.48446],[-9.13689,12.50875],[-8.94784,12.34842],[-8.80854,11.66715],[-8.40058,11.37466],[-8.66923,10.99397],[-8.35083,11.06234],[-8.2667,10.91762],[-8.32614,10.69273],[-8.22711,10.41722],[-8.10207,10.44649],[-7.9578,10.2703],[-7.97971,10.17117],[-7.92107,10.15577],[-7.63048,10.46334],[-7.54462,10.40921],[-7.52261,10.4655],[-7.44555,10.44602],[-7.3707,10.24677],[-7.13331,10.24877],[-7.0603,10.14711],[-7.00966,10.15794],[-6.97444,10.21644],[-7.01186,10.25111],[-6.93921,10.35291],[-6.68164,10.35074],[-6.63541,10.66893],[-6.52974,10.59104],[-6.42847,10.5694],[-6.40646,10.69922],[-6.325,10.68624],[-6.24795,10.74248],[-6.1731,10.46983],[-6.18851,10.24244],[-5.99478,10.19694],[-5.78124,10.43952],[-5.65135,10.46767],[-5.51058,10.43177],[-5.46643,10.56074],[-5.47083,10.75329],[-5.41579,10.84628],[-5.49284,11.07538],[-5.32994,11.13371],[-5.32553,11.21578],[-5.25949,11.24816],[-5.25509,11.36905],[-5.20665,11.43811],[-5.22867,11.60421],[-5.29251,11.61715],[-5.26389,11.75728],[-5.40258,11.8327],[-5.26389,11.84778],[-5.07897,11.97918],[-4.72893,12.01579],[-4.70692,12.06746],[-4.62987,12.06531],[-4.62546,12.13204],[-4.54841,12.1385],[-4.57703,12.19875],[-4.41412,12.31922],[-4.47356,12.71252],[-4.238,12.71467],[-4.21819,12.95722],[-4.34477,13.12927],[-3.96501,13.49778],[-3.90558,13.44375],[-3.96282,13.38164],[-3.7911,13.36665],[-3.54454,13.1781],[-3.4313,13.1588],[-3.43507,13.27272],[-3.23599,13.29035],[-3.28396,13.5422],[-3.26407,13.70699],[-2.88189,13.64921],[-2.90831,13.81174],[-2.84667,14.05532],[-2.66175,14.14713],[-2.47587,14.29671],[-2.10223,14.14878],[-1.9992,14.19011],[-1.97945,14.47709],[-1.68083,14.50023],[-1.32166,14.72774],[-1.05875,14.7921],[-0.72004,15.08655],[-0.24673,15.07805],[0.06588,14.96961],[0.23859,15.00135],[0.72632,14.95898],[0.96711,14.98275],[1.31275,15.27978],[3.01806,15.34571],[3.03134,15.42221],[3.50368,15.35934],[4.19893,16.39923],[4.21787,17.00118],[4.26762,17.00432],[4.26651,19.14224],[3.36082,18.9745],[3.12501,19.1366],[3.24648,19.81703],[1.20992,20.73533],[1.15698,21.12843],[-4.83423,24.99935],[-6.57191,25.0002],[-5.60725,16.49919],[-5.33435,16.33354],[-5.50165,15.50061],[-9.32979,15.50032],[-9.31106,15.69412],[-9.33314,15.7044],[-9.44673,15.60553],[-9.40447,15.4396],[-10.71721,15.4223],[-10.90932,15.11001],[-11.43483,15.62339],[-11.70705,15.51558],[-11.94903,14.76143],[-12.23936,14.76324]]]}},{"type":"Feature","properties":{"id":"MM"},"geometry":{"type":"Polygon","coordinates":[[[92.17752,21.17445],[92.26071,21.05697],[92.37665,20.72172],[92.28464,20.63179],[92.31348,20.57137],[92.4302,20.5688],[92.39837,20.38919],[92.61282,13.95915],[93.69443,13.6468],[94.6395,14.00732],[97.16045,11.79791],[97.63455,9.60854],[98.21525,9.56576],[98.33094,9.91973],[98.47298,9.95782],[98.52291,9.92389],[98.55174,9.92804],[98.7391,10.31488],[98.81944,10.52761],[98.77275,10.62548],[98.78511,10.68351],[98.86819,10.78336],[99.0069,10.85485],[98.99701,10.92962],[99.02337,10.97217],[99.06938,10.94857],[99.32756,11.28545],[99.31573,11.32081],[99.39485,11.3925],[99.47598,11.62434],[99.5672,11.62732],[99.64108,11.78948],[99.64891,11.82699],[99.53424,12.02317],[99.56445,12.14805],[99.47519,12.1353],[99.409,12.60603],[99.29254,12.68921],[99.18905,12.84799],[99.18748,12.9898],[99.10646,13.05804],[99.12225,13.19847],[99.20617,13.20575],[99.16695,13.72621],[98.97356,14.04868],[98.56762,14.37701],[98.24874,14.83013],[98.18821,15.13125],[98.22,15.21327],[98.30446,15.30667],[98.40522,15.25268],[98.41906,15.27103],[98.39351,15.34177],[98.4866,15.39154],[98.56027,15.33471],[98.58598,15.46821],[98.541,15.65406],[98.59853,15.87197],[98.57019,16.04578],[98.69585,16.13353],[98.8376,16.11706],[98.92656,16.36425],[98.84485,16.42354],[98.68074,16.27068],[98.63817,16.47424],[98.57912,16.55983],[98.5695,16.62826],[98.51113,16.64503],[98.51833,16.676],[98.51472,16.68521],[98.51579,16.69433],[98.51043,16.70107],[98.49713,16.69022],[98.50253,16.7139],[98.46994,16.73613],[98.53833,16.81934],[98.49603,16.8446],[98.52624,16.89979],[98.39441,17.06266],[98.34566,17.04822],[98.10439,17.33847],[98.11185,17.36829],[97.91829,17.54504],[97.76407,17.71595],[97.66794,17.88005],[97.73723,17.97912],[97.60841,18.23846],[97.64116,18.29778],[97.56219,18.33885],[97.50383,18.26844],[97.34522,18.54596],[97.36444,18.57138],[97.5258,18.4939],[97.76752,18.58097],[97.73836,18.88478],[97.66487,18.9371],[97.73654,18.9812],[97.73797,19.04261],[97.83479,19.09972],[97.84024,19.22217],[97.78606,19.26769],[97.84186,19.29526],[97.78769,19.39429],[97.88423,19.5041],[97.84715,19.55782],[98.04364,19.65755],[98.03314,19.80941],[98.13829,19.78541],[98.24884,19.67876],[98.51182,19.71303],[98.56065,19.67807],[98.83661,19.80931],[98.98679,19.7419],[99.0735,20.10298],[99.20328,20.12877],[99.416,20.08614],[99.52943,20.14811],[99.5569,20.20676],[99.46077,20.36198],[99.46008,20.39673],[99.68255,20.32077],[99.81096,20.33687],[99.86383,20.44371],[99.88211,20.44488],[99.88451,20.44596],[99.89168,20.44548],[99.89301,20.44311],[99.89692,20.44789],[99.90499,20.4487],[99.91616,20.44986],[99.95721,20.46301],[100.08404,20.36626],[100.1957,20.68247],[100.36375,20.82783],[100.51079,20.82194],[100.60112,20.8347],[100.64628,20.88279],[100.50974,20.88574],[100.55281,21.02796],[100.63578,21.05639],[100.72716,21.31786],[100.80173,21.2934],[101.00234,21.39612],[101.16198,21.52808],[101.15156,21.56129],[101.11744,21.77659],[100.87265,21.67396],[100.72143,21.51898],[100.57861,21.45637],[100.4811,21.46148],[100.42892,21.54325],[100.35201,21.53176],[100.25863,21.47043],[100.18447,21.51898],[100.1625,21.48704],[100.12542,21.50365],[100.10757,21.59945],[100.17486,21.65306],[100.12679,21.70539],[100.04956,21.66843],[99.98654,21.71064],[99.94003,21.82782],[99.99084,21.97053],[99.96612,22.05965],[99.85351,22.04183],[99.47585,22.13345],[99.33166,22.09656],[99.1552,22.15874],[99.19176,22.16983],[99.17318,22.18025],[99.28771,22.4105],[99.37972,22.50188],[99.38247,22.57544],[99.31243,22.73893],[99.45654,22.85726],[99.43537,22.94086],[99.54218,22.90014],[99.52214,23.08218],[99.34127,23.13099],[99.25741,23.09025],[99.04601,23.12215],[99.05975,23.16382],[98.88597,23.18656],[98.92515,23.29535],[98.93958,23.31414],[98.87573,23.33038],[98.92104,23.36946],[98.87683,23.48995],[98.82877,23.47908],[98.80294,23.5345],[98.88396,23.59555],[98.81775,23.694],[98.82933,23.72921],[98.79607,23.77947],[98.68209,23.80492],[98.67797,23.9644],[98.89632,24.10612],[98.87998,24.15624],[98.85319,24.13042],[98.59256,24.08371],[98.54476,24.13119],[98.20666,24.11406],[98.07806,24.07988],[98.06703,24.08028],[98.0607,24.07812],[98.05671,24.07961],[98.05302,24.07408],[98.04709,24.07616],[97.99583,24.04932],[97.98691,24.03897],[97.93951,24.01953],[97.90998,24.02094],[97.88616,24.00463],[97.88414,23.99405],[97.88814,23.98605],[97.89683,23.98389],[97.89676,23.97931],[97.8955,23.97758],[97.88811,23.97446],[97.86545,23.97723],[97.84328,23.97603],[97.79416,23.95663],[97.79456,23.94836],[97.72302,23.89288],[97.64667,23.84574],[97.5247,23.94032],[97.62363,24.00506],[97.72903,24.12606],[97.75305,24.16902],[97.72799,24.18883],[97.72998,24.2302],[97.76799,24.26365],[97.71941,24.29652],[97.66723,24.30027],[97.65624,24.33781],[97.7098,24.35658],[97.66998,24.45288],[97.60029,24.4401],[97.52757,24.43748],[97.56286,24.54535],[97.56525,24.72838],[97.54675,24.74202],[97.5542,24.74943],[97.56383,24.75535],[97.56648,24.76475],[97.64354,24.79171],[97.70181,24.84557],[97.73127,24.83015],[97.76481,24.8289],[97.79949,24.85655],[97.72903,24.91332],[97.72216,25.08508],[97.77023,25.11492],[97.83614,25.2715],[97.92541,25.20815],[98.14925,25.41547],[98.12591,25.50722],[98.18084,25.56298],[98.16848,25.62739],[98.25774,25.6051],[98.31268,25.55307],[98.40606,25.61129],[98.54064,25.85129],[98.63128,25.79937],[98.70818,25.86241],[98.60763,26.01512],[98.57085,26.11547],[98.63128,26.15492],[98.66884,26.09165],[98.7329,26.17218],[98.67797,26.24487],[98.72741,26.36183],[98.77547,26.61994],[98.7333,26.85615],[98.69582,27.56499],[98.43353,27.67086],[98.42529,27.55404],[98.32641,27.51385],[98.13964,27.9478],[98.15337,28.12114],[97.90069,28.3776],[97.79632,28.33168],[97.70705,28.5056],[97.56835,28.55628],[97.50518,28.49716],[97.47085,28.2688],[97.41729,28.29783],[97.34547,28.21385],[97.31292,28.06784],[97.35412,28.06663],[97.38845,28.01329],[97.35824,27.87256],[97.29919,27.92233],[96.90112,27.62149],[96.91431,27.45752],[97.17422,27.14052],[97.14675,27.09041],[96.89132,27.17474],[96.85287,27.2065],[96.88445,27.25046],[96.73888,27.36638],[96.55761,27.29928],[96.40779,27.29818],[96.15591,27.24572],[96.04949,27.19428],[95.93002,27.04149],[95.81603,27.01335],[95.437,26.7083],[95.30339,26.65372],[95.23513,26.68499],[95.05798,26.45408],[95.12801,26.38397],[95.11428,26.1019],[95.18556,26.07338],[94.80117,25.49359],[94.68032,25.47003],[94.57458,25.20318],[94.74212,25.13606],[94.73937,25.00545],[94.60204,24.70889],[94.5526,24.70764],[94.50729,24.59281],[94.45279,24.56656],[94.32362,24.27692],[94.30215,24.23752],[94.14081,23.83333],[93.92089,23.95812],[93.80279,23.92549],[93.75952,24.0003],[93.62871,24.00922],[93.50616,23.94432],[93.46633,23.97067],[93.41415,24.07854],[93.34735,24.10151],[93.32351,24.04468],[93.36059,23.93176],[93.3908,23.92925],[93.3908,23.7622],[93.43475,23.68299],[93.38805,23.4728],[93.39981,23.38828],[93.38781,23.36139],[93.36862,23.35426],[93.38478,23.13698],[93.2878,23.00464],[93.12988,23.05772],[93.134,22.92498],[93.09417,22.69459],[93.134,22.59573],[93.11477,22.54374],[93.13537,22.45873],[93.18206,22.43716],[93.19991,22.25425],[93.14224,22.24535],[93.15734,22.18687],[93.04885,22.20595],[92.99255,22.05965],[92.99804,21.98964],[92.93899,22.02656],[92.89504,21.95143],[92.86208,22.05456],[92.70416,22.16017],[92.67532,22.03547],[92.60949,21.97638],[92.62187,21.87037],[92.59775,21.6092],[92.68152,21.28454],[92.60187,21.24615],[92.55105,21.3856],[92.43158,21.37025],[92.37939,21.47764],[92.20087,21.337],[92.17752,21.17445]]]}},{"type":"Feature","properties":{"id":"ME"},"geometry":{"type":"Polygon","coordinates":[[[18.43588,42.48556],[18.52152,42.42302],[18.54128,42.39171],[18.45131,42.21682],[19.26406,41.74971],[19.37597,41.84849],[19.37451,41.8842],[19.33812,41.90669],[19.34601,41.95675],[19.37691,41.96977],[19.36867,42.02564],[19.37548,42.06835],[19.40687,42.10024],[19.28623,42.17745],[19.42,42.33019],[19.42352,42.36546],[19.4836,42.40831],[19.65972,42.62774],[19.73244,42.66299],[19.77375,42.58517],[19.74731,42.57422],[19.76549,42.50237],[19.82333,42.46581],[19.9324,42.51699],[20.00842,42.5109],[20.01834,42.54622],[20.07761,42.55582],[20.0969,42.65559],[20.02915,42.71147],[20.02088,42.74789],[20.04898,42.77701],[20.2539,42.76245],[20.27869,42.81945],[20.35692,42.8335],[20.34528,42.90676],[20.16415,42.97177],[20.14896,42.99058],[20.12325,42.96237],[20.05431,42.99571],[20.04729,43.02732],[19.98887,43.0538],[19.96549,43.11098],[19.92576,43.08539],[19.79255,43.11951],[19.76918,43.16044],[19.64063,43.19027],[19.62661,43.2286],[19.54598,43.25158],[19.52962,43.31623],[19.48171,43.32644],[19.44315,43.38846],[19.22229,43.47926],[19.22807,43.5264],[19.15685,43.53943],[19.13933,43.5282],[19.04934,43.50384],[19.01078,43.55806],[18.91379,43.50299],[18.95469,43.49367],[18.96053,43.45042],[19.01078,43.43854],[19.04071,43.397],[19.08673,43.31453],[19.08206,43.29668],[19.04233,43.30008],[19.00844,43.24988],[18.95001,43.29327],[18.95819,43.32899],[18.90911,43.36383],[18.83912,43.34795],[18.84794,43.33735],[18.85342,43.32426],[18.76538,43.29838],[18.6976,43.25243],[18.71747,43.2286],[18.66605,43.2056],[18.64735,43.14766],[18.66254,43.03928],[18.52232,43.01451],[18.49076,42.95553],[18.49661,42.89306],[18.4935,42.86433],[18.47633,42.85829],[18.45921,42.81682],[18.47324,42.74992],[18.56789,42.72074],[18.55221,42.69045],[18.54603,42.69171],[18.54841,42.68328],[18.57373,42.64429],[18.52232,42.62279],[18.55504,42.58409],[18.53751,42.57376],[18.49778,42.58409],[18.43735,42.55921],[18.44307,42.51077],[18.43588,42.48556]]]}},{"type":"Feature","properties":{"id":"MN"},"geometry":{"type":"Polygon","coordinates":[[[87.73822,48.89582],[88.0788,48.71436],[87.96361,48.58478],[88.58939,48.34531],[88.58316,48.21893],[88.8011,48.11302],[88.93186,48.10263],[89.0711,47.98528],[89.55453,48.0423],[89.76624,47.82745],[90.06512,47.88177],[90.10871,47.7375],[90.33598,47.68303],[90.48854,47.41826],[90.48542,47.30438],[90.76108,46.99399],[90.84035,46.99525],[91.03649,46.72916],[91.0147,46.58171],[91.07696,46.57315],[90.89639,46.30711],[90.99672,46.14207],[91.03026,46.04194],[90.70907,45.73437],[90.65114,45.49314],[90.89169,45.19667],[91.64048,45.07408],[93.51161,44.95964],[94.10003,44.71016],[94.71959,44.35284],[95.01191,44.25274],[95.39772,44.2805],[95.32891,44.02407],[95.52594,43.99353],[95.89543,43.2528],[96.35658,42.90363],[96.37926,42.72055],[97.1777,42.7964],[99.50671,42.56535],[100.33297,42.68231],[100.84979,42.67087],[101.28833,42.58524],[101.80515,42.50074],[102.07645,42.22519],[102.42826,42.15137],[102.72403,42.14675],[103.3685,41.89696],[103.92804,41.78246],[104.52258,41.8706],[104.51667,41.66113],[104.91272,41.64619],[105.01119,41.58382],[105.24708,41.7442],[106.76517,42.28741],[107.24774,42.36107],[107.29755,42.41395],[107.49681,42.46221],[107.57258,42.40898],[108.23156,42.45532],[108.84489,42.40246],[109.00679,42.45302],[109.452,42.44842],[109.89402,42.63111],[110.08401,42.6411],[110.4327,42.78293],[111.0149,43.3289],[111.59087,43.51207],[111.79758,43.6637],[111.93776,43.68709],[111.96289,43.81596],[111.40498,44.3461],[111.76275,44.98032],[111.98695,45.09074],[112.4164,45.06858],[112.74662,44.86297],[113.63821,44.74326],[113.909,44.91444],[114.08071,44.92847],[114.5166,45.27189],[114.54801,45.38337],[114.74612,45.43585],[114.94546,45.37377],[115.35757,45.39106],[115.69688,45.45761],[115.91898,45.6227],[116.16989,45.68603],[116.27366,45.78637],[116.24012,45.8778],[116.26678,45.96479],[116.58612,46.30211],[116.75551,46.33083],[116.83166,46.38637],[117.07252,46.35818],[117.36609,46.36335],[117.41782,46.57862],[117.60748,46.59771],[117.69554,46.50991],[118.30534,46.73519],[118.78747,46.68689],[118.8337,46.77742],[118.89974,46.77139],[118.92616,46.72765],[119.00541,46.74273],[119.10448,46.65516],[119.24978,46.64761],[119.30261,46.6083],[119.37306,46.61132],[119.42827,46.63783],[119.65265,46.62342],[119.68127,46.59015],[119.77373,46.62947],[119.80455,46.67631],[119.89261,46.66423],[119.91242,46.90091],[119.85518,46.92196],[119.71209,47.19192],[119.62403,47.24575],[119.56019,47.24874],[119.54918,47.29505],[119.31964,47.42617],[119.35892,47.48104],[119.13995,47.53997],[119.12343,47.66458],[118.7564,47.76947],[118.55766,47.99277],[118.29654,48.00246],[118.22677,48.03853],[118.11009,48.04],[118.03676,48.00982],[117.80196,48.01661],[117.50181,47.77216],[117.37875,47.63627],[117.08918,47.82242],[116.87527,47.88836],[116.67405,47.89039],[116.4465,47.83662],[116.2527,47.87766],[116.08431,47.80693],[115.94296,47.67741],[115.57128,47.91988],[115.52082,48.15367],[115.811,48.25699],[115.78876,48.51781],[116.06565,48.81716],[116.03781,48.87014],[116.71193,49.83813],[116.62502,49.92919],[116.22402,50.04477],[115.73602,49.87688],[115.26068,49.97367],[114.9703,50.19254],[114.325,50.28098],[113.20216,49.83356],[113.02647,49.60772],[110.64493,49.1816],[110.39891,49.25083],[110.24373,49.16676],[109.51325,49.22859],[109.18017,49.34709],[108.53969,49.32325],[108.27937,49.53167],[107.95387,49.66659],[107.96116,49.93191],[107.36407,49.97612],[107.1174,50.04239],[107.00007,50.1977],[106.80326,50.30177],[106.58373,50.34044],[106.51122,50.34408],[106.49628,50.32436],[106.47156,50.31909],[106.07865,50.33474],[106.05562,50.40582],[105.32528,50.4648],[103.70343,50.13952],[102.71178,50.38873],[102.32194,50.67982],[102.14032,51.35566],[101.5044,51.50467],[101.39085,51.45753],[100.61116,51.73028],[99.89203,51.74903],[99.75578,51.90108],[99.27888,51.96876],[98.87768,52.14563],[98.74142,51.8637],[98.33222,51.71832],[98.22053,51.46579],[98.05257,51.46696],[97.83305,51.00248],[98.01472,50.86652],[97.9693,50.78044],[98.06393,50.61262],[98.31373,50.4996],[98.29481,50.33561],[97.85197,49.91339],[97.76871,49.99861],[97.56432,49.92801],[97.56811,49.84265],[97.24639,49.74737],[96.97388,49.88413],[95.80056,50.04239],[95.74757,49.97915],[95.02465,49.96941],[94.97166,50.04725],[94.6121,50.04239],[94.49477,50.17832],[94.39258,50.22193],[94.30823,50.57498],[92.99595,50.63183],[93.01109,50.79001],[92.44714,50.78762],[92.07173,50.69585],[91.86048,50.73734],[89.59711,49.90851],[89.70687,49.72535],[88.82499,49.44808],[88.42449,49.48821],[88.17223,49.46934],[88.15543,49.30314],[87.98977,49.18147],[87.81333,49.17354],[87.88171,48.95853],[87.73822,48.89582]]]}},{"type":"Feature","properties":{"id":"MZ"},"geometry":{"type":"Polygon","coordinates":[[[30.22098,-14.99447],[30.41902,-15.62269],[30.42568,-15.9962],[30.91597,-15.99924],[30.97761,-16.05848],[31.13171,-15.98019],[31.30563,-16.01193],[31.42451,-16.15154],[31.67988,-16.19595],[31.90223,-16.34388],[31.91324,-16.41569],[32.02772,-16.43892],[32.28529,-16.43892],[32.42838,-16.4727],[32.71017,-16.59932],[32.69917,-16.66893],[32.78943,-16.70267],[32.97655,-16.70689],[32.91051,-16.89446],[32.84113,-16.92259],[32.96554,-17.11971],[33.00517,-17.30477],[33.0426,-17.3468],[32.96554,-17.48964],[32.98536,-17.55891],[33.0492,-17.60298],[32.94133,-17.99705],[33.03159,-18.35054],[33.02278,-18.4696],[32.88629,-18.51344],[32.88629,-18.58023],[32.95013,-18.69079],[32.9017,-18.7992],[32.82465,-18.77419],[32.70137,-18.84712],[32.73439,-18.92628],[32.69917,-18.94293],[32.72118,-19.02204],[32.84006,-19.0262],[32.87088,-19.09279],[32.85107,-19.29238],[32.77966,-19.36098],[32.78282,-19.47513],[32.84446,-19.48343],[32.84666,-19.68462],[32.95013,-19.67219],[33.06461,-19.77787],[33.01178,-20.02007],[32.93032,-20.03868],[32.85987,-20.16686],[32.85987,-20.27841],[32.66174,-20.56106],[32.55167,-20.56312],[32.48122,-20.63319],[32.51644,-20.91929],[32.37115,-21.133],[32.48236,-21.32873],[32.41234,-21.31246],[31.38336,-22.36919],[31.30611,-22.422],[31.55779,-23.176],[31.56539,-23.47268],[31.67942,-23.60858],[31.70223,-23.72695],[31.77445,-23.90082],[31.87707,-23.95293],[31.90368,-24.18892],[31.9835,-24.29983],[32.03196,-25.10785],[32.01676,-25.38117],[31.97875,-25.46356],[32.00631,-25.65044],[31.92649,-25.84216],[31.974,-25.95387],[32.00916,-25.999],[32.08599,-26.00978],[32.10435,-26.15656],[32.07352,-26.40185],[32.13409,-26.5317],[32.13315,-26.84345],[32.19409,-26.84032],[32.22302,-26.84136],[32.29584,-26.852],[32.35222,-26.86027],[32.89816,-26.8579],[33.10054,-26.92273],[39.10324,-21.48967],[41.06663,-17.08802],[42.99868,-12.65261],[42.93552,-11.11413],[40.74206,-10.25691],[40.44265,-10.4618],[40.00295,-10.80255],[39.58249,-10.96043],[39.24395,-11.17433],[38.88996,-11.16978],[38.47258,-11.4199],[38.21598,-11.27289],[37.93618,-11.26228],[37.8388,-11.3123],[37.76614,-11.53352],[37.3936,-11.68949],[36.80309,-11.56836],[36.62068,-11.72884],[36.19094,-11.70008],[36.19094,-11.57593],[35.82767,-11.41081],[35.63599,-11.55927],[34.96296,-11.57354],[34.64241,-11.57499],[34.57917,-11.87849],[34.82903,-12.04837],[34.70739,-12.15652],[34.46088,-12.0174],[34.37831,-12.17408],[34.60253,-13.48487],[34.86229,-13.48958],[35.47989,-14.15594],[35.5299,-14.27714],[35.86945,-14.67481],[35.87212,-14.89478],[35.91812,-14.89514],[35.78799,-15.17428],[35.85303,-15.41913],[35.80487,-16.03907],[35.70107,-16.10147],[35.52365,-16.15414],[35.43355,-16.11371],[35.30157,-16.2211],[35.25828,-16.4792],[35.14235,-16.56812],[35.27219,-16.69402],[35.30929,-16.82871],[35.27065,-16.93817],[35.3062,-17.1244],[35.0923,-17.13235],[35.04805,-17.00027],[35.17017,-16.93521],[35.13771,-16.81687],[35.04805,-16.83167],[34.40344,-16.20923],[34.43126,-16.04737],[34.25195,-15.90321],[34.44981,-15.60864],[34.43126,-15.44778],[34.57503,-15.30619],[34.61522,-14.99583],[34.567,-14.77345],[34.54503,-14.74672],[34.52057,-14.68263],[34.53516,-14.67782],[34.55112,-14.64494],[34.53962,-14.59776],[34.52366,-14.5667],[34.49636,-14.55091],[34.48932,-14.53646],[34.47628,-14.53363],[34.45053,-14.49873],[34.44641,-14.47746],[34.4192,-14.43191],[34.39277,-14.39467],[34.35843,-14.38652],[34.34453,-14.3985],[34.22355,-14.43607],[34.18733,-14.43823],[34.08588,-14.48893],[33.92898,-14.47929],[33.88503,-14.51652],[33.7247,-14.4989],[33.66677,-14.61306],[33.24249,-14.00019],[30.22098,-14.99447]]]}},{"type":"Feature","properties":{"id":"MR"},"geometry":{"type":"Polygon","coordinates":[[[-17.15288,16.07139],[-16.50854,16.09032],[-16.48967,16.0496],[-16.44814,16.09753],[-16.4429,16.20605],[-16.27016,16.51565],[-15.6509,16.50315],[-15.00557,16.64997],[-14.32144,16.61495],[-13.80075,16.13961],[-13.43135,16.09022],[-13.11029,15.52116],[-12.23936,14.76324],[-11.94903,14.76143],[-11.70705,15.51558],[-11.43483,15.62339],[-10.90932,15.11001],[-10.71721,15.4223],[-9.40447,15.4396],[-9.44673,15.60553],[-9.33314,15.7044],[-9.31106,15.69412],[-9.32979,15.50032],[-5.50165,15.50061],[-5.33435,16.33354],[-5.60725,16.49919],[-6.57191,25.0002],[-4.83423,24.99935],[-8.66674,27.31569],[-8.66721,25.99918],[-12.0002,25.9986],[-12.00251,23.4538],[-12.14969,23.41935],[-12.36213,23.3187],[-12.5741,23.28975],[-13.00412,23.02297],[-13.10753,22.89493],[-13.15313,22.75649],[-13.08438,22.53866],[-13.01525,21.33343],[-16.95474,21.33997],[-16.99806,21.12142],[-17.0357,21.05368],[-17.0396,20.9961],[-17.06781,20.92697],[-17.0695,20.85742],[-17.0471,20.76408],[-17.15288,16.07139]]]}},{"type":"Feature","properties":{"id":"MW"},"geometry":{"type":"Polygon","coordinates":[[[32.66468,-13.60019],[32.68654,-13.64268],[32.7828,-13.64805],[32.84528,-13.71576],[32.76962,-13.77224],[32.79015,-13.80755],[32.88985,-13.82956],[32.99042,-13.95689],[33.02977,-14.05022],[33.07568,-13.98447],[33.16749,-13.93992],[33.24249,-14.00019],[33.66677,-14.61306],[33.7247,-14.4989],[33.88503,-14.51652],[33.92898,-14.47929],[34.08588,-14.48893],[34.18733,-14.43823],[34.22355,-14.43607],[34.34453,-14.3985],[34.35843,-14.38652],[34.39277,-14.39467],[34.4192,-14.43191],[34.44641,-14.47746],[34.45053,-14.49873],[34.47628,-14.53363],[34.48932,-14.53646],[34.49636,-14.55091],[34.52366,-14.5667],[34.53962,-14.59776],[34.55112,-14.64494],[34.53516,-14.67782],[34.52057,-14.68263],[34.54503,-14.74672],[34.567,-14.77345],[34.61522,-14.99583],[34.57503,-15.30619],[34.43126,-15.44778],[34.44981,-15.60864],[34.25195,-15.90321],[34.43126,-16.04737],[34.40344,-16.20923],[35.04805,-16.83167],[35.13771,-16.81687],[35.17017,-16.93521],[35.04805,-17.00027],[35.0923,-17.13235],[35.3062,-17.1244],[35.27065,-16.93817],[35.30929,-16.82871],[35.27219,-16.69402],[35.14235,-16.56812],[35.25828,-16.4792],[35.30157,-16.2211],[35.43355,-16.11371],[35.52365,-16.15414],[35.70107,-16.10147],[35.80487,-16.03907],[35.85303,-15.41913],[35.78799,-15.17428],[35.91812,-14.89514],[35.87212,-14.89478],[35.86945,-14.67481],[35.5299,-14.27714],[35.47989,-14.15594],[34.86229,-13.48958],[34.60253,-13.48487],[34.37831,-12.17408],[34.46088,-12.0174],[34.70739,-12.15652],[34.82903,-12.04837],[34.57917,-11.87849],[34.64241,-11.57499],[34.96296,-11.57354],[34.91153,-11.39799],[34.79375,-11.32245],[34.63305,-11.11731],[34.61161,-11.01611],[34.67047,-10.93796],[34.65946,-10.6828],[34.57581,-10.56271],[34.51911,-10.12279],[34.54499,-10.0678],[34.03865,-9.49398],[33.95829,-9.54066],[33.9638,-9.62206],[33.93298,-9.71647],[33.76677,-9.58516],[33.48052,-9.62442],[33.31581,-9.48554],[33.14925,-9.49322],[32.99397,-9.36712],[32.95389,-9.40138],[33.00476,-9.5133],[33.00256,-9.63053],[33.05485,-9.61316],[33.10163,-9.66525],[33.12144,-9.58929],[33.2095,-9.61099],[33.31517,-9.82364],[33.36581,-9.81063],[33.37902,-9.9104],[33.31297,-10.05133],[33.53863,-10.20148],[33.54797,-10.36077],[33.70675,-10.56896],[33.47636,-10.78465],[33.28022,-10.84428],[33.25998,-10.88862],[33.39697,-11.15296],[33.29267,-11.3789],[33.29267,-11.43536],[33.23663,-11.40637],[33.24252,-11.59302],[33.32692,-11.59248],[33.33937,-11.91252],[33.25998,-12.14242],[33.3705,-12.34931],[33.47636,-12.32498],[33.54485,-12.35996],[33.37517,-12.54085],[33.28177,-12.54692],[33.18837,-12.61377],[33.05917,-12.59554],[32.94397,-12.76868],[32.96733,-12.88251],[33.02181,-12.88707],[32.98289,-13.12671],[33.0078,-13.19492],[32.86113,-13.47292],[32.84176,-13.52794],[32.73683,-13.57682],[32.68436,-13.55769],[32.66468,-13.60019]]]}},{"type":"Feature","properties":{"id":"NA"},"geometry":{"type":"Polygon","coordinates":[[[10.5065,-17.25284],[15.70388,-29.23989],[16.45332,-28.63117],[16.46592,-28.57126],[16.59922,-28.53246],[16.90446,-28.057],[17.15405,-28.08573],[17.4579,-28.68718],[18.99885,-28.89165],[19.99882,-28.42622],[19.99817,-24.76768],[19.99912,-21.99991],[20.99751,-22.00026],[20.99904,-18.31743],[21.45556,-18.31795],[23.0996,-18.00075],[23.29618,-17.99855],[23.61088,-18.4881],[24.19416,-18.01919],[24.40577,-17.95726],[24.57485,-18.07151],[24.6303,-17.9863],[24.71887,-17.9218],[24.73364,-17.89338],[24.95586,-17.79674],[25.05895,-17.84452],[25.16882,-17.78253],[25.26433,-17.79571],[25.00198,-17.58221],[24.70864,-17.49501],[24.5621,-17.52963],[24.38712,-17.46818],[24.32811,-17.49082],[24.23619,-17.47489],[23.47474,-17.62877],[21.42741,-18.02787],[21.14283,-17.94318],[18.84226,-17.80375],[18.39229,-17.38927],[14.28743,-17.38814],[13.95896,-17.43141],[13.36212,-16.98048],[12.97145,-16.98567],[12.52111,-17.24495],[12.07076,-17.15165],[11.75063,-17.25013],[10.5065,-17.25284]]]}},{"type":"Feature","properties":{"id":"NE"},"geometry":{"type":"Polygon","coordinates":[[[0.16936,14.51654],[0.38051,14.05575],[0.61924,13.68491],[0.77377,13.6866],[0.77637,13.64442],[0.99514,13.5668],[1.02813,13.46635],[1.20088,13.38951],[1.24429,13.39373],[1.28509,13.35488],[1.24516,13.33968],[1.21217,13.37853],[1.18873,13.31771],[0.99253,13.37515],[0.99167,13.10727],[2.26349,12.41915],[2.05785,12.35539],[2.39723,11.89473],[2.45824,11.98672],[2.39657,12.10952],[2.37783,12.24804],[2.6593,12.30631],[2.83978,12.40585],[3.25352,12.01467],[3.31613,11.88495],[3.48187,11.86092],[3.59375,11.70269],[3.61075,11.69181],[3.67988,11.75429],[3.67122,11.80865],[3.63063,11.83042],[3.61955,11.91847],[3.67775,11.97599],[3.63136,12.11826],[3.66364,12.25884],[3.65111,12.52223],[3.94339,12.74979],[4.10006,12.98862],[4.14367,13.17189],[4.14186,13.47586],[4.23456,13.47725],[4.4668,13.68286],[4.87425,13.78],[4.9368,13.7345],[5.07396,13.75052],[5.21026,13.73627],[5.27797,13.75474],[5.35437,13.83567],[5.52957,13.8845],[6.15771,13.64564],[6.27411,13.67835],[6.43053,13.6006],[6.69617,13.34057],[6.94445,12.99825],[7.0521,13.00076],[7.12676,13.02445],[7.22399,13.1293],[7.39241,13.09717],[7.81085,13.34902],[8.07997,13.30847],[8.25185,13.20369],[8.41853,13.06166],[8.49493,13.07519],[8.60431,13.01768],[8.64251,12.93985],[8.97413,12.83661],[9.65995,12.80614],[10.00373,13.18171],[10.19993,13.27129],[10.46731,13.28819],[10.66004,13.36422],[11.4535,13.37773],[11.88236,13.2527],[12.04209,13.14452],[12.16189,13.10056],[12.19315,13.12423],[12.47095,13.06673],[12.58033,13.27805],[12.6793,13.29157],[12.87376,13.48919],[13.05085,13.53984],[13.19844,13.52802],[13.33213,13.71195],[13.6302,13.71094],[13.47559,14.40881],[13.48259,14.46704],[13.68573,14.55276],[13.67878,14.64013],[13.809,14.72915],[13.78991,14.87519],[13.86301,15.04043],[14.37425,15.72591],[15.50373,16.89649],[15.6032,18.77402],[15.75098,19.93002],[15.99632,20.35364],[15.6721,20.70069],[15.59841,20.74039],[15.56004,20.79488],[15.55382,20.86507],[15.57248,20.92138],[15.62515,20.95395],[15.28332,21.44557],[15.20213,21.49365],[15.19692,21.99339],[14.99751,23.00539],[14.22918,22.61719],[13.5631,23.16574],[11.96886,23.51735],[7.48273,20.87258],[7.38361,20.79165],[5.8153,19.45101],[4.26651,19.14224],[4.26762,17.00432],[4.21787,17.00118],[4.19893,16.39923],[3.50368,15.35934],[3.03134,15.42221],[3.01806,15.34571],[1.31275,15.27978],[0.96711,14.98275],[0.72632,14.95898],[0.23859,15.00135],[0.16936,14.51654]]]}},{"type":"Feature","properties":{"id":"NG"},"geometry":{"type":"Polygon","coordinates":[[[2.67523,7.87825],[2.73095,7.7755],[2.73405,7.5423],[2.78668,7.5116],[2.79442,7.43486],[2.74489,7.42565],[2.76965,7.13543],[2.71702,6.95722],[2.74024,6.92802],[2.73405,6.78508],[2.78823,6.76356],[2.78204,6.70514],[2.7325,6.64057],[2.74334,6.57291],[2.70464,6.50831],[2.70566,6.38038],[2.74181,6.13349],[5.87055,3.78489],[8.34397,4.30689],[8.60302,4.87353],[8.78027,5.1243],[8.92029,5.58403],[8.83687,5.68483],[8.88156,5.78857],[8.84209,5.82562],[9.51757,6.43874],[9.70674,6.51717],[9.77824,6.79088],[9.86314,6.77756],[10.15135,7.03781],[10.21466,6.88996],[10.53639,6.93432],[10.57214,7.16345],[10.59746,7.14719],[10.60789,7.06885],[10.83727,6.9358],[10.8179,6.83377],[10.94302,6.69325],[11.09644,6.68437],[11.09495,6.51717],[11.42041,6.53789],[11.42264,6.5882],[11.51499,6.60892],[11.57755,6.74059],[11.55818,6.86186],[11.63117,6.9905],[11.87396,7.09398],[11.84864,7.26098],[11.93205,7.47812],[12.01844,7.52981],[11.99908,7.67302],[12.20909,7.97553],[12.19271,8.10826],[12.24782,8.17904],[12.26123,8.43696],[12.4489,8.52536],[12.44146,8.6152],[12.68722,8.65938],[12.71701,8.7595],[12.79,8.75361],[12.81085,8.91992],[12.90022,9.11411],[12.91958,9.33905],[12.85628,9.36698],[13.02385,9.49334],[13.22642,9.57266],[13.25472,9.76795],[13.29941,9.8296],[13.25025,9.86042],[13.24132,9.91031],[13.27409,9.93232],[13.286,9.9822],[13.25323,10.00127],[13.25025,10.03647],[13.34111,10.12299],[13.43644,10.13326],[13.5705,10.53183],[13.54964,10.61236],[13.73434,10.9255],[13.70753,10.94451],[13.7403,11.00593],[13.78945,11.00154],[13.97489,11.30258],[14.17821,11.23831],[14.6124,11.51283],[14.64591,11.66166],[14.55207,11.72001],[14.61612,11.7798],[14.6474,12.17466],[14.4843,12.35223],[14.22215,12.36533],[14.17523,12.41916],[14.20204,12.53405],[14.08251,13.0797],[13.6302,13.71094],[13.33213,13.71195],[13.19844,13.52802],[13.05085,13.53984],[12.87376,13.48919],[12.6793,13.29157],[12.58033,13.27805],[12.47095,13.06673],[12.19315,13.12423],[12.16189,13.10056],[12.04209,13.14452],[11.88236,13.2527],[11.4535,13.37773],[10.66004,13.36422],[10.46731,13.28819],[10.19993,13.27129],[10.00373,13.18171],[9.65995,12.80614],[8.97413,12.83661],[8.64251,12.93985],[8.60431,13.01768],[8.49493,13.07519],[8.41853,13.06166],[8.25185,13.20369],[8.07997,13.30847],[7.81085,13.34902],[7.39241,13.09717],[7.22399,13.1293],[7.12676,13.02445],[7.0521,13.00076],[6.94445,12.99825],[6.69617,13.34057],[6.43053,13.6006],[6.27411,13.67835],[6.15771,13.64564],[5.52957,13.8845],[5.35437,13.83567],[5.27797,13.75474],[5.21026,13.73627],[5.07396,13.75052],[4.9368,13.7345],[4.87425,13.78],[4.4668,13.68286],[4.23456,13.47725],[4.14186,13.47586],[4.14367,13.17189],[4.10006,12.98862],[3.94339,12.74979],[3.65111,12.52223],[3.66364,12.25884],[3.63136,12.11826],[3.67775,11.97599],[3.61955,11.91847],[3.63063,11.83042],[3.67122,11.80865],[3.67988,11.75429],[3.61075,11.69181],[3.59375,11.70269],[3.49175,11.29765],[3.71505,11.13015],[3.84243,10.59316],[3.78292,10.40538],[3.6844,10.46351],[3.57275,10.27185],[3.66908,10.18136],[3.54429,9.87739],[3.35383,9.83641],[3.32099,9.78032],[3.34726,9.70696],[3.25093,9.61632],[3.13928,9.47167],[3.14147,9.28375],[3.08017,9.10006],[2.77907,9.06924],[2.67523,7.87825]]]}},{"type":"Feature","properties":{"id":"NI"},"geometry":{"type":"Polygon","coordinates":[[[-88.11443,12.63306],[-86.14524,11.09059],[-85.71223,11.06868],[-85.60529,11.22607],[-84.92439,10.9497],[-84.68197,11.07568],[-83.90838,10.71161],[-83.66597,10.79916],[-83.68276,11.01562],[-82.56142,11.91792],[-82.06974,14.49418],[-83.04763,15.03256],[-83.13724,15.00002],[-83.49268,15.01158],[-83.62101,14.89448],[-83.89551,14.76697],[-84.10584,14.76353],[-84.48373,14.63249],[-84.70119,14.68078],[-84.82596,14.82212],[-84.90082,14.80489],[-85.1575,14.53934],[-85.18602,14.24929],[-85.32149,14.2562],[-85.45762,14.11304],[-85.73964,13.9698],[-85.75477,13.8499],[-86.03458,13.99181],[-86.00685,14.08474],[-86.14801,14.04317],[-86.35219,13.77157],[-86.76812,13.79605],[-86.71267,13.30348],[-86.87066,13.30641],[-86.93383,13.18677],[-86.93197,13.05313],[-87.03785,12.98682],[-87.06306,13.00892],[-87.37107,12.98646],[-87.55124,13.12523],[-87.7346,13.13228],[-88.11443,12.63306]]]}},{"type":"Feature","properties":{"id":"IN-OR"},"geometry":{"type":"Polygon","coordinates":[[[81.39221,17.81014],[81.77398,17.88596],[82.04383,18.06622],[82.25532,17.98199],[82.35351,18.14193],[82.42835,18.49198],[82.63366,18.23522],[82.82592,18.43727],[82.96737,18.33692],[83.08822,18.54081],[83.11019,18.77176],[83.37936,18.83481],[83.33816,19.01084],[83.65058,19.12311],[83.88748,18.80296],[84.03991,18.79581],[84.08128,18.74478],[84.2284,18.78883],[84.31594,18.78411],[84.50408,19.04394],[84.59369,19.02317],[84.65961,19.06925],[84.59335,19.11662],[84.70287,19.15068],[84.76158,19.07055],[85.11932,18.86211],[87.74779,20.78694],[87.43709,21.76045],[87.27264,21.81114],[87.22457,21.96024],[87.05635,21.85066],[86.94992,22.08627],[86.71371,22.1448],[86.7247,22.21569],[86.03324,22.56012],[85.96115,22.48242],[86.01779,22.30434],[85.90587,21.95801],[85.38986,22.15783],[85.22952,22.00003],[85.01426,22.10886],[85.10662,22.318],[85.05958,22.48083],[84.4876,22.40785],[84.27955,22.32467],[83.99425,22.53602],[84.04129,22.46005],[84.00421,22.37261],[83.65436,22.22967],[83.54347,22.05159],[83.58844,21.84078],[83.48167,21.81242],[83.46828,21.72569],[83.3385,21.50226],[83.40236,21.33958],[83.27499,21.3722],[83.1792,21.11044],[82.67555,21.16008],[82.4517,20.82608],[82.34252,20.85688],[82.39437,20.05302],[82.70439,20.00141],[82.72258,19.85036],[82.58285,19.76444],[82.58628,19.86263],[82.45513,19.91461],[82.34939,19.83776],[81.93809,20.09527],[81.82617,19.92558],[82.06375,19.78221],[82.2512,18.91473],[82.17945,18.90401],[82.16468,18.79094],[81.90101,18.64266],[81.84402,18.5714],[81.79664,18.477],[81.69158,18.42196],[81.706,18.39916],[81.61468,18.31052],[81.54275,18.26864],[81.50722,18.19217],[81.52679,18.16248],[81.44988,17.89707],[81.40165,17.88727],[81.39221,17.81014]]]}},{"type":"Feature","properties":{"id":"BV"},"geometry":{"type":"Polygon","coordinates":[[[2.85578,-54.70531],[3.87126,-54.71036],[3.87947,-54.15611],[2.86398,-54.15099],[2.85578,-54.70531]]]}},{"type":"Feature","properties":{"id":"NP"},"geometry":{"type":"Polygon","coordinates":[[[80.05743,28.91479],[80.06957,28.82763],[80.12125,28.82346],[80.37188,28.63371],[80.44504,28.63098],[80.52443,28.54897],[80.50575,28.6706],[80.55142,28.69182],[80.89648,28.47237],[81.08507,28.38346],[81.19847,28.36284],[81.32923,28.13521],[81.38683,28.17638],[81.48179,28.12148],[81.47867,28.08303],[81.91223,27.84995],[81.97214,27.93322],[82.06554,27.92222],[82.46405,27.6716],[82.70378,27.72122],[82.74119,27.49838],[82.93261,27.50328],[82.94938,27.46036],[83.19413,27.45632],[83.27197,27.38309],[83.2673,27.36235],[83.29999,27.32778],[83.35136,27.33885],[83.38872,27.39276],[83.39495,27.4798],[83.61288,27.47013],[83.85595,27.35797],[83.86182,27.4241],[83.93306,27.44939],[84.02229,27.43836],[84.10791,27.52399],[84.21376,27.45218],[84.25735,27.44941],[84.29315,27.39],[84.62161,27.33885],[84.69166,27.21294],[84.64496,27.04669],[84.793,26.9968],[84.82913,27.01989],[84.85754,26.98984],[84.96687,26.95599],[84.97186,26.9149],[85.00536,26.89523],[85.05592,26.88991],[85.02635,26.85381],[85.15883,26.86966],[85.19291,26.86909],[85.18046,26.80519],[85.21159,26.75933],[85.34302,26.74954],[85.47752,26.79292],[85.56471,26.84133],[85.5757,26.85955],[85.59461,26.85161],[85.61621,26.86721],[85.66239,26.84822],[85.73483,26.79613],[85.72315,26.67471],[85.76907,26.63076],[85.83126,26.61134],[85.85126,26.60866],[85.8492,26.56667],[86.02729,26.66756],[86.13596,26.60651],[86.22513,26.58863],[86.26235,26.61886],[86.31564,26.61925],[86.49726,26.54218],[86.54258,26.53819],[86.57073,26.49825],[86.61313,26.48658],[86.62686,26.46891],[86.69124,26.45169],[86.74025,26.42386],[86.76797,26.45892],[86.82898,26.43919],[86.94543,26.52076],[86.95912,26.52076],[87.01559,26.53228],[87.04691,26.58685],[87.0707,26.58571],[87.09147,26.45039],[87.14751,26.40542],[87.18863,26.40558],[87.24682,26.4143],[87.26587,26.40592],[87.26568,26.37294],[87.34568,26.34787],[87.37314,26.40815],[87.46566,26.44058],[87.51571,26.43106],[87.55274,26.40596],[87.59175,26.38342],[87.66803,26.40294],[87.67893,26.43501],[87.76004,26.40711],[87.7918,26.46737],[87.84193,26.43663],[87.89085,26.48565],[87.90115,26.44923],[88.00895,26.36029],[88.09414,26.43732],[88.09963,26.54195],[88.16452,26.64111],[88.1659,26.68177],[88.19107,26.75516],[88.12302,26.95324],[88.13422,26.98705],[88.11719,26.98758],[87.9887,27.11045],[88.01587,27.21388],[88.01646,27.21612],[88.07277,27.43007],[88.04008,27.49223],[88.19107,27.79285],[88.1973,27.85067],[88.13378,27.88015],[87.82681,27.95248],[87.72718,27.80938],[87.56996,27.84517],[87.11696,27.84104],[87.03757,27.94835],[86.75582,28.04182],[86.74181,28.10638],[86.56265,28.09569],[86.51609,27.96623],[86.42736,27.91122],[86.22966,27.9786],[86.18607,28.17364],[86.088,28.09264],[86.08333,28.02121],[86.12069,27.93047],[86.06309,27.90021],[85.94946,27.9401],[85.97813,27.99023],[85.90743,28.05144],[85.84672,28.18187],[85.74864,28.23126],[85.71907,28.38064],[85.69105,28.38475],[85.60854,28.25045],[85.59765,28.30529],[85.4233,28.32996],[85.38127,28.28336],[85.10729,28.34092],[85.18668,28.54076],[85.19135,28.62825],[85.06059,28.68562],[84.85511,28.58041],[84.62317,28.73887],[84.47528,28.74023],[84.2231,28.89571],[84.24801,29.02783],[84.18107,29.23451],[83.97559,29.33091],[83.82303,29.30513],[83.63156,29.16249],[83.44787,29.30513],[83.28131,29.56813],[83.07116,29.61957],[82.73024,29.81695],[82.5341,29.9735],[82.38622,30.02608],[82.16984,30.0692],[82.19475,30.16884],[82.10757,30.23745],[82.10135,30.35439],[81.99082,30.33423],[81.62033,30.44703],[81.41018,30.42153],[81.39928,30.21862],[81.33355,30.15303],[81.2623,30.14596],[81.29032,30.08806],[81.24362,30.0126],[81.12842,30.01395],[81.03953,30.20059],[80.93695,30.18229],[80.8778,30.13384],[80.67076,29.95732],[80.60226,29.95732],[80.56957,29.88176],[80.56247,29.86661],[80.48997,29.79566],[80.43458,29.80466],[80.41554,29.79451],[80.36803,29.73865],[80.38428,29.68513],[80.41858,29.63581],[80.37939,29.57098],[80.24322,29.44299],[80.31428,29.30784],[80.28626,29.20327],[80.24112,29.21414],[80.26602,29.13938],[80.23178,29.11626],[80.18085,29.13649],[80.05743,28.91479]]]}},{"type":"Feature","properties":{"id":"NR"},"geometry":{"type":"Polygon","coordinates":[[[166.65,-0.8],[167.2,-0.8],[167.2,-0.26],[166.65,-0.26],[166.65,-0.8]]]}},{"type":"Feature","properties":{"id":"PK"},"geometry":{"type":"Polygon","coordinates":[[[60.87231,29.86514],[61.31508,29.38903],[61.53765,29.00507],[61.65978,28.77937],[61.93581,28.55284],[62.40259,28.42703],[62.59499,28.24842],[62.79412,28.28108],[62.7638,28.02992],[62.84905,27.47627],[62.79684,27.34381],[62.80604,27.22412],[63.19649,27.25674],[63.32283,27.14437],[63.25005,27.08692],[63.25005,26.84212],[63.18688,26.83844],[63.1889,26.65072],[62.77352,26.64099],[62.31484,26.528],[62.21304,26.26601],[62.05117,26.31647],[61.89391,26.26251],[61.83831,26.07249],[61.83968,25.7538],[61.683,25.66638],[61.6433,25.27541],[61.57592,25.0492],[61.5251,24.57287],[68.11329,23.53945],[68.20763,23.85849],[68.39339,23.96838],[68.74643,23.97027],[68.7416,24.31904],[68.90914,24.33156],[68.97781,24.26021],[69.07806,24.29777],[69.19341,24.25646],[69.29778,24.28712],[69.59579,24.29777],[69.73335,24.17007],[70.03428,24.172],[70.11712,24.30915],[70.5667,24.43787],[70.57906,24.27774],[70.71502,24.23517],[70.88393,24.27398],[70.85784,24.30903],[70.94985,24.3791],[71.04461,24.34657],[71.12838,24.42662],[71.00341,24.46038],[70.97594,24.60904],[71.09405,24.69017],[70.94002,24.92843],[70.89148,25.15064],[70.66695,25.39314],[70.67382,25.68186],[70.60378,25.71898],[70.53649,25.68928],[70.37444,25.67443],[70.2687,25.71156],[70.0985,25.93238],[70.08193,26.08094],[70.17532,26.24118],[70.17532,26.55362],[70.05584,26.60398],[69.88555,26.56836],[69.50904,26.74892],[69.58519,27.18109],[70.03136,27.56627],[70.12502,27.8057],[70.37307,28.01208],[70.60927,28.02178],[70.79054,27.68423],[71.89921,27.96035],[71.9244,28.11555],[72.20329,28.3869],[72.29495,28.66367],[72.40402,28.78283],[72.94272,29.02487],[73.01337,29.16422],[73.05886,29.1878],[73.28094,29.56646],[73.3962,29.94707],[73.58665,30.01848],[73.80299,30.06969],[73.97225,30.19829],[73.95736,30.28466],[73.88993,30.36305],[74.5616,31.04153],[74.67971,31.05479],[74.6852,31.12771],[74.60006,31.13711],[74.60281,31.10419],[74.56023,31.08303],[74.51629,31.13829],[74.53223,31.30321],[74.59773,31.4136],[74.64713,31.45605],[74.59319,31.50197],[74.61517,31.55698],[74.57498,31.60382],[74.47771,31.72227],[74.58907,31.87824],[74.79919,31.95983],[74.86236,32.04485],[74.9269,32.0658],[75.00793,32.03786],[75.25649,32.10187],[75.38046,32.26836],[75.28259,32.36556],[75.03265,32.49538],[74.97634,32.45367],[74.84725,32.49075],[74.68362,32.49298],[74.67431,32.56676],[74.65251,32.56416],[74.64424,32.60985],[74.69542,32.66792],[74.65345,32.71225],[74.7113,32.84219],[74.64675,32.82604],[74.6289,32.75561],[74.45312,32.77755],[74.41467,32.90563],[74.31227,32.92795],[74.34875,32.97823],[74.31854,33.02891],[74.17571,33.07495],[74.15374,33.13477],[74.02144,33.18908],[74.01366,33.25199],[74.08782,33.26232],[74.17983,33.3679],[74.18121,33.4745],[74.10115,33.56392],[74.03576,33.56718],[73.97367,33.64061],[73.98968,33.66155],[73.96423,33.73071],[74.00891,33.75437],[74.05898,33.82089],[74.14001,33.83002],[74.26086,33.92237],[74.25262,34.01577],[74.21554,34.03853],[73.91341,34.01235],[73.88732,34.05105],[73.90677,34.10504],[73.98208,34.2522],[73.90517,34.35317],[73.8475,34.32935],[73.74862,34.34183],[73.74999,34.3781],[73.88732,34.48911],[73.89419,34.54568],[73.93951,34.57169],[73.93401,34.63386],[73.96423,34.68244],[74.12897,34.70073],[74.31239,34.79626],[74.58083,34.77386],[74.6663,34.703],[75.01479,34.64629],[75.38009,34.55021],[75.75438,34.51827],[76.04614,34.67566],[76.15463,34.6429],[76.47186,34.78965],[76.67648,34.76371],[76.74377,34.84039],[76.74514,34.92488],[76.87193,34.96906],[76.99251,34.93349],[77.11796,35.05419],[76.93465,35.39866],[76.85088,35.39754],[76.75475,35.52617],[76.77323,35.66062],[76.50961,35.8908],[76.33453,35.84296],[76.14913,35.82848],[76.15325,35.9264],[75.93028,36.13136],[76.00906,36.17511],[76.0324,36.41198],[75.92391,36.56986],[75.72737,36.7529],[75.45562,36.71971],[75.40481,36.95382],[75.13839,37.02622],[74.56453,37.03023],[74.53739,36.96224],[74.43389,37.00977],[74.04856,36.82648],[73.82685,36.91421],[72.6323,36.84601],[72.18135,36.71838],[71.80267,36.49924],[71.60491,36.39429],[71.19505,36.04134],[71.37969,35.95865],[71.55273,35.71483],[71.49917,35.6267],[71.65435,35.4479],[71.54294,35.31037],[71.5541,35.28776],[71.67495,35.21262],[71.52938,35.09023],[71.55273,35.02615],[71.49917,35.00478],[71.50329,34.97328],[71.29472,34.87728],[71.28356,34.80882],[71.08718,34.69034],[71.11602,34.63047],[71.0089,34.54568],[71.02401,34.44835],[71.17662,34.36769],[71.12815,34.26619],[71.13078,34.16503],[71.09453,34.13524],[71.09307,34.11961],[71.06933,34.10564],[71.07345,34.06242],[70.88119,33.97933],[70.54336,33.9463],[69.90203,34.04194],[69.87307,33.9689],[69.85671,33.93719],[70.00503,33.73528],[70.14236,33.71701],[70.14785,33.6553],[70.20141,33.64387],[70.17062,33.53535],[70.32775,33.34496],[70.13686,33.21064],[70.07369,33.22557],[70.02563,33.14282],[69.85259,33.09451],[69.79766,33.13247],[69.71526,33.09911],[69.57656,33.09911],[69.49004,33.01509],[69.49854,32.88843],[69.5436,32.8768],[69.47082,32.85834],[69.38018,32.76601],[69.43649,32.7302],[69.44747,32.6678],[69.38155,32.56601],[69.2868,32.53938],[69.23599,32.45946],[69.27932,32.29119],[69.27032,32.14141],[69.3225,31.93186],[69.20577,31.85957],[69.11514,31.70782],[69.00939,31.62249],[68.95995,31.64822],[68.91078,31.59687],[68.79997,31.61665],[68.6956,31.75687],[68.57475,31.83158],[68.44222,31.76446],[68.27605,31.75863],[68.25614,31.80357],[68.1655,31.82691],[68.00071,31.6564],[67.86887,31.63536],[67.72056,31.52304],[67.58323,31.52772],[67.62374,31.40473],[67.7748,31.4188],[67.78854,31.33203],[67.29964,31.19586],[67.03323,31.24519],[67.04147,31.31561],[66.83273,31.26867],[66.72561,31.20526],[66.68166,31.07597],[66.58175,30.97532],[66.42645,30.95309],[66.39194,30.9408],[66.28413,30.57001],[66.34869,30.404],[66.23609,30.06321],[66.36042,29.9583],[66.24175,29.85181],[65.04005,29.53957],[64.62116,29.58903],[64.19796,29.50407],[64.12966,29.39157],[63.5876,29.50456],[62.47751,29.40782],[60.87231,29.86514]]]}},{"type":"Feature","properties":{"id":"IN-JH"},"geometry":{"type":"Polygon","coordinates":[[[83.32134,24.10131],[83.4185,24.08596],[83.55342,23.8783],[83.69487,23.82209],[83.71564,23.68587],[83.78929,23.58853],[84.02652,23.63068],[83.97039,23.37424],[84.06978,23.33059],[84.02961,23.16592],[84.14909,22.97546],[84.3695,22.97704],[84.40177,22.89325],[83.99425,22.53602],[84.27955,22.32467],[84.4876,22.40785],[85.05958,22.48083],[85.10662,22.318],[85.01426,22.10886],[85.22952,22.00003],[85.38986,22.15783],[85.90587,21.95801],[86.01779,22.30434],[85.96115,22.48242],[86.03324,22.56012],[86.7247,22.21569],[86.88812,22.24715],[86.78031,22.56487],[86.42188,22.77586],[86.5472,22.97641],[86.21761,22.98747],[86.04423,23.14572],[85.92269,23.12236],[85.82279,23.26784],[85.89969,23.37062],[85.8633,23.41316],[85.87223,23.47489],[86.04389,23.48245],[86.0123,23.56619],[86.14311,23.56619],[86.14208,23.47647],[86.31374,23.42544],[86.44214,23.62816],[86.5242,23.62628],[86.59286,23.67156],[86.7374,23.68194],[86.79508,23.68351],[86.8198,23.76115],[86.79748,23.82806],[86.89704,23.89054],[87.08312,23.80639],[87.27933,23.87516],[87.23281,24.04238],[87.4443,23.97527],[87.71038,24.14048],[87.63587,24.21628],[87.7811,24.34928],[87.77904,24.57147],[87.89543,24.57616],[87.83431,24.7381],[87.95173,24.97174],[87.78831,25.15212],[87.86521,25.27139],[87.65373,25.28009],[87.58369,25.35271],[87.53906,25.27947],[87.48962,25.29933],[87.47348,25.19686],[87.32688,25.22016],[87.28946,25.09741],[87.21668,25.09243],[87.1511,25.02246],[87.15866,24.89391],[87.10235,24.84812],[87.05532,24.61237],[86.60316,24.60457],[86.45004,24.36586],[86.28833,24.46027],[86.32163,24.5824],[86.12491,24.61143],[86.12869,24.71876],[85.7373,24.8154],[85.66108,24.61518],[84.89307,24.36304],[84.81994,24.529],[84.57447,24.41151],[84.49756,24.28546],[83.9994,24.63141],[83.94584,24.54899],[83.75015,24.50245],[83.49883,24.52651],[83.39275,24.50027],[83.46347,24.36992],[83.37387,24.3155],[83.4027,24.26793],[83.32134,24.10131]]]}},{"type":"Feature","properties":{"id":"PA"},"geometry":{"type":"Polygon","coordinates":[[[-83.05209,8.33394],[-82.9388,8.26634],[-82.88641,8.10219],[-82.89137,8.05755],[-82.89978,8.04083],[-82.94503,7.93865],[-82.13751,6.97312],[-78.06168,7.07793],[-77.89178,7.22681],[-77.81426,7.48319],[-77.72157,7.47612],[-77.72514,7.72348],[-77.57185,7.51147],[-77.17257,7.97422],[-77.45064,8.49991],[-77.32389,8.81247],[-77.58292,9.22278],[-78.79327,9.93766],[-82.51044,9.65379],[-82.56507,9.57279],[-82.61345,9.49881],[-82.66667,9.49746],[-82.77206,9.59573],[-82.87919,9.62645],[-82.84871,9.4973],[-82.93516,9.46741],[-82.93516,9.07687],[-82.72126,8.97125],[-82.88253,8.83331],[-82.91377,8.774],[-82.92068,8.74832],[-82.8794,8.6981],[-82.82739,8.60153],[-82.83975,8.54755],[-82.83322,8.52464],[-82.8382,8.48117],[-82.8679,8.44042],[-82.93056,8.43465],[-83.05209,8.33394]]]}},{"type":"Feature","properties":{"id":"PE"},"geometry":{"type":"Polygon","coordinates":[[[-84.52388,-3.36941],[-84.46057,-7.80762],[-78.15039,-17.99635],[-73.98689,-20.10822],[-70.59118,-18.35072],[-70.378,-18.3495],[-70.31267,-18.31258],[-70.16394,-18.31737],[-69.96732,-18.25992],[-69.81607,-18.12582],[-69.75305,-17.94605],[-69.82868,-17.72048],[-69.79087,-17.65563],[-69.66483,-17.65083],[-69.46897,-17.4988],[-69.46863,-17.37466],[-69.62883,-17.28142],[-69.16896,-16.72233],[-69.00853,-16.66769],[-69.04027,-16.57214],[-68.98358,-16.42165],[-68.79464,-16.33272],[-68.96238,-16.194],[-69.09986,-16.22693],[-69.20291,-16.16668],[-69.40336,-15.61358],[-69.14856,-15.23478],[-69.36254,-14.94634],[-68.88135,-14.18639],[-69.05265,-13.68546],[-68.8864,-13.40792],[-68.85615,-12.87769],[-68.65044,-12.50689],[-68.98115,-11.8979],[-69.57156,-10.94555],[-69.57835,-10.94051],[-69.90896,-10.92744],[-70.38791,-11.07096],[-70.51395,-10.92249],[-70.64134,-11.0108],[-70.62487,-9.80666],[-70.55429,-9.76692],[-70.58453,-9.58303],[-70.53373,-9.42628],[-71.23394,-9.9668],[-72.14742,-9.98049],[-72.31883,-9.5184],[-72.72216,-9.41397],[-73.21498,-9.40904],[-72.92886,-9.04074],[-73.76576,-7.89884],[-73.65485,-7.77897],[-73.96938,-7.58465],[-73.77011,-7.28944],[-73.73986,-6.87919],[-73.12983,-6.43852],[-73.24579,-6.05764],[-72.83973,-5.14765],[-72.64391,-5.0391],[-71.87003,-4.51661],[-70.96814,-4.36915],[-70.77601,-4.15717],[-70.33236,-4.15214],[-70.19582,-4.3607],[-70.11305,-4.27281],[-70.00888,-4.37833],[-69.94708,-4.2431],[-70.3374,-3.79505],[-70.52393,-3.87553],[-70.71396,-3.7921],[-70.04609,-2.73906],[-70.94377,-2.23142],[-71.75223,-2.15058],[-72.92587,-2.44514],[-73.65312,-1.26222],[-74.26675,-0.97229],[-74.42701,-0.50218],[-75.18513,-0.0308],[-75.25764,-0.11943],[-75.40192,-0.17196],[-75.61997,-0.10012],[-75.60169,-0.18708],[-75.53615,-0.19213],[-75.22862,-0.60048],[-75.22862,-0.95588],[-75.3872,-0.9374],[-75.57429,-1.55961],[-76.05203,-2.12179],[-76.6324,-2.58397],[-77.94147,-3.05454],[-78.19369,-3.36431],[-78.14324,-3.47653],[-78.22642,-3.51113],[-78.24589,-3.39907],[-78.34362,-3.38633],[-78.68394,-4.60754],[-78.85149,-4.66795],[-79.01659,-5.01481],[-79.1162,-4.97774],[-79.26248,-4.95167],[-79.59402,-4.46848],[-79.79722,-4.47558],[-80.13945,-4.29786],[-80.39256,-4.48269],[-80.46386,-4.41516],[-80.32114,-4.21323],[-80.45023,-4.20938],[-80.4822,-4.05477],[-80.46386,-4.01342],[-80.13232,-3.90317],[-80.19926,-3.68894],[-80.18741,-3.63994],[-80.19848,-3.59249],[-80.21642,-3.5888],[-80.20535,-3.51667],[-80.22629,-3.501],[-80.23651,-3.48652],[-80.24586,-3.48677],[-80.24475,-3.47846],[-80.24123,-3.46124],[-80.20647,-3.431],[-80.30602,-3.39149],[-84.52388,-3.36941]]]}},{"type":"Feature","properties":{"id":"PG"},"geometry":{"type":"Polygon","coordinates":[[[140.85295,-6.72996],[141.01763,-6.90181],[141.00782,-9.1242],[140.88922,-9.34945],[142.0601,-9.56571],[142.0953,-9.23534],[142.1462,-9.19923],[142.23304,-9.19253],[142.31447,-9.24611],[142.5723,-9.35994],[142.81927,-9.31709],[144.30183,-9.48146],[155.22803,-12.9001],[154.74815,-7.33315],[155.60735,-6.92266],[155.69784,-6.92661],[155.92557,-6.84664],[156.03993,-6.65703],[156.03296,-6.55528],[157.60997,-5.69776],[156.88247,-1.39237],[141.00167,0.68547],[140.99813,-6.3233],[140.85295,-6.72996]]]}},{"type":"Feature","properties":{"id":"PL"},"geometry":{"type":"Polygon","coordinates":[[[14.12256,52.84311],[14.13806,52.82392],[14.22071,52.81175],[14.61073,52.59847],[14.6289,52.57136],[14.60081,52.53116],[14.63056,52.48993],[14.54423,52.42568],[14.55228,52.35264],[14.56378,52.33838],[14.58149,52.28007],[14.70139,52.25038],[14.71319,52.22144],[14.68344,52.19612],[14.70616,52.16927],[14.67683,52.13936],[14.6917,52.10283],[14.72971,52.09167],[14.76026,52.06624],[14.71339,52.00337],[14.70488,51.97679],[14.7139,51.95643],[14.71836,51.95606],[14.72163,51.95188],[14.7177,51.94048],[14.70601,51.92944],[14.6933,51.9044],[14.6588,51.88359],[14.59089,51.83302],[14.60493,51.80473],[14.64625,51.79472],[14.66386,51.73282],[14.69065,51.70842],[14.75392,51.67445],[14.75759,51.62318],[14.7727,51.61263],[14.71125,51.56209],[14.73047,51.54606],[14.72652,51.53902],[14.73219,51.52922],[14.94749,51.47155],[14.9652,51.44793],[14.96899,51.38367],[14.98008,51.33449],[15.04288,51.28387],[15.01242,51.21285],[15.0047,51.16874],[14.99311,51.16249],[14.99414,51.15813],[15.00083,51.14974],[14.99646,51.14365],[14.99079,51.14284],[14.99689,51.12205],[14.98229,51.11354],[14.97938,51.07742],[14.95529,51.04552],[14.92942,50.99744],[14.89252,50.94999],[14.89681,50.9422],[14.81664,50.88148],[14.82803,50.86966],[14.99852,50.86817],[15.01088,50.97984],[14.96419,50.99108],[15.02433,51.0242],[15.03895,51.0123],[15.06218,51.02269],[15.10152,51.01095],[15.11937,50.99021],[15.16744,51.01959],[15.1743,50.9833],[15.2361,50.99886],[15.27043,50.97724],[15.2773,50.8907],[15.36656,50.83956],[15.3803,50.77187],[15.43798,50.80833],[15.73186,50.73885],[15.81683,50.75666],[15.87331,50.67188],[15.97219,50.69799],[16.0175,50.63009],[15.98317,50.61528],[16.02437,50.60046],[16.10265,50.66405],[16.20839,50.63096],[16.23174,50.67101],[16.33611,50.66579],[16.44597,50.58041],[16.34572,50.49575],[16.31413,50.50274],[16.19526,50.43291],[16.21585,50.40627],[16.22821,50.41054],[16.28118,50.36891],[16.30289,50.38292],[16.36495,50.37679],[16.3622,50.34875],[16.39379,50.3207],[16.42674,50.32509],[16.56407,50.21009],[16.55446,50.16613],[16.63137,50.1142],[16.7014,50.09659],[16.8456,50.20834],[16.98018,50.24172],[17.00353,50.21449],[17.02825,50.23118],[16.99803,50.25753],[17.02138,50.27772],[16.99803,50.30316],[16.94448,50.31281],[16.90877,50.38642],[16.85933,50.41093],[16.89229,50.45117],[17.1224,50.39494],[17.14498,50.38117],[17.19579,50.38817],[17.19991,50.3654],[17.27681,50.32246],[17.34273,50.32947],[17.34548,50.2628],[17.3702,50.28123],[17.58889,50.27837],[17.67764,50.28977],[17.69292,50.32859],[17.74648,50.29966],[17.72176,50.25665],[17.76296,50.23382],[17.70528,50.18812],[17.59404,50.16437],[17.66683,50.10275],[17.6888,50.12037],[17.7506,50.07896],[17.77669,50.02253],[17.86886,49.97452],[18.00191,50.01723],[18.04585,50.01194],[18.04585,50.03311],[18.00396,50.04954],[18.03212,50.06574],[18.07898,50.04535],[18.10628,50.00223],[18.20241,49.99958],[18.21752,49.97309],[18.27107,49.96779],[18.27794,49.93863],[18.31914,49.91565],[18.33278,49.92415],[18.33562,49.94747],[18.41604,49.93498],[18.53423,49.89906],[18.54495,49.9079],[18.54299,49.92537],[18.57697,49.91565],[18.57045,49.87849],[18.60341,49.86256],[18.57183,49.83334],[18.61278,49.7618],[18.61368,49.75426],[18.62645,49.75002],[18.62943,49.74603],[18.62676,49.71983],[18.69817,49.70473],[18.72838,49.68163],[18.80479,49.6815],[18.84786,49.5446],[18.84521,49.51672],[18.94536,49.52143],[18.97283,49.49914],[18.9742,49.39557],[19.18019,49.41165],[19.25435,49.53391],[19.36009,49.53747],[19.37795,49.574],[19.45348,49.61583],[19.52626,49.57311],[19.53313,49.52856],[19.57845,49.46077],[19.64162,49.45184],[19.6375,49.40897],[19.72127,49.39288],[19.78581,49.41701],[19.82237,49.27806],[19.75286,49.20751],[19.86409,49.19316],[19.90529,49.23532],[19.98494,49.22904],[20.08238,49.1813],[20.13738,49.31685],[20.21977,49.35265],[20.31453,49.34817],[20.31728,49.39914],[20.39939,49.3896],[20.46422,49.41612],[20.5631,49.375],[20.61666,49.41791],[20.72274,49.41813],[20.77971,49.35383],[20.9229,49.29626],[20.98733,49.30774],[21.09799,49.37176],[21.041,49.41791],[21.12477,49.43666],[21.19756,49.4054],[21.27858,49.45988],[21.43376,49.41433],[21.62328,49.4447],[21.77983,49.35443],[21.82927,49.39467],[21.96385,49.3437],[22.04427,49.22136],[22.56155,49.08865],[22.89122,49.00725],[22.86336,49.10513],[22.72009,49.20288],[22.748,49.32759],[22.69444,49.49378],[22.64534,49.53094],[22.78304,49.65543],[22.80261,49.69098],[22.83179,49.69875],[22.99329,49.84249],[23.28221,50.0957],[23.67635,50.33385],[23.71382,50.38248],[23.79445,50.40481],[23.99563,50.41289],[24.03668,50.44507],[24.07048,50.5071],[24.0996,50.60752],[24.0595,50.71625],[23.95925,50.79271],[23.99254,50.83847],[24.0952,50.83262],[24.14524,50.86128],[24.04576,50.90196],[23.92217,51.00836],[23.90376,51.07697],[23.80678,51.18405],[23.63858,51.32182],[23.69905,51.40871],[23.62751,51.50512],[23.56236,51.53673],[23.57053,51.55938],[23.53198,51.74298],[23.62691,51.78208],[23.61523,51.92066],[23.68733,51.9906],[23.64066,52.07626],[23.61,52.11264],[23.54314,52.12148],[23.47859,52.18215],[23.20071,52.22848],[23.18196,52.28812],[23.34141,52.44845],[23.45112,52.53774],[23.58296,52.59868],[23.73615,52.6149],[23.93763,52.71332],[23.91805,52.94016],[23.94689,52.95919],[23.92184,53.02079],[23.87548,53.0831],[23.91393,53.16469],[23.85657,53.22923],[23.81995,53.24131],[23.62004,53.60942],[23.51284,53.95052],[23.48261,53.98855],[23.52702,54.04622],[23.49196,54.14764],[23.45223,54.17775],[23.42418,54.17911],[23.39525,54.21672],[23.3494,54.25155],[23.24656,54.25701],[23.15938,54.29894],[23.15526,54.31076],[23.13905,54.31567],[23.104,54.29794],[23.04323,54.31567],[23.05726,54.34565],[22.99649,54.35927],[23.00584,54.38514],[22.83756,54.40827],[22.79705,54.36264],[21.41123,54.32395],[20.63871,54.3706],[19.8038,54.44203],[19.64312,54.45423],[18.57853,55.25302],[14.20811,54.12784],[14.22634,53.9291],[14.20647,53.91671],[14.18544,53.91258],[14.20823,53.90776],[14.21323,53.8664],[14.27249,53.74464],[14.26782,53.69866],[14.2836,53.67721],[14.27133,53.66613],[14.28477,53.65955],[14.2853,53.63392],[14.31904,53.61581],[14.30416,53.55499],[14.3273,53.50587],[14.35209,53.49506],[14.4215,53.27724],[14.44133,53.27427],[14.45125,53.26241],[14.40662,53.21098],[14.37853,53.20405],[14.36696,53.16444],[14.38679,53.13669],[14.35044,53.05829],[14.25954,53.00264],[14.14056,52.95786],[14.15873,52.87715],[14.12256,52.84311]]]}},{"type":"Feature","properties":{"id":"KP"},"geometry":{"type":"Polygon","coordinates":[[[123.85601,37.49093],[124.67666,38.05679],[124.84224,37.977],[124.87921,37.80827],[125.06408,37.66334],[125.37112,37.62643],[125.81159,37.72949],[126.13074,37.70512],[126.18776,37.74728],[126.19097,37.81462],[126.24402,37.83113],[126.43239,37.84095],[126.46818,37.80873],[126.56709,37.76857],[126.59918,37.76364],[126.66067,37.7897],[126.68793,37.83728],[126.68793,37.9175],[126.67023,37.95852],[126.84961,38.0344],[126.88106,38.10246],[126.95887,38.1347],[126.95338,38.17735],[127.04479,38.25518],[127.15749,38.30722],[127.38727,38.33227],[127.49672,38.30647],[127.55013,38.32257],[128.02917,38.31861],[128.27652,38.41657],[128.31105,38.58462],[128.37487,38.62345],[128.65655,38.61914],[131.95041,41.5445],[130.65022,42.32281],[130.66367,42.38024],[130.64181,42.41422],[130.60805,42.4317],[130.56835,42.43281],[130.55143,42.52158],[130.50123,42.61636],[130.44361,42.54849],[130.41826,42.6011],[130.2385,42.71127],[130.23068,42.80125],[130.26095,42.9027],[130.09764,42.91425],[130.12957,42.98361],[129.96409,42.97306],[129.95082,43.01051],[129.8865,43.00395],[129.85261,42.96494],[129.83277,42.86746],[129.80719,42.79218],[129.7835,42.76521],[129.77183,42.69435],[129.75294,42.59409],[129.72541,42.43739],[129.60482,42.44461],[129.54701,42.37254],[129.42882,42.44702],[129.28541,42.41574],[129.22423,42.3553],[129.22285,42.26491],[129.15178,42.17224],[128.96068,42.06657],[128.94007,42.03537],[128.04487,42.01769],[128.15119,41.74568],[128.30716,41.60322],[128.20061,41.40895],[128.18546,41.41279],[128.12967,41.37931],[128.03311,41.39232],[128.02633,41.42103],[127.92943,41.44291],[127.29712,41.49473],[127.17841,41.59714],[126.90729,41.79955],[126.60631,41.65565],[126.53189,41.35206],[126.242,41.15454],[126.00335,40.92835],[125.76869,40.87908],[125.71172,40.85223],[124.86913,40.45387],[124.40719,40.13655],[124.38556,40.11047],[124.3322,40.05573],[124.37089,40.03004],[124.35029,39.95639],[124.23201,39.9248],[124.17532,39.8232],[123.90497,38.79949],[123.85601,37.49093]]]}},{"type":"Feature","properties":{"id":"PT"},"geometry":{"type":"Polygon","coordinates":[[[-32.42346,39.07068],[-15.92339,29.50503],[-14.33337,30.94071],[-7.37282,36.96896],[-7.39769,37.16868],[-7.41133,37.20314],[-7.41854,37.23813],[-7.43227,37.25152],[-7.43974,37.38913],[-7.46878,37.47127],[-7.51759,37.56119],[-7.41981,37.75729],[-7.33441,37.81193],[-7.27314,37.90145],[-7.24544,37.98884],[-7.12648,38.00296],[-7.10366,38.04404],[-7.05966,38.01966],[-7.00375,38.01914],[-6.93418,38.21454],[-7.09389,38.17227],[-7.15581,38.27597],[-7.32529,38.44336],[-7.265,38.61674],[-7.26174,38.72107],[-7.03848,38.87221],[-7.051,38.907],[-6.95211,39.0243],[-6.97004,39.07619],[-7.04011,39.11919],[-7.10692,39.10275],[-7.14929,39.11287],[-7.12811,39.17101],[-7.23566,39.20132],[-7.23403,39.27579],[-7.3149,39.34857],[-7.2927,39.45847],[-7.49477,39.58794],[-7.54121,39.66717],[-7.33507,39.64569],[-7.24707,39.66576],[-7.01613,39.66877],[-6.97492,39.81488],[-6.91463,39.86618],[-6.86737,40.01986],[-6.94233,40.10716],[-7.00589,40.12087],[-7.02544,40.18564],[-7.00426,40.23169],[-6.86085,40.26776],[-6.86085,40.2976],[-6.80218,40.33239],[-6.78426,40.36468],[-6.84618,40.42177],[-6.84944,40.46394],[-6.7973,40.51723],[-6.80218,40.55067],[-6.84292,40.56801],[-6.79567,40.65955],[-6.82826,40.74603],[-6.82337,40.84472],[-6.79892,40.84842],[-6.80707,40.88047],[-6.84292,40.89771],[-6.8527,40.93958],[-6.9357,41.02888],[-6.913,41.03922],[-6.88843,41.03027],[-6.84781,41.02692],[-6.80942,41.03629],[-6.79241,41.05397],[-6.75655,41.10187],[-6.77319,41.13049],[-6.69711,41.1858],[-6.68286,41.21641],[-6.65046,41.24725],[-6.55937,41.24417],[-6.38551,41.35274],[-6.38553,41.38655],[-6.3306,41.37677],[-6.26777,41.48796],[-6.19128,41.57638],[-6.29863,41.66432],[-6.44204,41.68258],[-6.49907,41.65823],[-6.54633,41.68623],[-6.56426,41.74219],[-6.51374,41.8758],[-6.56752,41.88429],[-6.5447,41.94371],[-6.58544,41.96674],[-6.61967,41.94008],[-6.75004,41.94129],[-6.76959,41.98734],[-6.81196,41.99097],[-6.82174,41.94493],[-6.94396,41.94403],[-6.95537,41.96553],[-6.98144,41.9728],[-7.01078,41.94977],[-7.07596,41.94977],[-7.08574,41.97401],[-7.14115,41.98855],[-7.18549,41.97515],[-7.18677,41.88793],[-7.32366,41.8406],[-7.37092,41.85031],[-7.42864,41.80589],[-7.42854,41.83262],[-7.44759,41.84451],[-7.45566,41.86488],[-7.49803,41.87095],[-7.52737,41.83939],[-7.62188,41.83089],[-7.58603,41.87944],[-7.65774,41.88308],[-7.69848,41.90977],[-7.84188,41.88065],[-7.88055,41.84571],[-7.88751,41.92553],[-7.90707,41.92432],[-7.92336,41.8758],[-7.9804,41.87337],[-8.01136,41.83453],[-8.0961,41.81024],[-8.16455,41.81753],[-8.16944,41.87944],[-8.19551,41.87459],[-8.2185,41.91237],[-8.16232,41.9828],[-8.08796,42.01398],[-8.08847,42.05767],[-8.11729,42.08537],[-8.18178,42.06436],[-8.19406,42.12141],[-8.18947,42.13853],[-8.1986,42.15402],[-8.22406,42.1328],[-8.24681,42.13993],[-8.2732,42.12396],[-8.29809,42.106],[-8.32161,42.10218],[-8.33912,42.08358],[-8.36353,42.09065],[-8.38323,42.07683],[-8.40143,42.08052],[-8.42512,42.07199],[-8.44123,42.08218],[-8.48185,42.0811],[-8.52837,42.07658],[-8.5252,42.06264],[-8.54563,42.0537],[-8.58086,42.05147],[-8.59493,42.05708],[-8.63791,42.04691],[-8.64626,42.03668],[-8.65832,42.02972],[-8.6681,41.99703],[-8.69071,41.98862],[-8.7478,41.96282],[-8.74606,41.9469],[-8.75712,41.92833],[-8.81794,41.90375],[-8.87157,41.86488],[-9.14112,41.86623],[-30.18705,41.4962],[-32.42346,39.07068]]]}},{"type":"Feature","properties":{"id":"PY"},"geometry":{"type":"Polygon","coordinates":[[[-62.64455,-22.25091],[-62.51761,-22.37684],[-62.22768,-22.55807],[-61.9756,-23.0507],[-61.0782,-23.62932],[-60.99754,-23.80934],[-60.28163,-24.04436],[-60.03367,-24.00701],[-59.45482,-24.34787],[-59.33886,-24.49935],[-58.33055,-24.97099],[-58.25492,-24.92528],[-57.80821,-25.13863],[-57.57431,-25.47269],[-57.87176,-25.93604],[-58.1188,-26.16704],[-58.3198,-26.83443],[-58.65321,-27.14028],[-58.59549,-27.29973],[-58.04205,-27.2387],[-56.85337,-27.5165],[-56.18313,-27.29851],[-55.89195,-27.3467],[-55.74475,-27.44485],[-55.59094,-27.32444],[-55.62322,-27.1941],[-55.39611,-26.97679],[-55.25243,-26.93808],[-55.16948,-26.96068],[-55.06351,-26.80195],[-55.00584,-26.78754],[-54.80868,-26.55669],[-54.70732,-26.45099],[-54.69333,-26.37705],[-54.67359,-25.98607],[-54.60664,-25.9691],[-54.62063,-25.91213],[-54.59398,-25.59224],[-54.59509,-25.53696],[-54.60196,-25.48397],[-54.62033,-25.46026],[-54.4423,-25.13381],[-54.28207,-24.07305],[-54.32807,-24.01865],[-54.6238,-23.83078],[-55.02691,-23.97317],[-55.0518,-23.98666],[-55.12292,-23.99669],[-55.41784,-23.9657],[-55.44117,-23.9185],[-55.43585,-23.87157],[-55.5555,-23.28237],[-55.52288,-23.2595],[-55.5446,-23.22811],[-55.63849,-22.95122],[-55.62493,-22.62765],[-55.68742,-22.58407],[-55.6986,-22.56268],[-55.72366,-22.5519],[-55.741,-22.52018],[-55.74941,-22.46436],[-55.8331,-22.29008],[-56.23206,-22.25347],[-56.45893,-22.08072],[-56.5212,-22.11556],[-56.6508,-22.28387],[-57.98625,-22.09157],[-57.94642,-21.73799],[-57.88239,-21.6868],[-57.93492,-21.65505],[-57.84536,-20.93155],[-58.16225,-20.16193],[-58.23216,-19.80058],[-59.06965,-19.29148],[-60.00638,-19.2981],[-61.73723,-19.63958],[-61.93912,-20.10053],[-62.26883,-20.55311],[-62.2757,-21.06657],[-62.64455,-22.25091]]]}},{"type":"Feature","properties":{"id":"QA"},"geometry":{"type":"Polygon","coordinates":[[[50.57069,25.57887],[50.8133,24.74049],[50.92992,24.54396],[51.09638,24.46907],[51.29972,24.50747],[51.39468,24.62785],[51.58834,24.66608],[51.83108,24.71675],[51.83682,26.70231],[50.93865,26.30758],[50.81266,25.88946],[50.86149,25.6965],[50.7801,25.595],[50.80824,25.54641],[50.57069,25.57887]]]}},{"type":"Feature","properties":{"id":"RO"},"geometry":{"type":"Polygon","coordinates":[[[20.26068,46.12332],[20.35862,45.99356],[20.54818,45.89939],[20.65645,45.82801],[20.70069,45.7493],[20.77416,45.75601],[20.78446,45.78522],[20.82364,45.77738],[20.80361,45.65875],[20.76798,45.60969],[20.83321,45.53567],[20.77217,45.49788],[20.86026,45.47295],[20.87948,45.42743],[21.09894,45.30144],[21.17612,45.32566],[21.20392,45.2677],[21.29398,45.24148],[21.48278,45.19557],[21.51299,45.15345],[21.4505,45.04294],[21.35855,45.01941],[21.54938,44.9327],[21.56328,44.89502],[21.48202,44.87199],[21.44013,44.87613],[21.35643,44.86364],[21.38802,44.78133],[21.55007,44.77304],[21.60019,44.75208],[21.61942,44.67059],[21.67504,44.67107],[21.71692,44.65349],[21.7795,44.66165],[21.99364,44.63395],[22.08016,44.49844],[22.13234,44.47444],[22.18315,44.48179],[22.30844,44.6619],[22.45301,44.7194],[22.61917,44.61489],[22.69196,44.61587],[22.76749,44.54446],[22.70981,44.51852],[22.61368,44.55719],[22.56493,44.53419],[22.54021,44.47836],[22.45436,44.47258],[22.56012,44.30712],[22.68166,44.28206],[22.67173,44.21564],[23.04988,44.07694],[23.01674,44.01946],[22.87873,43.9844],[22.83753,43.88055],[22.85314,43.84452],[23.05288,43.79494],[23.26772,43.84843],[23.4507,43.84936],[23.61687,43.79289],[23.73978,43.80627],[24.18149,43.68218],[24.35364,43.70211],[24.50264,43.76314],[24.62281,43.74082],[24.73542,43.68523],[24.96682,43.72693],[25.10718,43.6831],[25.17144,43.70261],[25.39528,43.61866],[25.72792,43.69263],[25.94911,43.85745],[26.05584,43.90925],[26.10115,43.96908],[26.38764,44.04356],[26.62712,44.05698],[26.95141,44.13555],[27.26845,44.12602],[27.39757,44.0141],[27.60834,44.01206],[27.64542,44.04958],[27.73468,43.95326],[27.92008,44.00761],[27.99558,43.84193],[28.23293,43.76],[29.24336,43.70874],[30.04414,45.08461],[29.69272,45.19227],[29.65428,45.25629],[29.68175,45.26885],[29.59798,45.38857],[29.42632,45.44545],[29.24779,45.43388],[28.96077,45.33164],[28.94292,45.28045],[28.81383,45.3384],[28.78911,45.24179],[28.71358,45.22631],[28.5735,45.24759],[28.34554,45.32102],[28.28504,45.43907],[28.21139,45.46895],[28.18741,45.47358],[28.08927,45.6051],[28.16568,45.6421],[28.13111,45.92819],[28.08612,46.01105],[28.13684,46.18099],[28.10937,46.22852],[28.19864,46.31869],[28.18902,46.35283],[28.25769,46.43334],[28.22281,46.50481],[28.24808,46.64305],[28.12173,46.82283],[28.09095,46.97621],[27.81892,47.1381],[27.73172,47.29248],[27.68706,47.28962],[27.60263,47.32507],[27.55731,47.46637],[27.47942,47.48113],[27.3979,47.59473],[27.32202,47.64009],[27.25519,47.71366],[27.29069,47.73722],[27.1618,47.92391],[27.15622,47.98538],[27.02985,48.09083],[27.04118,48.12522],[26.96119,48.13003],[26.98042,48.15752],[26.94265,48.1969],[26.87708,48.19919],[26.81161,48.25049],[26.62823,48.25804],[26.55202,48.22445],[26.33504,48.18418],[26.17711,47.99246],[26.05901,47.9897],[25.77723,47.93919],[25.63878,47.94924],[25.23778,47.89403],[25.11144,47.75203],[24.88896,47.7234],[24.81893,47.82031],[24.70632,47.84428],[24.61994,47.95062],[24.43578,47.97131],[24.34926,47.9244],[24.22566,47.90231],[24.11281,47.91487],[24.06466,47.95317],[24.02999,47.95087],[24.00801,47.968],[23.98553,47.96076],[23.96337,47.96672],[23.94192,47.94868],[23.89352,47.94512],[23.8602,47.9329],[23.80904,47.98142],[23.75188,47.99705],[23.66262,47.98786],[23.63894,48.00293],[23.5653,48.00499],[23.52803,48.01818],[23.4979,47.96858],[23.33577,48.0237],[23.27397,48.08245],[23.15999,48.12188],[23.1133,48.08061],[23.08858,48.00716],[23.0158,47.99338],[22.92241,48.02002],[22.94301,47.96672],[22.89849,47.95851],[22.77991,47.87211],[22.76617,47.8417],[22.67247,47.7871],[22.46559,47.76583],[22.41979,47.7391],[22.31816,47.76126],[22.00917,47.50492],[22.03389,47.42508],[22.01055,47.37767],[21.94463,47.38046],[21.78395,47.11104],[21.648,47.03902],[21.68645,46.99595],[21.59581,46.91628],[21.59307,46.86935],[21.52028,46.84118],[21.48935,46.7577],[21.5151,46.72147],[21.43926,46.65109],[21.33214,46.63035],[21.26929,46.4993],[21.28061,46.44941],[21.16872,46.30118],[21.06572,46.24897],[20.86797,46.28884],[20.74574,46.25467],[20.76085,46.21002],[20.63863,46.12728],[20.49718,46.18721],[20.45377,46.14405],[20.35573,46.16629],[20.28324,46.1438],[20.26068,46.12332]]]}},{"type":"Feature","properties":{"id":"RU-KGD"},"geometry":{"type":"Polygon","coordinates":[[[18.57853,55.25302],[19.64312,54.45423],[19.8038,54.44203],[20.63871,54.3706],[21.41123,54.32395],[22.79705,54.36264],[22.7253,54.41732],[22.70208,54.45312],[22.67788,54.532],[22.71293,54.56454],[22.68021,54.58486],[22.7522,54.63525],[22.74225,54.64339],[22.75467,54.6483],[22.73397,54.66604],[22.73631,54.72952],[22.87317,54.79492],[22.85083,54.88711],[22.76422,54.92521],[22.68723,54.9811],[22.65451,54.97037],[22.60075,55.01863],[22.58907,55.07085],[22.47688,55.04408],[22.31562,55.0655],[22.14267,55.05345],[22.11697,55.02131],[22.06087,55.02935],[22.02582,55.05078],[22.03984,55.07888],[21.99543,55.08691],[21.96505,55.07353],[21.85521,55.09493],[21.64954,55.1791],[21.55605,55.20311],[21.51095,55.18507],[21.46766,55.21115],[21.38446,55.29348],[21.35465,55.28427],[21.26425,55.24456],[20.95181,55.27994],[20.60454,55.40986],[18.57853,55.25302]]]}},{"type":"Feature","properties":{"id":"RW"},"geometry":{"type":"Polygon","coordinates":[[[28.86193,-2.53185],[28.87943,-2.55165],[28.89288,-2.55848],[28.90226,-2.62385],[28.89793,-2.66111],[28.94346,-2.69124],[29.00357,-2.70596],[29.04081,-2.7416],[29.0562,-2.58632],[29.32234,-2.6483],[29.36805,-2.82933],[29.88237,-2.75105],[29.95911,-2.33348],[30.14034,-2.43626],[30.42933,-2.31064],[30.54501,-2.41404],[30.83915,-2.35795],[30.89303,-2.08223],[30.80802,-1.91477],[30.84079,-1.64652],[30.71974,-1.43244],[30.57123,-1.33264],[30.50889,-1.16412],[30.45116,-1.10641],[30.47194,-1.0555],[30.35212,-1.06896],[30.16369,-1.34303],[29.912,-1.48269],[29.82657,-1.31187],[29.59061,-1.39016],[29.53062,-1.40499],[29.45038,-1.5054],[29.36322,-1.50887],[29.24323,-1.66826],[29.24458,-1.69663],[29.11847,-1.90576],[29.17562,-2.12278],[29.105,-2.27043],[29.00051,-2.29001],[28.95642,-2.37321],[28.89601,-2.37321],[28.86826,-2.41888],[28.86846,-2.44866],[28.89132,-2.47557],[28.89342,-2.49017],[28.88846,-2.50493],[28.87497,-2.50887],[28.86209,-2.5231],[28.86193,-2.53185]]]}},{"type":"Feature","properties":{"id":"EH"},"geometry":{"type":"Polygon","coordinates":[[[-17.35589,20.80492],[-17.0471,20.76408],[-17.0695,20.85742],[-17.06781,20.92697],[-17.0396,20.9961],[-17.0357,21.05368],[-16.99806,21.12142],[-16.95474,21.33997],[-13.01525,21.33343],[-13.08438,22.53866],[-13.15313,22.75649],[-13.10753,22.89493],[-13.00412,23.02297],[-12.5741,23.28975],[-12.36213,23.3187],[-12.14969,23.41935],[-12.00251,23.4538],[-12.0002,25.9986],[-8.66721,25.99918],[-8.66674,27.31569],[-8.66879,27.6666],[-8.77527,27.66663],[-8.71787,26.9898],[-9.08698,26.98639],[-9.56957,26.90042],[-9.81998,26.71379],[-10.68417,26.90984],[-11.35695,26.8505],[-11.23622,26.72023],[-11.38635,26.611],[-11.62052,26.05229],[-12.06001,26.04442],[-12.12281,25.13682],[-12.92147,24.39502],[-13.00628,24.01923],[-13.75627,23.77231],[-14.10361,22.75501],[-14.1291,22.41636],[-14.48112,22.00886],[-14.47329,21.63839],[-14.78487,21.36587],[-16.44269,21.39745],[-16.9978,21.36239],[-17.02707,21.34022],[-17.21511,21.34226],[-17.35589,20.80492]]]}},{"type":"Feature","properties":{"id":"SA"},"geometry":{"type":"Polygon","coordinates":[[[34.46254,27.99552],[34.51305,27.70027],[37.8565,22.00903],[39.63762,18.37348],[41.37609,16.19728],[42.15205,16.40211],[42.76801,16.40371],[42.94625,16.39721],[42.94351,16.49467],[42.97215,16.51093],[43.11601,16.53166],[43.15274,16.67248],[43.22066,16.65179],[43.21325,16.74416],[43.25857,16.75304],[43.26303,16.79479],[43.24801,16.80613],[43.22956,16.80613],[43.22012,16.83932],[43.18338,16.84852],[43.1398,16.90696],[43.19328,16.94703],[43.1813,16.98438],[43.18233,17.02673],[43.23967,17.03428],[43.17787,17.14717],[43.20156,17.25901],[43.32653,17.31179],[43.22533,17.38343],[43.29185,17.53224],[43.43005,17.56148],[43.70631,17.35762],[44.50126,17.47475],[46.31018,17.20464],[46.76494,17.29151],[47.00571,16.94765],[47.48245,17.10808],[47.58351,17.50366],[48.19996,18.20584],[49.04884,18.59899],[52.00311,19.00083],[54.99756,20.00083],[55.66469,21.99658],[55.2137,22.71065],[55.13599,22.63334],[52.56622,22.94341],[51.59617,24.12041],[51.58871,24.27256],[51.41644,24.39615],[51.58834,24.66608],[51.39468,24.62785],[51.29972,24.50747],[51.09638,24.46907],[50.92992,24.54396],[50.8133,24.74049],[50.57069,25.57887],[50.302,25.87592],[50.26923,26.08243],[50.38162,26.53976],[50.71771,26.73086],[50.37726,27.89227],[49.98877,27.87827],[49.00421,28.81495],[48.42991,28.53628],[47.70561,28.5221],[47.59863,28.66798],[47.58376,28.83382],[47.46202,29.0014],[46.5527,29.10283],[46.42415,29.05947],[44.72255,29.19736],[42.97796,30.48295],[42.97601,30.72204],[40.01521,32.05667],[39.29903,32.23259],[38.99233,31.99721],[36.99791,31.50081],[37.99354,30.49998],[37.66395,30.33245],[37.4971,29.99949],[36.75083,29.86903],[36.50005,29.49696],[36.07081,29.18469],[34.95987,29.35727],[34.88293,29.37455],[34.46254,27.99552]]]}},{"type":"Feature","properties":{"id":"CN-LN"},"geometry":{"type":"Polygon","coordinates":[[[118.88992,40.9576],[118.90296,40.75297],[119.12406,40.67647],[119.26277,40.53154],[119.55253,40.54876],[119.58137,40.36799],[119.73586,40.11431],[119.98931,39.77661],[120.97044,38.45359],[123.90497,38.79949],[124.17532,39.8232],[124.23201,39.9248],[124.35029,39.95639],[124.37089,40.03004],[124.3322,40.05573],[124.38556,40.11047],[124.40719,40.13655],[124.86913,40.45387],[125.71172,40.85223],[125.66574,40.91403],[125.56892,40.89327],[125.63552,40.95086],[125.78487,41.16185],[125.75225,41.23005],[125.63724,41.26877],[125.63449,41.33325],[125.57544,41.39174],[125.54283,41.39767],[125.49167,41.53222],[125.44738,41.67393],[125.32241,41.67034],[125.28671,41.9554],[125.41854,42.09159],[125.25443,42.31387],[125.18096,42.29813],[124.97909,42.77574],[124.84863,42.79086],[124.85961,43.17563],[124.45793,42.81907],[124.35836,42.88854],[124.41261,43.06738],[124.28832,43.14608],[124.28077,43.21268],[124.14619,43.2412],[123.79806,43.49627],[123.68682,43.3756],[123.55224,42.99862],[123.24737,42.98255],[122.80517,42.73087],[122.41241,42.8659],[121.92077,42.67032],[121.86309,42.53588],[121.66534,42.43967],[121.56646,42.51968],[121.28494,42.43359],[121.03774,42.27019],[120.5722,42.16747],[120.40878,41.98297],[120.18424,41.84245],[120.09498,41.68932],[120.02975,41.71341],[120.03662,41.81277],[119.83474,42.21428],[119.54498,42.29356],[119.50584,42.39709],[119.27032,42.25901],[119.23736,42.19596],[119.29916,42.12522],[119.3795,42.08803],[119.28268,41.78155],[119.32456,41.62519],[119.39392,41.58566],[119.36576,41.43191],[119.29435,41.32732],[119.23562,41.3149],[119.24972,41.27264],[119.07325,41.08608],[118.92631,41.06382],[119.01695,40.97523],[118.88992,40.9576]]]}},{"type":"Feature","properties":{"id":"SD"},"geometry":{"type":"Polygon","coordinates":[[[21.81432,12.81362],[21.89371,12.68001],[21.98711,12.63292],[22.15679,12.66634],[22.22684,12.74682],[22.46345,12.61925],[22.38873,12.45514],[22.50548,12.16769],[22.48369,12.02766],[22.64092,12.07485],[22.54907,11.64372],[22.7997,11.40424],[22.93124,11.41645],[22.97249,11.21955],[22.87758,10.91915],[23.02221,10.69235],[23.3128,10.45214],[23.67164,9.86923],[23.69155,9.67566],[24.09319,9.66572],[24.12744,9.73784],[24.49389,9.79962],[24.84653,9.80643],[24.97739,9.9081],[25.05688,10.06776],[25.0918,10.33718],[25.78141,10.42599],[25.93163,10.38159],[25.93241,10.17941],[26.21338,9.91545],[26.35815,9.57946],[26.70685,9.48735],[27.14427,9.62858],[27.90704,9.61323],[28.99983,9.67155],[29.06988,9.74826],[29.53844,9.75133],[29.54,10.07949],[29.94629,10.29245],[30.00389,10.28633],[30.53005,9.95992],[30.82893,9.71451],[30.84605,9.7498],[31.28504,9.75287],[31.77539,10.28939],[31.99177,10.65065],[32.46967,11.04662],[32.39358,11.18207],[32.39578,11.70208],[32.10079,11.95203],[32.73921,11.95203],[32.73921,12.22757],[33.25876,12.22111],[33.13988,11.43248],[33.26977,10.83632],[33.24645,10.77913],[33.52294,10.64382],[33.66604,10.44254],[33.80913,10.32994],[33.90159,10.17179],[33.96984,10.15446],[33.99185,9.99623],[33.96323,9.80972],[33.9082,9.762],[33.87958,9.49937],[34.10229,9.50238],[34.08717,9.55243],[34.13186,9.7492],[34.20484,9.9033],[34.22718,10.02506],[34.32102,10.11599],[34.34783,10.23914],[34.2823,10.53508],[34.4372,10.781],[34.59062,10.89072],[34.77383,10.74588],[34.77532,10.69027],[34.86618,10.74588],[34.86916,10.78832],[34.97491,10.86147],[34.97789,10.91559],[34.93172,10.95946],[35.01215,11.19626],[34.95704,11.24448],[35.09556,11.56278],[35.05832,11.71158],[35.11492,11.85156],[35.24302,11.91132],[35.70476,12.67101],[36.01458,12.72478],[36.14268,12.70879],[36.16651,12.88019],[36.13374,12.92665],[36.24545,13.36759],[36.38993,13.56459],[36.48824,13.83954],[36.44653,13.95666],[36.54376,14.25597],[36.44337,15.14963],[36.54276,15.23478],[36.69761,15.75323],[36.76371,15.80831],[36.92193,16.23451],[36.99777,17.07172],[37.42694,17.04041],[37.50967,17.32199],[38.13362,17.53906],[38.37133,17.66269],[38.45916,17.87167],[38.57727,17.98125],[39.63762,18.37348],[37.8565,22.00903],[34.0765,22.00501],[33.99686,21.76784],[33.57251,21.72406],[33.17563,22.00405],[24.99885,21.99535],[24.99794,19.99661],[23.99715,20.00038],[23.99539,19.49944],[23.99997,15.69575],[23.62785,15.7804],[23.38812,15.69649],[23.10792,15.71297],[22.93201,15.55107],[22.92579,15.47007],[22.99584,15.40105],[22.99584,15.22989],[22.66115,14.86308],[22.70474,14.69149],[22.38562,14.58907],[22.44944,14.24986],[22.55997,14.23024],[22.5553,14.11704],[22.22995,13.96754],[22.08674,13.77863],[22.29689,13.3731],[22.1599,13.19281],[22.02914,13.13976],[21.94819,13.05637],[21.81432,12.81362]]]}},{"type":"Feature","properties":{"id":"SS"},"geometry":{"type":"Polygon","coordinates":[[[23.44744,8.99128],[23.59065,8.99743],[23.51905,8.71749],[24.25691,8.69288],[24.13238,8.36959],[24.35965,8.26177],[24.85156,8.16933],[24.98855,7.96588],[25.25319,7.8487],[25.29214,7.66675],[25.20649,7.61115],[25.20337,7.50312],[25.35281,7.42595],[25.37461,7.33024],[25.90076,7.09549],[26.38022,6.63493],[26.32729,6.36272],[26.58259,6.1987],[26.51721,6.09655],[27.22705,5.71254],[27.22705,5.62889],[27.28621,5.56382],[27.23017,5.37167],[27.26886,5.25876],[27.44012,5.07349],[27.56656,4.89375],[27.65462,4.89375],[27.76469,4.79284],[27.79551,4.59976],[28.20719,4.35614],[28.6651,4.42638],[28.8126,4.48784],[29.03054,4.48784],[29.22207,4.34297],[29.43341,4.50101],[29.49726,4.7007],[29.82087,4.56246],[29.79666,4.37809],[30.06964,4.13221],[30.1621,4.10586],[30.22374,3.93896],[30.27658,3.95653],[30.47691,3.83353],[30.55396,3.84451],[30.57378,3.74567],[30.56277,3.62703],[30.78512,3.67097],[30.80713,3.60506],[30.85997,3.5743],[30.85153,3.48867],[30.97601,3.693],[31.16666,3.79853],[31.29476,3.8015],[31.50478,3.67814],[31.50776,3.63652],[31.72075,3.74354],[31.81459,3.82083],[31.86821,3.78664],[31.96205,3.6499],[31.95907,3.57408],[32.05187,3.589],[32.08491,3.56287],[32.08866,3.53543],[32.19888,3.50867],[32.20782,3.6053],[32.41337,3.748],[32.72021,3.77327],[32.89746,3.81339],[33.02852,3.89296],[33.18356,3.77812],[33.51264,3.75068],[33.9873,4.23316],[34.47601,4.72162],[35.34151,5.02364],[35.30992,4.90402],[35.47843,4.91872],[35.42366,4.76969],[35.51424,4.61643],[35.9419,4.61933],[35.82118,4.77382],[35.81968,5.10757],[35.8576,5.33413],[35.50792,5.42431],[35.29938,5.34042],[35.31188,5.50106],[35.13058,5.62118],[35.12611,5.68937],[35.00546,5.89387],[34.96227,6.26415],[35.01738,6.46991],[34.87736,6.60161],[34.77459,6.5957],[34.65096,6.72589],[34.53776,6.74808],[34.53925,6.82794],[34.47669,6.91076],[34.35753,6.91963],[34.19369,7.04382],[34.19369,7.12807],[34.01495,7.25664],[34.03878,7.27437],[34.02984,7.36449],[33.87642,7.5491],[33.71407,7.65983],[33.44745,7.7543],[33.32531,7.71297],[33.24637,7.77939],[33.04944,7.78989],[33.0006,7.90333],[33.08401,8.05822],[33.18083,8.13047],[33.1853,8.29264],[33.19721,8.40317],[33.3119,8.45474],[33.54575,8.47094],[33.66938,8.44442],[33.71407,8.3678],[33.87195,8.41938],[33.89579,8.4842],[34.01346,8.50041],[34.14453,8.60204],[34.14304,9.04654],[34.10229,9.50238],[33.87958,9.49937],[33.9082,9.762],[33.96323,9.80972],[33.99185,9.99623],[33.96984,10.15446],[33.90159,10.17179],[33.80913,10.32994],[33.66604,10.44254],[33.52294,10.64382],[33.24645,10.77913],[33.26977,10.83632],[33.13988,11.43248],[33.25876,12.22111],[32.73921,12.22757],[32.73921,11.95203],[32.10079,11.95203],[32.39578,11.70208],[32.39358,11.18207],[32.46967,11.04662],[31.99177,10.65065],[31.77539,10.28939],[31.28504,9.75287],[30.84605,9.7498],[30.82893,9.71451],[30.53005,9.95992],[30.00389,10.28633],[29.94629,10.29245],[29.54,10.07949],[29.53844,9.75133],[29.06988,9.74826],[28.99983,9.67155],[27.90704,9.61323],[27.14427,9.62858],[26.70685,9.48735],[26.35815,9.57946],[26.21338,9.91545],[25.93241,10.17941],[25.93163,10.38159],[25.78141,10.42599],[25.0918,10.33718],[25.05688,10.06776],[24.97739,9.9081],[24.84653,9.80643],[24.49389,9.79962],[24.12744,9.73784],[24.09319,9.66572],[23.69155,9.67566],[23.62179,9.53823],[23.64981,9.44303],[23.64358,9.28637],[23.56263,9.19418],[23.4848,9.16959],[23.44744,8.99128]]]}},{"type":"Feature","properties":{"id":"SN"},"geometry":{"type":"Polygon","coordinates":[[[-18.35085,14.63444],[-17.43598,13.59273],[-15.47902,13.58758],[-15.36504,13.79313],[-14.93719,13.80173],[-14.34721,13.46578],[-13.8955,13.59126],[-13.79409,13.34472],[-14.36795,13.23033],[-15.14917,13.57989],[-15.26908,13.37768],[-15.80478,13.34832],[-15.80355,13.16729],[-16.69343,13.16791],[-16.74676,13.06025],[-17.43966,13.04579],[-17.4623,11.92379],[-16.70562,12.34803],[-16.38191,12.36449],[-16.20591,12.46157],[-15.67302,12.42974],[-15.17582,12.6847],[-13.70523,12.68013],[-13.05296,12.64003],[-13.06603,12.49342],[-12.87336,12.51892],[-12.35415,12.32758],[-11.91331,12.42008],[-11.46267,12.44559],[-11.37536,12.40788],[-11.39935,12.97808],[-11.63025,13.39174],[-11.83345,13.33333],[-12.06897,13.71049],[-11.93043,13.84505],[-12.23936,14.76324],[-13.11029,15.52116],[-13.43135,16.09022],[-13.80075,16.13961],[-14.32144,16.61495],[-15.00557,16.64997],[-15.6509,16.50315],[-16.27016,16.51565],[-16.4429,16.20605],[-16.44814,16.09753],[-16.48967,16.0496],[-16.50854,16.09032],[-17.15288,16.07139],[-18.35085,14.63444]]]}},{"type":"Feature","properties":{"id":"SG"},"geometry":{"type":"Polygon","coordinates":[[[103.56591,1.19719],[103.66049,1.18825],[103.74084,1.12902],[104.03085,1.26954],[104.12282,1.27714],[104.08072,1.35998],[104.09162,1.39694],[104.08871,1.42015],[104.07348,1.43322],[104.04622,1.44691],[104.02277,1.4438],[104.00131,1.42405],[103.93384,1.42926],[103.89565,1.42841],[103.86383,1.46288],[103.81181,1.47953],[103.76395,1.45183],[103.74161,1.4502],[103.7219,1.46108],[103.67468,1.43166],[103.62738,1.35255],[103.56591,1.19719]]]}},{"type":"Feature","properties":{"id":"SL"},"geometry":{"type":"Polygon","coordinates":[[[-14.36218,8.64107],[-12.15048,6.15992],[-11.50429,6.92704],[-11.4027,6.97746],[-11.29417,7.21576],[-10.60422,7.7739],[-10.60492,8.04072],[-10.57523,8.04829],[-10.51554,8.1393],[-10.45023,8.15627],[-10.35227,8.15223],[-10.29839,8.21283],[-10.31635,8.28554],[-10.30084,8.30008],[-10.27575,8.48711],[-10.37257,8.48941],[-10.54891,8.31174],[-10.63934,8.35326],[-10.70565,8.29235],[-10.61422,8.5314],[-10.47707,8.67669],[-10.56197,8.81225],[-10.5783,9.06386],[-10.74484,9.07998],[-10.6534,9.29919],[-11.2118,10.00098],[-11.89624,9.99763],[-11.91023,9.93927],[-12.12634,9.87203],[-12.24262,9.92386],[-12.47254,9.86834],[-12.76788,9.3133],[-12.94095,9.26335],[-13.08953,9.0409],[-13.18586,9.0925],[-13.29911,9.04245],[-14.36218,8.64107]]]}},{"type":"Feature","properties":{"id":"SV"},"geometry":{"type":"Polygon","coordinates":[[[-90.55276,12.8866],[-88.11443,12.63306],[-87.7346,13.13228],[-87.55124,13.12523],[-87.69751,13.25228],[-87.73714,13.32715],[-87.80177,13.35689],[-87.84675,13.41078],[-87.83467,13.44655],[-87.77354,13.45767],[-87.73841,13.44169],[-87.72115,13.46083],[-87.71657,13.50577],[-87.78148,13.52906],[-87.73106,13.75443],[-87.68821,13.80829],[-87.7966,13.91353],[-88.00331,13.86948],[-88.07641,13.98447],[-88.23018,13.99915],[-88.25791,13.91108],[-88.48982,13.86458],[-88.49738,13.97224],[-88.70661,14.04317],[-88.73182,14.10919],[-88.815,14.11652],[-88.85785,14.17763],[-88.94608,14.20207],[-89.04187,14.33644],[-89.34776,14.43013],[-89.39028,14.44561],[-89.57441,14.41637],[-89.58814,14.33165],[-89.50614,14.26084],[-89.52397,14.22628],[-89.61844,14.21937],[-89.70756,14.1537],[-89.75569,14.07073],[-89.73251,14.04133],[-89.76103,14.02923],[-89.81807,14.07073],[-89.88937,14.0396],[-90.10505,13.85104],[-90.11344,13.73679],[-90.55276,12.8866]]]}},{"type":"Feature","properties":{"id":"SM"},"geometry":{"type":"Polygon","coordinates":[[[12.40415,43.95485],[12.40506,43.94325],[12.41165,43.93769],[12.41551,43.92984],[12.40733,43.92379],[12.41233,43.90956],[12.40935,43.9024],[12.41641,43.89991],[12.44184,43.90498],[12.45648,43.89369],[12.48771,43.89706],[12.49429,43.90973],[12.49247,43.91774],[12.49724,43.92248],[12.50269,43.92363],[12.50496,43.93017],[12.51553,43.94096],[12.51427,43.94897],[12.50655,43.95796],[12.50875,43.96198],[12.50622,43.97131],[12.51109,43.97201],[12.51064,43.98165],[12.5154,43.98508],[12.51463,43.99122],[12.50678,43.99113],[12.49406,43.98492],[12.47853,43.98052],[12.46205,43.97463],[12.44684,43.96597],[12.43662,43.95698],[12.42005,43.9578],[12.41414,43.95273],[12.40415,43.95485]]]}},{"type":"Feature","properties":{"id":"RS"},"geometry":{"type":"Polygon","coordinates":[[[18.81394,45.91329],[18.85783,45.85493],[18.90305,45.71863],[18.96691,45.66731],[18.88776,45.57253],[18.94562,45.53712],[19.07471,45.53086],[19.08364,45.48804],[18.99918,45.49333],[18.97446,45.37528],[19.10774,45.29547],[19.28208,45.23813],[19.41941,45.23475],[19.43589,45.17137],[19.19144,45.17863],[19.14063,45.12972],[19.07952,45.14668],[19.1011,45.01191],[19.05205,44.97692],[19.15573,44.95409],[19.06853,44.89915],[19.02871,44.92541],[18.98957,44.90645],[19.01994,44.85493],[19.18183,44.92055],[19.36722,44.88164],[19.32543,44.74058],[19.26388,44.65412],[19.16699,44.52197],[19.13369,44.52521],[19.12278,44.50132],[19.14837,44.45253],[19.14681,44.41463],[19.11785,44.40313],[19.10749,44.39421],[19.10704,44.38249],[19.10365,44.37795],[19.10298,44.36924],[19.11865,44.36712],[19.1083,44.3558],[19.11547,44.34218],[19.13556,44.338],[19.13332,44.31492],[19.16741,44.28648],[19.18328,44.28383],[19.20508,44.2917],[19.23306,44.26097],[19.26945,44.26957],[19.32464,44.27185],[19.34773,44.23244],[19.3588,44.18353],[19.40927,44.16722],[19.43905,44.13088],[19.47338,44.15034],[19.48386,44.14332],[19.47321,44.1193],[19.51167,44.08158],[19.55999,44.06894],[19.57467,44.04716],[19.61991,44.05254],[19.61836,44.01464],[19.56498,43.99922],[19.52515,43.95573],[19.38439,43.96611],[19.24363,44.01502],[19.23465,43.98764],[19.3986,43.79668],[19.5176,43.71403],[19.50455,43.58385],[19.42696,43.57987],[19.41941,43.54056],[19.36653,43.60921],[19.33426,43.58833],[19.2553,43.5938],[19.24774,43.53061],[19.22807,43.5264],[19.22229,43.47926],[19.44315,43.38846],[19.48171,43.32644],[19.52962,43.31623],[19.54598,43.25158],[19.62661,43.2286],[19.64063,43.19027],[19.76918,43.16044],[19.79255,43.11951],[19.92576,43.08539],[19.96549,43.11098],[19.98887,43.0538],[20.04729,43.02732],[20.05431,42.99571],[20.12325,42.96237],[20.14896,42.99058],[20.16415,42.97177],[20.34528,42.90676],[20.35692,42.8335],[20.40594,42.84853],[20.43734,42.83157],[20.53484,42.8885],[20.48692,42.93208],[20.59929,43.01067],[20.64557,43.00826],[20.69515,43.09641],[20.59929,43.20492],[20.68688,43.21335],[20.73811,43.25068],[20.82145,43.26769],[20.88685,43.21697],[20.83727,43.17842],[20.96287,43.12416],[21.00749,43.13984],[21.05378,43.10707],[21.08952,43.13471],[21.14465,43.11089],[21.16734,42.99694],[21.2041,43.02277],[21.23877,43.00848],[21.23534,42.95523],[21.2719,42.8994],[21.32974,42.90424],[21.36941,42.87397],[21.44047,42.87276],[21.39045,42.74888],[21.47498,42.74695],[21.59154,42.72643],[21.58755,42.70418],[21.6626,42.67813],[21.75025,42.70125],[21.79413,42.65923],[21.75672,42.62695],[21.7327,42.55041],[21.70522,42.54176],[21.7035,42.51899],[21.62556,42.45106],[21.64209,42.41081],[21.62887,42.37664],[21.59029,42.38042],[21.57021,42.3647],[21.53467,42.36809],[21.5264,42.33634],[21.56772,42.30946],[21.58992,42.25915],[21.70111,42.23789],[21.77176,42.2648],[21.84654,42.3247],[21.91595,42.30392],[21.94405,42.34669],[22.02908,42.29848],[22.16384,42.32103],[22.29605,42.37477],[22.29275,42.34913],[22.34773,42.31725],[22.45919,42.33822],[22.47498,42.3915],[22.51961,42.3991],[22.55669,42.50144],[22.43983,42.56851],[22.4997,42.74144],[22.43309,42.82057],[22.54302,42.87774],[22.74826,42.88701],[22.78397,42.98253],[22.89521,43.03625],[22.98104,43.11199],[23.00806,43.19279],[22.89727,43.22417],[22.82036,43.33665],[22.53397,43.47225],[22.47582,43.6558],[22.41043,43.69566],[22.35558,43.81281],[22.41449,44.00514],[22.61688,44.06534],[22.61711,44.16938],[22.67173,44.21564],[22.68166,44.28206],[22.56012,44.30712],[22.45436,44.47258],[22.54021,44.47836],[22.56493,44.53419],[22.61368,44.55719],[22.70981,44.51852],[22.76749,44.54446],[22.69196,44.61587],[22.61917,44.61489],[22.45301,44.7194],[22.30844,44.6619],[22.18315,44.48179],[22.13234,44.47444],[22.08016,44.49844],[21.99364,44.63395],[21.7795,44.66165],[21.71692,44.65349],[21.67504,44.67107],[21.61942,44.67059],[21.60019,44.75208],[21.55007,44.77304],[21.38802,44.78133],[21.35643,44.86364],[21.44013,44.87613],[21.48202,44.87199],[21.56328,44.89502],[21.54938,44.9327],[21.35855,45.01941],[21.4505,45.04294],[21.51299,45.15345],[21.48278,45.19557],[21.29398,45.24148],[21.20392,45.2677],[21.17612,45.32566],[21.09894,45.30144],[20.87948,45.42743],[20.86026,45.47295],[20.77217,45.49788],[20.83321,45.53567],[20.76798,45.60969],[20.80361,45.65875],[20.82364,45.77738],[20.78446,45.78522],[20.77416,45.75601],[20.70069,45.7493],[20.65645,45.82801],[20.54818,45.89939],[20.35862,45.99356],[20.26068,46.12332],[20.09713,46.17315],[20.03533,46.14509],[20.01816,46.17696],[19.93508,46.17553],[19.81491,46.1313],[19.66007,46.19005],[19.56113,46.16824],[19.52473,46.1171],[19.28826,45.99694],[19.14543,45.9998],[19.10388,46.04015],[19.0791,45.96458],[19.01284,45.96529],[18.99712,45.93537],[18.81394,45.91329]]]}},{"type":"Feature","properties":{"id":"SR"},"geometry":{"type":"Polygon","coordinates":[[[-58.0307,3.95513],[-57.35891,3.32121],[-56.70519,2.02964],[-56.55439,2.02003],[-56.47045,1.95135],[-55.99278,1.83137],[-55.89863,1.89861],[-55.92159,2.05236],[-56.13054,2.27723],[-55.96292,2.53188],[-55.71493,2.40342],[-55.01919,2.564],[-54.6084,2.32856],[-54.42864,2.42442],[-54.28534,2.67798],[-53.9849,3.58697],[-53.98914,3.627],[-54.05128,3.63557],[-54.19367,3.84387],[-54.38444,4.13222],[-54.4717,4.91964],[-54.26916,5.26909],[-54.01877,5.52789],[-54.01074,5.68785],[-53.7094,6.2264],[-56.84822,6.73257],[-57.31629,5.33714],[-57.22536,5.15605],[-57.37442,5.0208],[-57.8699,4.89394],[-58.0307,3.95513]]]}},{"type":"Feature","properties":{"id":"SK"},"geometry":{"type":"Polygon","coordinates":[[[16.83317,48.38138],[16.84243,48.35258],[16.90903,48.32519],[16.89461,48.31332],[16.97701,48.17385],[17.02919,48.13996],[17.05735,48.14179],[17.09168,48.09366],[17.07039,48.0317],[17.16001,48.00636],[17.23699,48.02094],[17.71215,47.7548],[18.02938,47.75665],[18.29305,47.73541],[18.56496,47.76588],[18.66521,47.76772],[18.74074,47.8157],[18.8506,47.82308],[18.76821,47.87469],[18.76134,47.97499],[18.82176,48.04206],[19.01952,48.07052],[19.23924,48.0595],[19.28182,48.08336],[19.47957,48.09437],[19.52489,48.19791],[19.63338,48.25006],[19.92452,48.1283],[20.24312,48.2784],[20.29943,48.26104],[20.5215,48.53336],[20.83248,48.5824],[21.11516,48.49546],[21.44063,48.58456],[21.6068,48.50365],[21.67134,48.3989],[21.72525,48.34628],[21.8279,48.33321],[21.83339,48.36242],[22.14689,48.4005],[22.16023,48.56548],[22.21379,48.6218],[22.34151,48.68893],[22.42934,48.92857],[22.48296,48.99172],[22.54338,49.01424],[22.56155,49.08865],[22.04427,49.22136],[21.96385,49.3437],[21.82927,49.39467],[21.77983,49.35443],[21.62328,49.4447],[21.43376,49.41433],[21.27858,49.45988],[21.19756,49.4054],[21.12477,49.43666],[21.041,49.41791],[21.09799,49.37176],[20.98733,49.30774],[20.9229,49.29626],[20.77971,49.35383],[20.72274,49.41813],[20.61666,49.41791],[20.5631,49.375],[20.46422,49.41612],[20.39939,49.3896],[20.31728,49.39914],[20.31453,49.34817],[20.21977,49.35265],[20.13738,49.31685],[20.08238,49.1813],[19.98494,49.22904],[19.90529,49.23532],[19.86409,49.19316],[19.75286,49.20751],[19.82237,49.27806],[19.78581,49.41701],[19.72127,49.39288],[19.6375,49.40897],[19.64162,49.45184],[19.57845,49.46077],[19.53313,49.52856],[19.52626,49.57311],[19.45348,49.61583],[19.37795,49.574],[19.36009,49.53747],[19.25435,49.53391],[19.18019,49.41165],[18.9742,49.39557],[18.97283,49.49914],[18.94536,49.52143],[18.84521,49.51672],[18.74761,49.492],[18.67757,49.50895],[18.6144,49.49824],[18.57183,49.51162],[18.53063,49.49022],[18.54848,49.47059],[18.44686,49.39467],[18.4084,49.40003],[18.4139,49.36517],[18.36446,49.3267],[18.18456,49.28909],[18.15022,49.24518],[18.1104,49.08624],[18.06885,49.03157],[17.91814,49.01784],[17.87831,48.92679],[17.77944,48.92318],[17.73126,48.87885],[17.7094,48.86721],[17.5295,48.81117],[17.45671,48.85004],[17.3853,48.80936],[17.29054,48.85546],[17.19355,48.87602],[17.11202,48.82925],[17.00215,48.70887],[16.93955,48.60371],[16.94611,48.53614],[16.85204,48.44968],[16.8497,48.38321],[16.83588,48.3844],[16.83317,48.38138]]]}},{"type":"Feature","properties":{"id":"SI"},"geometry":{"type":"Polygon","coordinates":[[[13.37671,46.29668],[13.42218,46.20758],[13.47587,46.22725],[13.56114,46.2054],[13.56682,46.18703],[13.64451,46.18966],[13.66472,46.17392],[13.64053,46.13587],[13.57072,46.09022],[13.50104,46.05986],[13.49568,46.04839],[13.50998,46.04498],[13.49702,46.01832],[13.47474,46.00546],[13.50104,45.98078],[13.52963,45.96588],[13.56759,45.96991],[13.58903,45.99009],[13.62074,45.98388],[13.63458,45.98947],[13.64307,45.98326],[13.6329,45.94894],[13.63815,45.93607],[13.61931,45.91782],[13.60857,45.89907],[13.59565,45.89446],[13.58644,45.88173],[13.57563,45.8425],[13.58858,45.83503],[13.59784,45.8072],[13.66986,45.79955],[13.8235,45.7176],[13.83332,45.70855],[13.83422,45.68703],[13.87933,45.65207],[13.9191,45.6322],[13.8695,45.60835],[13.86771,45.59898],[13.84106,45.58185],[13.78445,45.5825],[13.74587,45.59811],[13.7198,45.59352],[13.6076,45.64761],[13.45644,45.59464],[13.56979,45.4895],[13.62902,45.45898],[13.67398,45.4436],[13.7785,45.46787],[13.81742,45.43729],[13.88124,45.42637],[13.90771,45.45149],[13.97309,45.45258],[13.99488,45.47551],[13.96063,45.50825],[14.00578,45.52352],[14.07116,45.48752],[14.20348,45.46896],[14.22371,45.50388],[14.24239,45.50607],[14.26611,45.48239],[14.27681,45.4902],[14.32487,45.47142],[14.36693,45.48642],[14.49769,45.54424],[14.5008,45.60852],[14.53816,45.6205],[14.57397,45.67165],[14.60977,45.66403],[14.59576,45.62812],[14.69694,45.57366],[14.68605,45.53006],[14.71718,45.53442],[14.80124,45.49515],[14.81992,45.45913],[14.90554,45.47769],[14.92266,45.52788],[15.02385,45.48533],[15.05187,45.49079],[15.16862,45.42309],[15.27758,45.46678],[15.33051,45.45258],[15.38188,45.48752],[15.30249,45.53224],[15.29837,45.5841],[15.27747,45.60504],[15.31027,45.6303],[15.34695,45.63382],[15.34214,45.64702],[15.38952,45.63682],[15.4057,45.64727],[15.34919,45.71623],[15.30872,45.69014],[15.25423,45.72275],[15.40836,45.79491],[15.47531,45.79802],[15.47325,45.8253],[15.52234,45.82195],[15.57952,45.84953],[15.64185,45.82915],[15.66662,45.84085],[15.70411,45.8465],[15.68232,45.86819],[15.68383,45.88867],[15.67967,45.90455],[15.70636,45.92116],[15.70327,46.00015],[15.71246,46.01196],[15.72977,46.04682],[15.62317,46.09103],[15.6083,46.11992],[15.59909,46.14761],[15.64904,46.19229],[15.6434,46.21396],[15.67395,46.22478],[15.75436,46.21969],[15.75479,46.20336],[15.78817,46.21719],[15.79284,46.25811],[15.97965,46.30652],[16.07616,46.3463],[16.07314,46.36458],[16.05065,46.3833],[16.05281,46.39141],[16.14859,46.40547],[16.18824,46.38282],[16.30233,46.37837],[16.30162,46.40437],[16.27329,46.41467],[16.27398,46.42875],[16.25124,46.48067],[16.23961,46.49653],[16.26759,46.50566],[16.26733,46.51505],[16.29793,46.5121],[16.37193,46.55008],[16.38771,46.53608],[16.44036,46.5171],[16.5007,46.49644],[16.52604,46.47831],[16.59527,46.47524],[16.52604,46.5051],[16.52885,46.53303],[16.50139,46.56684],[16.39217,46.63673],[16.38594,46.6549],[16.41863,46.66238],[16.42641,46.69228],[16.37816,46.69975],[16.30966,46.7787],[16.31303,46.79838],[16.3408,46.80641],[16.34547,46.83836],[16.2941,46.87137],[16.2365,46.87775],[16.21892,46.86961],[16.15711,46.85434],[16.14365,46.8547],[16.10983,46.867],[16.05786,46.83927],[15.99054,46.82772],[15.99126,46.78199],[15.98432,46.74991],[15.99769,46.7266],[16.02808,46.71094],[16.04347,46.68694],[16.04036,46.6549],[15.99988,46.67947],[15.98512,46.68463],[15.94864,46.68769],[15.87691,46.7211],[15.8162,46.71897],[15.78518,46.70712],[15.76771,46.69863],[15.73823,46.70011],[15.72279,46.69548],[15.69523,46.69823],[15.67411,46.70735],[15.6543,46.70616],[15.6543,46.69228],[15.6365,46.6894],[15.63255,46.68069],[15.62317,46.67947],[15.59826,46.68908],[15.54533,46.66985],[15.55333,46.64988],[15.54431,46.6312],[15.46906,46.61321],[15.45514,46.63697],[15.41235,46.65556],[15.23711,46.63994],[15.14215,46.66131],[15.01451,46.641],[14.98024,46.6009],[14.96002,46.63459],[14.92283,46.60848],[14.87129,46.61],[14.86419,46.59411],[14.83549,46.56614],[14.81836,46.51046],[14.72185,46.49974],[14.66892,46.44936],[14.5942,46.43434],[14.56463,46.37208],[14.52176,46.42617],[14.45877,46.41717],[14.42608,46.44614],[14.314,46.43327],[14.28326,46.44315],[14.15989,46.43327],[14.12097,46.47724],[14.04002,46.49117],[14.00422,46.48474],[13.89837,46.52331],[13.7148,46.5222],[13.68684,46.43881],[13.59777,46.44137],[13.5763,46.42613],[13.5763,46.40915],[13.47019,46.3621],[13.43418,46.35992],[13.44808,46.33507],[13.37671,46.29668]]]}},{"type":"Feature","properties":{"id":"SE"},"geometry":{"type":"Polygon","coordinates":[[[10.40861,58.38489],[12.16597,56.60205],[12.07466,56.29488],[12.65312,56.04345],[12.6372,55.91371],[12.88472,55.63369],[12.60345,55.42675],[12.84405,55.13257],[14.28399,55.1553],[14.89259,55.5623],[15.79951,55.54655],[19.64795,57.06466],[19.84909,57.57876],[20.5104,59.15546],[19.08191,60.19152],[19.23413,60.61414],[20.15877,63.06556],[24.14112,65.39731],[24.15107,65.81427],[24.14798,65.83466],[24.15791,65.85385],[23.90497,66.15802],[23.71339,66.21299],[23.64982,66.30603],[23.67591,66.3862],[23.63776,66.43568],[23.85959,66.56434],[23.89488,66.772],[23.98059,66.79585],[23.98563,66.84149],[23.56214,67.17038],[23.58735,67.20752],[23.54701,67.25435],[23.75372,67.29914],[23.75372,67.43688],[23.39577,67.46974],[23.54701,67.59306],[23.45627,67.85297],[23.65793,67.9497],[23.40081,68.05545],[23.26469,68.15134],[23.15377,68.14759],[23.10336,68.26551],[22.73028,68.40881],[22.00429,68.50692],[21.03001,68.88969],[20.90649,68.89696],[20.85104,68.93142],[20.91658,68.96764],[20.78802,69.03087],[20.55258,69.06069],[20.0695,69.04469],[20.28444,68.93283],[20.33435,68.80174],[20.22027,68.67246],[19.95647,68.55546],[20.22027,68.48759],[19.93508,68.35911],[18.97255,68.52416],[18.63032,68.50849],[18.39503,68.58672],[18.1241,68.53721],[18.13836,68.20874],[17.90787,67.96537],[17.30416,68.11591],[16.7409,67.91037],[16.38441,67.52923],[16.12774,67.52106],[16.09922,67.4364],[16.39154,67.21653],[16.35589,67.06419],[15.37197,66.48217],[15.49318,66.28509],[15.05113,66.15572],[14.53778,66.12399],[14.50926,65.31786],[13.64276,64.58402],[14.11117,64.46674],[14.16051,64.18725],[13.98222,64.00953],[13.23411,64.09087],[12.74105,64.02171],[12.14928,63.59373],[12.19919,63.47935],[11.98529,63.27487],[12.19919,63.00104],[12.07085,62.6297],[12.29187,62.25699],[12.14746,61.7147],[12.40595,61.57226],[12.57707,61.56547],[12.86939,61.35427],[12.69115,61.06584],[12.2277,61.02442],[12.59133,60.50559],[12.52003,60.13846],[12.36317,59.99259],[12.15641,59.8926],[11.87121,59.86039],[11.92112,59.69531],[11.69297,59.59442],[11.8213,59.24985],[11.65732,58.90177],[11.45199,58.89604],[11.4601,58.99022],[11.34459,59.11672],[11.15367,59.07862],[11.08911,58.98745],[10.64958,58.89391],[10.40861,58.38489]]]}},{"type":"Feature","properties":{"id":"SZ"},"geometry":{"type":"Polygon","coordinates":[[[30.78927,-26.48271],[30.81101,-26.84722],[30.88826,-26.79622],[30.97757,-26.92706],[30.96088,-27.0245],[31.15027,-27.20151],[31.49834,-27.31549],[31.97592,-27.31675],[31.97463,-27.11057],[32.00893,-26.8096],[32.09664,-26.80721],[32.13315,-26.84345],[32.13409,-26.5317],[32.07352,-26.40185],[32.10435,-26.15656],[32.08599,-26.00978],[32.00916,-25.999],[31.974,-25.95387],[31.86881,-25.99973],[31.4175,-25.71886],[31.31237,-25.7431],[31.13073,-25.91558],[30.95819,-26.26303],[30.78927,-26.48271]]]}},{"type":"Feature","properties":{"id":"SY"},"geometry":{"type":"Polygon","coordinates":[[[35.48515,34.70851],[35.97386,34.63322],[35.98718,34.64977],[36.29165,34.62991],[36.32399,34.69334],[36.35135,34.68516],[36.35384,34.65447],[36.42941,34.62505],[36.46003,34.6378],[36.45299,34.59438],[36.41429,34.61175],[36.39846,34.55672],[36.3369,34.52629],[36.34745,34.5002],[36.4442,34.50165],[36.46179,34.46541],[36.55853,34.41609],[36.53039,34.3798],[36.56556,34.31881],[36.60778,34.31009],[36.58667,34.27667],[36.59195,34.2316],[36.62537,34.20251],[36.5128,34.09916],[36.50576,34.05982],[36.41078,34.05253],[36.28589,33.91981],[36.38263,33.86579],[36.3967,33.83365],[36.14517,33.85118],[36.06778,33.82927],[35.9341,33.6596],[36.05723,33.57904],[35.94465,33.52774],[35.94816,33.47886],[35.88668,33.43183],[35.82577,33.40479],[35.81324,33.36354],[35.77477,33.33609],[35.813,33.3172],[35.77513,33.27342],[35.81295,33.24841],[35.81647,33.2028],[35.83846,33.19397],[35.84285,33.16673],[35.81911,33.1336],[35.81911,33.11077],[35.84802,33.1031],[35.87188,32.98028],[35.89298,32.9456],[35.87012,32.91976],[35.84021,32.8725],[35.83758,32.82817],[35.78745,32.77938],[35.75983,32.74803],[35.88405,32.71321],[35.93307,32.71966],[35.96633,32.66237],[36.02239,32.65911],[36.08074,32.51463],[36.20379,32.52751],[36.20875,32.49529],[36.23948,32.50108],[36.40959,32.37908],[36.83946,32.31293],[38.79171,33.37328],[40.64314,34.31604],[40.97676,34.39788],[41.12388,34.65742],[41.2345,34.80049],[41.21654,35.1508],[41.26569,35.42708],[41.38184,35.62502],[41.37027,35.84095],[41.2564,36.06012],[41.28864,36.35368],[41.40058,36.52502],[41.81736,36.58782],[42.36697,37.0627],[42.35724,37.10998],[42.32313,37.17814],[42.34735,37.22548],[42.2824,37.2798],[42.26039,37.27017],[42.23683,37.2863],[42.21548,37.28026],[42.20454,37.28715],[42.22381,37.30238],[42.22257,37.31395],[42.2112,37.32491],[42.19301,37.31323],[42.18225,37.28569],[42.00894,37.17209],[41.515,37.08084],[41.21937,37.07665],[40.90856,37.13147],[40.69136,37.0996],[39.81589,36.75538],[39.21538,36.66834],[39.03217,36.70911],[38.74042,36.70629],[38.55908,36.84429],[38.38859,36.90064],[38.21064,36.91842],[37.81974,36.76055],[37.68048,36.75065],[37.49103,36.66904],[37.47253,36.63243],[37.21988,36.6736],[37.16177,36.66069],[37.10894,36.6704],[37.08279,36.63495],[37.02088,36.66422],[37.01647,36.69512],[37.04619,36.71101],[37.04399,36.73483],[36.99886,36.74012],[36.99557,36.75997],[36.66727,36.82901],[36.61581,36.74629],[36.62681,36.71189],[36.57398,36.65186],[36.58829,36.58295],[36.54206,36.49539],[36.6081,36.33772],[36.65653,36.33861],[36.68672,36.23677],[36.6125,36.22592],[36.50463,36.2419],[36.4617,36.20461],[36.39206,36.22088],[36.37474,36.01163],[36.33956,35.98687],[36.30099,36.00985],[36.28338,36.00273],[36.29769,35.96086],[36.27678,35.94839],[36.25366,35.96264],[36.19973,35.95195],[36.17441,35.92076],[36.1623,35.80925],[36.14029,35.81015],[36.13919,35.83692],[36.11827,35.85923],[35.99829,35.88242],[36.01844,35.92403],[36.00514,35.94113],[35.98499,35.94107],[35.931,35.92109],[35.51152,36.10954],[35.48515,34.70851]]]}},{"type":"Feature","properties":{"id":"TD"},"geometry":{"type":"Polygon","coordinates":[[[13.47559,14.40881],[13.6302,13.71094],[14.08251,13.0797],[14.46881,13.08259],[14.56101,12.91036],[14.55058,12.78256],[14.83314,12.62963],[14.90827,12.3269],[14.89019,12.16593],[14.96952,12.0925],[15.00146,12.1223],[15.0349,12.10698],[15.05786,12.0608],[15.04808,11.8731],[15.11579,11.79313],[15.06595,11.71126],[15.13149,11.5537],[15.0585,11.40481],[15.10021,11.04101],[15.04957,11.02347],[15.09127,10.87431],[15.06737,10.80921],[15.15532,10.62846],[15.14936,10.53915],[15.23724,10.47764],[15.30874,10.31063],[15.50535,10.1098],[15.68761,9.99344],[15.41408,9.92876],[15.24618,9.99246],[15.14043,9.99246],[15.05999,9.94845],[14.95722,9.97926],[14.80082,9.93818],[14.4673,10.00264],[14.20411,10.00055],[14.1317,9.82413],[14.01793,9.73169],[13.97544,9.6365],[14.37094,9.2954],[14.35707,9.19611],[14.83566,8.80557],[15.09484,8.65982],[15.20426,8.50892],[15.50743,7.79302],[15.59272,7.7696],[15.56964,7.58936],[15.49743,7.52179],[15.73118,7.52006],[15.79942,7.44149],[16.40703,7.68809],[16.41583,7.77971],[16.58315,7.88657],[16.59415,7.76444],[16.658,7.75353],[16.6668,7.67281],[16.8143,7.53971],[17.67288,7.98905],[17.93926,7.95853],[18.02731,8.01085],[18.6085,8.05009],[18.64153,8.08714],[18.62612,8.14163],[18.67455,8.22226],[18.79783,8.25929],[19.11044,8.68172],[18.86388,8.87971],[19.06421,9.00367],[20.36748,9.11019],[20.82979,9.44696],[21.26348,9.97642],[21.34934,9.95907],[21.52766,10.2105],[21.63553,10.217],[21.71479,10.29932],[21.72139,10.64136],[22.45889,11.00246],[22.87758,10.91915],[22.97249,11.21955],[22.93124,11.41645],[22.7997,11.40424],[22.54907,11.64372],[22.64092,12.07485],[22.48369,12.02766],[22.50548,12.16769],[22.38873,12.45514],[22.46345,12.61925],[22.22684,12.74682],[22.15679,12.66634],[21.98711,12.63292],[21.89371,12.68001],[21.81432,12.81362],[21.94819,13.05637],[22.02914,13.13976],[22.1599,13.19281],[22.29689,13.3731],[22.08674,13.77863],[22.22995,13.96754],[22.5553,14.11704],[22.55997,14.23024],[22.44944,14.24986],[22.38562,14.58907],[22.70474,14.69149],[22.66115,14.86308],[22.99584,15.22989],[22.99584,15.40105],[22.92579,15.47007],[22.93201,15.55107],[23.10792,15.71297],[23.38812,15.69649],[23.62785,15.7804],[23.99997,15.69575],[23.99539,19.49944],[15.99566,23.49639],[14.99751,23.00539],[15.19692,21.99339],[15.20213,21.49365],[15.28332,21.44557],[15.62515,20.95395],[15.57248,20.92138],[15.55382,20.86507],[15.56004,20.79488],[15.59841,20.74039],[15.6721,20.70069],[15.99632,20.35364],[15.75098,19.93002],[15.6032,18.77402],[15.50373,16.89649],[14.37425,15.72591],[13.86301,15.04043],[13.78991,14.87519],[13.809,14.72915],[13.67878,14.64013],[13.68573,14.55276],[13.48259,14.46704],[13.47559,14.40881]]]}},{"type":"Feature","properties":{"id":"IN-GA"},"geometry":{"type":"Polygon","coordinates":[[[73.34747,15.61245],[73.87481,14.75496],[74.16217,14.94976],[74.20543,14.92819],[74.29195,15.02869],[74.2741,15.09996],[74.31838,15.1805],[74.25075,15.25371],[74.33486,15.28352],[74.24903,15.49206],[74.25659,15.64551],[74.11617,15.65411],[74.01592,15.60253],[73.97472,15.62799],[73.94691,15.74236],[73.80477,15.74401],[73.68598,15.72484],[73.34747,15.61245]]]}},{"type":"Feature","properties":{"id":"TG"},"geometry":{"type":"Polygon","coordinates":[[[-0.14462,11.10811],[-0.05733,11.08628],[-0.0275,11.11202],[-0.00514,11.10763],[0.00342,11.08317],[0.02395,11.06229],[0.03355,10.9807],[-0.0063,10.96417],[-0.00908,10.91644],[-0.02685,10.8783],[-0.0228,10.81916],[-0.07183,10.76794],[-0.07327,10.71845],[-0.09141,10.7147],[-0.05945,10.63458],[0.12886,10.53149],[0.18846,10.4096],[0.29453,10.41546],[0.33028,10.30408],[0.39584,10.31112],[0.35293,10.09412],[0.41371,10.06361],[0.41252,10.02018],[0.36366,10.03309],[0.32075,9.72781],[0.34816,9.71607],[0.34816,9.66907],[0.32313,9.6491],[0.28261,9.69022],[0.26712,9.66437],[0.29334,9.59387],[0.36008,9.6256],[0.38153,9.58682],[0.23851,9.57389],[0.2409,9.52335],[0.30406,9.521],[0.31241,9.50337],[0.2254,9.47869],[0.25758,9.42696],[0.33148,9.44812],[0.36485,9.49749],[0.49118,9.48339],[0.56388,9.40697],[0.45424,9.04581],[0.52455,8.87746],[0.37319,8.75262],[0.47211,8.59945],[0.64731,8.48866],[0.73432,8.29529],[0.63897,8.25873],[0.5913,8.19622],[0.61156,8.18324],[0.6056,8.13959],[0.58891,8.12779],[0.62943,7.85751],[0.58295,7.62368],[0.51979,7.58706],[0.52455,7.45354],[0.57223,7.39326],[0.62943,7.41099],[0.65327,7.31643],[0.59606,7.01252],[0.52217,6.9723],[0.52098,6.94391],[0.56508,6.92971],[0.52853,6.82921],[0.57406,6.80348],[0.58176,6.76049],[0.6497,6.73682],[0.63659,6.63857],[0.74862,6.56517],[0.71048,6.53083],[0.89283,6.33779],[0.99652,6.33779],[1.03108,6.24064],[1.05969,6.22998],[1.09187,6.17074],[1.19966,6.17069],[1.19771,6.11522],[1.27574,5.93551],[1.67336,6.02702],[1.62913,6.24075],[1.79826,6.28221],[1.76906,6.43189],[1.58105,6.68619],[1.61812,6.74843],[1.55877,6.99737],[1.64249,6.99562],[1.61838,9.0527],[1.5649,9.16941],[1.41746,9.3226],[1.33675,9.54765],[1.36624,9.5951],[1.35507,9.99525],[0.77666,10.37665],[0.80358,10.71459],[0.8804,10.803],[0.91245,10.99597],[0.66104,10.99964],[0.4958,10.93269],[0.50521,10.98035],[0.48852,10.98561],[0.50388,11.01011],[-0.13493,11.14075],[-0.14462,11.10811]]]}},{"type":"Feature","properties":{"id":"TH"},"geometry":{"type":"Polygon","coordinates":[[[97.19814,8.18901],[99.31854,5.99868],[99.50117,6.44501],[99.91873,6.50233],[100.0756,6.4045],[100.12,6.42105],[100.19511,6.72559],[100.29651,6.68439],[100.30828,6.66462],[100.31618,6.66781],[100.31884,6.66423],[100.32671,6.66526],[100.32607,6.65933],[100.31929,6.65413],[100.35413,6.54932],[100.41152,6.52299],[100.41791,6.5189],[100.42351,6.51762],[100.43027,6.52389],[100.66986,6.45086],[100.74361,6.50811],[100.74822,6.46231],[100.81045,6.45086],[100.85884,6.24929],[101.10313,6.25617],[101.12618,6.19431],[101.06165,6.14161],[101.12388,6.11411],[101.087,5.9193],[101.02708,5.91013],[100.98815,5.79464],[101.14062,5.61613],[101.25755,5.71065],[101.25524,5.78633],[101.58019,5.93534],[101.69773,5.75881],[101.75074,5.79091],[101.80144,5.74505],[101.89188,5.8386],[101.91776,5.84269],[101.92819,5.85511],[101.94712,5.98421],[101.9714,6.00575],[101.97114,6.01992],[101.99209,6.04075],[102.01835,6.05407],[102.09182,6.14161],[102.07732,6.193],[102.08127,6.22679],[102.09086,6.23546],[102.46318,7.22462],[102.47649,9.66162],[102.52395,11.25257],[102.91449,11.65512],[102.90973,11.75613],[102.83957,11.8519],[102.78427,11.98746],[102.77026,12.06815],[102.70176,12.1686],[102.73134,12.37091],[102.78116,12.40284],[102.7796,12.43781],[102.57567,12.65358],[102.51963,12.66117],[102.4994,12.71736],[102.53053,12.77506],[102.49335,12.92711],[102.48694,12.97537],[102.52275,12.99813],[102.46011,13.08057],[102.43422,13.09061],[102.36146,13.26006],[102.36001,13.31142],[102.34611,13.35618],[102.35692,13.38274],[102.35563,13.47307],[102.361,13.50551],[102.33828,13.55613],[102.36859,13.57488],[102.44601,13.5637],[102.5358,13.56933],[102.57573,13.60461],[102.62483,13.60883],[102.58635,13.6286],[102.5481,13.6589],[102.56848,13.69366],[102.72727,13.77806],[102.77864,13.93374],[102.91251,14.01531],[102.93275,14.19044],[103.16469,14.33075],[103.39353,14.35639],[103.53518,14.42575],[103.71109,14.4348],[103.70175,14.38052],[103.93836,14.3398],[104.27616,14.39861],[104.55014,14.36091],[104.69335,14.42726],[104.97667,14.38806],[105.02804,14.23722],[105.08408,14.20402],[105.14012,14.23873],[105.17748,14.34432],[105.20894,14.34967],[105.43783,14.43865],[105.53864,14.55731],[105.5121,14.80802],[105.61162,15.00037],[105.46661,15.13132],[105.58043,15.32724],[105.50662,15.32054],[105.4692,15.33709],[105.47635,15.3796],[105.58191,15.41031],[105.60446,15.53301],[105.61756,15.68792],[105.46573,15.74742],[105.42285,15.76971],[105.37959,15.84074],[105.34115,15.92737],[105.38508,15.987],[105.42001,16.00657],[105.06204,16.09792],[105.00262,16.25627],[104.88057,16.37311],[104.73349,16.565],[104.76099,16.69302],[104.7397,16.81005],[104.76442,16.84752],[104.7373,16.91125],[104.73712,17.01404],[104.80716,17.19025],[104.80061,17.39367],[104.69867,17.53038],[104.45404,17.66788],[104.35432,17.82871],[104.2757,17.86139],[104.21776,17.99335],[104.10927,18.10826],[104.06533,18.21656],[103.97725,18.33631],[103.93916,18.33914],[103.85642,18.28666],[103.82449,18.33979],[103.699,18.34125],[103.60957,18.40528],[103.47773,18.42841],[103.41044,18.4486],[103.30977,18.4341],[103.24779,18.37807],[103.23818,18.34875],[103.29757,18.30475],[103.17093,18.2618],[103.14994,18.23172],[103.1493,18.17799],[103.07343,18.12351],[103.07823,18.03833],[103.0566,18.00144],[103.01998,17.97095],[102.9912,17.9949],[102.95812,18.0054],[102.86323,17.97531],[102.81988,17.94233],[102.79044,17.93612],[102.75954,17.89561],[102.68538,17.86653],[102.67543,17.84529],[102.69946,17.81686],[102.68194,17.80151],[102.59485,17.83537],[102.5896,17.84889],[102.61432,17.92273],[102.60971,17.95411],[102.59234,17.96127],[102.45523,17.97106],[102.11359,18.21532],[101.88485,18.02474],[101.78087,18.07559],[101.72294,17.92867],[101.44667,17.7392],[101.15108,17.47586],[100.96541,17.57926],[101.02185,17.87637],[101.1793,18.0544],[101.19118,18.2125],[101.15108,18.25624],[101.18227,18.34367],[101.06047,18.43247],[101.27585,18.68875],[101.22832,18.73377],[101.25803,18.89545],[101.35606,19.04716],[101.261,19.12717],[101.24911,19.33334],[101.20604,19.35296],[101.21347,19.46223],[101.26991,19.48324],[101.26545,19.59242],[101.08928,19.59748],[100.90302,19.61901],[100.77231,19.48324],[100.64606,19.55884],[100.58219,19.49164],[100.49604,19.53504],[100.398,19.75047],[100.5094,19.87904],[100.58808,20.15791],[100.55218,20.17741],[100.51052,20.14928],[100.47567,20.19133],[100.4537,20.19971],[100.44992,20.23644],[100.41473,20.25625],[100.37439,20.35156],[100.33383,20.4028],[100.25769,20.3992],[100.22076,20.31598],[100.16668,20.2986],[100.1712,20.24324],[100.11785,20.24787],[100.09337,20.26293],[100.09999,20.31614],[100.08404,20.36626],[99.95721,20.46301],[99.91616,20.44986],[99.90499,20.4487],[99.89692,20.44789],[99.89301,20.44311],[99.89168,20.44548],[99.88451,20.44596],[99.88211,20.44488],[99.86383,20.44371],[99.81096,20.33687],[99.68255,20.32077],[99.46008,20.39673],[99.46077,20.36198],[99.5569,20.20676],[99.52943,20.14811],[99.416,20.08614],[99.20328,20.12877],[99.0735,20.10298],[98.98679,19.7419],[98.83661,19.80931],[98.56065,19.67807],[98.51182,19.71303],[98.24884,19.67876],[98.13829,19.78541],[98.03314,19.80941],[98.04364,19.65755],[97.84715,19.55782],[97.88423,19.5041],[97.78769,19.39429],[97.84186,19.29526],[97.78606,19.26769],[97.84024,19.22217],[97.83479,19.09972],[97.73797,19.04261],[97.73654,18.9812],[97.66487,18.9371],[97.73836,18.88478],[97.76752,18.58097],[97.5258,18.4939],[97.36444,18.57138],[97.34522,18.54596],[97.50383,18.26844],[97.56219,18.33885],[97.64116,18.29778],[97.60841,18.23846],[97.73723,17.97912],[97.66794,17.88005],[97.76407,17.71595],[97.91829,17.54504],[98.11185,17.36829],[98.10439,17.33847],[98.34566,17.04822],[98.39441,17.06266],[98.52624,16.89979],[98.49603,16.8446],[98.53833,16.81934],[98.46994,16.73613],[98.50253,16.7139],[98.49713,16.69022],[98.51043,16.70107],[98.51579,16.69433],[98.51472,16.68521],[98.51833,16.676],[98.51113,16.64503],[98.5695,16.62826],[98.57912,16.55983],[98.63817,16.47424],[98.68074,16.27068],[98.84485,16.42354],[98.92656,16.36425],[98.8376,16.11706],[98.69585,16.13353],[98.57019,16.04578],[98.59853,15.87197],[98.541,15.65406],[98.58598,15.46821],[98.56027,15.33471],[98.4866,15.39154],[98.39351,15.34177],[98.41906,15.27103],[98.40522,15.25268],[98.30446,15.30667],[98.22,15.21327],[98.18821,15.13125],[98.24874,14.83013],[98.56762,14.37701],[98.97356,14.04868],[99.16695,13.72621],[99.20617,13.20575],[99.12225,13.19847],[99.10646,13.05804],[99.18748,12.9898],[99.18905,12.84799],[99.29254,12.68921],[99.409,12.60603],[99.47519,12.1353],[99.56445,12.14805],[99.53424,12.02317],[99.64891,11.82699],[99.64108,11.78948],[99.5672,11.62732],[99.47598,11.62434],[99.39485,11.3925],[99.31573,11.32081],[99.32756,11.28545],[99.06938,10.94857],[99.02337,10.97217],[98.99701,10.92962],[99.0069,10.85485],[98.86819,10.78336],[98.78511,10.68351],[98.77275,10.62548],[98.81944,10.52761],[98.7391,10.31488],[98.55174,9.92804],[98.52291,9.92389],[98.47298,9.95782],[98.33094,9.91973],[98.21525,9.56576],[97.63455,9.60854],[97.19814,8.18901]]]}},{"type":"Feature","properties":{"id":"IN-RJ"},"geometry":{"type":"Polygon","coordinates":[[[69.50904,26.74892],[69.88555,26.56836],[70.05584,26.60398],[70.17532,26.55362],[70.17532,26.24118],[70.08193,26.08094],[70.0985,25.93238],[70.2687,25.71156],[70.37444,25.67443],[70.53649,25.68928],[70.60378,25.71898],[70.67382,25.68186],[70.66695,25.39314],[70.89148,25.15064],[70.94002,24.92843],[71.09405,24.69017],[72.18292,24.60894],[72.44144,24.49214],[72.50083,24.40088],[72.69996,24.44527],[72.74116,24.35491],[72.97084,24.34866],[73.00277,24.48777],[73.2328,24.36476],[73.0783,24.20829],[73.2431,24.00319],[73.37425,24.13359],[73.42231,23.92601],[73.35639,23.77591],[73.6211,23.66024],[73.64135,23.4393],[73.83172,23.44749],[73.89953,23.33248],[73.99017,23.33405],[74.24182,23.19244],[74.3201,23.0573],[74.39769,23.11004],[74.53502,23.09868],[74.75063,23.22841],[74.69707,23.27572],[74.53605,23.30095],[74.61124,23.45694],[74.78702,23.54321],[74.93877,23.6376],[74.90924,23.86166],[74.98958,24.03235],[74.88143,24.21816],[74.91371,24.24226],[74.87182,24.27607],[74.75269,24.27576],[74.81002,24.41714],[74.90375,24.46058],[74.86907,24.48996],[74.74616,24.539],[74.80659,24.67322],[74.80522,24.79483],[74.90066,24.65107],[75.03318,24.75431],[74.84607,24.81135],[74.83543,24.98294],[75.03078,24.84563],[75.11352,24.88986],[75.17291,25.05356],[75.35659,25.03397],[75.30715,24.90138],[75.42629,24.8855],[75.18527,24.75057],[75.46989,24.68944],[75.58593,24.72562],[75.62919,24.68632],[75.78712,24.7699],[75.92101,24.51838],[75.88737,24.42401],[75.78987,24.47183],[75.73081,24.38118],[75.82076,24.24727],[75.7418,24.13766],[75.84377,24.10257],[75.70953,23.96617],[75.53203,24.0659],[75.45993,23.9144],[75.6879,23.7602],[75.73596,23.89651],[75.87879,23.88489],[75.98384,23.93574],[75.96324,24.02357],[76.0889,24.08564],[76.18846,24.33364],[76.21215,24.21283],[76.35875,24.25103],[76.91768,24.13735],[76.94343,24.20751],[76.83494,24.3718],[76.82224,24.544],[76.91802,24.54181],[76.94789,24.4509],[77.05879,24.52838],[77.06737,24.64639],[76.95304,24.75805],[76.85211,24.74745],[76.78481,24.83098],[76.94274,24.86401],[76.85554,25.03646],[77.00248,25.07316],[77.27439,25.11482],[77.31044,25.07938],[77.39559,25.11979],[77.41069,25.22109],[77.35507,25.2776],[77.35645,25.42932],[77.27508,25.42746],[77.19646,25.30647],[77.0763,25.33813],[76.93691,25.28071],[76.83734,25.32944],[76.68079,25.34309],[76.59942,25.39304],[76.52046,25.5319],[76.48544,25.71795],[76.59187,25.87745],[76.79408,25.94353],[76.91493,26.09533],[78.21029,26.82407],[78.26042,26.92941],[78.14575,26.94961],[78.04275,26.87001],[77.78045,26.92819],[77.45704,26.74315],[77.41722,26.85776],[77.75848,27.00469],[77.49412,27.08297],[77.67127,27.17341],[77.6493,27.24303],[77.44331,27.3931],[77.28126,27.80689],[77.03235,27.78623],[76.96884,27.65555],[76.88575,27.67075],[76.96317,28.14269],[76.86635,28.22681],[76.80747,28.21562],[76.79958,28.16796],[76.65607,28.09954],[76.66225,28.01774],[76.54792,27.97393],[76.49333,28.15404],[76.27,28.17538],[76.36184,28.12543],[76.30262,28.09999],[76.35618,28.07591],[76.34519,28.02804],[76.31635,28.01925],[76.24958,28.07031],[76.22451,28.04986],[76.17216,28.05546],[76.20614,28.02486],[76.17267,28.01849],[76.22177,27.81296],[75.99449,27.85789],[75.91964,27.93329],[76.04032,28.08561],[75.93097,28.0959],[76.01886,28.16948],[76.09336,28.1498],[75.94333,28.36663],[75.80223,28.40227],[75.56877,28.61225],[75.4656,28.92689],[75.51744,28.9733],[75.51315,29.01504],[75.44448,29.01609],[75.36294,29.14301],[75.41084,29.19982],[75.33462,29.28909],[75.08159,29.22889],[75.05207,29.281],[74.80453,29.39563],[74.59785,29.32472],[74.57382,29.45992],[74.62188,29.52985],[74.57244,29.56449],[74.61158,29.76199],[74.50035,29.74053],[74.46464,29.78106],[74.55116,29.85553],[74.52094,29.94303],[73.88992,29.96921],[73.92219,30.06196],[73.97225,30.19829],[73.80299,30.06969],[73.58665,30.01848],[73.3962,29.94707],[73.28094,29.56646],[73.05886,29.1878],[73.01337,29.16422],[72.94272,29.02487],[72.40402,28.78283],[72.29495,28.66367],[72.20329,28.3869],[71.9244,28.11555],[71.89921,27.96035],[70.79054,27.68423],[70.60927,28.02178],[70.37307,28.01208],[70.12502,27.8057],[70.03136,27.56627],[69.58519,27.18109],[69.50904,26.74892]]]}},{"type":"Feature","properties":{"id":"TM"},"geometry":{"type":"Polygon","coordinates":[[[51.7708,40.29239],[53.89734,37.3464],[54.24565,37.32047],[54.36211,37.34912],[54.58664,37.45809],[54.67247,37.43532],[54.77822,37.51597],[54.81804,37.61285],[54.77684,37.62264],[54.851,37.75739],[55.13412,37.94705],[55.44152,38.08564],[55.76561,38.12238],[55.97847,38.08024],[56.33278,38.08132],[56.32454,38.18502],[56.43303,38.26054],[56.62255,38.24005],[56.73928,38.27887],[57.03453,38.18717],[57.21169,38.28965],[57.37236,38.09321],[57.35042,37.98546],[57.79534,37.89299],[58.21399,37.77281],[58.22999,37.6856],[58.39959,37.63134],[58.47786,37.6433],[58.5479,37.70526],[58.6921,37.64548],[58.9338,37.67374],[59.22905,37.51161],[59.33507,37.53146],[59.39797,37.47892],[59.39385,37.34257],[59.55178,37.13594],[59.74678,37.12499],[60.00768,37.04102],[60.34767,36.63214],[61.14516,36.64644],[61.18187,36.55348],[61.1393,36.38782],[61.22719,36.12759],[61.12007,35.95992],[61.22444,35.92879],[61.26152,35.80749],[61.22719,35.67038],[61.27371,35.61482],[61.58742,35.43803],[61.77693,35.41341],[61.97743,35.4604],[62.05709,35.43803],[62.15871,35.33278],[62.29191,35.25964],[62.29878,35.13312],[62.48006,35.28796],[62.62288,35.22067],[62.74098,35.25432],[62.90853,35.37086],[63.0898,35.43131],[63.12276,35.53196],[63.10079,35.63024],[63.23262,35.67487],[63.10318,35.81782],[63.12276,35.86208],[63.29579,35.85985],[63.53475,35.90881],[63.56496,35.95106],[63.98519,36.03773],[64.05385,36.10433],[64.43288,36.24401],[64.57295,36.34362],[64.62514,36.44311],[64.61141,36.6351],[64.97945,37.21913],[65.51778,37.23881],[65.64263,37.34388],[65.64137,37.45061],[65.72274,37.55438],[66.30993,37.32409],[66.55743,37.35409],[66.52303,37.39827],[66.65761,37.45497],[66.52852,37.58568],[66.53676,37.80084],[66.67684,37.96776],[66.56697,38.0435],[66.41042,38.02403],[66.24013,38.16238],[65.83913,38.25733],[65.55873,38.29052],[64.32576,38.98691],[64.19086,38.95561],[63.70778,39.22349],[63.6913,39.27666],[62.43337,39.98528],[62.34273,40.43206],[62.11751,40.58242],[61.87856,41.12257],[61.4446,41.29407],[61.39732,41.19873],[61.33199,41.14946],[61.22212,41.14946],[61.03261,41.25691],[60.5078,41.21694],[60.06581,41.4363],[60.18117,41.60082],[60.06032,41.76287],[60.08504,41.80997],[60.33223,41.75058],[59.95046,41.97966],[60.0356,42.01028],[60.04659,42.08982],[59.96419,42.1428],[60.00539,42.212],[59.94633,42.27655],[59.4341,42.29738],[59.2955,42.37064],[59.17317,42.52248],[58.93422,42.5407],[58.6266,42.79314],[58.57991,42.64988],[58.27504,42.69632],[58.14321,42.62159],[58.29427,42.56497],[58.51674,42.30348],[58.40688,42.29535],[58.3492,42.43335],[57.99214,42.50021],[57.90975,42.4374],[57.92897,42.24047],[57.84932,42.18555],[57.6296,42.16519],[57.30275,42.14076],[57.03633,41.92043],[56.96218,41.80383],[57.03359,41.41777],[57.13796,41.36625],[57.03423,41.25435],[56.00314,41.32584],[55.45471,41.25609],[54.95182,41.92424],[54.20635,42.38477],[52.97575,42.1308],[52.47884,41.78034],[52.26048,41.69249],[51.7708,40.29239]]]}},{"type":"Feature","properties":{"id":"TL"},"geometry":{"type":"Polygon","coordinates":[[[124.04286,-9.34243],[124.10539,-9.41206],[124.14517,-9.42324],[124.21247,-9.36904],[124.28115,-9.42189],[124.28115,-9.50453],[124.3535,-9.48493],[124.35258,-9.43002],[124.38554,-9.3582],[124.45971,-9.30263],[124.46701,-9.13002],[124.94011,-8.85617],[124.97742,-9.08128],[125.11764,-8.96359],[125.18632,-9.03142],[125.18907,-9.16434],[125.09434,-9.19669],[125.04044,-9.17093],[124.97892,-9.19281],[125.09025,-9.46406],[125.68138,-9.85176],[127.55165,-9.05052],[127.53551,-8.41485],[127.21788,-8.22363],[125.87691,-8.31789],[125.65946,-8.06136],[125.31127,-8.22976],[124.92337,-8.75859],[124.33472,-9.11416],[124.04628,-9.22671],[124.04286,-9.34243]]]}},{"type":"Feature","properties":{"id":"TN"},"geometry":{"type":"Polygon","coordinates":[[[7.52851,34.06493],[7.54088,33.7726],[7.73687,33.42114],[7.83028,33.18851],[8.11433,33.10175],[8.1179,33.05086],[8.31895,32.83483],[8.35999,32.50101],[9.07483,32.07865],[9.55544,30.23971],[9.76848,30.34366],[9.88152,30.34074],[10.29516,30.90337],[10.12239,31.42098],[10.31364,31.72648],[10.48497,31.72956],[10.62788,31.96629],[10.7315,31.97235],[11.04234,32.2145],[11.53898,32.4138],[11.57828,32.48013],[11.46037,32.6307],[11.51549,33.09826],[11.55852,33.1409],[11.56255,33.16754],[11.66543,33.34642],[12.02012,35.25036],[11.2718,37.6713],[7.89009,38.19924],[8.59123,37.14286],[8.64044,36.9401],[8.62972,36.86499],[8.67706,36.8364],[8.57613,36.78062],[8.46537,36.7706],[8.47609,36.66607],[8.16167,36.48817],[8.18936,36.44939],[8.40731,36.42208],[8.2626,35.91733],[8.26472,35.73669],[8.35371,35.66373],[8.36086,35.47774],[8.30329,35.29884],[8.47318,35.23376],[8.3555,35.10007],[8.30727,34.95378],[8.25189,34.92009],[8.29655,34.72798],[8.20482,34.57575],[7.86264,34.3987],[7.81242,34.21841],[7.74207,34.16492],[7.66174,34.20167],[7.52851,34.06493]]]}},{"type":"Feature","properties":{"id":"TR"},"geometry":{"type":"Polygon","coordinates":[[[25.61285,40.17161],[25.94257,39.39358],[26.43357,39.43096],[26.70773,39.0312],[26.61814,38.81372],[26.21136,38.65436],[26.32173,38.48731],[26.24183,38.44695],[26.21136,38.17558],[27.05537,37.9131],[27.16428,37.72343],[26.99377,37.69034],[26.95583,37.64989],[27.14757,37.32],[27.20312,36.94571],[27.45627,36.9008],[27.24613,36.71622],[27.46117,36.53789],[27.89482,36.69898],[27.95037,36.46155],[28.23708,36.56812],[29.30783,36.01033],[29.48192,36.18377],[29.61002,36.1731],[29.61805,36.14179],[29.69611,36.10365],[29.73302,35.92555],[32.82353,35.70297],[35.51152,36.10954],[35.931,35.92109],[35.98499,35.94107],[36.00514,35.94113],[36.01844,35.92403],[35.99829,35.88242],[36.11827,35.85923],[36.13919,35.83692],[36.14029,35.81015],[36.1623,35.80925],[36.17441,35.92076],[36.19973,35.95195],[36.25366,35.96264],[36.27678,35.94839],[36.29769,35.96086],[36.28338,36.00273],[36.30099,36.00985],[36.33956,35.98687],[36.37474,36.01163],[36.39206,36.22088],[36.4617,36.20461],[36.50463,36.2419],[36.6125,36.22592],[36.68672,36.23677],[36.65653,36.33861],[36.6081,36.33772],[36.54206,36.49539],[36.58829,36.58295],[36.57398,36.65186],[36.62681,36.71189],[36.61581,36.74629],[36.66727,36.82901],[36.99557,36.75997],[36.99886,36.74012],[37.04399,36.73483],[37.04619,36.71101],[37.01647,36.69512],[37.02088,36.66422],[37.08279,36.63495],[37.10894,36.6704],[37.16177,36.66069],[37.21988,36.6736],[37.47253,36.63243],[37.49103,36.66904],[37.68048,36.75065],[37.81974,36.76055],[38.21064,36.91842],[38.38859,36.90064],[38.55908,36.84429],[38.74042,36.70629],[39.03217,36.70911],[39.21538,36.66834],[39.81589,36.75538],[40.69136,37.0996],[40.90856,37.13147],[41.21937,37.07665],[41.515,37.08084],[42.00894,37.17209],[42.18225,37.28569],[42.19301,37.31323],[42.2112,37.32491],[42.22257,37.31395],[42.22381,37.30238],[42.20454,37.28715],[42.21548,37.28026],[42.23683,37.2863],[42.26039,37.27017],[42.2824,37.2798],[42.34735,37.22548],[42.32313,37.17814],[42.35724,37.10998],[42.56725,37.14878],[42.78887,37.38615],[42.93705,37.32015],[43.11403,37.37436],[43.30083,37.30629],[43.33508,37.33105],[43.50787,37.24436],[43.56702,37.25675],[43.63085,37.21957],[43.7009,37.23692],[43.8052,37.22825],[43.82699,37.19477],[43.84878,37.22205],[43.90949,37.22453],[44.02002,37.33229],[44.13521,37.32486],[44.2613,37.25055],[44.27998,37.16501],[44.22239,37.15756],[44.18503,37.09551],[44.25975,36.98119],[44.30645,36.97373],[44.35937,37.02843],[44.35315,37.04955],[44.38117,37.05825],[44.42631,37.05825],[44.63179,37.19229],[44.76698,37.16162],[44.78319,37.1431],[44.7868,37.16644],[44.75986,37.21549],[44.81021,37.2915],[44.58449,37.45018],[44.61401,37.60165],[44.56887,37.6429],[44.62096,37.71985],[44.55498,37.783],[44.45948,37.77065],[44.3883,37.85433],[44.22509,37.88859],[44.42476,38.25763],[44.50115,38.33939],[44.44386,38.38295],[44.38309,38.36117],[44.3119,38.37887],[44.3207,38.49799],[44.32058,38.62752],[44.28065,38.6465],[44.26155,38.71427],[44.30322,38.81581],[44.18863,38.93881],[44.20946,39.13975],[44.1043,39.19842],[44.03667,39.39223],[44.22452,39.4169],[44.29818,39.378],[44.37921,39.4131],[44.42832,39.4131],[44.41849,39.56659],[44.48111,39.61579],[44.47298,39.68788],[44.6137,39.78393],[44.65422,39.72163],[44.71806,39.71124],[44.81043,39.62677],[44.80977,39.65768],[44.75779,39.7148],[44.61845,39.8281],[44.46635,39.97733],[44.26973,40.04866],[44.1778,40.02845],[44.1057,40.03555],[43.92307,40.01787],[43.65688,40.11199],[43.65221,40.14889],[43.71136,40.16673],[43.59928,40.34019],[43.60862,40.43267],[43.54791,40.47413],[43.63664,40.54159],[43.7425,40.66805],[43.74872,40.7365],[43.67712,40.84846],[43.67712,40.93084],[43.58683,40.98961],[43.47319,41.02251],[43.44984,41.0988],[43.4717,41.12611],[43.44973,41.17666],[43.36118,41.2028],[43.23096,41.17536],[43.1945,41.25242],[43.13373,41.25503],[43.21707,41.30331],[43.02956,41.37891],[42.8785,41.50516],[42.84899,41.47265],[42.78995,41.50126],[42.84471,41.58912],[42.72794,41.59714],[42.59202,41.58183],[42.51772,41.43606],[42.26387,41.49346],[41.95134,41.52466],[41.81939,41.43621],[41.7124,41.47417],[41.7148,41.4932],[41.54366,41.52185],[40.89217,41.72528],[34.8305,42.4581],[28.32297,41.98371],[28.02971,41.98066],[27.91479,41.97902],[27.83492,41.99709],[27.81235,41.94803],[27.69949,41.97515],[27.55191,41.90928],[27.52379,41.93756],[27.45478,41.96591],[27.27411,42.10409],[27.22376,42.10152],[27.19251,42.06028],[27.08486,42.08735],[27.03277,42.0809],[26.95638,42.00741],[26.79143,41.97386],[26.62996,41.97644],[26.56051,41.92995],[26.57961,41.90024],[26.53968,41.82653],[26.36952,41.82265],[26.33589,41.76802],[26.32952,41.73637],[26.35957,41.71149],[26.47958,41.67037],[26.5209,41.62592],[26.59196,41.60491],[26.59742,41.48058],[26.61767,41.42281],[26.62997,41.34613],[26.5837,41.32131],[26.5209,41.33993],[26.39861,41.25053],[26.32259,41.24929],[26.31928,41.07386],[26.3606,41.02027],[26.33297,40.98388],[26.35894,40.94292],[26.32259,40.94042],[26.28623,40.93005],[26.29441,40.89119],[26.26169,40.9168],[26.20856,40.86048],[26.21351,40.83298],[26.15685,40.80709],[26.12854,40.77339],[26.12495,40.74283],[26.08638,40.73214],[26.0754,40.72772],[26.03489,40.73051],[25.94795,40.72797],[26.04292,40.3958],[25.61285,40.17161]]]}},{"type":"Feature","properties":{"id":"TW"},"geometry":{"type":"Polygon","coordinates":[[[118.09488,24.38193],[118.179,24.33015],[118.41371,24.06775],[120.69238,21.52331],[121.8109,21.77688],[121.75634,23.51406],[122.32924,25.44232],[122.26612,25.98197],[120.49232,25.22863],[118.56434,24.49266],[118.42453,24.54644],[118.35291,24.51645],[118.28244,24.51231],[118.09488,24.38193]]]}},{"type":"Feature","properties":{"id":"TZ"},"geometry":{"type":"Polygon","coordinates":[[[29.43673,-4.44845],[29.52552,-6.2731],[30.2567,-7.14121],[30.79243,-8.27382],[31.00796,-8.58615],[31.37533,-8.60769],[31.57147,-8.70619],[31.57147,-8.81388],[31.71158,-8.91386],[31.81587,-8.88618],[31.94663,-8.93846],[31.94196,-9.02303],[31.98866,-9.07069],[32.08206,-9.04609],[32.16146,-9.05993],[32.25486,-9.13371],[32.43543,-9.11988],[32.49147,-9.14754],[32.53661,-9.24281],[32.75611,-9.28583],[32.76233,-9.31963],[32.95389,-9.40138],[32.99397,-9.36712],[33.14925,-9.49322],[33.31581,-9.48554],[33.48052,-9.62442],[33.76677,-9.58516],[33.93298,-9.71647],[33.9638,-9.62206],[33.95829,-9.54066],[34.03865,-9.49398],[34.54499,-10.0678],[34.51911,-10.12279],[34.57581,-10.56271],[34.65946,-10.6828],[34.67047,-10.93796],[34.61161,-11.01611],[34.63305,-11.11731],[34.79375,-11.32245],[34.91153,-11.39799],[34.96296,-11.57354],[35.63599,-11.55927],[35.82767,-11.41081],[36.19094,-11.57593],[36.19094,-11.70008],[36.62068,-11.72884],[36.80309,-11.56836],[37.3936,-11.68949],[37.76614,-11.53352],[37.8388,-11.3123],[37.93618,-11.26228],[38.21598,-11.27289],[38.47258,-11.4199],[38.88996,-11.16978],[39.24395,-11.17433],[39.58249,-10.96043],[40.00295,-10.80255],[40.44265,-10.4618],[40.74206,-10.25691],[40.14328,-4.64201],[39.62121,-4.68136],[39.44306,-4.93877],[39.21631,-4.67835],[37.81321,-3.69179],[37.75036,-3.54243],[37.63099,-3.50723],[37.5903,-3.42735],[37.71745,-3.304],[37.67199,-3.06222],[34.0824,-1.02264],[34.03084,-1.05101],[34.02286,-1.00779],[33.93107,-0.99298],[30.80408,-0.99911],[30.76635,-0.9852],[30.70631,-1.01175],[30.64166,-1.06601],[30.47194,-1.0555],[30.45116,-1.10641],[30.50889,-1.16412],[30.57123,-1.33264],[30.71974,-1.43244],[30.84079,-1.64652],[30.80802,-1.91477],[30.89303,-2.08223],[30.83915,-2.35795],[30.54501,-2.41404],[30.41789,-2.66266],[30.52747,-2.65841],[30.40662,-2.86151],[30.4987,-2.9573],[30.57926,-2.89791],[30.6675,-2.98987],[30.83823,-2.97837],[30.84165,-3.25152],[30.45915,-3.56532],[30.22042,-4.01738],[30.03323,-4.26631],[29.88172,-4.35743],[29.82885,-4.36153],[29.77289,-4.41733],[29.75109,-4.45836],[29.63827,-4.44681],[29.43673,-4.44845]]]}},{"type":"Feature","properties":{"id":"UG"},"geometry":{"type":"Polygon","coordinates":[[[29.58388,-0.89821],[29.59061,-1.39016],[29.82657,-1.31187],[29.912,-1.48269],[30.16369,-1.34303],[30.35212,-1.06896],[30.47194,-1.0555],[30.64166,-1.06601],[30.70631,-1.01175],[30.76635,-0.9852],[30.80408,-0.99911],[33.93107,-0.99298],[33.9264,-0.54188],[33.98449,-0.13079],[33.90936,0.10581],[34.10067,0.36372],[34.08727,0.44713],[34.11408,0.48884],[34.13493,0.58118],[34.20196,0.62289],[34.27345,0.63182],[34.31516,0.75693],[34.40041,0.80266],[34.43349,0.85254],[34.52369,1.10692],[34.57427,1.09868],[34.58029,1.14712],[34.67562,1.21265],[34.80223,1.22754],[34.82606,1.26626],[34.82606,1.30944],[34.7918,1.36752],[34.87819,1.5596],[34.92734,1.56109],[34.9899,1.6668],[34.98692,1.97348],[34.90947,2.42447],[34.95267,2.47209],[34.77244,2.70272],[34.78137,2.76223],[34.73967,2.85447],[34.65774,2.8753],[34.60114,2.93034],[34.56242,3.11478],[34.45815,3.18319],[34.40006,3.37949],[34.41794,3.44342],[34.39112,3.48802],[34.44922,3.51627],[34.45815,3.67385],[34.15429,3.80464],[34.06046,4.15235],[33.9873,4.23316],[33.51264,3.75068],[33.18356,3.77812],[33.02852,3.89296],[32.89746,3.81339],[32.72021,3.77327],[32.41337,3.748],[32.20782,3.6053],[32.19888,3.50867],[32.08866,3.53543],[32.08491,3.56287],[32.05187,3.589],[31.95907,3.57408],[31.96205,3.6499],[31.86821,3.78664],[31.81459,3.82083],[31.72075,3.74354],[31.50776,3.63652],[31.50478,3.67814],[31.29476,3.8015],[31.16666,3.79853],[30.97601,3.693],[30.85153,3.48867],[30.94081,3.50847],[30.93486,3.40737],[30.84251,3.26908],[30.77101,3.04897],[30.8574,2.9508],[30.8857,2.83923],[30.75612,2.5863],[30.74271,2.43601],[30.83059,2.42559],[30.91102,2.33332],[30.96911,2.41071],[31.06593,2.35862],[31.07934,2.30207],[31.12104,2.27676],[31.1985,2.29462],[31.20148,2.2217],[31.28042,2.17853],[31.30127,2.11006],[30.48503,1.21675],[30.24671,1.14974],[30.22139,0.99635],[30.1484,0.89805],[29.98307,0.84295],[29.95477,0.64486],[29.97413,0.52124],[29.87284,0.39166],[29.81922,0.16824],[29.77454,0.16675],[29.7224,0.07291],[29.72687,-0.08051],[29.65091,-0.46777],[29.67474,-0.47969],[29.67176,-0.55714],[29.62708,-0.71055],[29.63006,-0.8997],[29.58388,-0.89821]]]}},{"type":"Feature","properties":{"id":"UA"},"geometry":{"type":"Polygon","coordinates":[[[22.14689,48.4005],[22.2083,48.42534],[22.38133,48.23726],[22.49806,48.25189],[22.59007,48.15121],[22.58733,48.10813],[22.66835,48.09162],[22.73427,48.12005],[22.81804,48.11363],[22.87847,48.04665],[22.84276,47.98602],[22.89849,47.95851],[22.94301,47.96672],[22.92241,48.02002],[23.0158,47.99338],[23.08858,48.00716],[23.1133,48.08061],[23.15999,48.12188],[23.27397,48.08245],[23.33577,48.0237],[23.4979,47.96858],[23.52803,48.01818],[23.5653,48.00499],[23.63894,48.00293],[23.66262,47.98786],[23.75188,47.99705],[23.80904,47.98142],[23.8602,47.9329],[23.89352,47.94512],[23.94192,47.94868],[23.96337,47.96672],[23.98553,47.96076],[24.00801,47.968],[24.02999,47.95087],[24.06466,47.95317],[24.11281,47.91487],[24.22566,47.90231],[24.34926,47.9244],[24.43578,47.97131],[24.61994,47.95062],[24.70632,47.84428],[24.81893,47.82031],[24.88896,47.7234],[25.11144,47.75203],[25.23778,47.89403],[25.63878,47.94924],[25.77723,47.93919],[26.05901,47.9897],[26.17711,47.99246],[26.33504,48.18418],[26.55202,48.22445],[26.62823,48.25804],[26.6839,48.35828],[26.79239,48.29071],[26.82809,48.31629],[26.71274,48.40388],[26.85556,48.41095],[26.93384,48.36558],[27.03821,48.37653],[27.0231,48.42485],[27.08078,48.43214],[27.13434,48.37288],[27.27855,48.37534],[27.32159,48.4434],[27.37604,48.44398],[27.37741,48.41026],[27.44333,48.41209],[27.46942,48.454],[27.5889,48.49224],[27.59027,48.46311],[27.6658,48.44034],[27.74422,48.45926],[27.79225,48.44244],[27.81902,48.41874],[27.87533,48.4037],[27.88391,48.36699],[27.95883,48.32368],[28.04527,48.32661],[28.09873,48.3124],[28.07504,48.23494],[28.17666,48.25963],[28.19314,48.20749],[28.2856,48.23202],[28.32508,48.23384],[28.35519,48.24957],[28.36996,48.20543],[28.34912,48.1787],[28.30586,48.1597],[28.30609,48.14018],[28.34009,48.13147],[28.38712,48.17567],[28.43701,48.15832],[28.42454,48.12047],[28.48428,48.0737],[28.53921,48.17453],[28.69896,48.13106],[28.85232,48.12506],[28.8414,48.03392],[28.9306,47.96255],[29.1723,47.99013],[29.19839,47.89261],[29.27804,47.88893],[29.20663,47.80367],[29.27255,47.79953],[29.22242,47.73607],[29.22414,47.60012],[29.11743,47.55001],[29.18603,47.43387],[29.3261,47.44664],[29.39889,47.30179],[29.47854,47.30366],[29.48678,47.36043],[29.5733,47.36508],[29.59665,47.25521],[29.54996,47.24962],[29.57696,47.13581],[29.49732,47.12878],[29.53044,47.07851],[29.61038,47.09932],[29.62137,47.05069],[29.57056,46.94766],[29.72986,46.92234],[29.75458,46.8604],[29.87405,46.88199],[29.98814,46.82358],[29.94522,46.80055],[29.9743,46.75325],[29.94409,46.56002],[29.88916,46.54302],[30.02511,46.45132],[30.16794,46.40967],[30.09103,46.38694],[29.94114,46.40114],[29.88329,46.35851],[29.74496,46.45605],[29.66359,46.4215],[29.6763,46.36041],[29.5939,46.35472],[29.49914,46.45889],[29.35357,46.49505],[29.24886,46.37912],[29.23547,46.55435],[29.02409,46.49582],[29.01241,46.46177],[28.9306,46.45699],[29.004,46.31495],[28.98478,46.31803],[28.94953,46.25852],[29.06656,46.19716],[28.94643,46.09176],[29.00613,46.04962],[28.98004,46.00385],[28.74383,45.96664],[28.78503,45.83475],[28.69852,45.81753],[28.70401,45.78019],[28.52823,45.73803],[28.47879,45.66994],[28.51587,45.6613],[28.54196,45.58062],[28.49252,45.56716],[28.51449,45.49982],[28.43072,45.48538],[28.41836,45.51715],[28.30201,45.54744],[28.21139,45.46895],[28.28504,45.43907],[28.34554,45.32102],[28.5735,45.24759],[28.71358,45.22631],[28.78911,45.24179],[28.81383,45.3384],[28.94292,45.28045],[28.96077,45.33164],[29.24779,45.43388],[29.42632,45.44545],[29.59798,45.38857],[29.68175,45.26885],[29.65428,45.25629],[29.69272,45.19227],[30.04414,45.08461],[31.62627,45.50633],[33.54017,46.0123],[33.59087,46.06013],[33.57318,46.10317],[33.61467,46.13561],[33.63854,46.14147],[33.61517,46.22615],[33.646,46.23028],[33.74047,46.18555],[33.79715,46.20482],[33.85234,46.19863],[33.91549,46.15938],[34.05272,46.10838],[34.07311,46.11769],[34.12929,46.10494],[34.181,46.06804],[34.25111,46.0532],[34.33912,46.06114],[34.41221,46.00245],[34.44155,45.95995],[34.48729,45.94267],[34.52011,45.95097],[34.55889,45.99347],[34.60861,45.99347],[34.66679,45.97136],[34.75479,45.90705],[34.80153,45.90047],[34.79905,45.81009],[34.96015,45.75634],[35.23066,45.79231],[37.62608,46.82615],[38.12112,46.86078],[38.3384,46.98085],[38.22955,47.12069],[38.23049,47.2324],[38.32112,47.2585],[38.33074,47.30508],[38.22225,47.30788],[38.28954,47.39255],[38.28679,47.53552],[38.35062,47.61631],[38.76379,47.69346],[38.79628,47.81109],[38.87979,47.87719],[39.73935,47.82876],[39.82213,47.96396],[39.77544,48.04206],[39.88256,48.04482],[39.83724,48.06501],[39.94847,48.22811],[40.00752,48.22445],[39.99241,48.31768],[39.97325,48.31399],[39.9693,48.29904],[39.95248,48.29972],[39.91465,48.26743],[39.90041,48.3049],[39.84273,48.30947],[39.84136,48.33321],[39.94847,48.35055],[39.88794,48.44226],[39.86196,48.46633],[39.84548,48.57821],[39.79764,48.58668],[39.67226,48.59368],[39.71765,48.68673],[39.73104,48.7325],[39.79466,48.83739],[39.97182,48.79398],[40.08168,48.87443],[40.03636,48.91957],[39.98967,48.86901],[39.78368,48.91596],[39.74874,48.98675],[39.72649,48.9754],[39.71353,48.98959],[39.6683,48.99454],[39.6836,49.05121],[39.93437,49.05709],[40.01988,49.1761],[40.22176,49.25683],[40.18331,49.34996],[40.14912,49.37681],[40.1141,49.38798],[40.03087,49.45452],[40.03636,49.52321],[40.16683,49.56865],[40.13249,49.61672],[39.84548,49.56064],[39.65047,49.61761],[39.59142,49.73758],[39.44496,49.76067],[39.27968,49.75976],[39.1808,49.88911],[38.9391,49.79524],[38.90477,49.86787],[38.73311,49.90238],[38.68677,50.00904],[38.65688,49.97176],[38.35408,50.00664],[38.32524,50.08866],[38.18517,50.08161],[38.21675,49.98104],[38.02999,49.90592],[38.02999,49.94482],[37.90776,50.04194],[37.79515,50.08425],[37.75807,50.07896],[37.61113,50.21976],[37.62879,50.24481],[37.62486,50.29966],[37.47243,50.36277],[37.48204,50.46079],[37.08468,50.34935],[36.91762,50.34963],[36.69377,50.26982],[36.64571,50.218],[36.56655,50.2413],[36.58371,50.28563],[36.47817,50.31457],[36.30101,50.29088],[36.20763,50.3943],[36.06893,50.45205],[35.8926,50.43829],[35.80388,50.41356],[35.73659,50.35489],[35.61711,50.35707],[35.58003,50.45117],[35.47463,50.49247],[35.39464,50.64751],[35.48116,50.66405],[35.47704,50.77274],[35.41367,50.80227],[35.39307,50.92145],[35.32598,50.94524],[35.40837,51.04119],[35.31774,51.08434],[35.20375,51.04723],[35.12685,51.16191],[35.14058,51.23162],[34.97304,51.2342],[34.82472,51.17483],[34.6874,51.18],[34.6613,51.25053],[34.38802,51.2746],[34.31661,51.23936],[34.23009,51.26429],[34.33446,51.363],[34.22048,51.4187],[34.30562,51.5205],[34.17599,51.63253],[34.07765,51.67065],[34.42922,51.72852],[34.41136,51.82793],[34.09413,52.00835],[34.11199,52.14087],[34.05239,52.20132],[33.78789,52.37204],[33.55718,52.30324],[33.48027,52.31499],[33.51323,52.35779],[33.18913,52.3754],[32.89937,52.2461],[32.85405,52.27888],[32.69475,52.25535],[32.54781,52.32423],[32.3528,52.32842],[32.38988,52.24946],[32.33083,52.23685],[32.34044,52.1434],[32.2777,52.10266],[32.23331,52.08085],[32.08813,52.03319],[31.92159,52.05144],[31.96141,52.08015],[31.85018,52.11305],[31.81722,52.09955],[31.7822,52.11406],[31.38326,52.12991],[31.25142,52.04131],[31.13332,52.1004],[30.95589,52.07775],[30.90897,52.00699],[30.76443,51.89739],[30.68804,51.82806],[30.51946,51.59649],[30.64992,51.35014],[30.56203,51.25655],[30.36153,51.33984],[30.34642,51.42555],[30.17888,51.51025],[29.77376,51.4461],[29.7408,51.53417],[29.54372,51.48372],[29.49773,51.39814],[29.42357,51.4187],[29.32881,51.37843],[29.25191,51.49828],[29.25603,51.57089],[29.20659,51.56918],[29.16402,51.64679],[29.1187,51.65872],[28.99098,51.56833],[28.95528,51.59222],[28.81795,51.55552],[28.76027,51.48802],[28.78224,51.45294],[28.75615,51.41442],[28.73143,51.46236],[28.69161,51.44695],[28.64429,51.5664],[28.47051,51.59734],[28.37592,51.54505],[28.23452,51.66988],[28.10658,51.57857],[27.95827,51.56065],[27.91844,51.61952],[27.85253,51.62293],[27.76052,51.47604],[27.67125,51.50854],[27.71932,51.60672],[27.55727,51.63486],[27.51058,51.5854],[27.47212,51.61184],[27.24828,51.60161],[27.26613,51.65957],[27.20948,51.66713],[27.20602,51.77291],[26.99422,51.76933],[26.9489,51.73788],[26.80043,51.75777],[26.69759,51.82284],[26.46962,51.80501],[26.39367,51.87315],[26.19084,51.86781],[26.00408,51.92967],[25.83217,51.92587],[25.80574,51.94556],[25.73673,51.91973],[25.46163,51.92205],[25.20228,51.97143],[24.98784,51.91273],[24.37123,51.88222],[24.29021,51.80841],[24.3163,51.75063],[24.13075,51.66979],[23.99907,51.58369],[23.8741,51.59734],[23.91118,51.63316],[23.7766,51.66809],[23.60906,51.62122],[23.6736,51.50255],[23.62751,51.50512],[23.69905,51.40871],[23.63858,51.32182],[23.80678,51.18405],[23.90376,51.07697],[23.92217,51.00836],[24.04576,50.90196],[24.14524,50.86128],[24.0952,50.83262],[23.99254,50.83847],[23.95925,50.79271],[24.0595,50.71625],[24.0996,50.60752],[24.07048,50.5071],[24.03668,50.44507],[23.99563,50.41289],[23.79445,50.40481],[23.71382,50.38248],[23.67635,50.33385],[23.28221,50.0957],[22.99329,49.84249],[22.83179,49.69875],[22.80261,49.69098],[22.78304,49.65543],[22.64534,49.53094],[22.69444,49.49378],[22.748,49.32759],[22.72009,49.20288],[22.86336,49.10513],[22.89122,49.00725],[22.56155,49.08865],[22.54338,49.01424],[22.48296,48.99172],[22.42934,48.92857],[22.34151,48.68893],[22.21379,48.6218],[22.16023,48.56548],[22.14689,48.4005]]]}},{"type":"Feature","properties":{"id":"UY"},"geometry":{"type":"Polygon","coordinates":[[[-58.44442,-33.84033],[-58.34425,-34.15035],[-57.83001,-34.69099],[-55.71154,-35.78518],[-53.54511,-34.54062],[-53.18243,-33.86894],[-53.37138,-33.74313],[-53.39593,-33.75169],[-53.44031,-33.69344],[-53.52794,-33.68908],[-53.53459,-33.16843],[-53.1111,-32.71147],[-53.37671,-32.57005],[-53.39572,-32.58596],[-53.76024,-32.0751],[-54.17384,-31.86168],[-55.50821,-30.91349],[-55.50841,-30.9027],[-55.51862,-30.89828],[-55.52712,-30.89997],[-55.53276,-30.90218],[-55.53431,-30.89714],[-55.54572,-30.89051],[-55.55218,-30.88193],[-55.55373,-30.8732],[-55.5634,-30.8686],[-55.58866,-30.84117],[-55.87388,-31.05053],[-56.4619,-30.38457],[-56.4795,-30.3899],[-56.49267,-30.39471],[-56.90236,-30.02578],[-57.22502,-30.26121],[-57.65132,-30.19229],[-57.61478,-30.25165],[-57.64859,-30.35095],[-57.89115,-30.49572],[-57.8024,-30.77193],[-57.89476,-30.95994],[-57.86729,-31.06352],[-57.9908,-31.34924],[-57.98127,-31.3872],[-58.07569,-31.44916],[-58.0023,-31.53084],[-58.00076,-31.65016],[-58.20252,-31.86966],[-58.10036,-32.25338],[-58.22362,-32.52416],[-58.1224,-32.98842],[-58.40475,-33.11777],[-58.44442,-33.84033]]]}},{"type":"Feature","properties":{"id":"IN-UT"},"geometry":{"type":"Polygon","coordinates":[[[77.5542,30.40278],[77.92945,30.24661],[77.70629,29.8722],[77.80792,29.67075],[77.94181,29.71489],[77.98507,29.5418],[78.33732,29.79536],[78.49044,29.73874],[78.52683,29.6248],[78.91067,29.45335],[78.71429,29.32053],[79.00268,29.12127],[79.0686,29.15276],[79.29416,28.95858],[79.40711,28.92854],[79.41089,28.85339],[79.66529,28.85369],[79.79026,28.88736],[79.96673,28.70233],[80.06957,28.82763],[80.05743,28.91479],[80.18085,29.13649],[80.23178,29.11626],[80.26602,29.13938],[80.24112,29.21414],[80.28626,29.20327],[80.31428,29.30784],[80.24322,29.44299],[80.37939,29.57098],[80.41858,29.63581],[80.38428,29.68513],[80.36803,29.73865],[80.41554,29.79451],[80.43458,29.80466],[80.48997,29.79566],[80.56247,29.86661],[80.56957,29.88176],[80.60226,29.95732],[80.67076,29.95732],[80.8778,30.13384],[80.93695,30.18229],[81.03953,30.20059],[80.83343,30.32023],[80.54504,30.44936],[80.20721,30.58541],[79.93255,30.88288],[79.59884,30.93943],[79.22805,31.34963],[79.14016,31.43403],[79.01931,31.42817],[78.77898,31.31209],[78.99581,31.10821],[78.292,31.28676],[77.80174,31.05822],[77.69016,30.76927],[77.76946,30.63111],[77.7238,30.59359],[77.80757,30.52086],[77.5542,30.40278]]]}},{"type":"Feature","properties":{"id":"VA"},"geometry":{"type":"Polygon","coordinates":[[[12.44582,41.90194],[12.44834,41.90095],[12.45181,41.90056],[12.45446,41.90028],[12.45435,41.90143],[12.45626,41.90172],[12.45691,41.90125],[12.4577,41.90115],[12.45834,41.90174],[12.45826,41.90281],[12.45755,41.9033],[12.45762,41.9058],[12.45561,41.90629],[12.45543,41.90738],[12.45091,41.90625],[12.44984,41.90545],[12.44815,41.90326],[12.44582,41.90194]]]}},{"type":"Feature","properties":{"id":"VE"},"geometry":{"type":"Polygon","coordinates":[[[-73.36905,9.16636],[-73.02119,9.27584],[-72.94052,9.10663],[-72.77415,9.10165],[-72.65474,8.61428],[-72.4042,8.36513],[-72.36987,8.19976],[-72.35163,8.01163],[-72.39137,8.03534],[-72.47213,7.96106],[-72.48801,7.94329],[-72.48183,7.92909],[-72.47042,7.92306],[-72.45806,7.91141],[-72.46183,7.90682],[-72.44454,7.86031],[-72.46763,7.79518],[-72.47827,7.65604],[-72.45321,7.57232],[-72.47415,7.48928],[-72.43132,7.40034],[-72.19437,7.37034],[-72.04895,7.03837],[-71.82441,7.04314],[-71.44118,7.02116],[-71.42212,7.03854],[-71.37234,7.01588],[-71.03941,6.98163],[-70.7596,7.09799],[-70.10716,6.96516],[-69.41843,6.1072],[-67.60654,6.2891],[-67.4625,6.20625],[-67.43513,5.98835],[-67.58558,5.84537],[-67.63914,5.64963],[-67.59141,5.5369],[-67.83341,5.31104],[-67.85358,4.53249],[-67.62671,3.74303],[-67.50067,3.75812],[-67.30945,3.38393],[-67.85862,2.86727],[-67.85862,2.79173],[-67.65696,2.81691],[-67.21967,2.35778],[-66.85795,1.22998],[-66.28507,0.74585],[-65.6727,1.01353],[-65.50158,0.92086],[-65.57288,0.62856],[-65.11657,1.12046],[-64.38932,1.5125],[-64.34654,1.35569],[-64.08274,1.64792],[-64.06135,1.94722],[-63.39827,2.16098],[-63.39114,2.4317],[-64.0257,2.48156],[-64.02908,2.79797],[-64.48379,3.7879],[-64.84028,4.24665],[-64.72977,4.28931],[-64.57648,4.12576],[-64.14512,4.12932],[-63.99183,3.90172],[-63.86082,3.94796],[-63.70218,3.91417],[-63.67099,4.01731],[-63.50611,3.83592],[-63.42233,3.89995],[-63.4464,3.9693],[-63.21111,3.96219],[-62.98296,3.59935],[-62.7655,3.73099],[-62.74411,4.03331],[-62.57656,4.04754],[-62.44822,4.18621],[-62.13094,4.08309],[-61.54629,4.2822],[-61.48569,4.43149],[-61.29675,4.44216],[-61.31457,4.54167],[-61.15703,4.49839],[-60.98303,4.54167],[-60.86539,4.70512],[-60.5802,4.94312],[-60.73204,5.20931],[-61.4041,5.95304],[-61.15058,6.19558],[-61.20762,6.58174],[-61.13632,6.70922],[-60.54873,6.8631],[-60.39419,6.94847],[-60.28074,7.1162],[-60.44116,7.20817],[-60.54098,7.14804],[-60.63367,7.25061],[-60.59802,7.33194],[-60.71923,7.55817],[-60.64793,7.56877],[-60.51959,7.83373],[-60.38056,7.8302],[-60.02407,8.04557],[-59.97059,8.20791],[-59.83156,8.23261],[-59.80661,8.28906],[-59.85562,8.35213],[-59.98508,8.53046],[-59.54058,8.6862],[-60.89962,9.81445],[-62.08693,10.04435],[-61.62505,11.18974],[-63.73917,11.92623],[-63.25348,15.97077],[-63.85239,16.0256],[-65.4181,12.36848],[-67.89186,12.4116],[-68.01417,11.77722],[-68.33524,11.78151],[-68.99639,11.79035],[-69.4514,12.18025],[-70.24399,12.38063],[-70.34259,12.92535],[-71.19849,12.65801],[-70.92579,11.96275],[-71.3275,11.85],[-71.9675,11.65536],[-72.24983,11.14138],[-72.4767,11.1117],[-72.88002,10.44309],[-72.98085,9.85253],[-73.36905,9.16636]]]}},{"type":"Feature","properties":{"id":"VN"},"geometry":{"type":"Polygon","coordinates":[[[102.14099,22.40092],[102.18712,22.30403],[102.51734,22.02676],[102.49092,21.99002],[102.62301,21.91447],[102.67145,21.65894],[102.74189,21.66713],[102.82115,21.73667],[102.81894,21.83888],[102.85637,21.84501],[102.86077,21.71213],[102.97965,21.74076],[102.98846,21.58936],[102.86297,21.4255],[102.94223,21.46034],[102.88939,21.3107],[102.80794,21.25736],[102.89825,21.24707],[102.97745,21.05821],[103.03469,21.05821],[103.12055,20.89994],[103.21497,20.89832],[103.38032,20.79501],[103.45737,20.82382],[103.68633,20.66324],[103.73478,20.6669],[103.82282,20.8732],[103.98024,20.91531],[104.11121,20.96779],[104.27412,20.91433],[104.63957,20.6653],[104.38199,20.47155],[104.40621,20.3849],[104.47886,20.37459],[104.66158,20.47774],[104.72102,20.40554],[104.62195,20.36633],[104.61315,20.24452],[104.86852,20.14121],[104.91695,20.15567],[104.9874,20.09573],[104.8465,19.91783],[104.8355,19.80395],[104.68359,19.72729],[104.64837,19.62365],[104.53169,19.61743],[104.41281,19.70035],[104.23229,19.70242],[104.06498,19.66926],[104.05617,19.61743],[104.10832,19.51575],[104.06058,19.43484],[103.87125,19.31854],[104.5361,18.97747],[104.64617,18.85668],[105.12829,18.70453],[105.19654,18.64196],[105.1327,18.58355],[105.10408,18.43533],[105.15942,18.38691],[105.38366,18.15315],[105.46292,18.22008],[105.64784,17.96687],[105.60381,17.89356],[105.76612,17.67147],[105.85744,17.63221],[106.09019,17.36399],[106.18991,17.28227],[106.24444,17.24714],[106.29287,17.3018],[106.31929,17.20509],[106.43597,17.01362],[106.50862,16.9673],[106.55045,17.0031],[106.54824,16.92729],[106.51963,16.92097],[106.52183,16.87884],[106.55265,16.86831],[106.55485,16.68704],[106.59013,16.62259],[106.58267,16.6012],[106.61477,16.60713],[106.66052,16.56892],[106.65832,16.47816],[106.74418,16.41904],[106.84104,16.55415],[106.88727,16.52671],[106.88067,16.43594],[106.96638,16.34938],[106.97385,16.30204],[107.02597,16.31132],[107.09091,16.3092],[107.15035,16.26271],[107.14595,16.17816],[107.25822,16.13587],[107.33968,16.05549],[107.44975,16.08511],[107.46296,16.01106],[107.39471,15.88829],[107.34188,15.89464],[107.21419,15.83747],[107.21859,15.74638],[107.27143,15.71459],[107.27583,15.62769],[107.34408,15.62345],[107.3815,15.49832],[107.50699,15.48771],[107.53341,15.40496],[107.62367,15.42193],[107.60605,15.37524],[107.62587,15.2266],[107.58844,15.20111],[107.61926,15.13949],[107.61486,15.0566],[107.46516,15.00982],[107.48277,14.93751],[107.59285,14.87795],[107.51579,14.79282],[107.54361,14.69092],[107.55371,14.628],[107.52102,14.59034],[107.52569,14.54665],[107.48521,14.40346],[107.44941,14.41552],[107.39493,14.32655],[107.40427,14.24509],[107.33577,14.11832],[107.37158,14.07906],[107.35757,14.02319],[107.38247,13.99147],[107.44318,13.99751],[107.46498,13.91593],[107.45252,13.78897],[107.53503,13.73908],[107.61909,13.52577],[107.62843,13.3668],[107.49144,13.01215],[107.49611,12.88926],[107.55993,12.7982],[107.5755,12.52177],[107.55059,12.36824],[107.4463,12.29373],[107.42917,12.24657],[107.34511,12.33327],[107.15831,12.27547],[106.99953,12.08983],[106.92325,12.06548],[106.79405,12.0807],[106.70687,11.96956],[106.4111,11.97413],[106.4687,11.86751],[106.44068,11.86294],[106.44535,11.8279],[106.41577,11.76999],[106.45158,11.68616],[106.44691,11.66787],[106.37219,11.69836],[106.30525,11.67549],[106.26478,11.72122],[106.18539,11.75171],[106.13158,11.73283],[106.06708,11.77761],[106.02038,11.77457],[106.00792,11.7197],[105.95188,11.63738],[105.88962,11.67854],[105.8507,11.66635],[105.80867,11.60536],[105.81645,11.56876],[105.87328,11.55953],[105.88962,11.43605],[105.86782,11.28343],[106.10444,11.07879],[106.1527,11.10476],[106.1757,11.07301],[106.20095,10.97795],[106.14301,10.98176],[106.18539,10.79451],[106.06708,10.8098],[105.94535,10.9168],[105.93403,10.83853],[105.84603,10.85873],[105.86376,10.89839],[105.77751,11.03671],[105.50045,10.94586],[105.42884,10.96878],[105.34011,10.86179],[105.11449,10.96332],[105.08326,10.95656],[105.02722,10.89236],[105.09571,10.72722],[104.95094,10.64003],[104.87933,10.52833],[104.59018,10.53073],[104.49869,10.4057],[104.47963,10.43046],[104.43778,10.42386],[103.99198,10.48391],[102.47649,9.66162],[104.81582,8.03101],[109.55486,8.10026],[110.2534,15.19951],[107.44022,18.66249],[108.26073,20.07614],[108.10003,21.47338],[108.0569,21.53604],[108.02926,21.54997],[107.97932,21.54503],[107.97383,21.53961],[107.97074,21.54072],[107.96774,21.53601],[107.95232,21.5388],[107.92652,21.58906],[107.90006,21.5905],[107.86114,21.65128],[107.80355,21.66141],[107.66967,21.60787],[107.56537,21.61945],[107.54047,21.5934],[107.49065,21.59774],[107.49532,21.62958],[107.47197,21.6672],[107.41593,21.64839],[107.38636,21.59774],[107.35989,21.60063],[107.35834,21.6672],[107.29296,21.74674],[107.24625,21.7077],[107.20734,21.71493],[107.10771,21.79879],[107.02615,21.81981],[107.00964,21.85948],[107.06101,21.88982],[107.05634,21.92303],[106.99252,21.95191],[106.97228,21.92592],[106.92714,21.93459],[106.9178,21.97357],[106.81038,21.97934],[106.74345,22.00965],[106.72551,21.97923],[106.69276,21.96013],[106.68274,21.99811],[106.70142,22.02409],[106.6983,22.15102],[106.67495,22.1885],[106.69986,22.22309],[106.6516,22.33977],[106.55976,22.34841],[106.57221,22.37],[106.55665,22.46498],[106.58395,22.474],[106.61269,22.60301],[106.65316,22.5757],[106.71698,22.58432],[106.72321,22.63606],[106.76293,22.73491],[106.82404,22.7881],[106.83685,22.8098],[106.81271,22.8226],[106.78422,22.81532],[106.71128,22.85982],[106.71387,22.88296],[106.6734,22.89587],[106.6516,22.86862],[106.60179,22.92884],[106.55976,22.92311],[106.51306,22.94891],[106.49749,22.91164],[106.34961,22.86718],[106.27022,22.87722],[106.19705,22.98475],[106.00179,22.99049],[105.99568,22.94178],[105.90119,22.94168],[105.8726,22.92756],[105.72382,23.06641],[105.57594,23.075],[105.56037,23.16806],[105.49966,23.20669],[105.42805,23.30824],[105.40782,23.28107],[105.32376,23.39684],[105.22569,23.27249],[105.17276,23.28679],[105.11672,23.25247],[105.07002,23.26248],[104.98712,23.19176],[104.96532,23.20463],[104.9486,23.17235],[104.91435,23.18666],[104.87992,23.17141],[104.87382,23.12854],[104.79478,23.12934],[104.8334,23.01484],[104.86765,22.95178],[104.84942,22.93631],[104.77114,22.90017],[104.72755,22.81984],[104.65283,22.83419],[104.60457,22.81841],[104.58122,22.85571],[104.47225,22.75813],[104.35593,22.69353],[104.25683,22.76534],[104.27084,22.8457],[104.11384,22.80363],[104.03734,22.72945],[104.01088,22.51823],[103.99247,22.51958],[103.97384,22.50634],[103.96783,22.51173],[103.96352,22.50584],[103.95191,22.5134],[103.94513,22.52553],[103.93286,22.52703],[103.87904,22.56683],[103.64506,22.79979],[103.56255,22.69499],[103.57812,22.65764],[103.52675,22.59155],[103.43646,22.70648],[103.43179,22.75816],[103.32282,22.8127],[103.28079,22.68063],[103.18895,22.64471],[103.15782,22.59873],[103.17961,22.55705],[103.07843,22.50097],[103.0722,22.44775],[102.9321,22.48659],[102.8636,22.60735],[102.60675,22.73376],[102.57095,22.7036],[102.51802,22.77969],[102.46665,22.77108],[102.42618,22.69212],[102.38415,22.67919],[102.41061,22.64184],[102.25339,22.4607],[102.26428,22.41321],[102.16621,22.43336],[102.14099,22.40092]]]}},{"type":"Feature","properties":{"id":"YE"},"geometry":{"type":"Polygon","coordinates":[[[41.29956,15.565],[42.63806,13.58268],[43.29075,12.79154],[43.32909,12.59711],[43.90659,12.3823],[50.51849,13.0483],[51.12877,12.56479],[52.253,11.68582],[55.69862,12.12478],[53.32998,16.16312],[53.09917,16.67084],[52.81185,17.28568],[52.74267,17.29519],[52.78009,17.35124],[52.00311,19.00083],[49.04884,18.59899],[48.19996,18.20584],[47.58351,17.50366],[47.48245,17.10808],[47.00571,16.94765],[46.76494,17.29151],[46.31018,17.20464],[44.50126,17.47475],[43.70631,17.35762],[43.43005,17.56148],[43.29185,17.53224],[43.22533,17.38343],[43.32653,17.31179],[43.20156,17.25901],[43.17787,17.14717],[43.23967,17.03428],[43.18233,17.02673],[43.1813,16.98438],[43.19328,16.94703],[43.1398,16.90696],[43.18338,16.84852],[43.22012,16.83932],[43.22956,16.80613],[43.24801,16.80613],[43.26303,16.79479],[43.25857,16.75304],[43.21325,16.74416],[43.22066,16.65179],[43.15274,16.67248],[43.11601,16.53166],[42.97215,16.51093],[42.94351,16.49467],[42.94625,16.39721],[42.76801,16.40371],[42.15205,16.40211],[41.37609,16.19728],[41.29956,15.565]]]}},{"type":"Feature","properties":{"id":"ZM"},"geometry":{"type":"Polygon","coordinates":[[[21.97988,-13.00148],[22.00323,-16.18028],[22.17217,-16.50269],[23.20038,-17.47563],[23.47474,-17.62877],[24.23619,-17.47489],[24.32811,-17.49082],[24.38712,-17.46818],[24.5621,-17.52963],[24.70864,-17.49501],[25.00198,-17.58221],[25.26433,-17.79571],[25.51646,-17.86232],[25.6827,-17.81987],[25.85738,-17.91403],[25.85892,-17.97726],[26.08925,-17.98168],[26.0908,-17.93021],[26.21601,-17.88608],[26.55918,-17.99638],[26.68403,-18.07411],[26.74314,-18.0199],[26.89926,-17.98756],[27.14196,-17.81398],[27.30736,-17.60487],[27.61377,-17.34378],[27.62795,-17.24365],[27.83141,-16.96274],[28.73725,-16.5528],[28.76199,-16.51575],[28.81454,-16.48611],[28.8501,-16.04537],[28.9243,-15.93987],[29.01298,-15.93805],[29.21955,-15.76589],[29.4437,-15.68702],[29.8317,-15.6126],[30.35574,-15.6513],[30.41902,-15.62269],[30.22098,-14.99447],[33.24249,-14.00019],[33.16749,-13.93992],[33.07568,-13.98447],[33.02977,-14.05022],[32.99042,-13.95689],[32.88985,-13.82956],[32.79015,-13.80755],[32.76962,-13.77224],[32.84528,-13.71576],[32.7828,-13.64805],[32.68654,-13.64268],[32.66468,-13.60019],[32.68436,-13.55769],[32.73683,-13.57682],[32.84176,-13.52794],[32.86113,-13.47292],[33.0078,-13.19492],[32.98289,-13.12671],[33.02181,-12.88707],[32.96733,-12.88251],[32.94397,-12.76868],[33.05917,-12.59554],[33.18837,-12.61377],[33.28177,-12.54692],[33.37517,-12.54085],[33.54485,-12.35996],[33.47636,-12.32498],[33.3705,-12.34931],[33.25998,-12.14242],[33.33937,-11.91252],[33.32692,-11.59248],[33.24252,-11.59302],[33.23663,-11.40637],[33.29267,-11.43536],[33.29267,-11.3789],[33.39697,-11.15296],[33.25998,-10.88862],[33.28022,-10.84428],[33.47636,-10.78465],[33.70675,-10.56896],[33.54797,-10.36077],[33.53863,-10.20148],[33.31297,-10.05133],[33.37902,-9.9104],[33.36581,-9.81063],[33.31517,-9.82364],[33.2095,-9.61099],[33.12144,-9.58929],[33.10163,-9.66525],[33.05485,-9.61316],[33.00256,-9.63053],[33.00476,-9.5133],[32.95389,-9.40138],[32.76233,-9.31963],[32.75611,-9.28583],[32.53661,-9.24281],[32.49147,-9.14754],[32.43543,-9.11988],[32.25486,-9.13371],[32.16146,-9.05993],[32.08206,-9.04609],[31.98866,-9.07069],[31.94196,-9.02303],[31.94663,-8.93846],[31.81587,-8.88618],[31.71158,-8.91386],[31.57147,-8.81388],[31.57147,-8.70619],[31.37533,-8.60769],[31.00796,-8.58615],[30.79243,-8.27382],[28.88917,-8.4831],[28.9711,-8.66935],[28.38526,-9.23393],[28.36562,-9.30091],[28.52636,-9.35379],[28.51627,-9.44726],[28.56208,-9.49122],[28.68532,-9.78],[28.62795,-9.92942],[28.65032,-10.65133],[28.37241,-11.57848],[28.48357,-11.87532],[29.18592,-12.37921],[29.4992,-12.43843],[29.48404,-12.23604],[29.8139,-12.14898],[29.81551,-13.44683],[29.65078,-13.41844],[29.60531,-13.21685],[29.01918,-13.41353],[28.33199,-12.41375],[27.59932,-12.22123],[27.21025,-11.76157],[27.22541,-11.60323],[27.04351,-11.61312],[26.88687,-12.01868],[26.01777,-11.91488],[25.33058,-11.65767],[25.34069,-11.19707],[24.42612,-11.44975],[24.34528,-11.06816],[24.00027,-10.89356],[24.02603,-11.15368],[23.98804,-12.13149],[24.06672,-12.29058],[23.90937,-12.844],[24.03339,-12.99091],[21.97988,-13.00148]]]}},{"type":"Feature","properties":{"id":"ZW"},"geometry":{"type":"Polygon","coordinates":[[[25.23909,-17.90832],[25.31799,-18.07091],[25.39972,-18.12691],[25.53465,-18.39041],[25.68859,-18.56165],[25.79217,-18.6355],[25.82353,-18.82808],[25.94326,-18.90362],[25.99837,-19.02943],[25.96226,-19.08152],[26.17227,-19.53709],[26.72246,-19.92707],[27.21278,-20.08244],[27.29831,-20.28935],[27.28865,-20.49873],[27.69361,-20.48531],[27.72972,-20.51735],[27.69171,-21.08409],[27.91407,-21.31621],[28.01669,-21.57624],[28.29416,-21.59037],[28.49942,-21.66634],[28.58114,-21.63455],[29.07763,-21.81877],[29.04023,-21.85864],[29.02191,-21.90647],[29.02191,-21.95665],[29.04108,-22.00563],[29.08495,-22.04867],[29.14501,-22.07275],[29.1974,-22.07472],[29.24648,-22.05967],[29.3533,-22.18363],[29.37703,-22.19581],[29.64609,-22.12917],[29.76848,-22.14128],[29.92242,-22.19408],[30.13147,-22.30841],[30.2265,-22.2961],[30.28351,-22.35587],[30.38614,-22.34533],[30.48686,-22.31368],[30.6294,-22.32599],[30.86696,-22.28907],[31.08932,-22.34884],[31.16344,-22.32599],[31.30611,-22.422],[31.38336,-22.36919],[32.41234,-21.31246],[32.48236,-21.32873],[32.37115,-21.133],[32.51644,-20.91929],[32.48122,-20.63319],[32.55167,-20.56312],[32.66174,-20.56106],[32.85987,-20.27841],[32.85987,-20.16686],[32.93032,-20.03868],[33.01178,-20.02007],[33.06461,-19.77787],[32.95013,-19.67219],[32.84666,-19.68462],[32.84446,-19.48343],[32.78282,-19.47513],[32.77966,-19.36098],[32.85107,-19.29238],[32.87088,-19.09279],[32.84006,-19.0262],[32.72118,-19.02204],[32.69917,-18.94293],[32.73439,-18.92628],[32.70137,-18.84712],[32.82465,-18.77419],[32.9017,-18.7992],[32.95013,-18.69079],[32.88629,-18.58023],[32.88629,-18.51344],[33.02278,-18.4696],[33.03159,-18.35054],[32.94133,-17.99705],[33.0492,-17.60298],[32.98536,-17.55891],[32.96554,-17.48964],[33.0426,-17.3468],[33.00517,-17.30477],[32.96554,-17.11971],[32.84113,-16.92259],[32.91051,-16.89446],[32.97655,-16.70689],[32.78943,-16.70267],[32.69917,-16.66893],[32.71017,-16.59932],[32.42838,-16.4727],[32.28529,-16.43892],[32.02772,-16.43892],[31.91324,-16.41569],[31.90223,-16.34388],[31.67988,-16.19595],[31.42451,-16.15154],[31.30563,-16.01193],[31.13171,-15.98019],[30.97761,-16.05848],[30.91597,-15.99924],[30.42568,-15.9962],[30.41902,-15.62269],[30.35574,-15.6513],[29.8317,-15.6126],[29.4437,-15.68702],[29.21955,-15.76589],[29.01298,-15.93805],[28.9243,-15.93987],[28.8501,-16.04537],[28.81454,-16.48611],[28.76199,-16.51575],[28.73725,-16.5528],[27.83141,-16.96274],[27.62795,-17.24365],[27.61377,-17.34378],[27.30736,-17.60487],[27.14196,-17.81398],[26.89926,-17.98756],[26.74314,-18.0199],[26.68403,-18.07411],[26.55918,-17.99638],[26.21601,-17.88608],[26.0908,-17.93021],[26.08925,-17.98168],[25.85892,-17.97726],[25.85738,-17.91403],[25.6827,-17.81987],[25.51646,-17.86232],[25.26433,-17.79571],[25.23909,-17.90832]]]}},{"type":"Feature","properties":{"id":"US-AK"},"geometry":{"type":"Polygon","coordinates":[[[-179.55295,50.81807],[-133.92876,54.62289],[-130.61931,54.70835],[-130.64499,54.76912],[-130.44184,54.85377],[-130.27203,54.97174],[-130.18765,55.07744],[-130.08035,55.21556],[-129.97513,55.28029],[-130.15373,55.74895],[-130.00857,55.91344],[-130.00093,56.00325],[-130.10173,56.12178],[-130.33965,56.10849],[-130.77769,56.36185],[-131.8271,56.62247],[-133.38523,58.42773],[-133.84645,58.73543],[-134.27175,58.8634],[-134.48059,59.13231],[-134.55699,59.1297],[-134.7047,59.2458],[-135.00267,59.28745],[-135.03069,59.56208],[-135.48007,59.79937],[-136.31566,59.59083],[-136.22381,59.55526],[-136.33727,59.44466],[-136.47323,59.46617],[-136.52365,59.16752],[-136.82619,59.16198],[-137.4925,58.89415],[-137.60623,59.24465],[-138.62145,59.76431],[-138.71149,59.90728],[-139.05365,59.99655],[-139.20603,60.08896],[-139.05831,60.35205],[-139.68991,60.33693],[-139.98024,60.18027],[-140.45648,60.30919],[-140.5227,60.22077],[-141.00116,60.30648],[-141.00555,72.20369],[-168.25765,71.99091],[-168.95635,65.98512],[-169.03888,65.48473],[-172.76104,63.77445],[-179.55295,57.62081],[-179.55295,50.81807]]]}},{"type":"Feature","properties":{"id":"GL"},"geometry":{"type":"Polygon","coordinates":[[[-74.12379,75.70014],[-53.68108,62.9266],[-45.64471,55.43944],[-25.70385,67.46637],[-10.71459,70.09565],[-9.68082,72.73731],[-3.52068,82.6752],[-34.32457,84.11035],[-59.93819,82.31398],[-63.1988,81.66522],[-67.48417,80.75493],[-73.91222,78.42484],[-74.12379,75.70014]]]}},{"type":"Feature","properties":{"id":"IN-HP"},"geometry":{"type":"Polygon","coordinates":[[[75.58284,32.07384],[75.71948,32.06541],[75.89904,31.94808],[75.96977,31.81281],[75.92822,31.80522],[76.16546,31.39526],[76.18743,31.28999],[76.34056,31.34278],[76.31996,31.40082],[76.37283,31.43569],[76.50672,31.27913],[76.64817,31.21015],[76.61384,31.00144],[76.7704,30.9087],[76.90017,30.89751],[76.92386,30.83415],[76.99802,30.80024],[77.22083,30.49246],[77.5542,30.40278],[77.80757,30.52086],[77.7238,30.59359],[77.76946,30.63111],[77.69016,30.76927],[77.80174,31.05822],[78.292,31.28676],[78.99581,31.10821],[78.77898,31.31209],[78.71032,31.50197],[78.84516,31.60631],[78.69933,31.78723],[78.78036,31.99478],[78.74404,32.00384],[78.68754,32.10256],[78.49609,32.2762],[78.4645,32.45367],[78.38897,32.53938],[78.32565,32.75263],[77.97477,32.58905],[77.88345,32.7942],[77.66784,32.97007],[77.32795,32.82305],[76.76902,33.26337],[76.31584,33.1341],[75.95329,32.88362],[75.77888,32.9355],[75.92513,32.64689],[75.82936,32.52664],[75.93921,32.41474],[75.7521,32.28364],[75.64756,32.24707],[75.62885,32.10148],[75.58284,32.07384]]]}},{"type":"Feature","properties":{"id":"LK"},"geometry":{"type":"Polygon","coordinates":[[[79.37385,8.98767],[79.9245,5.46963],[82.74996,6.54691],[80.48418,10.20786],[79.42124,9.80115],[79.45362,9.159],[79.37385,8.98767]]]}},{"type":"Feature","properties":{"id":"CN-GZ"},"geometry":{"type":"Polygon","coordinates":[[[103.61377,27.00591],[103.68621,27.06248],[103.78063,26.949],[103.7051,26.83173],[103.8153,26.53417],[104.00104,26.51389],[104.15279,26.67323],[104.34162,26.62444],[104.40925,26.73028],[104.47963,26.58422],[104.56031,26.59405],[104.68666,26.3691],[104.59258,26.31926],[104.47002,26.02007],[104.309,25.65947],[104.44633,25.47861],[104.52152,25.52695],[104.66022,25.2745],[104.78622,25.28195],[104.83119,25.172],[104.72545,25.19096],[104.71206,25.00348],[104.60151,24.89889],[104.52804,24.73498],[104.73884,24.62017],[105.02792,24.79982],[105.10345,24.94186],[105.21606,24.9985],[105.4502,24.91135],[105.49621,24.80917],[105.8052,24.70254],[105.93875,24.72936],[106.016,24.63079],[106.1856,24.78954],[106.19522,24.87491],[106.13994,24.95618],[106.43726,25.02121],[106.63913,25.13533],[106.63621,25.16734],[106.69595,25.18148],[106.89216,25.18723],[106.91757,25.25214],[106.99722,25.245],[106.96083,25.44203],[107.07206,25.56226],[107.23171,25.57682],[107.35153,25.39428],[107.43118,25.28909],[107.48233,25.30414],[107.46568,25.21736],[107.6061,25.2641],[107.6497,25.32106],[107.69313,25.19282],[107.75218,25.24314],[107.77622,25.11979],[108.11096,25.21363],[108.18923,25.45319],[108.34648,25.535],[108.61976,25.30306],[108.60671,25.49348],[108.73237,25.64709],[108.80721,25.53067],[109.07501,25.53376],[109.06745,25.72877],[108.88275,25.68299],[109.03312,25.79865],[109.19929,25.7665],[109.26521,25.71702],[109.47669,26.03334],[109.45129,26.30449],[109.28649,26.28664],[109.38056,26.57931],[109.28581,26.70022],[109.51652,26.75726],[109.49043,27.06524],[109.40734,27.15264],[109.13268,27.06462],[108.87451,27.00652],[108.78936,27.08908],[109.0472,27.29643],[109.04651,27.33578],[109.10659,27.3495],[109.14642,27.45344],[109.2937,27.42541],[109.45197,27.5722],[109.46708,27.69508],[109.33799,27.78198],[109.31533,27.9856],[109.38056,28.03683],[109.29336,28.05531],[109.39807,28.27717],[109.26881,28.3145],[109.28495,28.3772],[109.2616,28.39034],[109.25302,28.4711],[109.26993,28.49849],[109.26898,28.50437],[109.24324,28.4969],[109.22753,28.48317],[109.20075,28.48642],[109.17054,28.4582],[109.15981,28.42597],[109.08531,28.18884],[109.02385,28.20972],[108.99707,28.15828],[108.88137,28.22182],[108.75091,28.2073],[108.72001,28.29228],[108.76739,28.31465],[108.77872,28.42492],[108.70731,28.50098],[108.63178,28.46506],[108.68911,28.40136],[108.65959,28.3343],[108.60706,28.32523],[108.56414,28.37931],[108.60603,28.44092],[108.56552,28.5423],[108.60877,28.54924],[108.63109,28.6457],[108.52981,28.65112],[108.45874,28.62852],[108.33103,28.68637],[108.38012,28.80647],[108.28708,29.09577],[108.22837,29.02405],[108.18477,29.07207],[108.14323,29.05737],[108.0622,29.09037],[108.00899,29.04206],[107.88574,29.01114],[107.84042,28.96309],[107.75184,29.21031],[107.67219,29.14916],[107.4044,29.19472],[107.36457,29.00333],[107.44148,28.93845],[107.26089,28.76103],[107.1833,28.88977],[106.98211,28.86031],[106.96838,28.76585],[106.88804,28.80436],[106.81182,28.7514],[106.86881,28.62611],[106.81251,28.58934],[106.76238,28.62732],[106.77406,28.55919],[106.70677,28.44997],[106.55914,28.51153],[106.65183,28.66649],[106.5715,28.70624],[106.46781,28.84106],[106.44927,28.78631],[106.51245,28.67673],[106.47743,28.53567],[106.36756,28.52662],[105.96588,28.7496],[105.88142,28.602],[105.68778,28.57547],[105.61981,28.43488],[105.65895,28.308],[105.8876,28.23785],[105.9233,28.1277],[106.13857,28.16948],[106.20826,28.13497],[106.35864,27.83907],[105.92262,27.72973],[105.60676,27.69751],[105.31219,27.71088],[105.21057,27.37603],[105.08079,27.42114],[104.86312,27.28362],[104.85145,27.34523],[104.6046,27.30528],[104.50984,27.40712],[104.37217,27.47233],[104.18334,27.2708],[103.94165,27.45375],[103.83865,27.27202],[103.62716,27.11872],[103.61377,27.00591]]]}},{"type":"Feature","properties":{"id":"IS"},"geometry":{"type":"Polygon","coordinates":[[[-25.70385,67.46637],[-25.58144,62.99867],[-12.08632,63.06873],[-12.20873,67.52551],[-25.70385,67.46637]]]}},{"type":"Feature","properties":{"id":"BS"},"geometry":{"type":"Polygon","coordinates":[[[-80.16442,23.44484],[-73.62304,20.6935],[-72.94479,20.79216],[-72.41726,22.40371],[-76.80329,26.86841],[-78.4311,27.53866],[-79.36558,27.02964],[-80.16442,23.44484]]]}},{"type":"Feature","properties":{"id":"VI"},"geometry":{"type":"Polygon","coordinates":[[[-65.27974,17.56928],[-64.35558,17.48384],[-64.646,18.10286],[-64.64067,18.36478],[-64.86049,18.39954],[-65.02435,18.73231],[-65.27974,17.56928]]]}},{"type":"Feature","properties":{"id":"MV"},"geometry":{"type":"Polygon","coordinates":[[[72.15131,7.6285],[72.64576,-1.32013],[74.20495,-1.22734],[74.03744,7.70688],[72.15131,7.6285]]]}},{"type":"Feature","properties":{"id":"IO"},"geometry":{"type":"Polygon","coordinates":[[[70.64391,-7.71751],[72.09053,-7.71938],[73.19616,-7.72081],[73.19718,-6.94577],[73.19979,-4.96078],[70.64754,-4.95745],[70.64391,-7.71751]]]}},{"type":"Feature","properties":{"id":"CN-ZJ"},"geometry":{"type":"Polygon","coordinates":[[[118.0323,29.10057],[118.25134,28.92523],[118.3509,28.8164],[118.4254,28.68486],[118.40343,28.57457],[118.47381,28.47925],[118.43364,28.41193],[118.48308,28.32856],[118.42121,28.29239],[118.47759,28.23876],[118.53973,28.28594],[118.79035,28.24572],[118.71002,27.98773],[118.79722,27.94164],[118.89678,27.64643],[118.89541,27.47294],[119.12132,27.44186],[119.25247,27.43425],[119.61845,27.67988],[119.65999,27.5381],[119.76985,27.30741],[120.03662,27.34371],[120.13275,27.42053],[120.25909,27.43089],[120.42011,27.26531],[120.40603,27.20273],[120.43281,27.17219],[121.03532,26.8787],[123.5458,31.01942],[121.26434,30.68516],[121.21456,30.78726],[121.12152,30.78018],[121.12529,30.86509],[121.03122,30.82265],[120.98865,30.89603],[120.98659,31.01939],[120.89424,31.01822],[120.84754,30.99173],[120.7703,30.9988],[120.73459,30.96289],[120.67485,30.957],[120.70747,30.88572],[120.64739,30.85095],[120.5801,30.85566],[120.49873,30.75953],[120.42835,30.91459],[120.35007,30.88896],[120.36208,30.97054],[119.91439,31.17051],[119.63149,31.1329],[119.58412,30.97407],[119.57382,30.85743],[119.43134,30.64145],[119.38671,30.69018],[119.24663,30.61575],[119.23393,30.53062],[119.31152,30.53032],[119.38705,30.37761],[119.22912,30.28871],[118.89404,30.35391],[118.90914,30.20508],[118.85627,30.16709],[118.89816,30.02332],[118.75808,29.76258],[118.48548,29.52447],[118.33717,29.48503],[118.20052,29.38178],[118.07281,29.2852],[118.0323,29.10057]]]}},{"type":"Feature","properties":{"id":"RE"},"geometry":{"type":"Polygon","coordinates":[[[54.32269,-20.37973],[54.43368,-22.02482],[56.73473,-21.9174],[56.62373,-20.2711],[54.32269,-20.37973]]]}},{"type":"Feature","properties":{"id":"MU"},"geometry":{"type":"Polygon","coordinates":[[[56.09755,-9.55401],[56.62373,-20.2711],[56.73473,-21.9174],[64.11105,-21.5783],[63.47388,-9.1938],[56.09755,-9.55401]]]}},{"type":"Feature","properties":{"id":"SC"},"geometry":{"type":"Polygon","coordinates":[[[45.39948,-9.09441],[46.52682,-10.83678],[48.86266,-10.8109],[51.51407,-10.78153],[57.144,-7.697],[56.94974,-2.9998],[53.06458,-3.53165],[45.39948,-9.09441]]]}},{"type":"Feature","properties":{"id":"KM"},"geometry":{"type":"Polygon","coordinates":[[[42.93552,-11.11413],[42.99868,-12.65261],[44.75722,-12.58368],[44.69407,-11.04481],[42.93552,-11.11413]]]}},{"type":"Feature","properties":{"id":"FO"},"geometry":{"type":"Polygon","coordinates":[[[-8.51774,62.35338],[-6.51083,60.95272],[-5.70102,62.77194],[-8.51774,62.35338]]]}},{"type":"Feature","properties":{"id":"CN-XJ"},"geometry":{"type":"Polygon","coordinates":[[[73.5004,39.38402],[73.55396,39.3543],[73.54572,39.27567],[73.60638,39.24534],[73.75823,39.023],[73.81728,39.04007],[73.82964,38.91517],[73.7445,38.93867],[73.7033,38.84782],[73.80656,38.66449],[73.79806,38.61106],[73.97933,38.52945],[74.17022,38.65504],[74.51217,38.47034],[74.69619,38.42947],[74.69894,38.22155],[74.80331,38.19889],[74.82665,38.07359],[74.9063,38.03033],[74.92416,37.83428],[75.00935,37.77486],[74.8912,37.67576],[74.94338,37.55501],[75.06011,37.52779],[75.15899,37.41443],[75.09719,37.37297],[75.12328,37.31839],[74.88887,37.23275],[74.80605,37.21565],[74.49981,37.24518],[74.56453,37.03023],[75.13839,37.02622],[75.40481,36.95382],[75.45562,36.71971],[75.72737,36.7529],[75.92391,36.56986],[76.0324,36.41198],[76.00906,36.17511],[75.93028,36.13136],[76.15325,35.9264],[76.14913,35.82848],[76.33453,35.84296],[76.50961,35.8908],[76.77323,35.66062],[76.84539,35.67356],[76.96624,35.5932],[77.44277,35.46132],[77.70232,35.46244],[77.80532,35.52058],[78.11664,35.48022],[78.03466,35.3785],[78.00033,35.23954],[78.22692,34.88771],[78.18435,34.7998],[78.27781,34.61484],[78.54964,34.57283],[78.56475,34.50835],[78.74465,34.45174],[79.05364,34.32482],[79.05418,34.4154],[79.83283,34.48958],[80.45287,35.45172],[81.66961,35.24337],[82.01568,35.34201],[82.45238,35.7309],[82.966,35.62716],[83.1253,35.39688],[84.19784,35.35881],[85.26489,35.80333],[85.57662,35.64055],[86.09298,35.8679],[86.2619,36.19995],[88.53332,36.48755],[88.76438,36.29077],[88.94119,36.35716],[89.691,36.0935],[89.95056,36.08018],[90.01922,36.2631],[90.86379,36.02577],[91.10961,36.10792],[91.02035,36.54053],[90.7196,36.59347],[90.84869,36.93342],[91.31149,37.02887],[91.06567,37.48575],[90.5136,37.74465],[90.52322,38.31903],[90.31585,38.22955],[90.14076,38.33734],[90.18127,38.39764],[90.09406,38.49014],[90.44975,38.49928],[92.40874,39.03625],[92.92785,40.58058],[93.76556,40.66605],[94.80789,41.53428],[95.19103,41.7498],[95.35171,41.54559],[96.18324,41.97225],[96.04934,42.38796],[96.37926,42.72055],[96.35658,42.90363],[95.89543,43.2528],[95.52594,43.99353],[95.32891,44.02407],[95.39772,44.2805],[95.01191,44.25274],[94.71959,44.35284],[94.10003,44.71016],[93.51161,44.95964],[91.64048,45.07408],[90.89169,45.19667],[90.65114,45.49314],[90.70907,45.73437],[91.03026,46.04194],[90.99672,46.14207],[90.89639,46.30711],[91.07696,46.57315],[91.0147,46.58171],[91.03649,46.72916],[90.84035,46.99525],[90.76108,46.99399],[90.48542,47.30438],[90.48854,47.41826],[90.33598,47.68303],[90.10871,47.7375],[90.06512,47.88177],[89.76624,47.82745],[89.55453,48.0423],[89.0711,47.98528],[88.93186,48.10263],[88.8011,48.11302],[88.58316,48.21893],[88.58939,48.34531],[87.96361,48.58478],[88.0788,48.71436],[87.73822,48.89582],[87.88171,48.95853],[87.81333,49.17354],[87.48983,49.13794],[87.478,49.07403],[87.28386,49.11626],[86.87238,49.12432],[86.73568,48.99918],[86.75343,48.70331],[86.38069,48.46064],[85.73581,48.3939],[85.5169,48.05493],[85.61067,47.49753],[85.69696,47.2898],[85.54294,47.06171],[85.22443,47.04816],[84.93995,46.87399],[84.73077,47.01394],[83.92184,46.98912],[83.04622,47.19053],[82.21792,45.56619],[82.58474,45.40027],[82.51374,45.1755],[81.73278,45.3504],[80.11169,45.03352],[79.8987,44.89957],[80.38384,44.63073],[80.40229,44.23319],[80.40031,44.10986],[80.75156,43.44948],[80.69718,43.32589],[80.77771,43.30065],[80.78817,43.14235],[80.62913,43.141],[80.3735,43.01557],[80.58999,42.9011],[80.38169,42.83142],[80.26886,42.8366],[80.16892,42.61137],[80.26841,42.23797],[80.17807,42.21166],[80.17842,42.03211],[79.92977,42.04113],[78.3732,41.39603],[78.15757,41.38565],[78.12873,41.23091],[77.81287,41.14307],[77.76206,41.01574],[77.52723,41.00227],[77.3693,41.0375],[77.28004,41.0033],[76.99302,41.0696],[76.75681,40.95354],[76.5261,40.46114],[76.33659,40.3482],[75.96168,40.38064],[75.91361,40.2948],[75.69663,40.28642],[75.5854,40.66874],[75.22834,40.45382],[75.08243,40.43945],[74.82013,40.52197],[74.78168,40.44886],[74.85996,40.32857],[74.69875,40.34668],[74.35063,40.09742],[74.25533,40.13191],[73.97049,40.04378],[73.83006,39.76136],[73.9051,39.75073],[73.92354,39.69565],[73.94683,39.60733],[73.87018,39.47879],[73.59831,39.46425],[73.59241,39.40843],[73.5004,39.38402]]]}},{"type":"Feature","properties":{"id":"PM"},"geometry":{"type":"Polygon","coordinates":[[[-56.70773,46.51478],[-55.8643,46.64935],[-56.25228,47.31192],[-56.67989,47.3339],[-56.70773,46.51478]]]}},{"type":"Feature","properties":{"id":"JP"},"geometry":{"type":"Polygon","coordinates":[[[122.20217,23.54946],[136.0511,20.05526],[155.16731,23.60141],[145.97944,43.07828],[145.76215,43.50342],[145.23667,43.76813],[145.82343,44.571],[140.9182,45.92937],[133.61399,37.41],[129.2669,34.87122],[127.42045,32.33183],[123.1407,27.24938],[122.20217,23.54946]]]}},{"type":"Feature","properties":{"id":"IN-KL"},"geometry":{"type":"Polygon","coordinates":[[[74.66307,12.69394],[75.18012,11.478],[75.52551,11.6993],[75.53821,11.76384],[75.55864,11.72317],[75.53787,11.6872],[75.19042,11.45378],[76.72283,7.82138],[77.22358,8.44758],[77.20024,8.50734],[77.27954,8.52296],[77.17655,8.7385],[77.26135,8.843],[77.15045,9.01496],[77.42065,9.51543],[77.16865,9.61632],[77.24693,9.80447],[77.25997,10.02971],[77.20298,10.11759],[77.27645,10.13382],[77.21465,10.36423],[76.96403,10.221],[76.82327,10.3237],[76.80679,10.63159],[76.87236,10.63226],[76.85691,10.68051],[76.8988,10.77327],[76.84112,10.81138],[76.81777,10.86163],[76.6492,10.924],[76.7237,11.20736],[76.43531,11.19456],[76.53934,11.35079],[76.23344,11.51871],[76.23722,11.58699],[76.37145,11.59136],[76.42948,11.66568],[76.18949,11.87608],[76.11757,11.85105],[76.11259,11.97887],[76.00307,11.93185],[75.86059,11.95502],[75.78987,12.08296],[75.54302,12.20279],[75.49392,12.29103],[75.43109,12.31249],[75.37067,12.45602],[75.43659,12.47144],[75.39882,12.50161],[75.34698,12.46105],[75.27214,12.5502],[75.33393,12.57534],[75.28106,12.61856],[75.23471,12.56662],[75.19798,12.6132],[75.14579,12.63648],[75.16124,12.67969],[75.11438,12.67752],[75.08777,12.70029],[75.06872,12.66228],[75.04108,12.67484],[75.0531,12.71804],[74.98323,12.73998],[75.01327,12.79137],[74.86049,12.76057],[74.66307,12.69394]]]}},{"type":"Feature","properties":{"id":"TV"},"geometry":{"type":"Polygon","coordinates":[[[174,-11.5],[179.99999,-11.5],[179.99999,-5],[174,-5],[174,-11.5]]]}},{"type":"Feature","properties":{"id":"VU"},"geometry":{"type":"Polygon","coordinates":[[[162.93363,-17.28904],[173.07304,-22.54607],[168.14096,-12.74443],[165.31108,-12.67903],[162.93363,-17.28904]]]}},{"type":"Feature","properties":{"id":"SB"},"geometry":{"type":"Polygon","coordinates":[[[154.74815,-7.33315],[160.37269,-13.44534],[165.31108,-12.67903],[168.14096,-12.74443],[171.12712,-12.81344],[171.21374,-9.22564],[159.32766,-4.77078],[157.60997,-5.69776],[156.03296,-6.55528],[156.03993,-6.65703],[155.92557,-6.84664],[155.69784,-6.92661],[155.60735,-6.92266],[154.74815,-7.33315]]]}},{"type":"Feature","properties":{"id":"MP"},"geometry":{"type":"Polygon","coordinates":[[[143.82485,13.92273],[146.25931,13.85876],[146.6755,21.00809],[144.18594,21.03576],[143.82485,13.92273]]]}},{"type":"Feature","properties":{"id":"MH"},"geometry":{"type":"Polygon","coordinates":[[[159.04653,10.59067],[161.58988,8.892633],[165.35175,6.367],[169,3.9],[173.53711,5.70687],[169.29099,15.77133],[159.04653,10.59067]]]}},{"type":"Feature","properties":{"id":"FM"},"geometry":{"type":"Polygon","coordinates":[[[136.04605,12.45908],[136.27107,6.73747],[148.49862,1.920402],[154.49668,-0.44964],[156.88247,-1.39237],[161.87397,3.186785],[165.35175,6.367],[161.58988,8.892633],[159.04653,10.59067],[153.83475,11.01511],[148.42679,11.45488],[136.04605,12.45908]]]}},{"type":"Feature","properties":{"id":"MY"},"geometry":{"type":"Polygon","coordinates":[[[99.31854,5.99868],[99.75778,3.86466],[103.03657,1.30383],[103.56591,1.19719],[103.62738,1.35255],[103.67468,1.43166],[103.7219,1.46108],[103.74161,1.4502],[103.76395,1.45183],[103.81181,1.47953],[103.86383,1.46288],[103.89565,1.42841],[103.93384,1.42926],[104.00131,1.42405],[104.02277,1.4438],[104.04622,1.44691],[104.07348,1.43322],[104.08871,1.42015],[104.09162,1.39694],[104.08072,1.35998],[104.12282,1.27714],[104.34728,1.33529],[104.56723,1.44271],[105.01437,3.24936],[108.10426,5.42408],[109.71058,2.32059],[109.64506,2.08014],[109.62558,1.99182],[109.53794,1.91771],[109.57923,1.80624],[109.66397,1.79972],[109.66397,1.60425],[110.35354,0.98869],[110.49182,0.88088],[110.62374,0.873],[111.22979,1.08326],[111.55434,0.97864],[111.82846,0.99349],[111.94553,1.12016],[112.15679,1.17004],[112.2127,1.44135],[112.48648,1.56516],[113.021,1.57819],[113.01448,1.42832],[113.64677,1.23933],[114.03788,1.44787],[114.57892,1.5],[114.80706,1.92351],[114.80706,2.21665],[115.1721,2.49671],[115.11343,2.82879],[115.53713,3.14776],[115.58276,3.93499],[115.90217,4.37708],[117.25801,4.35108],[117.47313,4.18857],[117.67641,4.16535],[117.89538,4.16637],[118.07935,4.15511],[118.8663,4.44172],[118.75416,4.59798],[119.44841,5.09568],[119.34756,5.53889],[117.89159,6.25755],[117.43832,7.3895],[117.17735,7.52841],[116.79524,7.43869],[115.02521,5.35005],[115.16236,5.01011],[115.15092,4.87604],[115.20737,4.8256],[115.27819,4.63661],[115.2851,4.42295],[115.36346,4.33563],[115.31275,4.30806],[115.09978,4.39123],[115.07737,4.53418],[115.04064,4.63706],[115.02278,4.74137],[115.02955,4.82087],[115.05038,4.90275],[114.99417,4.88201],[114.96982,4.81146],[114.88841,4.81905],[114.8266,4.75062],[114.77303,4.72871],[114.83189,4.42387],[114.88039,4.4257],[114.78539,4.12205],[114.64211,4.00694],[114.49922,4.13108],[114.4416,4.27588],[114.32176,4.2552],[114.32176,4.34942],[114.26876,4.49878],[114.15813,4.57],[114.07448,4.58441],[114.08532,4.64632],[109.55486,8.10026],[104.81582,8.03101],[102.46318,7.22462],[102.09086,6.23546],[102.08127,6.22679],[102.07732,6.193],[102.09182,6.14161],[102.01835,6.05407],[101.99209,6.04075],[101.97114,6.01992],[101.9714,6.00575],[101.94712,5.98421],[101.92819,5.85511],[101.91776,5.84269],[101.89188,5.8386],[101.80144,5.74505],[101.75074,5.79091],[101.69773,5.75881],[101.58019,5.93534],[101.25524,5.78633],[101.25755,5.71065],[101.14062,5.61613],[100.98815,5.79464],[101.02708,5.91013],[101.087,5.9193],[101.12388,6.11411],[101.06165,6.14161],[101.12618,6.19431],[101.10313,6.25617],[100.85884,6.24929],[100.81045,6.45086],[100.74822,6.46231],[100.74361,6.50811],[100.66986,6.45086],[100.43027,6.52389],[100.42351,6.51762],[100.41791,6.5189],[100.41152,6.52299],[100.35413,6.54932],[100.31929,6.65413],[100.32607,6.65933],[100.32671,6.66526],[100.31884,6.66423],[100.31618,6.66781],[100.30828,6.66462],[100.29651,6.68439],[100.19511,6.72559],[100.12,6.42105],[100.0756,6.4045],[99.91873,6.50233],[99.50117,6.44501],[99.31854,5.99868]]]}},{"type":"Feature","properties":{"id":"ID"},"geometry":{"type":"Polygon","coordinates":[[[93.82619,5.95573],[96.82918,-7.16134],[122.91521,-11.65621],[125.68138,-9.85176],[125.09025,-9.46406],[124.97892,-9.19281],[125.04044,-9.17093],[125.09434,-9.19669],[125.18907,-9.16434],[125.18632,-9.03142],[125.11764,-8.96359],[124.97742,-9.08128],[124.94011,-8.85617],[124.46701,-9.13002],[124.45971,-9.30263],[124.38554,-9.3582],[124.35258,-9.43002],[124.3535,-9.48493],[124.28115,-9.50453],[124.28115,-9.42189],[124.21247,-9.36904],[124.14517,-9.42324],[124.10539,-9.41206],[124.04286,-9.34243],[124.04628,-9.22671],[124.33472,-9.11416],[124.92337,-8.75859],[125.31127,-8.22976],[125.65946,-8.06136],[125.87691,-8.31789],[127.21788,-8.22363],[127.53551,-8.41485],[127.55165,-9.05052],[139.41724,-8.97063],[140.88922,-9.34945],[141.00782,-9.1242],[141.01763,-6.90181],[140.85295,-6.72996],[140.99813,-6.3233],[141.00167,0.68547],[134.40878,1.79674],[128.97621,3.08804],[126.69413,6.02692],[124.97752,4.82064],[118.41402,3.99509],[118.07935,4.15511],[117.89538,4.16637],[117.67641,4.16535],[117.47313,4.18857],[117.25801,4.35108],[115.90217,4.37708],[115.58276,3.93499],[115.53713,3.14776],[115.11343,2.82879],[115.1721,2.49671],[114.80706,2.21665],[114.80706,1.92351],[114.57892,1.5],[114.03788,1.44787],[113.64677,1.23933],[113.01448,1.42832],[113.021,1.57819],[112.48648,1.56516],[112.2127,1.44135],[112.15679,1.17004],[111.94553,1.12016],[111.82846,0.99349],[111.55434,0.97864],[111.22979,1.08326],[110.62374,0.873],[110.49182,0.88088],[110.35354,0.98869],[109.66397,1.60425],[109.66397,1.79972],[109.57923,1.80624],[109.53794,1.91771],[109.62558,1.99182],[109.64506,2.08014],[109.71058,2.32059],[108.10426,5.42408],[105.01437,3.24936],[104.56723,1.44271],[104.34728,1.33529],[104.12282,1.27714],[104.03085,1.26954],[103.74084,1.12902],[103.66049,1.18825],[103.56591,1.19719],[103.03657,1.30383],[99.75778,3.86466],[97.65314,5.70549],[94.98735,6.60903],[93.82619,5.95573]]]}},{"type":"Feature","properties":{"id":"IN-BR"},"geometry":{"type":"Polygon","coordinates":[[[83.34125,25.0125],[83.39824,24.78735],[83.5033,24.73747],[83.49883,24.52651],[83.75015,24.50245],[83.94584,24.54899],[83.9994,24.63141],[84.49756,24.28546],[84.57447,24.41151],[84.81994,24.529],[84.89307,24.36304],[85.66108,24.61518],[85.7373,24.8154],[86.12869,24.71876],[86.12491,24.61143],[86.32163,24.5824],[86.28833,24.46027],[86.45004,24.36586],[86.60316,24.60457],[87.05532,24.61237],[87.10235,24.84812],[87.15866,24.89391],[87.1511,25.02246],[87.21668,25.09243],[87.28946,25.09741],[87.32688,25.22016],[87.47348,25.19686],[87.48962,25.29933],[87.53906,25.27947],[87.58369,25.35271],[87.65373,25.28009],[87.86521,25.27139],[87.78865,25.34495],[87.76514,25.42529],[87.92667,25.53717],[88.0688,25.48047],[88.03859,25.54182],[88.04923,25.68794],[87.89989,25.76866],[87.90058,25.85304],[87.78625,25.87559],[87.84393,26.04537],[87.95036,26.06511],[88.0046,26.14341],[88.29093,26.3568],[88.23034,26.37679],[88.26158,26.4263],[88.19137,26.47549],[88.23394,26.55413],[88.14313,26.51097],[88.09963,26.54195],[88.09414,26.43732],[88.00895,26.36029],[87.90115,26.44923],[87.89085,26.48565],[87.84193,26.43663],[87.7918,26.46737],[87.76004,26.40711],[87.67893,26.43501],[87.66803,26.40294],[87.59175,26.38342],[87.55274,26.40596],[87.51571,26.43106],[87.46566,26.44058],[87.37314,26.40815],[87.34568,26.34787],[87.26568,26.37294],[87.26587,26.40592],[87.24682,26.4143],[87.18863,26.40558],[87.14751,26.40542],[87.09147,26.45039],[87.0707,26.58571],[87.04691,26.58685],[87.01559,26.53228],[86.95912,26.52076],[86.94543,26.52076],[86.82898,26.43919],[86.76797,26.45892],[86.74025,26.42386],[86.69124,26.45169],[86.62686,26.46891],[86.61313,26.48658],[86.57073,26.49825],[86.54258,26.53819],[86.49726,26.54218],[86.31564,26.61925],[86.26235,26.61886],[86.22513,26.58863],[86.13596,26.60651],[86.02729,26.66756],[85.8492,26.56667],[85.85126,26.60866],[85.83126,26.61134],[85.76907,26.63076],[85.72315,26.67471],[85.73483,26.79613],[85.66239,26.84822],[85.61621,26.86721],[85.59461,26.85161],[85.5757,26.85955],[85.56471,26.84133],[85.47752,26.79292],[85.34302,26.74954],[85.21159,26.75933],[85.18046,26.80519],[85.19291,26.86909],[85.15883,26.86966],[85.02635,26.85381],[85.05592,26.88991],[85.00536,26.89523],[84.97186,26.9149],[84.96687,26.95599],[84.85754,26.98984],[84.82913,27.01989],[84.793,26.9968],[84.64496,27.04669],[84.69166,27.21294],[84.62161,27.33885],[84.29315,27.39],[84.25735,27.44941],[84.21376,27.45218],[84.10791,27.52399],[84.02229,27.43836],[83.93306,27.44939],[83.86182,27.4241],[83.85595,27.35797],[83.83048,27.29552],[84.02687,27.08847],[84.23973,26.86511],[84.30599,26.75082],[84.39594,26.61554],[84.1254,26.6318],[84.05296,26.54891],[83.87992,26.5225],[83.90258,26.44905],[84.17243,26.37495],[84.17106,26.26139],[84.01245,26.23676],[84.02309,26.13848],[84.15183,26.03334],[84.27955,25.94538],[84.54082,25.85737],[84.66613,25.74022],[84.4749,25.68485],[84.38804,25.76959],[84.32899,25.70588],[84.0921,25.72908],[84.05845,25.64833],[83.88061,25.51765],[83.871,25.49333],[83.81452,25.45459],[83.84593,25.43645],[83.76422,25.3859],[83.74242,25.40792],[83.65917,25.36745],[83.64852,25.34464],[83.49077,25.28614],[83.4621,25.25152],[83.41335,25.24966],[83.34897,25.17744],[83.34125,25.0125]]]}},{"type":"Feature","properties":{"id":"PW"},"geometry":{"type":"Polygon","coordinates":[[[128.97621,3.08804],[134.40878,1.79674],[136.27107,6.73747],[136.04605,12.45908],[128.97621,3.08804]]]}},{"type":"Feature","properties":{"id":"PH"},"geometry":{"type":"Polygon","coordinates":[[[116.28201,8.2483],[116.79524,7.43869],[117.17735,7.52841],[117.43832,7.3895],[117.89159,6.25755],[119.34756,5.53889],[119.44841,5.09568],[118.75416,4.59798],[118.8663,4.44172],[118.07935,4.15511],[118.41402,3.99509],[124.97752,4.82064],[126.69413,6.02692],[129.01382,8.04729],[121.8109,21.77688],[120.69238,21.52331],[116.28201,8.2483]]]}},{"type":"Feature","properties":{"id":"CN-GX"},"geometry":{"type":"Polygon","coordinates":[[[104.4659,24.65044],[104.56718,24.44527],[104.70588,24.31018],[104.71481,24.43777],[105.0238,24.43839],[105.19615,24.34209],[105.16868,24.14988],[105.49552,24.01949],[105.57174,24.13798],[105.64796,24.03831],[106.00364,24.12858],[106.15608,23.90592],[106.14097,23.5772],[106.00089,23.4519],[105.8773,23.53314],[105.59509,23.31766],[105.56037,23.16806],[105.57594,23.075],[105.72382,23.06641],[105.8726,22.92756],[105.90119,22.94168],[105.99568,22.94178],[106.00179,22.99049],[106.19705,22.98475],[106.27022,22.87722],[106.34961,22.86718],[106.49749,22.91164],[106.51306,22.94891],[106.55976,22.92311],[106.60179,22.92884],[106.6516,22.86862],[106.6734,22.89587],[106.71387,22.88296],[106.71128,22.85982],[106.78422,22.81532],[106.81271,22.8226],[106.83685,22.8098],[106.82404,22.7881],[106.76293,22.73491],[106.72321,22.63606],[106.71698,22.58432],[106.65316,22.5757],[106.61269,22.60301],[106.58395,22.474],[106.55665,22.46498],[106.57221,22.37],[106.55976,22.34841],[106.6516,22.33977],[106.69986,22.22309],[106.67495,22.1885],[106.6983,22.15102],[106.70142,22.02409],[106.68274,21.99811],[106.69276,21.96013],[106.72551,21.97923],[106.74345,22.00965],[106.81038,21.97934],[106.9178,21.97357],[106.92714,21.93459],[106.97228,21.92592],[106.99252,21.95191],[107.05634,21.92303],[107.06101,21.88982],[107.00964,21.85948],[107.02615,21.81981],[107.10771,21.79879],[107.20734,21.71493],[107.24625,21.7077],[107.29296,21.74674],[107.35834,21.6672],[107.35989,21.60063],[107.38636,21.59774],[107.41593,21.64839],[107.47197,21.6672],[107.49532,21.62958],[107.49065,21.59774],[107.54047,21.5934],[107.56537,21.61945],[107.66967,21.60787],[107.80355,21.66141],[107.86114,21.65128],[107.90006,21.5905],[107.92652,21.58906],[107.95232,21.5388],[107.96774,21.53601],[107.97074,21.54072],[107.97383,21.53961],[107.97932,21.54503],[108.02926,21.54997],[108.0569,21.53604],[108.10003,21.47338],[108.26073,20.07614],[109.78912,21.47351],[109.73968,21.6054],[109.76371,21.67178],[109.8904,21.65008],[109.92216,21.71198],[109.94585,21.84397],[109.98481,21.87185],[110.19458,21.90148],[110.24642,21.88332],[110.28573,21.91756],[110.32127,21.89351],[110.3841,21.89096],[110.39234,21.91199],[110.36556,21.93476],[110.34702,22.19567],[110.62442,22.15274],[110.67317,22.17659],[110.64193,22.23349],[110.78475,22.27353],[110.67626,22.47576],[110.73738,22.46307],[110.74424,22.56931],[110.99452,22.63682],[111.31965,22.85086],[111.35158,22.96123],[111.42711,23.03013],[111.34094,23.19654],[111.47724,23.62313],[111.63276,23.64641],[111.65645,23.83308],[111.79515,23.8133],[111.92596,23.97339],[111.87171,24.10978],[112.05711,24.35522],[111.93145,24.69506],[112.04166,24.77987],[111.68666,24.78486],[111.52633,24.63952],[111.42745,24.6832],[111.46179,25.02526],[111.28326,25.14528],[110.98525,24.9157],[110.97015,25.10922],[111.31347,25.47613],[111.30042,25.70155],[111.37596,25.73001],[111.48239,25.88208],[111.25579,25.85922],[111.19125,25.94693],[111.29287,26.24662],[111.09306,26.31188],[110.96328,26.3851],[110.9262,26.26694],[110.75317,26.25277],[110.61172,26.33465],[110.31028,25.96915],[110.09811,26.01914],[109.97486,26.19241],[109.81109,26.04259],[109.82276,25.88023],[109.68749,25.88517],[109.72663,26.00001],[109.47669,26.03334],[109.26521,25.71702],[109.19929,25.7665],[109.03312,25.79865],[108.88275,25.68299],[109.06745,25.72877],[109.07501,25.53376],[108.80721,25.53067],[108.73237,25.64709],[108.60671,25.49348],[108.61976,25.30306],[108.34648,25.535],[108.18923,25.45319],[108.11096,25.21363],[107.77622,25.11979],[107.75218,25.24314],[107.69313,25.19282],[107.6497,25.32106],[107.6061,25.2641],[107.46568,25.21736],[107.48233,25.30414],[107.43118,25.28909],[107.35153,25.39428],[107.23171,25.57682],[107.07206,25.56226],[106.96083,25.44203],[106.99722,25.245],[106.91757,25.25214],[106.89216,25.18723],[106.69595,25.18148],[106.63621,25.16734],[106.63913,25.13533],[106.43726,25.02121],[106.13994,24.95618],[106.19522,24.87491],[106.1856,24.78954],[106.016,24.63079],[105.93875,24.72936],[105.8052,24.70254],[105.49621,24.80917],[105.4502,24.91135],[105.21606,24.9985],[105.10345,24.94186],[105.02792,24.79982],[104.73884,24.62017],[104.52804,24.73498],[104.4659,24.65044]]]}},{"type":"Feature","properties":{"id":"JE"},"geometry":{"type":"Polygon","coordinates":[[[-2.56423,49.22209],[-2.5234,48.91595],[-2.00491,48.86706],[-1.83944,49.23037],[-2.09454,49.46288],[-2.56423,49.22209]]]}},{"type":"Feature","properties":{"id":"GG"},"geometry":{"type":"Polygon","coordinates":[[[-3.06097,49.47231],[-2.9511,49.31141],[-2.56423,49.22209],[-2.09454,49.46288],[-2.02963,49.91866],[-2.39388,49.94612],[-3.06097,49.47231]]]}},{"type":"Feature","properties":{"id":"IM"},"geometry":{"type":"Polygon","coordinates":[[[-5.83481,53.87749],[-5.37267,53.63269],[-3.64906,54.12723],[-4.1819,54.57861],[-4.86305,54.44148],[-5.83481,53.87749]]]}},{"type":"Feature","properties":{"id":"CN-HB"},"geometry":{"type":"Polygon","coordinates":[[[108.3657,29.84064],[108.4917,29.71966],[108.6098,29.86863],[108.67641,29.85255],[108.68499,29.70132],[108.90918,29.60331],[108.86455,29.46411],[108.93836,29.43601],[108.90918,29.32651],[108.97647,29.33085],[109.05029,29.4055],[109.10419,29.36691],[109.10745,29.21855],[109.2346,29.11829],[109.45678,29.55613],[109.53609,29.62331],[109.70088,29.60928],[109.78637,29.76556],[110.14514,29.78374],[110.37036,29.63345],[110.64742,29.77272],[110.4943,29.91923],[110.52246,30.06523],[110.75386,30.04888],[110.75729,30.12523],[110.94646,30.06493],[111.24481,30.04383],[111.40274,29.91268],[111.51912,29.93232],[111.6053,29.89006],[111.79447,29.91209],[111.95548,29.82843],[112.06706,29.73188],[112.10861,29.66001],[112.2377,29.65673],[112.28713,29.50147],[112.46566,29.6433],[112.68093,29.59734],[112.80796,29.74917],[112.8955,29.79328],[112.9264,29.69014],[112.94769,29.47188],[113.15505,29.46112],[113.51898,29.82813],[113.56704,29.67254],[113.7363,29.58928],[113.62403,29.52118],[113.7569,29.44767],[113.59588,29.25914],[113.69132,29.2187],[113.69132,29.06637],[113.81835,29.10837],[113.85749,29.04056],[113.9447,29.05196],[114.0525,29.20761],[114.23034,29.2193],[114.25231,29.31993],[114.88128,29.38397],[114.95063,29.55852],[115.16693,29.50176],[115.11199,29.68029],[115.26786,29.63674],[115.40107,29.67492],[115.50064,29.8323],[115.65994,29.85851],[115.93803,29.71906],[116.12823,29.82754],[116.08222,30.12434],[115.91949,30.30472],[115.90061,30.50992],[115.7698,30.6701],[115.85082,30.75865],[115.84156,30.8312],[116.07776,30.96966],[115.87692,31.1423],[115.77461,31.10527],[115.69667,31.20604],[115.57823,31.14465],[115.36165,31.40228],[115.21018,31.58204],[114.83184,31.45092],[114.58465,31.71648],[114.18708,31.85452],[113.9859,31.75736],[113.84582,31.84314],[113.7284,32.08432],[113.75038,32.26855],[113.71467,32.43329],[113.41804,32.27784],[113.2505,32.39213],[112.55149,32.39851],[112.31323,32.32862],[112.0008,32.45864],[111.67293,32.62636],[111.57474,32.59455],[111.46488,32.73732],[111.29665,32.85622],[111.18163,33.10534],[110.9801,33.2605],[110.7003,33.09384],[110.55713,33.26653],[110.46958,33.17721],[110.22926,33.15882],[110.16197,33.20996],[110.03974,33.19158],[109.61299,33.2783],[109.42794,33.15479],[109.79324,33.0691],[109.75925,32.91273],[109.79049,32.87929],[109.86259,32.911],[110.02481,32.87482],[110.03391,32.86041],[110.13725,32.81238],[110.19218,32.62029],[110.04524,32.55144],[109.71393,32.61508],[109.55703,32.48543],[109.49901,32.3028],[109.62364,32.10177],[109.58381,31.72933],[109.72595,31.7083],[109.73522,31.58497],[110.12695,31.41108],[110.20042,31.15405],[110.1139,31.09527],[110.16952,30.9829],[110.06652,30.79729],[109.92919,30.91106],[109.53025,30.66154],[109.35138,30.48625],[109.30469,30.63584],[109.13749,30.52086],[109.08256,30.59418],[109.11861,30.6385],[109.04273,30.65637],[108.96995,30.62934],[108.83056,30.50311],[108.7413,30.4972],[108.6589,30.60098],[108.63796,30.53979],[108.56998,30.48211],[108.41789,30.49306],[108.40072,30.38827],[108.58131,30.25669],[108.5202,29.8722],[108.3657,29.84064]]]}},{"type":"Feature","properties":{"id":"AX"},"geometry":{"type":"Polygon","coordinates":[[[19.08191,60.19152],[20.5104,59.15546],[21.35468,59.67511],[21.02509,60.12142],[21.15143,60.54555],[20.96741,60.71528],[19.23413,60.61414],[19.08191,60.19152]]]}},{"type":"Feature","properties":{"id":"VG"},"geometry":{"type":"Polygon","coordinates":[[[-65.02435,18.73231],[-64.86049,18.39954],[-64.64067,18.36478],[-64.646,18.10286],[-63.95092,18.07976],[-63.90607,18.93262],[-64.62855,18.98678],[-65.02435,18.73231]]]}},{"type":"Feature","properties":{"id":"IN-MH"},"geometry":{"type":"Polygon","coordinates":[[[72.4768,20.16425],[73.34747,15.61245],[73.68598,15.72484],[73.80477,15.74401],[73.94691,15.74236],[73.97472,15.62799],[74.01592,15.60253],[74.11617,15.65411],[74.20165,15.77903],[74.34345,15.76417],[74.33967,15.85171],[74.46292,16.04746],[74.36576,16.03822],[74.41486,16.10255],[74.48249,16.09694],[74.50241,16.22489],[74.32662,16.31816],[74.35958,16.37746],[74.26483,16.51904],[74.37057,16.53748],[74.4691,16.65888],[74.6284,16.57762],[74.69398,16.7138],[74.90341,16.77101],[74.92744,16.93793],[75.07713,16.95566],[75.20553,16.83214],[75.27969,16.95697],[75.68206,16.95303],[75.58439,17.34883],[75.63846,17.49346],[75.69425,17.40994],[75.82609,17.42517],[75.892,17.36816],[75.92428,17.32835],[76.05525,17.36178],[76.07276,17.33081],[76.11928,17.37242],[76.18606,17.30459],[76.17439,17.34654],[76.24031,17.37652],[76.27326,17.32917],[76.31429,17.33998],[76.36545,17.30885],[76.40596,17.3526],[76.37592,17.37259],[76.37128,17.42943],[76.33043,17.4558],[76.34674,17.49468],[76.32974,17.57939],[76.40201,17.60426],[76.48424,17.71206],[76.5172,17.71925],[76.52166,17.75833],[76.56423,17.76928],[76.57402,17.70061],[76.61178,17.77631],[76.6892,17.68082],[76.69898,17.72792],[76.79134,17.82289],[76.7383,17.88269],[76.76868,17.90001],[76.88129,17.89413],[76.92043,17.91291],[76.91305,17.96779],[76.91596,18.03489],[76.94978,18.03848],[76.94532,18.08042],[76.9666,18.09592],[76.91871,18.12431],[76.98205,18.19355],[77.00351,18.16053],[77.03733,18.18189],[77.05355,18.15955],[77.11758,18.15775],[77.11741,18.19869],[77.17234,18.28453],[77.20822,18.2785],[77.24899,18.40714],[77.30718,18.44053],[77.324,18.41838],[77.36108,18.45225],[77.37138,18.40095],[77.41653,18.39427],[77.35988,18.30857],[77.42752,18.31118],[77.49343,18.26847],[77.5082,18.31183],[77.56785,18.28849],[77.60965,18.5522],[77.73994,18.55204],[77.74251,18.68267],[77.85684,18.81905],[77.94353,18.82604],[77.74251,19.02577],[77.84379,19.18359],[77.86422,19.3207],[78.00653,19.30158],[78.14695,19.22898],[78.19141,19.42903],[78.3011,19.46885],[78.26694,19.69544],[78.35861,19.75604],[78.27449,19.90476],[78.82793,19.75749],[78.84613,19.65778],[78.95839,19.66037],[78.94432,19.54943],[79.19048,19.46044],[79.23408,19.61219],[79.47578,19.49928],[79.63165,19.57887],[79.804,19.60054],[79.86991,19.5009],[79.93858,19.47792],[79.97051,19.35358],[79.96261,18.86145],[79.9094,18.82474],[80.11196,18.6869],[80.27503,18.72104],[80.36636,18.83091],[80.24825,18.95565],[80.55587,19.40313],[80.72341,19.27355],[80.8937,19.47306],[80.51467,19.92687],[80.54488,20.07528],[80.38284,20.23256],[80.60806,20.32273],[80.5799,20.6694],[80.54214,20.92681],[80.46935,20.92681],[80.42129,21.09923],[80.64308,21.25418],[80.65784,21.32967],[80.56377,21.36037],[80.40824,21.3738],[80.38696,21.49619],[80.28499,21.59742],[80.20946,21.6354],[80.13427,21.61115],[80.06732,21.55528],[79.95025,21.5572],[79.91489,21.52207],[79.75662,21.60062],[79.53861,21.54634],[79.4914,21.67306],[79.33021,21.70719],[79.14585,21.62583],[78.91136,21.59295],[78.9347,21.49268],[78.43654,21.50099],[78.37989,21.62296],[78.00842,21.41887],[77.56484,21.38019],[77.49893,21.76332],[77.23422,21.7158],[77.07733,21.72474],[76.90429,21.60349],[76.80198,21.59519],[76.65847,21.28201],[76.38656,21.07809],[76.17301,21.08386],[76.15653,21.2625],[75.96324,21.39618],[75.22304,21.40928],[75.11455,21.45306],[75.07575,21.55209],[74.91783,21.63062],[74.64317,21.65583],[74.51408,21.72314],[74.52609,21.90769],[74.43717,22.03282],[74.14947,21.95323],[73.83636,21.84684],[73.79379,21.62041],[73.85662,21.49939],[74.10724,21.5639],[74.21161,21.53101],[74.30911,21.5655],[74.33332,21.50945],[74.26328,21.46265],[74.11085,21.44492],[74.06776,21.48118],[74.05265,21.41983],[74.01712,21.42047],[73.94897,21.29737],[73.83619,21.26953],[73.83447,21.19337],[73.74315,21.16568],[73.74538,21.14279],[73.58573,21.15591],[73.7325,21.10163],[73.91635,20.92232],[73.93901,20.73588],[73.88854,20.72946],[73.7495,20.5624],[73.6695,20.56208],[73.44978,20.71726],[73.4333,20.2055],[73.29769,20.20453],[73.29048,20.1549],[73.23383,20.14266],[73.19675,20.05625],[72.98492,20.11784],[72.9808,20.21323],[72.8754,20.22869],[72.80021,20.12622],[72.4768,20.16425]]]}},{"type":"Feature","properties":{"id":"AQ"},"geometry":{"type":"Polygon","coordinates":[[[-180,-85],[180,-85],[180,-60],[-180,-60],[-180,-85]]]}},{"type":"Feature","properties":{"id":"AW"},"geometry":{"type":"Polygon","coordinates":[[[-70.34259,12.92535],[-70.24399,12.38063],[-69.4514,12.18025],[-69.5195,12.75292],[-70.34259,12.92535]]]}},{"type":"Feature","properties":{"id":"CX"},"geometry":{"type":"Polygon","coordinates":[[[105.29647,-10.80676],[105.9699,-10.81333],[105.97626,-10.18257],[105.30283,-10.176],[105.29647,-10.80676]]]}},{"type":"Feature","properties":{"id":"CC"},"geometry":{"type":"Polygon","coordinates":[[[96.53724,-12.46709],[97.24513,-12.47233],[97.25212,-11.57036],[96.54423,-11.5651],[96.53724,-12.46709]]]}},{"type":"Feature","properties":{"id":"TK"},"geometry":{"type":"Polygon","coordinates":[[[-174.18707,-7.54408],[-174.17993,-10.13616],[-167.75195,-10.12005],[-167.75329,-7.52784],[-174.18707,-7.54408]]]}},{"type":"Feature","properties":{"id":"CK"},"geometry":{"type":"Polygon","coordinates":[[[-167.75329,-7.52784],[-167.75195,-10.12005],[-167.73854,-14.92809],[-167.73129,-23.22266],[-156.46451,-23.21255],[-156.4957,-12.32002],[-156.50903,-7.4975],[-167.75329,-7.52784]]]}},{"type":"Feature","properties":{"id":"IN-PB"},"geometry":{"type":"Polygon","coordinates":[[[73.88992,29.96921],[74.52094,29.94303],[74.63115,29.90494],[74.69467,29.9695],[74.80144,29.99092],[74.87285,29.96296],[74.98821,29.86357],[75.09155,29.91774],[75.1015,29.81294],[75.14099,29.77063],[75.17806,29.83826],[75.20072,29.832],[75.22991,29.75603],[75.1966,29.69073],[75.15747,29.66747],[75.21858,29.61495],[75.22716,29.54598],[75.31162,29.58122],[75.27934,29.60779],[75.34046,29.66747],[75.33908,29.68984],[75.37891,29.71161],[75.39813,29.76378],[75.44448,29.80788],[75.60173,29.7456],[75.65288,29.77987],[75.69339,29.75573],[75.70232,29.81145],[75.83003,29.81354],[75.86162,29.75424],[75.9423,29.73069],[76.04049,29.74798],[76.08169,29.80877],[76.11602,29.80222],[76.24168,29.85761],[76.2355,29.88649],[76.18057,29.88947],[76.2276,30.12656],[76.43394,30.15195],[76.44664,30.10385],[76.50089,30.0783],[76.60903,30.07978],[76.6238,30.14497],[76.63873,30.20493],[76.56045,30.26381],[76.73375,30.36458],[76.69864,30.39257],[76.75769,30.43727],[76.80747,30.41196],[76.83151,30.43328],[76.84885,30.40604],[76.88438,30.38516],[76.877,30.36265],[76.88833,30.35569],[76.92987,30.39686],[76.91579,30.40145],[76.88798,30.44038],[76.92026,30.52618],[76.89571,30.53579],[76.89931,30.55206],[76.91193,30.60504],[76.87133,30.63997],[76.85846,30.6416],[76.85923,30.65762],[76.84902,30.66693],[76.83794,30.65755],[76.81949,30.66139],[76.81468,30.68693],[76.8025,30.67527],[76.78945,30.67054],[76.76095,30.68619],[76.7513,30.68512],[76.73894,30.70136],[76.73014,30.72479],[76.71967,30.73202],[76.71306,30.7419],[76.69014,30.74699],[76.69066,30.75968],[76.70808,30.77045],[76.72285,30.77067],[76.73864,30.7908],[76.75975,30.79928],[76.777,30.78483],[76.76911,30.77683],[76.78104,30.77392],[76.79632,30.78623],[76.80413,30.779],[76.79254,30.76647],[76.82825,30.76411],[76.7704,30.9087],[76.61384,31.00144],[76.64817,31.21015],[76.50672,31.27913],[76.37283,31.43569],[76.31996,31.40082],[76.34056,31.34278],[76.18743,31.28999],[76.16546,31.39526],[75.92822,31.80522],[75.96977,31.81281],[75.89904,31.94808],[75.71948,32.06541],[75.58284,32.07384],[75.62885,32.10148],[75.64756,32.24707],[75.7521,32.28364],[75.93921,32.41474],[75.82936,32.52664],[75.78506,32.47095],[75.57083,32.36836],[75.49941,32.28074],[75.28259,32.36556],[75.38046,32.26836],[75.25649,32.10187],[75.00793,32.03786],[74.9269,32.0658],[74.86236,32.04485],[74.79919,31.95983],[74.58907,31.87824],[74.47771,31.72227],[74.57498,31.60382],[74.61517,31.55698],[74.59319,31.50197],[74.64713,31.45605],[74.59773,31.4136],[74.53223,31.30321],[74.51629,31.13829],[74.56023,31.08303],[74.60281,31.10419],[74.60006,31.13711],[74.6852,31.12771],[74.67971,31.05479],[74.5616,31.04153],[73.88993,30.36305],[73.95736,30.28466],[73.97225,30.19829],[73.88992,29.96921]]]}},{"type":"Feature","properties":{"id":"FK"},"geometry":{"type":"Polygon","coordinates":[[[-62.78369,-53.1401],[-58.84651,-53.93403],[-55.76919,-51.15168],[-62.3754,-50.36819],[-62.78369,-53.1401]]]}},{"type":"Feature","properties":{"id":"GS"},"geometry":{"type":"Polygon","coordinates":[[[-43.57991,-52.56305],[-40.68557,-57.40649],[-26.52505,-59.90465],[-23.50385,-54.792],[-43.57991,-52.56305]]]}},{"type":"Feature","properties":{"id":"GU"},"geometry":{"type":"Polygon","coordinates":[[[143.82485,13.92273],[144.61642,12.82462],[146.25931,13.85876],[143.82485,13.92273]]]}},{"type":"Feature","properties":{"id":"HM"},"geometry":{"type":"Polygon","coordinates":[[[71.08716,-53.87687],[75.44182,-53.99822],[72.87012,-51.48322],[71.08716,-53.87687]]]}},{"type":"Feature","properties":{"id":"HK"},"geometry":{"type":"Polygon","coordinates":[[[113.81621,22.2163],[113.83338,22.1826],[113.92195,22.13873],[114.50148,22.15017],[114.44998,22.55977],[114.25154,22.55977],[114.22888,22.5436],[114.22185,22.55343],[114.20655,22.55706],[114.18338,22.55444],[114.17247,22.55944],[114.1597,22.56041],[114.15123,22.55163],[114.1482,22.54091],[114.13823,22.54319],[114.12665,22.54003],[114.11656,22.53415],[114.11181,22.52878],[114.1034,22.5352],[114.09692,22.53435],[114.09048,22.53716],[114.08606,22.53276],[114.07817,22.52997],[114.07267,22.51855],[114.06272,22.51617],[114.05729,22.51104],[114.05438,22.5026],[114.03113,22.5065],[113.86771,22.42972],[113.81621,22.2163]]]}},{"type":"Feature","properties":{"id":"PR"},"geometry":{"type":"Polygon","coordinates":[[[-68.20301,17.83927],[-65.27974,17.56928],[-65.02435,18.73231],[-67.99519,18.97186],[-68.20301,17.83927]]]}},{"type":"Feature","properties":{"id":"MO"},"geometry":{"type":"Polygon","coordinates":[[[113.52659,22.18271],[113.54093,22.15497],[113.54942,22.14519],[113.54839,22.10909],[113.57191,22.07696],[113.63011,22.10782],[113.60504,22.20464],[113.57123,22.20416],[113.56865,22.20973],[113.5508,22.21672],[113.54333,22.21688],[113.54093,22.21314],[113.53593,22.2137],[113.53301,22.21235],[113.53552,22.20607],[113.52659,22.18271]]]}},{"type":"Feature","properties":{"id":"CN-CQ"},"geometry":{"type":"Polygon","coordinates":[[[105.29193,29.58122],[105.37261,29.42285],[105.44128,29.40131],[105.43888,29.31783],[105.65036,29.24357],[105.7101,29.30047],[105.74958,29.01894],[105.90408,28.9054],[106.0033,28.97811],[106.26113,28.83715],[106.36756,28.52662],[106.47743,28.53567],[106.51245,28.67673],[106.44927,28.78631],[106.46781,28.84106],[106.5715,28.70624],[106.65183,28.66649],[106.55914,28.51153],[106.70677,28.44997],[106.77406,28.55919],[106.76238,28.62732],[106.81251,28.58934],[106.86881,28.62611],[106.81182,28.7514],[106.88804,28.80436],[106.96838,28.76585],[106.98211,28.86031],[107.1833,28.88977],[107.26089,28.76103],[107.44148,28.93845],[107.36457,29.00333],[107.4044,29.19472],[107.67219,29.14916],[107.75184,29.21031],[107.84042,28.96309],[107.88574,29.01114],[108.00899,29.04206],[108.0622,29.09037],[108.14323,29.05737],[108.18477,29.07207],[108.22837,29.02405],[108.28708,29.09577],[108.38012,28.80647],[108.33103,28.68637],[108.45874,28.62852],[108.52981,28.65112],[108.63109,28.6457],[108.60877,28.54924],[108.56552,28.5423],[108.60603,28.44092],[108.56414,28.37931],[108.60706,28.32523],[108.65959,28.3343],[108.68911,28.40136],[108.63178,28.46506],[108.70731,28.50098],[108.77872,28.42492],[108.76739,28.31465],[108.72001,28.29228],[108.75091,28.2073],[108.88137,28.22182],[108.99707,28.15828],[109.02385,28.20972],[109.08531,28.18884],[109.15981,28.42597],[109.17054,28.4582],[109.20075,28.48642],[109.22753,28.48317],[109.24324,28.4969],[109.26898,28.50437],[109.26727,28.51787],[109.27645,28.52202],[109.29121,28.57268],[109.31576,28.58595],[109.29671,28.62913],[109.19466,28.60275],[109.18556,28.63184],[109.29885,28.73018],[109.23688,28.78255],[109.23208,28.87985],[109.31877,29.05827],[109.2346,29.11829],[109.22916,29.12217],[109.10745,29.21855],[109.10419,29.36691],[109.05029,29.4055],[108.97647,29.33085],[108.90918,29.32651],[108.93836,29.43601],[108.86455,29.46411],[108.90918,29.60331],[108.68499,29.70132],[108.67641,29.85255],[108.6098,29.86863],[108.4917,29.71966],[108.3657,29.84064],[108.5202,29.8722],[108.58131,30.25669],[108.40072,30.38827],[108.41789,30.49306],[108.56998,30.48211],[108.63796,30.53979],[108.6589,30.60098],[108.7413,30.4972],[108.83056,30.50311],[108.96995,30.62934],[109.04273,30.65637],[109.11861,30.6385],[109.08256,30.59418],[109.13749,30.52086],[109.30469,30.63584],[109.35138,30.48625],[109.53025,30.66154],[109.92919,30.91106],[110.06652,30.79729],[110.16952,30.9829],[110.1139,31.09527],[110.20042,31.15405],[110.12695,31.41108],[109.73522,31.58497],[109.72595,31.7083],[109.58381,31.72933],[109.27619,31.71823],[109.20066,31.85248],[108.50234,32.20641],[108.27369,31.92885],[108.54011,31.67559],[108.02032,31.24803],[108.07182,31.18049],[107.92282,30.92578],[107.99114,30.91076],[107.84866,30.79405],[107.69657,30.876],[107.63683,30.81233],[107.48508,30.84476],[107.42637,30.7318],[107.50431,30.63732],[107.19291,30.18727],[107.03155,30.04532],[106.96941,30.08484],[106.76582,30.01738],[106.54643,30.32843],[106.21067,30.18134],[106.16397,30.30413],[105.79627,30.44393],[105.68778,30.26618],[105.61431,30.26381],[105.59062,30.11216],[105.75302,30.01619],[105.70667,29.83796],[105.60127,29.83707],[105.45707,29.67612],[105.29193,29.58122]]]}},{"type":"Feature","properties":{"id":"YT"},"geometry":{"type":"Polygon","coordinates":[[[44.75722,-12.58368],[44.82644,-13.30845],[45.54824,-13.22353],[45.45962,-12.30345],[44.75722,-12.58368]]]}},{"type":"Feature","properties":{"id":"NU"},"geometry":{"type":"Polygon","coordinates":[[[-173.13438,-14.94228],[-173.11048,-23.23027],[-167.73129,-23.22266],[-167.73854,-14.92809],[-171.14262,-14.93704],[-173.13438,-14.94228]]]}},{"type":"Feature","properties":{"id":"NF"},"geometry":{"type":"Polygon","coordinates":[[[165.46901,-28.32101],[169.35326,-30.60259],[169.6687,-29.09191],[166.75333,-27.25416],[165.46901,-28.32101]]]}},{"type":"Feature","properties":{"id":"CN-JS"},"geometry":{"type":"Polygon","coordinates":[[[116.37405,34.64676],[116.95014,34.39841],[117.02567,34.15556],[117.50907,34.06176],[117.74322,33.89264],[117.71026,33.74718],[118.18405,33.74546],[117.96775,33.33052],[118.03024,33.12777],[118.20121,33.2203],[118.22456,32.9332],[118.37425,32.72144],[118.7059,32.71624],[118.85559,32.95855],[119.17762,32.83286],[119.22225,32.60756],[119.08218,32.45531],[118.89747,32.58905],[118.54659,32.58442],[118.68049,32.45647],[118.6956,32.36198],[118.64444,32.21657],[118.50299,32.19479],[118.50128,32.14393],[118.39004,32.02612],[118.35605,31.93788],[118.49716,31.84373],[118.47587,31.78246],[118.69354,31.7194],[118.64204,31.64812],[118.71894,31.62415],[118.73954,31.67851],[118.8652,31.62415],[118.86314,31.43745],[118.71482,31.29967],[118.78761,31.23394],[119.07257,31.23394],[119.17968,31.29908],[119.27238,31.25272],[119.35134,31.30143],[119.36782,31.19107],[119.50378,31.1611],[119.57656,31.11174],[119.63149,31.1329],[119.91439,31.17051],[120.36208,30.97054],[120.35007,30.88896],[120.42835,30.91459],[120.49873,30.75953],[120.5801,30.85566],[120.64739,30.85095],[120.70747,30.88572],[120.67485,30.957],[120.73459,30.96289],[120.7703,30.9988],[120.84754,30.99173],[120.89424,31.01822],[120.89836,31.09028],[120.85475,31.10938],[120.88325,31.14083],[121.03671,31.14171],[121.07276,31.16345],[121.05903,31.23658],[121.06006,31.27356],[121.11808,31.28529],[121.1495,31.27752],[121.15722,31.28515],[121.14057,31.31038],[121.12581,31.30348],[121.11173,31.37459],[121.15447,31.41108],[121.14246,31.44492],[121.23722,31.49704],[121.25335,31.47933],[121.3821,31.54723],[121.09954,31.75853],[121.30554,31.88338],[121.44286,31.76086],[121.76147,31.63818],[122.29378,31.76513],[122.80525,33.30571],[119.30259,35.07833],[118.88442,35.04349],[118.76495,34.73822],[118.51226,34.69194],[118.42849,34.44655],[118.17718,34.36837],[118.14559,34.54389],[117.93411,34.68404],[117.78991,34.51447],[117.15957,34.52692],[116.96456,34.88367],[116.43859,34.89944],[116.37405,34.64676]]]}},{"type":"Feature","properties":{"id":"MF"},"geometry":{"type":"Polygon","coordinates":[[[-63.35989,18.06012],[-63.33064,17.9615],[-63.13584,18.0541],[-63.11096,18.05368],[-63.09686,18.04608],[-63.07759,18.04943],[-63.0579,18.06614],[-63.04039,18.05619],[-63.02323,18.05757],[-62.93924,18.02904],[-62.75637,18.13489],[-62.86666,18.19278],[-63.35989,18.06012]]]}},{"type":"Feature","properties":{"id":"BL"},"geometry":{"type":"Polygon","coordinates":[[[-63.07669,17.79659],[-62.76692,17.64353],[-62.54836,17.8636],[-62.75637,18.13489],[-62.93924,18.02904],[-63.07669,17.79659]]]}},{"type":"Feature","properties":{"id":"AC"},"geometry":{"type":"Polygon","coordinates":[[[-14.91926,-6.63386],[-14.82771,-8.70814],[-13.33271,-8.07391],[-14.91926,-6.63386]]]}},{"type":"Feature","properties":{"id":"IC"},"geometry":{"type":"Polygon","coordinates":[[[-18.8556,26.96222],[-14.43883,27.02969],[-12.42686,29.61659],[-14.33337,30.94071],[-15.92339,29.50503],[-18.67893,29.62861],[-18.8556,26.96222]]]}},{"type":"Feature","properties":{"id":"ES-CE"},"geometry":{"type":"Polygon","coordinates":[[[-5.38491,35.92591],[-5.37338,35.88417],[-5.35844,35.87375],[-5.34379,35.8711],[-5.27056,35.88794],[-5.27635,35.91222],[-5.38491,35.92591]]]}},{"type":"Feature","properties":{"id":"ES-ML"},"geometry":{"type":"Polygon","coordinates":[[[-2.97035,35.28852],[-2.96507,35.28801],[-2.96826,35.28296],[-2.96516,35.27967],[-2.95431,35.2728],[-2.95065,35.26576],[-2.93893,35.26737],[-2.92674,35.27313],[-2.92181,35.28599],[-2.92224,35.3401],[-2.96038,35.31609],[-2.96648,35.30475],[-2.96978,35.29459],[-2.97035,35.28852]]]}},{"type":"Feature","properties":{"id":"IN-AP"},"geometry":{"type":"Polygon","coordinates":[[[76.76336,14.98442],[76.86996,14.97082],[76.86309,14.8401],[76.76628,14.67925],[76.80335,14.53257],[76.98205,14.48288],[76.89125,14.3966],[76.93862,14.24624],[77.04952,14.24774],[77.0866,14.191],[77.13466,14.33923],[77.27045,14.33241],[77.3767,14.21113],[77.4282,14.19998],[77.3628,14.34954],[77.48502,14.29332],[77.51472,14.15754],[77.38924,14.17419],[77.40949,14.12026],[77.33791,14.03967],[77.43215,13.98237],[77.45017,13.94772],[77.41172,13.88791],[77.35765,13.9339],[77.31954,14.03084],[77.15234,13.99187],[77.13415,14.03684],[77.0284,14.05432],[77.02651,14.16736],[76.95339,14.19233],[76.88112,14.14156],[76.98326,14.08596],[76.94463,14.05233],[76.93948,14.01719],[76.98772,14.0002],[77.05141,13.9214],[76.97862,13.82941],[77.00265,13.72837],[77.03081,13.78256],[77.05278,13.76739],[77.18393,13.76189],[77.1302,13.84891],[77.16556,13.9034],[77.23766,13.90824],[77.26221,13.85341],[77.41945,13.84541],[77.45206,13.81057],[77.47369,13.76289],[77.45326,13.70236],[77.48022,13.67751],[77.49206,13.71303],[77.52983,13.69585],[77.5245,13.75839],[77.56227,13.72721],[77.6711,13.78773],[77.71934,13.74021],[77.72209,13.7889],[77.83229,13.86158],[77.81839,13.93523],[77.9516,13.9344],[78.06146,13.88791],[78.12635,13.86208],[78.11485,13.76456],[78.11622,13.65716],[78.19965,13.64348],[78.19879,13.58592],[78.40461,13.59343],[78.37818,13.50748],[78.38058,13.40581],[78.36547,13.3634],[78.57439,13.31512],[78.57181,13.18061],[78.47637,12.98699],[78.40908,12.94517],[78.43809,12.92743],[78.46744,12.90334],[78.46813,12.86971],[78.39054,12.90652],[78.35706,12.93965],[78.315,12.85966],[78.26076,12.86469],[78.23295,12.76526],[78.2151,12.68991],[78.46401,12.61454],[78.63292,12.97143],[78.84681,13.07613],[79.14997,13.00422],[79.2152,13.13063],[79.40025,13.142],[79.36832,13.30711],[79.53414,13.30944],[79.77996,13.21254],[79.92484,13.33884],[80.02784,13.52718],[80.2153,13.48512],[80.29632,13.37626],[80.32104,13.44372],[80.67259,13.46443],[82.9708,16.27499],[82.19078,16.71874],[82.21618,16.76378],[83.0072,16.31915],[85.11932,18.86211],[84.76158,19.07055],[84.70287,19.15068],[84.59335,19.11662],[84.65961,19.06925],[84.59369,19.02317],[84.50408,19.04394],[84.31594,18.78411],[84.2284,18.78883],[84.08128,18.74478],[84.03991,18.79581],[83.88748,18.80296],[83.65058,19.12311],[83.33816,19.01084],[83.37936,18.83481],[83.11019,18.77176],[83.08822,18.54081],[82.96737,18.33692],[82.82592,18.43727],[82.63366,18.23522],[82.42835,18.49198],[82.35351,18.14193],[82.25532,17.98199],[82.04383,18.06622],[81.77398,17.88596],[81.40594,17.3585],[80.91499,17.20081],[80.83671,17.02494],[80.68771,17.06794],[80.61733,17.13226],[80.50369,17.1083],[80.4467,17.01772],[80.38867,17.08139],[80.36189,16.96683],[80.57544,16.91855],[80.58711,16.772],[80.45871,16.7881],[80.45391,16.81702],[80.40138,16.85613],[80.31864,16.87387],[80.26027,17.0082],[80.18199,17.04628],[80.04432,16.96256],[79.99248,16.8604],[80.0735,16.81242],[80.02544,16.71249],[79.94476,16.62731],[79.79507,16.72137],[79.31304,16.57302],[79.21485,16.48251],[79.21623,16.21665],[78.68408,16.04581],[78.41766,16.08012],[78.12,15.82892],[78.03108,15.90421],[77.65754,15.88869],[77.51197,15.92864],[77.44039,15.94548],[77.27113,15.96132],[77.11818,15.94036],[77.03613,15.856],[77.09278,15.71625],[76.97227,15.50992],[77.03201,15.43614],[77.04145,15.37292],[77.16281,15.29279],[77.17037,15.17619],[77.1132,15.02985],[76.98308,15.00945],[76.80044,15.09681],[76.76336,14.98442]]]}},{"type":"Feature","properties":{"id":"DG"},"geometry":{"type":"Polygon","coordinates":[[[72.0768,-6.94304],[72.09053,-7.71938],[73.19616,-7.72081],[73.19718,-6.94577],[72.0768,-6.94304]]]}},{"type":"Feature","properties":{"id":"TA"},"geometry":{"type":"Polygon","coordinates":[[[-13.48367,-36.6746],[-13.41694,-37.88844],[-11.48092,-37.8367],[-11.55782,-36.60319],[-13.48367,-36.6746]]]}},{"type":"Feature","properties":{"id":"AU-WA"},"geometry":{"type":"Polygon","coordinates":[[[99.6403,-26.70736],[129,-43.08851],[129.00183,-25.99861],[129.00057,-25.99861],[129,-14.42902],[127.55165,-9.05052],[125.68138,-9.85176],[122.91521,-11.65621],[99.6403,-26.70736]]]}},{"type":"Feature","properties":{"id":"AU-NT"},"geometry":{"type":"Polygon","coordinates":[[[127.55165,-9.05052],[129,-14.42902],[129.00057,-25.99861],[129.00183,-25.99861],[137.99993,-25.99819],[138.00067,-16.23841],[139.41724,-8.97063],[127.55165,-9.05052]]]}},{"type":"Feature","properties":{"id":"AU-SA"},"geometry":{"type":"Polygon","coordinates":[[[129,-43.08851],[137.66184,-47.26522],[140.64335,-39.23791],[140.96369,-38.2743],[140.9638,-33.98067],[141.00268,-34.02172],[140.99934,-28.99903],[141.00013,-26.00101],[137.99993,-25.99819],[129.00183,-25.99861],[129,-43.08851]]]}},{"type":"Feature","properties":{"id":"AU-TAS"},"geometry":{"type":"Polygon","coordinates":[[[137.66184,-47.26522],[158.89388,-55.66823],[159.92772,-54.25538],[152.57175,-39.16128],[140.64335,-39.23791],[137.66184,-47.26522]]]}},{"type":"Feature","properties":{"id":"AU-VIC"},"geometry":{"type":"Polygon","coordinates":[[[140.64335,-39.23791],[152.57175,-39.16128],[150.19768,-37.59458],[148.19405,-36.79602],[148.10753,-36.79272],[148.20366,-36.59782],[148.04573,-36.39248],[147.99217,-36.0457],[147.71202,-35.94237],[147.39616,-35.94681],[147.31926,-36.05458],[147.10503,-36.00683],[147.04185,-36.09898],[146.85097,-36.08788],[146.59966,-35.97349],[146.42387,-35.96794],[146.36894,-36.03571],[145.80589,-35.98461],[145.50789,-35.80772],[145.34447,-35.86005],[145.1165,-35.81774],[144.9778,-35.86673],[144.94896,-36.05236],[144.74022,-36.11895],[144.08241,-35.57238],[143.56743,-35.33634],[143.57155,-35.20741],[143.39027,-35.18047],[143.3271,-34.99618],[143.34221,-34.79344],[142.76268,-34.56871],[142.61711,-34.77765],[142.50999,-34.74267],[142.37404,-34.34563],[142.24495,-34.3014],[142.22023,-34.18334],[142.0211,-34.12651],[141.71349,-34.0924],[141.5377,-34.18902],[141.00268,-34.02172],[140.9638,-33.98067],[140.96369,-38.2743],[140.64335,-39.23791]]]}},{"type":"Feature","properties":{"id":"AU-QLD"},"geometry":{"type":"Polygon","coordinates":[[[137.99993,-25.99819],[141.00013,-26.00101],[140.99934,-28.99903],[148.95806,-28.99906],[149.19248,-28.77479],[149.37788,-28.68628],[149.48705,-28.58202],[149.58044,-28.57056],[149.67519,-28.62723],[150.30004,-28.53558],[150.43737,-28.66098],[150.74499,-28.63446],[151.27508,-28.94017],[151.30392,-29.15627],[151.39318,-29.17186],[151.55248,-28.94858],[151.72552,-28.86683],[151.7777,-28.9606],[152.01391,-28.89449],[152.06472,-28.69351],[151.94662,-28.54282],[152.49731,-28.25168],[152.57696,-28.3327],[152.60442,-28.27466],[152.74725,-28.35929],[152.87222,-28.30852],[153.10293,-28.35445],[153.18121,-28.25289],[153.36385,-28.242],[153.47715,-28.15789],[153.53414,-28.17635],[153.55096,-28.16364],[155.3142,-27.34698],[153.5901,-24.72709],[149.03078,-19.80828],[144.30183,-9.48146],[142.81927,-9.31709],[142.5723,-9.35994],[142.31447,-9.24611],[142.23304,-9.19253],[142.1462,-9.19923],[142.0953,-9.23534],[142.0601,-9.56571],[140.88922,-9.34945],[139.41724,-8.97063],[138.00067,-16.23841],[137.99993,-25.99819]]]}},{"type":"Feature","properties":{"id":"AU-ACT"},"geometry":{"type":"Polygon","coordinates":[[[148.76247,-35.49504],[148.78891,-35.69995],[148.85723,-35.76043],[148.8768,-35.715],[148.89431,-35.75095],[148.89602,-35.82504],[148.96194,-35.8971],[149.04811,-35.91684],[149.09824,-35.81223],[149.09549,-35.6411],[149.07936,-35.58193],[149.14219,-35.59337],[149.12983,-35.55288],[149.15283,-35.50566],[149.13429,-35.45338],[149.2057,-35.34732],[149.25136,-35.33024],[149.33719,-35.33976],[149.35058,-35.3518],[149.39796,-35.32435],[149.39418,-35.30362],[149.23488,-35.24336],[149.2469,-35.2285],[149.18956,-35.20157],[149.19746,-35.18502],[149.12159,-35.1241],[148.80951,-35.30698],[148.76247,-35.49504]]]}},{"type":"Feature","properties":{"id":"IN-KA"},"geometry":{"type":"Polygon","coordinates":[[[73.87481,14.75496],[74.66307,12.69394],[74.86049,12.76057],[75.01327,12.79137],[74.98323,12.73998],[75.0531,12.71804],[75.04108,12.67484],[75.06872,12.66228],[75.08777,12.70029],[75.11438,12.67752],[75.16124,12.67969],[75.14579,12.63648],[75.19798,12.6132],[75.23471,12.56662],[75.28106,12.61856],[75.33393,12.57534],[75.27214,12.5502],[75.34698,12.46105],[75.39882,12.50161],[75.43659,12.47144],[75.37067,12.45602],[75.43109,12.31249],[75.49392,12.29103],[75.54302,12.20279],[75.78987,12.08296],[75.86059,11.95502],[76.00307,11.93185],[76.11259,11.97887],[76.11757,11.85105],[76.18949,11.87608],[76.42948,11.66568],[76.539,11.69123],[76.61281,11.60717],[76.85623,11.59506],[76.84249,11.66938],[76.91013,11.79308],[76.97193,11.77628],[76.98772,11.81291],[77.12059,11.71863],[77.25465,11.81241],[77.42906,11.76199],[77.46665,11.84887],[77.49704,11.9426],[77.67917,11.94898],[77.72724,12.05409],[77.77925,12.112],[77.725,12.17963],[77.45738,12.20681],[77.48931,12.2766],[77.61806,12.36649],[77.63523,12.49088],[77.58853,12.51803],[77.60089,12.66579],[77.67514,12.68363],[77.67943,12.65625],[77.71265,12.66395],[77.71196,12.6817],[77.74114,12.67065],[77.73994,12.69962],[77.76329,12.6956],[77.77582,12.72273],[77.76277,12.72658],[77.7662,12.73663],[77.79384,12.74768],[77.78062,12.76928],[77.81032,12.82987],[77.79247,12.84092],[77.83281,12.86151],[77.93683,12.88192],[77.91975,12.82828],[77.94782,12.8354],[77.95349,12.85966],[77.97005,12.83105],[78.00215,12.80359],[78.03322,12.85406],[78.08678,12.83146],[78.12309,12.76861],[78.23295,12.76526],[78.26076,12.86469],[78.315,12.85966],[78.35706,12.93965],[78.39054,12.90652],[78.46813,12.86971],[78.46744,12.90334],[78.43809,12.92743],[78.40908,12.94517],[78.47637,12.98699],[78.57181,13.18061],[78.57439,13.31512],[78.36547,13.3634],[78.38058,13.40581],[78.37818,13.50748],[78.40461,13.59343],[78.19879,13.58592],[78.19965,13.64348],[78.11622,13.65716],[78.11485,13.76456],[78.12635,13.86208],[78.06146,13.88791],[77.9516,13.9344],[77.81839,13.93523],[77.83229,13.86158],[77.72209,13.7889],[77.71934,13.74021],[77.6711,13.78773],[77.56227,13.72721],[77.5245,13.75839],[77.52983,13.69585],[77.49206,13.71303],[77.48022,13.67751],[77.45326,13.70236],[77.47369,13.76289],[77.45206,13.81057],[77.41945,13.84541],[77.26221,13.85341],[77.23766,13.90824],[77.16556,13.9034],[77.1302,13.84891],[77.18393,13.76189],[77.05278,13.76739],[77.03081,13.78256],[77.00265,13.72837],[76.97862,13.82941],[77.05141,13.9214],[76.98772,14.0002],[76.93948,14.01719],[76.94463,14.05233],[76.98326,14.08596],[76.88112,14.14156],[76.95339,14.19233],[77.02651,14.16736],[77.0284,14.05432],[77.13415,14.03684],[77.15234,13.99187],[77.31954,14.03084],[77.35765,13.9339],[77.41172,13.88791],[77.45017,13.94772],[77.43215,13.98237],[77.33791,14.03967],[77.40949,14.12026],[77.38924,14.17419],[77.51472,14.15754],[77.48502,14.29332],[77.3628,14.34954],[77.4282,14.19998],[77.3767,14.21113],[77.27045,14.33241],[77.13466,14.33923],[77.0866,14.191],[77.04952,14.24774],[76.93862,14.24624],[76.89125,14.3966],[76.98205,14.48288],[76.80335,14.53257],[76.76628,14.67925],[76.86309,14.8401],[76.86996,14.97082],[76.76336,14.98442],[76.80044,15.09681],[76.98308,15.00945],[77.1132,15.02985],[77.17037,15.17619],[77.16281,15.29279],[77.04145,15.37292],[77.03201,15.43614],[76.97227,15.50992],[77.09278,15.71625],[77.03613,15.856],[77.11818,15.94036],[77.27113,15.96132],[77.44039,15.94548],[77.51197,15.92864],[77.49893,16.26906],[77.60364,16.29657],[77.59523,16.34336],[77.48451,16.38223],[77.28847,16.40595],[77.2344,16.47658],[77.32366,16.48942],[77.37636,16.48481],[77.47198,16.587],[77.47095,16.71216],[77.427,16.72252],[77.44279,16.78712],[77.47489,16.77956],[77.45532,16.92068],[77.50099,17.01657],[77.46356,17.11454],[77.36623,17.15883],[77.46202,17.28607],[77.45155,17.3721],[77.52244,17.35178],[77.53583,17.44007],[77.62716,17.44335],[77.67608,17.52751],[77.52571,17.57693],[77.44005,17.57693],[77.45841,17.70568],[77.57823,17.74378],[77.50837,17.79298],[77.66166,17.9686],[77.56296,18.04925],[77.61377,18.10033],[77.56785,18.28849],[77.5082,18.31183],[77.49343,18.26847],[77.42752,18.31118],[77.35988,18.30857],[77.41653,18.39427],[77.37138,18.40095],[77.36108,18.45225],[77.324,18.41838],[77.30718,18.44053],[77.24899,18.40714],[77.20822,18.2785],[77.17234,18.28453],[77.11741,18.19869],[77.11758,18.15775],[77.05355,18.15955],[77.03733,18.18189],[77.00351,18.16053],[76.98205,18.19355],[76.91871,18.12431],[76.9666,18.09592],[76.94532,18.08042],[76.94978,18.03848],[76.91596,18.03489],[76.91305,17.96779],[76.92043,17.91291],[76.88129,17.89413],[76.76868,17.90001],[76.7383,17.88269],[76.79134,17.82289],[76.69898,17.72792],[76.6892,17.68082],[76.61178,17.77631],[76.57402,17.70061],[76.56423,17.76928],[76.52166,17.75833],[76.5172,17.71925],[76.48424,17.71206],[76.40201,17.60426],[76.32974,17.57939],[76.34674,17.49468],[76.33043,17.4558],[76.37128,17.42943],[76.37592,17.37259],[76.40596,17.3526],[76.36545,17.30885],[76.31429,17.33998],[76.27326,17.32917],[76.24031,17.37652],[76.17439,17.34654],[76.18606,17.30459],[76.11928,17.37242],[76.07276,17.33081],[76.05525,17.36178],[75.92428,17.32835],[75.892,17.36816],[75.82609,17.42517],[75.69425,17.40994],[75.63846,17.49346],[75.58439,17.34883],[75.68206,16.95303],[75.27969,16.95697],[75.20553,16.83214],[75.07713,16.95566],[74.92744,16.93793],[74.90341,16.77101],[74.69398,16.7138],[74.6284,16.57762],[74.4691,16.65888],[74.37057,16.53748],[74.26483,16.51904],[74.35958,16.37746],[74.32662,16.31816],[74.50241,16.22489],[74.48249,16.09694],[74.41486,16.10255],[74.36576,16.03822],[74.46292,16.04746],[74.33967,15.85171],[74.34345,15.76417],[74.20165,15.77903],[74.11617,15.65411],[74.25659,15.64551],[74.24903,15.49206],[74.33486,15.28352],[74.25075,15.25371],[74.31838,15.1805],[74.2741,15.09996],[74.29195,15.02869],[74.20543,14.92819],[74.16217,14.94976],[73.87481,14.75496]]]}},{"type":"Feature","properties":{"id":"NL-BQ3"},"geometry":{"type":"Polygon","coordinates":[[[-63.22932,17.32592],[-63.11114,17.23125],[-62.76692,17.64353],[-63.07669,17.79659],[-63.22932,17.32592]]]}},{"type":"Feature","properties":{"id":"CA-BC"},"geometry":{"type":"Polygon","coordinates":[[[-139.05365,59.99655],[-138.71149,59.90728],[-138.62145,59.76431],[-137.60623,59.24465],[-137.4925,58.89415],[-136.82619,59.16198],[-136.52365,59.16752],[-136.47323,59.46617],[-136.33727,59.44466],[-136.22381,59.55526],[-136.31566,59.59083],[-135.48007,59.79937],[-135.03069,59.56208],[-135.00267,59.28745],[-134.7047,59.2458],[-134.55699,59.1297],[-134.48059,59.13231],[-134.27175,58.8634],[-133.84645,58.73543],[-133.38523,58.42773],[-131.8271,56.62247],[-130.77769,56.36185],[-130.33965,56.10849],[-130.10173,56.12178],[-130.00093,56.00325],[-130.00857,55.91344],[-130.15373,55.74895],[-129.97513,55.28029],[-130.08035,55.21556],[-130.18765,55.07744],[-130.27203,54.97174],[-130.44184,54.85377],[-130.64499,54.76912],[-130.61931,54.70835],[-133.92876,54.62289],[-133.36909,48.51151],[-125.03842,48.53282],[-123.50039,48.21223],[-123.15614,48.35395],[-123.26565,48.6959],[-123.0093,48.76586],[-123.0093,48.83186],[-123.32163,49.00419],[-117.03266,49.00056],[-116.04938,48.99999],[-114.0683,48.99885],[-114.74352,49.57064],[-114.70812,50.29534],[-120.00143,53.79861],[-120.00135,60.00043],[-123.86203,59.99964],[-139.05365,59.99655]]]}},{"type":"Feature","properties":{"id":"CA-AB"},"geometry":{"type":"Polygon","coordinates":[[[-120.00143,53.79861],[-114.70812,50.29534],[-114.74352,49.57064],[-114.0683,48.99885],[-110.0051,48.99901],[-110.00637,59.99944],[-120.00135,60.00043],[-120.00143,53.79861]]]}},{"type":"Feature","properties":{"id":"CA-SK"},"geometry":{"type":"Polygon","coordinates":[[[-110.00637,59.99944],[-110.0051,48.99901],[-104.05004,48.99925],[-101.36198,48.99935],[-101.98961,55.81762],[-102.00759,59.99922],[-110.00637,59.99944]]]}},{"type":"Feature","properties":{"id":"CA-MB"},"geometry":{"type":"Polygon","coordinates":[[[-102.00759,59.99922],[-101.98961,55.81762],[-101.36198,48.99935],[-97.24024,48.99952],[-95.15355,48.9996],[-95.15357,49.384],[-95.15374,52.84191],[-88.99084,56.84662],[-94.78348,59.99917],[-102.00759,59.99922]]]}},{"type":"Feature","properties":{"id":"IN-WB"},"geometry":{"type":"Polygon","coordinates":[[[85.82279,23.26784],[85.92269,23.12236],[86.04423,23.14572],[86.21761,22.98747],[86.5472,22.97641],[86.42188,22.77586],[86.78031,22.56487],[86.88812,22.24715],[86.7247,22.21569],[86.71371,22.1448],[86.94992,22.08627],[87.05635,21.85066],[87.22457,21.96024],[87.27264,21.81114],[87.43709,21.76045],[87.74779,20.78694],[89.13606,21.42955],[89.13927,21.60785],[89.03553,21.77397],[89.07114,22.15335],[88.9367,22.58527],[88.94614,22.66941],[88.9151,22.75228],[88.96713,22.83346],[88.87063,22.95235],[88.88327,23.03885],[88.86377,23.08759],[88.99148,23.21134],[88.71133,23.2492],[88.79254,23.46028],[88.79351,23.50535],[88.74841,23.47361],[88.56507,23.64044],[88.58087,23.87105],[88.66189,23.87607],[88.73743,23.91751],[88.6976,24.14703],[88.74841,24.1959],[88.68801,24.31464],[88.50934,24.32474],[88.12296,24.51301],[88.08786,24.63232],[88.00683,24.66477],[88.15515,24.85806],[88.14004,24.93529],[88.21832,24.96642],[88.27325,24.88796],[88.33917,24.86803],[88.46277,25.07468],[88.44766,25.20149],[88.94067,25.18534],[89.00463,25.26583],[89.01105,25.30303],[88.85278,25.34679],[88.81296,25.51546],[88.677,25.46959],[88.4559,25.59227],[88.45103,25.66245],[88.242,25.80811],[88.13138,25.78773],[88.08804,25.91334],[88.16581,26.0238],[88.1844,26.14417],[88.34757,26.22216],[88.35153,26.29123],[88.51649,26.35923],[88.48749,26.45855],[88.36938,26.48683],[88.35153,26.45241],[88.33093,26.48929],[88.41196,26.63837],[88.4298,26.54489],[88.62144,26.46783],[88.69485,26.38353],[88.67837,26.26291],[88.78961,26.31093],[88.85004,26.23211],[89.05328,26.2469],[88.91321,26.37984],[88.92357,26.40711],[88.95612,26.4564],[89.08899,26.38845],[89.15869,26.13708],[89.35953,26.0077],[89.53515,26.00382],[89.57101,25.9682],[89.63968,26.22595],[89.70201,26.15138],[89.73581,26.15818],[89.71298,26.26755],[89.84653,26.40078],[89.86885,26.46258],[89.86124,26.73307],[89.63369,26.74402],[89.42349,26.83727],[89.3901,26.84225],[89.38319,26.85963],[89.37913,26.86224],[89.1926,26.81329],[89.12825,26.81661],[89.09554,26.89089],[88.95807,26.92668],[88.92301,26.99286],[88.8714,26.97488],[88.86984,27.10937],[88.74219,27.144],[88.62842,27.1731],[88.52045,27.17753],[88.45161,27.07655],[88.33505,27.10176],[88.30226,27.12682],[88.22656,27.11842],[88.08563,27.14072],[88.08331,27.16501],[88.04932,27.21631],[88.01587,27.21388],[87.9887,27.11045],[88.11719,26.98758],[88.13422,26.98705],[88.12302,26.95324],[88.19107,26.75516],[88.1659,26.68177],[88.16452,26.64111],[88.09963,26.54195],[88.14313,26.51097],[88.23394,26.55413],[88.19137,26.47549],[88.26158,26.4263],[88.23034,26.37679],[88.29093,26.3568],[88.0046,26.14341],[87.95036,26.06511],[87.84393,26.04537],[87.78625,25.87559],[87.90058,25.85304],[87.89989,25.76866],[88.04923,25.68794],[88.03859,25.54182],[88.0688,25.48047],[87.92667,25.53717],[87.76514,25.42529],[87.78865,25.34495],[87.86521,25.27139],[87.78831,25.15212],[87.95173,24.97174],[87.83431,24.7381],[87.89543,24.57616],[87.77904,24.57147],[87.7811,24.34928],[87.63587,24.21628],[87.71038,24.14048],[87.4443,23.97527],[87.23281,24.04238],[87.27933,23.87516],[87.08312,23.80639],[86.89704,23.89054],[86.79748,23.82806],[86.8198,23.76115],[86.79508,23.68351],[86.7374,23.68194],[86.59286,23.67156],[86.5242,23.62628],[86.44214,23.62816],[86.31374,23.42544],[86.14208,23.47647],[86.14311,23.56619],[86.0123,23.56619],[86.04389,23.48245],[85.87223,23.47489],[85.8633,23.41316],[85.89969,23.37062],[85.82279,23.26784]]]}},{"type":"Feature","properties":{"id":"FM-KSA"},"geometry":{"type":"Polygon","coordinates":[[[161.58988,8.892633],[161.87397,3.186785],[165.35175,6.367],[161.58988,8.892633]]]}},{"type":"Feature","properties":{"id":"CA-ON"},"geometry":{"type":"Polygon","coordinates":[[[-95.15374,52.84191],[-95.15357,49.384],[-95.12903,49.37056],[-95.05825,49.35311],[-95.01419,49.35647],[-94.99532,49.36579],[-94.95681,49.37035],[-94.85381,49.32492],[-94.8159,49.32299],[-94.82487,49.29483],[-94.77355,49.11998],[-94.75017,49.09931],[-94.687,48.84077],[-94.70087,48.8339],[-94.70486,48.82365],[-94.69669,48.80918],[-94.69335,48.77883],[-94.58903,48.71803],[-94.54885,48.71543],[-94.53826,48.70216],[-94.44258,48.69223],[-94.4174,48.71049],[-94.27153,48.70232],[-94.25172,48.68404],[-94.25104,48.65729],[-94.23215,48.65202],[-93.85769,48.63284],[-93.83288,48.62745],[-93.80676,48.58232],[-93.80939,48.52439],[-93.79267,48.51631],[-93.66382,48.51845],[-93.47022,48.54357],[-93.44472,48.59147],[-93.40693,48.60948],[-93.39758,48.60364],[-93.3712,48.60599],[-93.33946,48.62787],[-93.25391,48.64266],[-92.94973,48.60866],[-92.7287,48.54005],[-92.6342,48.54133],[-92.62747,48.50278],[-92.69927,48.49573],[-92.71323,48.46081],[-92.65606,48.43471],[-92.50712,48.44921],[-92.45588,48.40624],[-92.48147,48.36609],[-92.37185,48.22259],[-92.27167,48.25046],[-92.30939,48.31251],[-92.26662,48.35651],[-92.202,48.35252],[-92.14732,48.36578],[-92.05339,48.35958],[-91.98929,48.25409],[-91.86125,48.21278],[-91.71231,48.19875],[-91.70451,48.11805],[-91.55649,48.10611],[-91.58025,48.04339],[-91.45829,48.07454],[-91.43248,48.04912],[-91.25025,48.08522],[-91.08016,48.18096],[-90.87588,48.2484],[-90.75045,48.09143],[-90.56444,48.12184],[-90.56312,48.09488],[-90.07418,48.11043],[-89.89974,47.98109],[-89.77248,48.02607],[-89.57972,48.00023],[-89.48837,48.01412],[-88.37033,48.30586],[-84.85871,46.88881],[-84.55635,46.45974],[-84.47607,46.45225],[-84.4481,46.48972],[-84.42101,46.49853],[-84.34174,46.50683],[-84.29893,46.49127],[-84.26351,46.49508],[-84.2264,46.53337],[-84.1945,46.54061],[-84.17723,46.52753],[-84.12885,46.53068],[-84.11196,46.50248],[-84.13451,46.39218],[-84.11254,46.32329],[-84.11615,46.2681],[-84.09756,46.25512],[-84.1096,46.23987],[-83.95399,46.05634],[-83.90453,46.05922],[-83.83329,46.12169],[-83.57017,46.105],[-83.43746,45.99749],[-83.59589,45.82131],[-82.48419,45.30225],[-82.42469,42.992],[-82.4146,42.97626],[-82.4253,42.95423],[-82.45331,42.93139],[-82.4826,42.8068],[-82.46613,42.76615],[-82.51063,42.66025],[-82.51858,42.611],[-82.57583,42.5718],[-82.58873,42.54984],[-82.64242,42.55594],[-82.82964,42.37355],[-83.02253,42.33045],[-83.07837,42.30978],[-83.09837,42.28877],[-83.12724,42.2376],[-83.14962,42.04089],[-83.11184,41.95671],[-82.67862,41.67615],[-80.53581,42.29896],[-79.77073,42.55308],[-78.93684,42.82887],[-78.90712,42.89733],[-78.90905,42.93022],[-78.93224,42.95229],[-78.96312,42.95509],[-78.98126,42.97],[-79.02074,42.98444],[-79.02424,43.01983],[-78.99941,43.05612],[-79.01055,43.06659],[-79.07486,43.07845],[-79.05671,43.10937],[-79.06881,43.12029],[-79.0427,43.13934],[-79.04652,43.16396],[-79.05384,43.17418],[-79.05002,43.20133],[-79.05544,43.21224],[-79.05512,43.25375],[-79.06921,43.26183],[-79.25796,43.54052],[-76.79706,43.63099],[-76.43859,44.09393],[-76.35324,44.13493],[-76.31222,44.19894],[-76.244,44.19643],[-76.1664,44.23051],[-76.16285,44.28262],[-76.00018,44.34896],[-75.95947,44.34463],[-75.8217,44.43176],[-75.76813,44.51537],[-75.41441,44.76614],[-75.2193,44.87821],[-75.01363,44.95608],[-74.99101,44.98051],[-74.8447,45.00606],[-74.66689,45.00646],[-74.50073,45.06927],[-74.32151,45.18844],[-74.47257,45.30253],[-74.38125,45.56562],[-74.48081,45.59638],[-74.52819,45.59157],[-74.61059,45.62183],[-74.64286,45.64008],[-74.71427,45.62856],[-74.94087,45.64536],[-75.02601,45.59589],[-75.13038,45.57715],[-75.24162,45.58677],[-75.33981,45.53581],[-75.4804,45.51368],[-75.58151,45.47361],[-75.61876,45.47192],[-75.68562,45.45826],[-75.69334,45.45187],[-75.70287,45.43712],[-75.70424,45.42706],[-75.70957,45.42345],[-75.71772,45.42158],[-75.7239,45.422],[-75.72381,45.41766],[-75.72982,45.41736],[-75.75935,45.4114],[-75.80535,45.3762],[-75.8493,45.37716],[-75.91522,45.41477],[-75.97152,45.47643],[-76.091,45.51735],[-76.19468,45.52023],[-76.23245,45.51109],[-76.24343,45.46873],[-76.36772,45.45814],[-76.5023,45.51638],[-76.60873,45.53226],[-76.65885,45.56015],[-76.67602,45.58466],[-76.6719,45.62357],[-76.71653,45.66438],[-76.68975,45.69172],[-76.77558,45.75308],[-76.7646,45.84978],[-76.77696,45.87273],[-76.893,45.90141],[-76.93077,45.89137],[-76.91085,45.80624],[-76.94107,45.789],[-76.98982,45.78613],[-77.01866,45.80863],[-77.04681,45.8072],[-77.07565,45.83543],[-77.12097,45.84165],[-77.19238,45.86556],[-77.2734,45.93962],[-77.28782,45.98258],[-77.27683,46.0174],[-77.31803,46.02741],[-77.35717,46.05696],[-77.67852,46.19925],[-77.69363,46.18452],[-78.24981,46.27714],[-78.31642,46.25388],[-78.38508,46.29138],[-78.703,46.32173],[-78.72703,46.3407],[-78.73115,46.38619],[-78.88496,46.45624],[-78.98796,46.54604],[-79.01817,46.63664],[-79.04563,46.64607],[-79.08958,46.68518],[-79.17335,46.82678],[-79.21317,46.83335],[-79.44869,47.10512],[-79.42535,47.25307],[-79.48921,47.30711],[-79.58877,47.42941],[-79.55581,47.51342],[-79.51787,47.53313],[-79.51659,51.46031],[-82.09357,52.92137],[-82.10455,55.13419],[-88.99084,56.84662],[-95.15374,52.84191]]]}},{"type":"Feature","properties":{"id":"CA-NS"},"geometry":{"type":"Polygon","coordinates":[[[-67.16117,44.20069],[-65.81187,42.91911],[-59.437,43.71683],[-57.60106,47.38123],[-60.49316,47.38172],[-61.75622,46.42845],[-62.49954,45.85952],[-63.58306,46.10096],[-64.03625,46.01901],[-64.04861,45.97703],[-64.1571,45.9799],[-64.28619,45.83274],[-64.33563,45.8557],[-64.54574,45.68615],[-67.16117,44.20069]]]}},{"type":"Feature","properties":{"id":"CA-PE"},"geometry":{"type":"Polygon","coordinates":[[[-64.66796,46.6005],[-63.75335,46.22936],[-63.58306,46.10096],[-62.49954,45.85952],[-61.75622,46.42845],[-64.01702,47.11511],[-64.66796,46.6005]]]}},{"type":"Feature","properties":{"id":"FM-PNI"},"geometry":{"type":"Polygon","coordinates":[[[153.83475,11.01511],[154.49668,-0.44964],[156.88247,-1.39237],[161.87397,3.186785],[161.58988,8.892633],[159.04653,10.59067],[153.83475,11.01511]]]}},{"type":"Feature","properties":{"id":"CA-NB"},"geometry":{"type":"Polygon","coordinates":[[[-69.05073,47.30076],[-69.05039,47.2456],[-68.89222,47.1807],[-68.70125,47.24399],[-68.60575,47.24659],[-68.57914,47.28431],[-68.38332,47.28723],[-68.37458,47.35851],[-68.23244,47.35712],[-67.94843,47.1925],[-67.87993,47.10377],[-67.78578,47.06473],[-67.78111,45.9392],[-67.75196,45.91814],[-67.80961,45.87531],[-67.75654,45.82324],[-67.80653,45.80022],[-67.80705,45.69528],[-67.6049,45.60725],[-67.43815,45.59162],[-67.42144,45.50584],[-67.50578,45.48971],[-67.42394,45.37969],[-67.48201,45.27351],[-67.34927,45.122],[-67.29754,45.14865],[-67.29748,45.18173],[-67.27039,45.1934],[-67.22751,45.16344],[-67.20349,45.1722],[-67.19603,45.16771],[-67.15965,45.16179],[-67.11316,45.11176],[-67.0216,44.95333],[-66.96824,44.90965],[-66.98249,44.87071],[-66.96824,44.83078],[-66.93432,44.82597],[-67.16117,44.20069],[-64.54574,45.68615],[-64.33563,45.8557],[-64.28619,45.83274],[-64.1571,45.9799],[-64.04861,45.97703],[-64.03625,46.01901],[-63.58306,46.10096],[-63.75335,46.22936],[-64.66796,46.6005],[-64.01702,47.11511],[-64.29855,48.12037],[-65.19393,47.92013],[-66.28295,48.03872],[-66.37908,48.08919],[-66.50405,48.0791],[-66.52465,48.04698],[-66.69012,48.00944],[-66.93664,47.97716],[-66.96548,47.89159],[-67.06161,47.93117],[-67.37884,47.85751],[-67.60406,47.93209],[-67.60543,48.00014],[-68.12316,48.00014],[-68.12454,47.91461],[-68.38409,47.91553],[-68.38546,47.55439],[-68.57223,47.42727],[-68.80844,47.34824],[-69.05073,47.30076]]]}},{"type":"Feature","properties":{"id":"CA-NL"},"geometry":{"type":"Polygon","coordinates":[[[-67.83623,54.45267],[-67.35283,52.90413],[-64.55407,51.57984],[-63.8082,51.99787],[-57.10774,51.99856],[-57.10928,51.37809],[-60.49316,47.38172],[-57.60106,47.38123],[-56.67989,47.3339],[-56.25228,47.31192],[-55.8643,46.64935],[-51.16966,45.93987],[-45.64471,55.43944],[-53.68108,62.9266],[-64.79302,60.27404],[-63.7603,54.63112],[-66.84746,55.09899],[-67.83623,54.45267]]]}},{"type":"Feature","properties":{"id":"CA-QC"},"geometry":{"type":"Polygon","coordinates":[[[-79.92119,54.66449],[-78.74291,52.08899],[-79.56139,51.58666],[-79.51659,51.46031],[-79.51787,47.53313],[-79.55581,47.51342],[-79.58877,47.42941],[-79.48921,47.30711],[-79.42535,47.25307],[-79.44869,47.10512],[-79.21317,46.83335],[-79.17335,46.82678],[-79.08958,46.68518],[-79.04563,46.64607],[-79.01817,46.63664],[-78.98796,46.54604],[-78.88496,46.45624],[-78.73115,46.38619],[-78.72703,46.3407],[-78.703,46.32173],[-78.38508,46.29138],[-78.31642,46.25388],[-78.24981,46.27714],[-77.69363,46.18452],[-77.67852,46.19925],[-77.35717,46.05696],[-77.31803,46.02741],[-77.27683,46.0174],[-77.28782,45.98258],[-77.2734,45.93962],[-77.19238,45.86556],[-77.12097,45.84165],[-77.07565,45.83543],[-77.04681,45.8072],[-77.01866,45.80863],[-76.98982,45.78613],[-76.94107,45.789],[-76.91085,45.80624],[-76.93077,45.89137],[-76.893,45.90141],[-76.77696,45.87273],[-76.7646,45.84978],[-76.77558,45.75308],[-76.68975,45.69172],[-76.71653,45.66438],[-76.6719,45.62357],[-76.67602,45.58466],[-76.65885,45.56015],[-76.60873,45.53226],[-76.5023,45.51638],[-76.36772,45.45814],[-76.24343,45.46873],[-76.23245,45.51109],[-76.19468,45.52023],[-76.091,45.51735],[-75.97152,45.47643],[-75.91522,45.41477],[-75.8493,45.37716],[-75.80535,45.3762],[-75.75935,45.4114],[-75.72982,45.41736],[-75.72381,45.41766],[-75.7239,45.422],[-75.71772,45.42158],[-75.70957,45.42345],[-75.70424,45.42706],[-75.70287,45.43712],[-75.69334,45.45187],[-75.68562,45.45826],[-75.61876,45.47192],[-75.58151,45.47361],[-75.4804,45.51368],[-75.33981,45.53581],[-75.24162,45.58677],[-75.13038,45.57715],[-75.02601,45.59589],[-74.94087,45.64536],[-74.71427,45.62856],[-74.64286,45.64008],[-74.61059,45.62183],[-74.52819,45.59157],[-74.48081,45.59638],[-74.38125,45.56562],[-74.47257,45.30253],[-74.32151,45.18844],[-74.50073,45.06927],[-74.66689,45.00646],[-74.32699,44.99029],[-73.35025,45.00942],[-71.50067,45.01357],[-71.48735,45.07784],[-71.42778,45.12624],[-71.40364,45.21382],[-71.44252,45.2361],[-71.37133,45.24624],[-71.29371,45.29996],[-71.22338,45.25184],[-71.19723,45.25438],[-71.14568,45.24128],[-71.08364,45.30623],[-71.01866,45.31573],[-71.0107,45.34819],[-70.95193,45.33895],[-70.91169,45.29849],[-70.89864,45.2398],[-70.84816,45.22698],[-70.80236,45.37444],[-70.82638,45.39828],[-70.78372,45.43269],[-70.65383,45.37592],[-70.62518,45.42286],[-70.72651,45.49771],[-70.68516,45.56964],[-70.54019,45.67291],[-70.38934,45.73215],[-70.41523,45.79497],[-70.25976,45.89675],[-70.24694,45.95138],[-70.31025,45.96424],[-70.23855,46.1453],[-70.29078,46.18832],[-70.18547,46.35357],[-70.05812,46.41768],[-69.99966,46.69543],[-69.22119,47.46461],[-69.05148,47.42012],[-69.05073,47.30076],[-68.80844,47.34824],[-68.57223,47.42727],[-68.38546,47.55439],[-68.38409,47.91553],[-68.12454,47.91461],[-68.12316,48.00014],[-67.60543,48.00014],[-67.60406,47.93209],[-67.37884,47.85751],[-67.06161,47.93117],[-66.96548,47.89159],[-66.93664,47.97716],[-66.69012,48.00944],[-66.52465,48.04698],[-66.50405,48.0791],[-66.37908,48.08919],[-66.28295,48.03872],[-65.19393,47.92013],[-64.29855,48.12037],[-64.01702,47.11511],[-61.75622,46.42845],[-60.49316,47.38172],[-57.10928,51.37809],[-57.10774,51.99856],[-63.8082,51.99787],[-64.55407,51.57984],[-67.35283,52.90413],[-67.83623,54.45267],[-66.84746,55.09899],[-63.7603,54.63112],[-64.79302,60.27404],[-68.84423,60.00396],[-69.3496,61.12682],[-73.67821,62.57769],[-78.62206,62.65853],[-79.23729,58.64783],[-77.32567,57.55654],[-77.17186,56.02851],[-78.98049,54.90049],[-79.92119,54.66449]]]}},{"type":"Feature","properties":{"id":"CA-YT"},"geometry":{"type":"Polygon","coordinates":[[[-141.00555,72.20369],[-141.00116,60.30648],[-140.5227,60.22077],[-140.45648,60.30919],[-139.98024,60.18027],[-139.68991,60.33693],[-139.05831,60.35205],[-139.20603,60.08896],[-139.05365,59.99655],[-123.86203,59.99964],[-124.71898,60.9114],[-126.80638,60.77223],[-134.09581,67.00286],[-136.15918,67.00031],[-136.20381,67.0511],[-136.21788,67.59731],[-136.4486,67.65377],[-136.4486,68.88195],[-136.61065,69.40701],[-141.00555,72.20369]]]}},{"type":"Feature","properties":{"id":"CA-NT"},"geometry":{"type":"Polygon","coordinates":[[[-141.00555,72.20369],[-136.61065,69.40701],[-136.4486,68.88195],[-136.4486,67.65377],[-136.21788,67.59731],[-136.20381,67.0511],[-136.15918,67.00031],[-134.09581,67.00286],[-126.80638,60.77223],[-124.71898,60.9114],[-123.86203,59.99964],[-120.00135,60.00043],[-110.00637,59.99944],[-102.00759,59.99922],[-102.08165,64.2419],[-111.26622,65.10654],[-120.71446,68.0217],[-120.71446,69.63965],[-110.07969,70.00345],[-110.08928,79.74266],[-141.00555,72.20369]]]}},{"type":"Feature","properties":{"id":"CA-NU"},"geometry":{"type":"Polygon","coordinates":[[[-120.71446,68.0217],[-111.26622,65.10654],[-102.08165,64.2419],[-102.00759,59.99922],[-94.78348,59.99917],[-88.99084,56.84662],[-82.10455,55.13419],[-82.09357,52.92137],[-79.51659,51.46031],[-79.56139,51.58666],[-78.74291,52.08899],[-79.92119,54.66449],[-78.98049,54.90049],[-77.17186,56.02851],[-77.32567,57.55654],[-79.23729,58.64783],[-78.62206,62.65853],[-73.67821,62.57769],[-69.3496,61.12682],[-68.84423,60.00396],[-64.79302,60.27404],[-53.68108,62.9266],[-74.12379,75.70014],[-73.91222,78.42484],[-67.48417,80.75493],[-63.1988,81.66522],[-59.93819,82.31398],[-62.36036,83.40597],[-85.36473,83.41631],[-110.08928,79.74266],[-110.07969,70.00345],[-120.71446,69.63965],[-120.71446,68.0217]]]}},{"type":"Feature","properties":{"id":"US-DC"},"geometry":{"type":"Polygon","coordinates":[[[-77.11962,38.93441],[-77.11536,38.92787],[-77.10592,38.91912],[-77.10201,38.91264],[-77.08897,38.90436],[-77.07047,38.90106],[-77.06759,38.89895],[-77.05957,38.88152],[-77.05493,38.87964],[-77.0491,38.87343],[-77.04592,38.87557],[-77.03021,38.86133],[-77.03906,38.79153],[-76.90939,38.89301],[-77.04117,38.99552],[-77.11962,38.93441]]]}},{"type":"Feature","properties":{"id":"US-AL"},"geometry":{"type":"Polygon","coordinates":[[[-88.47496,31.89065],[-88.37952,30.00457],[-87.51915,30.07055],[-87.51915,30.28187],[-87.44774,30.30677],[-87.50679,30.31863],[-87.3777,30.44658],[-87.42989,30.47144],[-87.44774,30.52113],[-87.39418,30.62518],[-87.40654,30.67362],[-87.52739,30.74093],[-87.63588,30.86596],[-87.59056,30.96375],[-87.5988,30.99671],[-85.00191,31.0026],[-85.00191,31.02143],[-85.09804,31.16255],[-85.10902,31.27295],[-85.04311,31.52965],[-85.07332,31.62676],[-85.14336,31.844],[-85.05547,32.01766],[-85.06233,32.13519],[-84.88518,32.26185],[-85.0074,32.33034],[-84.9662,32.42661],[-84.99916,32.51697],[-85.07057,32.5818],[-85.18318,32.85909],[-85.60478,34.98639],[-88.20305,35.00664],[-88.20029,34.99532],[-88.14949,34.9211],[-88.09868,34.89407],[-88.47496,31.89065]]]}},{"type":"Feature","properties":{"id":"FM-TRK"},"geometry":{"type":"Polygon","coordinates":[[[148.42679,11.45488],[148.49862,1.920402],[154.49668,-0.44964],[153.83475,11.01511],[148.42679,11.45488]]]}},{"type":"Feature","properties":{"id":"US-AZ"},"geometry":{"type":"Polygon","coordinates":[[[-114.82011,32.49609],[-112.34553,31.7357],[-111.07523,31.33232],[-109.05235,31.3333],[-109.04686,37.00061],[-114.05113,37.00171],[-114.04564,36.1991],[-114.12254,36.11372],[-114.14864,36.02936],[-114.2379,36.01715],[-114.30931,36.06379],[-114.37523,36.147],[-114.57298,36.15254],[-114.61281,36.13036],[-114.63066,36.14367],[-114.75014,36.09486],[-114.72404,36.03159],[-114.74052,36.0127],[-114.74602,35.98271],[-114.66774,35.87039],[-114.70482,35.85592],[-114.68971,35.65197],[-114.65263,35.60956],[-114.68147,35.49783],[-114.59633,35.33331],[-114.57024,35.15498],[-114.5826,35.12803],[-114.62791,35.12129],[-114.64577,35.10444],[-114.60732,35.07635],[-114.64165,35.01451],[-114.63203,34.86704],[-114.58672,34.83773],[-114.5565,34.77233],[-114.47411,34.71478],[-114.42879,34.58939],[-114.37798,34.52153],[-114.38484,34.45361],[-114.3409,34.44682],[-114.1404,34.3074],[-114.13628,34.26315],[-114.3821,34.11434],[-114.53728,33.93223],[-114.50432,33.87182],[-114.52766,33.85015],[-114.49745,33.69718],[-114.52904,33.68461],[-114.53316,33.55196],[-114.65263,33.41336],[-114.72954,33.40763],[-114.69795,33.35947],[-114.72816,33.3044],[-114.67186,33.22517],[-114.70894,33.0918],[-114.61693,33.0262],[-114.5208,33.03196],[-114.46724,32.91098],[-114.47136,32.84294],[-114.5359,32.79216],[-114.53178,32.75405],[-114.59633,32.73442],[-114.70482,32.7425],[-114.71871,32.71894],[-114.76736,32.64094],[-114.80584,32.62028],[-114.81141,32.55543],[-114.79524,32.55731],[-114.82011,32.49609]]]}},{"type":"Feature","properties":{"id":"US-AR"},"geometry":{"type":"Polygon","coordinates":[[[-94.61906,36.49995],[-94.43092,35.38371],[-94.48448,33.64004],[-94.38423,33.56455],[-94.07661,33.57828],[-94.0464,33.55539],[-94.04366,33.01929],[-91.16798,33.00432],[-91.14052,33.29866],[-91.08696,33.96299],[-90.58846,34.49776],[-90.56236,34.72946],[-90.24925,34.93349],[-90.31242,34.99989],[-90.16136,35.13252],[-90.07072,35.1314],[-90.11604,35.38483],[-89.89357,35.64528],[-89.94301,35.66871],[-89.95399,35.73228],[-89.72878,35.8047],[-89.70131,35.83366],[-89.77409,35.87261],[-89.73564,35.91044],[-89.67384,35.8804],[-89.64638,35.91489],[-89.73701,36.00048],[-90.37834,35.99826],[-90.11467,36.26446],[-90.07759,36.27442],[-90.07347,36.39833],[-90.13939,36.41711],[-90.1545,36.49885],[-94.61906,36.49995]]]}},{"type":"Feature","properties":{"id":"US-CA"},"geometry":{"type":"Polygon","coordinates":[[[-125.69978,42.00605],[-122.18305,33.57011],[-118.48109,32.5991],[-117.1243,32.53427],[-115.88053,32.63624],[-114.71871,32.71894],[-114.70482,32.7425],[-114.59633,32.73442],[-114.53178,32.75405],[-114.5359,32.79216],[-114.47136,32.84294],[-114.46724,32.91098],[-114.5208,33.03196],[-114.61693,33.0262],[-114.70894,33.0918],[-114.67186,33.22517],[-114.72816,33.3044],[-114.69795,33.35947],[-114.72954,33.40763],[-114.65263,33.41336],[-114.53316,33.55196],[-114.52904,33.68461],[-114.49745,33.69718],[-114.52766,33.85015],[-114.50432,33.87182],[-114.53728,33.93223],[-114.3821,34.11434],[-114.13628,34.26315],[-114.1404,34.3074],[-114.3409,34.44682],[-114.38484,34.45361],[-114.37798,34.52153],[-114.42879,34.58939],[-114.47411,34.71478],[-114.5565,34.77233],[-114.58672,34.83773],[-114.63203,34.86704],[-114.64165,35.01451],[-120.00023,38.99862],[-120.0016,41.99495],[-125.69978,42.00605]]]}},{"type":"Feature","properties":{"id":"US-CO"},"geometry":{"type":"Polygon","coordinates":[[[-109.05003,41.00069],[-109.04686,37.00061],[-103.00462,36.99417],[-102.04214,36.99314],[-102.04923,40.00324],[-102.05165,41.00235],[-104.0521,41.00188],[-109.05003,41.00069]]]}},{"type":"Feature","properties":{"id":"US-CT"},"geometry":{"type":"Polygon","coordinates":[[[-73.72761,41.10079],[-73.65535,41.01225],[-73.66067,41.00098],[-73.65947,40.99373],[-73.65723,40.99062],[-73.65981,40.98854],[-73.62136,40.9494],[-71.85736,41.32188],[-71.82955,41.34199],[-71.83917,41.3626],[-71.83333,41.37033],[-71.83367,41.38837],[-71.84191,41.39455],[-71.84363,41.40948],[-71.81926,41.41952],[-71.79866,41.41592],[-71.78733,41.65621],[-71.8001,42.00779],[-71.80067,42.0236],[-72.75464,42.03756],[-72.76837,42.00491],[-72.81712,41.9993],[-72.81369,42.03654],[-73.48746,42.0497],[-73.5508,41.2957],[-73.48283,41.21298],[-73.72761,41.10079]]]}},{"type":"Feature","properties":{"id":"FM-YAP"},"geometry":{"type":"Polygon","coordinates":[[[136.04605,12.45908],[136.27107,6.73747],[148.49862,1.920402],[148.42679,11.45488],[136.04605,12.45908]]]}},{"type":"Feature","properties":{"id":"US-DE"},"geometry":{"type":"Polygon","coordinates":[[[-75.78987,39.72204],[-75.78918,39.65388],[-75.69382,38.46017],[-74.98718,38.4507],[-75.01808,38.79724],[-75.38063,39.30382],[-75.56053,39.45773],[-75.55641,39.63352],[-75.46131,39.77457],[-75.40672,39.7962],[-75.41621,39.80165],[-75.43796,39.81414],[-75.46783,39.82548],[-75.49942,39.83365],[-75.53959,39.83945],[-75.57632,39.83945],[-75.59898,39.83734],[-75.62713,39.83259],[-75.65975,39.82337],[-75.68172,39.81387],[-75.71434,39.79515],[-75.72532,39.78644],[-75.74043,39.77378],[-75.76,39.75002],[-75.77476,39.7223],[-75.78987,39.72204]]]}},{"type":"Feature","properties":{"id":"US-FL"},"geometry":{"type":"Polygon","coordinates":[[[-87.63588,30.86596],[-87.52739,30.74093],[-87.40654,30.67362],[-87.39418,30.62518],[-87.44774,30.52113],[-87.42989,30.47144],[-87.3777,30.44658],[-87.50679,30.31863],[-87.44774,30.30677],[-87.51915,30.28187],[-87.51915,30.07055],[-83.18732,24.36791],[-82.02215,24.23074],[-80.16442,23.44484],[-79.36558,27.02964],[-81.34929,30.71298],[-81.56078,30.71535],[-81.95354,30.83098],[-81.97826,30.77554],[-82.01946,30.7897],[-82.05105,30.66575],[-82.00847,30.56765],[-82.04555,30.36287],[-82.17052,30.3605],[-82.20897,30.40908],[-82.2282,30.56765],[-84.86355,30.7118],[-84.92122,30.76256],[-84.9377,30.88285],[-85.00637,30.97591],[-85.00191,31.0026],[-87.5988,30.99671],[-87.59056,30.96375],[-87.63588,30.86596]]]}},{"type":"Feature","properties":{"id":"US-GA"},"geometry":{"type":"Polygon","coordinates":[[[-85.60478,34.98639],[-85.18318,32.85909],[-85.07057,32.5818],[-84.99916,32.51697],[-84.9662,32.42661],[-85.0074,32.33034],[-84.88518,32.26185],[-85.06233,32.13519],[-85.05547,32.01766],[-85.14336,31.844],[-85.07332,31.62676],[-85.04311,31.52965],[-85.10902,31.27295],[-85.09804,31.16255],[-85.00191,31.0026],[-85.00637,30.97591],[-84.9377,30.88285],[-84.92122,30.76256],[-84.86355,30.7118],[-82.2282,30.56765],[-82.20897,30.40908],[-82.17052,30.3605],[-82.04555,30.36287],[-82.00847,30.56765],[-82.05105,30.66575],[-82.01946,30.7897],[-81.97826,30.77554],[-81.95354,30.83098],[-81.56078,30.71535],[-81.34929,30.71298],[-80.49837,32.0326],[-80.92066,32.03667],[-81.00511,32.1001],[-81.05386,32.08497],[-81.11635,32.11638],[-81.11978,32.1937],[-81.15823,32.24017],[-81.11772,32.29127],[-81.20767,32.42409],[-81.19257,32.46292],[-81.27771,32.53531],[-81.28595,32.55904],[-81.3244,32.55788],[-81.38277,32.59086],[-81.41847,32.63193],[-81.39581,32.65101],[-81.42809,32.84101],[-81.45555,32.84851],[-81.50087,32.93557],[-81.49538,33.00988],[-81.62103,33.09564],[-81.64163,33.09276],[-81.70824,33.11807],[-81.76248,33.15947],[-81.7721,33.18303],[-81.75974,33.19912],[-81.77553,33.2198],[-81.78858,33.20716],[-81.85037,33.24622],[-81.85587,33.30248],[-81.93964,33.34609],[-81.91354,33.43953],[-81.92968,33.46674],[-81.9877,33.48794],[-81.99766,33.51342],[-82.05019,33.56464],[-82.10752,33.59782],[-82.1343,33.59095],[-82.19747,33.63013],[-82.20022,33.66214],[-82.3015,33.80062],[-82.39008,33.85651],[-82.56414,33.95567],[-82.59538,34.02855],[-82.64105,34.06809],[-82.64311,34.0951],[-82.71658,34.14882],[-82.74095,34.20789],[-82.75057,34.2709],[-82.78043,34.29672],[-82.79657,34.34039],[-82.83365,34.36419],[-82.87519,34.47408],[-82.90231,34.48625],[-83.00085,34.47238],[-83.03655,34.48625],[-83.16873,34.59259],[-83.17148,34.60728],[-83.22916,34.61096],[-83.34829,34.69455],[-83.35447,34.72814],[-83.32048,34.75861],[-83.32357,34.78878],[-83.2374,34.87417],[-83.11689,34.94033],[-83.12616,34.9544],[-83.09869,34.99098],[-83.10796,35.0011],[-84.32551,34.99393],[-85.60478,34.98639]]]}},{"type":"Feature","properties":{"id":"US-ID"},"geometry":{"type":"Polygon","coordinates":[[[-117.24003,44.37408],[-117.18921,44.34266],[-117.22149,44.30238],[-117.18304,44.26453],[-116.97841,44.24387],[-116.97155,44.19565],[-116.90151,44.17792],[-116.89602,44.15526],[-116.94271,44.09513],[-116.97429,44.08921],[-116.97704,44.05172],[-116.93722,44.03198],[-116.93859,43.98654],[-116.97704,43.96282],[-116.96194,43.91734],[-116.99215,43.8629],[-117.02923,43.83121],[-117.02619,42.00013],[-114.04073,42.00031],[-111.04628,42.00049],[-111.04897,44.47412],[-111.38328,44.75395],[-111.51237,44.64267],[-111.48765,44.539],[-112.31163,44.55662],[-112.39403,44.44888],[-112.71812,44.50571],[-112.83897,44.43712],[-112.82249,44.36255],[-113.00926,44.45476],[-113.13286,44.7754],[-113.25645,44.82802],[-113.3361,44.7871],[-113.5009,44.93506],[-113.44047,44.97005],[-113.45421,45.05742],[-113.75084,45.34385],[-113.82225,45.59809],[-113.98155,45.70752],[-114.33861,45.46148],[-114.54735,45.5731],[-114.55559,45.77653],[-114.39628,45.88752],[-114.49516,46.04407],[-114.31938,46.64887],[-114.61052,46.64322],[-115.33562,47.25631],[-115.75859,47.43311],[-115.63225,47.47953],[-115.75859,47.55002],[-115.68992,47.60746],[-116.04835,47.97742],[-116.04938,48.99999],[-117.03266,49.00056],[-117.04021,46.4257],[-117.03644,46.42309],[-117.03575,46.40794],[-117.04914,46.37787],[-117.06287,46.3665],[-117.06184,46.34873],[-117.04811,46.34281],[-117.03472,46.34138],[-116.92348,46.16048],[-116.98116,46.08242],[-116.94958,46.07004],[-116.91799,45.99567],[-116.77585,45.82129],[-116.54789,45.7533],[-116.46274,45.60746],[-116.67972,45.3185],[-116.75388,45.11342],[-116.84864,45.02321],[-116.85825,44.97563],[-116.83353,44.92995],[-116.9379,44.78588],[-117.05051,44.74298],[-117.15626,44.53093],[-117.22492,44.48392],[-117.24003,44.37408]]]}},{"type":"Feature","properties":{"id":"US-IL"},"geometry":{"type":"Polygon","coordinates":[[[-91.52996,40.18533],[-91.44756,39.8551],[-91.36242,39.80026],[-91.37615,39.73481],[-91.04656,39.45756],[-90.72933,39.25847],[-90.67989,39.09612],[-90.71491,39.05828],[-90.66822,38.94035],[-90.59475,38.87302],[-90.55767,38.87088],[-90.50342,38.90616],[-90.46429,38.96705],[-90.41141,38.96438],[-90.25554,38.91951],[-90.1086,38.84789],[-90.12234,38.79761],[-90.16079,38.7778],[-90.2116,38.73015],[-90.21366,38.70604],[-90.18894,38.68138],[-90.17795,38.64385],[-90.19031,38.60094],[-90.26104,38.54027],[-90.29674,38.43278],[-90.37914,38.32728],[-90.35168,38.20436],[-90.18139,38.07258],[-89.83806,37.90374],[-89.52221,37.69322],[-89.52221,37.52786],[-89.43706,37.4385],[-89.42882,37.35559],[-89.49199,37.3403],[-89.52495,37.28788],[-89.46728,37.20698],[-89.38488,37.04274],[-89.28325,36.99011],[-89.286,37.09314],[-89.19536,37.01862],[-89.09649,37.1676],[-88.95916,37.23323],[-88.62682,37.11505],[-88.55266,37.06247],[-88.46477,37.06247],[-88.42357,37.15884],[-88.51696,37.27476],[-88.47301,37.39487],[-88.40984,37.4276],[-88.35491,37.40142],[-88.30822,37.44286],[-88.06652,37.47121],[-88.15716,37.66279],[-88.03356,37.80181],[-88.09124,37.90807],[-88.02257,37.8864],[-88.03356,38.04231],[-87.93468,38.14606],[-87.97863,38.24535],[-87.74792,38.4005],[-87.75341,38.47364],[-87.66552,38.51234],[-87.61059,38.6712],[-87.52819,38.68406],[-87.49523,38.76121],[-87.55565,38.86821],[-87.5172,38.9537],[-87.57213,38.98786],[-87.57213,39.05188],[-87.65453,39.15845],[-87.59411,39.20103],[-87.59411,39.33286],[-87.52819,39.35835],[-87.51995,41.76174],[-87.20959,41.75764],[-87.02282,42.49706],[-90.64245,42.50785],[-90.65258,42.48406],[-90.43079,42.34617],[-90.40333,42.22019],[-90.19184,42.14692],[-90.14515,42.0287],[-90.18566,41.809],[-90.30651,41.75012],[-90.34325,41.65143],[-90.34187,41.58803],[-90.3956,41.57481],[-90.46581,41.52162],[-90.50667,41.51828],[-90.54581,41.5274],[-90.59267,41.51468],[-90.60572,41.49565],[-90.67303,41.46141],[-91.04107,41.43259],[-91.10149,41.28415],[-90.96416,41.01115],[-91.15093,40.66621],[-91.3377,40.60368],[-91.44307,40.37471],[-91.52996,40.18533]]]}},{"type":"Feature","properties":{"id":"US-IN"},"geometry":{"type":"Polygon","coordinates":[[[-88.09124,37.90807],[-88.03356,37.80181],[-87.95578,37.76983],[-87.90222,37.82273],[-87.94102,37.88427],[-87.89089,37.92842],[-87.83527,37.87478],[-87.67666,37.90079],[-87.67735,37.82273],[-87.60662,37.82761],[-87.58328,37.87912],[-87.62447,37.92463],[-87.59014,37.97336],[-87.5771,37.94629],[-87.51049,37.90567],[-87.41093,37.94683],[-87.23309,37.84768],[-87.16442,37.84334],[-87.13078,37.7853],[-87.09301,37.78313],[-87.05387,37.82002],[-87.04357,37.89971],[-86.81217,37.99717],[-86.74282,37.90133],[-86.65645,37.90794],[-86.63556,37.83675],[-86.58981,37.91303],[-86.52309,37.91813],[-86.52378,38.03288],[-86.32465,38.17552],[-86.27384,38.13989],[-86.27728,38.05937],[-86.20106,38.01611],[-86.10973,38.01557],[-86.04244,37.9582],[-86.01772,37.99771],[-85.94219,38.01016],[-85.91267,38.0664],[-85.90511,38.17552],[-85.83576,38.23379],[-85.84057,38.27316],[-85.79182,38.28717],[-85.74925,38.26345],[-85.65723,38.3125],[-85.6387,38.3825],[-85.41828,38.53574],[-85.443,38.72402],[-85.2734,38.73848],[-85.16628,38.68597],[-84.99188,38.77543],[-84.80991,38.78881],[-84.82845,38.83054],[-84.7852,38.88294],[-84.88064,38.90486],[-84.82433,38.97696],[-84.89643,39.05911],[-84.81884,39.10708],[-84.80645,41.69747],[-84.80614,41.761],[-87.20959,41.75764],[-87.51995,41.76174],[-87.52819,39.35835],[-87.59411,39.33286],[-87.59411,39.20103],[-87.65453,39.15845],[-87.57213,39.05188],[-87.57213,38.98786],[-87.5172,38.9537],[-87.55565,38.86821],[-87.49523,38.76121],[-87.52819,38.68406],[-87.61059,38.6712],[-87.66552,38.51234],[-87.75341,38.47364],[-87.74792,38.4005],[-87.97863,38.24535],[-87.93468,38.14606],[-88.03356,38.04231],[-88.02257,37.8864],[-88.09124,37.90807]]]}},{"type":"Feature","properties":{"id":"US-IA"},"geometry":{"type":"Polygon","coordinates":[[[-96.63614,42.74513],[-96.49057,42.57547],[-96.47134,42.49249],[-96.40268,42.49249],[-96.38071,42.46616],[-96.3862,42.4317],[-96.41641,42.40737],[-96.25162,42.02699],[-96.14999,41.9678],[-96.08682,41.53956],[-95.91928,41.45728],[-95.95224,41.34603],[-95.93507,41.32489],[-95.88701,41.31922],[-95.8719,41.30426],[-95.87602,41.28569],[-95.92203,41.26917],[-95.91173,41.23046],[-95.93095,41.20566],[-95.92203,41.18655],[-95.86092,41.18861],[-95.84512,41.18035],[-95.84581,41.16484],[-95.87534,41.16587],[-95.88426,41.14985],[-95.86298,41.08829],[-95.88495,41.05568],[-95.84238,40.67557],[-95.77211,40.58647],[-91.73074,40.61201],[-91.44307,40.37471],[-91.3377,40.60368],[-91.15093,40.66621],[-90.96416,41.01115],[-91.10149,41.28415],[-91.04107,41.43259],[-90.67303,41.46141],[-90.60572,41.49565],[-90.59267,41.51468],[-90.54581,41.5274],[-90.50667,41.51828],[-90.46581,41.52162],[-90.3956,41.57481],[-90.34187,41.58803],[-90.34325,41.65143],[-90.30651,41.75012],[-90.18566,41.809],[-90.14515,42.0287],[-90.19184,42.14692],[-90.40333,42.22019],[-90.43079,42.34617],[-90.65258,42.48406],[-90.64245,42.50785],[-90.70901,42.65026],[-91.02487,42.7068],[-91.08804,42.7774],[-91.09354,42.8761],[-91.1622,42.93646],[-91.15121,43.02085],[-91.16769,43.17528],[-91.07706,43.27334],[-91.09628,43.31932],[-91.21439,43.38123],[-91.22537,43.4989],[-96.45334,43.50083],[-96.60043,43.50089],[-96.52902,43.31333],[-96.58121,43.28334],[-96.54275,43.22733],[-96.48233,43.22133],[-96.43838,43.11516],[-96.63614,42.74513]]]}},{"type":"Feature","properties":{"id":"US-KS"},"geometry":{"type":"Polygon","coordinates":[[[-102.04923,40.00324],[-102.04214,36.99314],[-94.61795,36.9986],[-94.60772,39.11895],[-94.5909,39.13759],[-94.58953,39.15384],[-94.60601,39.16129],[-94.64686,39.1533],[-94.66128,39.15863],[-94.66094,39.17673],[-94.67845,39.18498],[-94.72239,39.16874],[-94.75157,39.17194],[-94.77011,39.18684],[-94.77664,39.20174],[-94.90298,39.30383],[-94.91122,39.35216],[-94.87895,39.37446],[-94.89405,39.39622],[-94.92839,39.38561],[-95.10348,39.53404],[-95.10279,39.57851],[-95.02177,39.67371],[-94.86247,39.74133],[-94.85903,39.75769],[-94.86865,39.773],[-94.90779,39.75875],[-94.93491,39.77221],[-94.93251,39.78804],[-94.88272,39.79542],[-94.87654,39.82391],[-95.31497,40.00166],[-102.04923,40.00324]]]}},{"type":"Feature","properties":{"id":"US-KY"},"geometry":{"type":"Polygon","coordinates":[[[-89.41668,36.50778],[-88.05987,36.49674],[-88.06536,36.67979],[-87.80993,36.63792],[-86.5932,36.65555],[-86.56848,36.63572],[-86.51355,36.65555],[-83.69109,36.58281],[-83.67455,36.60056],[-83.5239,36.66716],[-83.42125,36.66798],[-83.14074,36.75244],[-83.08032,36.84701],[-82.89904,36.88437],[-82.86059,36.98316],[-82.73425,37.04018],[-82.72326,37.12564],[-82.34698,37.2744],[-81.9707,37.53839],[-82.13961,37.56235],[-82.17669,37.63416],[-82.29754,37.67656],[-82.33462,37.77758],[-82.41702,37.84593],[-82.49392,37.93372],[-82.46646,37.98569],[-82.63263,38.13922],[-82.64361,38.1673],[-82.60791,38.17378],[-82.59692,38.21156],[-82.61203,38.24176],[-82.58319,38.25039],[-82.57495,38.32261],[-82.59692,38.342],[-82.59692,38.42382],[-82.61203,38.47329],[-82.72601,38.55603],[-82.79879,38.56355],[-82.84549,38.58502],[-82.87844,38.69121],[-82.8702,38.73943],[-82.89492,38.7555],[-82.97869,38.72765],[-83.02951,38.72872],[-83.0556,38.69336],[-83.10778,38.67621],[-83.14898,38.62258],[-83.20117,38.61614],[-83.24511,38.63116],[-83.27533,38.59897],[-83.31652,38.60112],[-83.33575,38.64618],[-83.52801,38.70408],[-83.62414,38.67621],[-83.66534,38.62902],[-83.7752,38.65047],[-83.79443,38.69765],[-83.95648,38.78762],[-84.07183,38.77263],[-84.23388,38.81331],[-84.23388,38.88176],[-84.29293,38.95334],[-84.30117,38.99445],[-84.34924,39.0382],[-84.41035,39.0446],[-84.43026,39.05739],[-84.4337,39.09577],[-84.4488,39.11922],[-84.47695,39.12188],[-84.49893,39.0995],[-84.51747,39.09151],[-84.54631,39.10163],[-84.56622,39.08671],[-84.62252,39.07392],[-84.68432,39.09844],[-84.74887,39.14851],[-84.81884,39.10708],[-84.89643,39.05911],[-84.82433,38.97696],[-84.88064,38.90486],[-84.7852,38.88294],[-84.82845,38.83054],[-84.80991,38.78881],[-84.99188,38.77543],[-85.16628,38.68597],[-85.2734,38.73848],[-85.443,38.72402],[-85.41828,38.53574],[-85.6387,38.3825],[-85.65723,38.3125],[-85.74925,38.26345],[-85.79182,38.28717],[-85.84057,38.27316],[-85.83576,38.23379],[-85.90511,38.17552],[-85.91267,38.0664],[-85.94219,38.01016],[-86.01772,37.99771],[-86.04244,37.9582],[-86.10973,38.01557],[-86.20106,38.01611],[-86.27728,38.05937],[-86.27384,38.13989],[-86.32465,38.17552],[-86.52378,38.03288],[-86.52309,37.91813],[-86.58981,37.91303],[-86.63556,37.83675],[-86.65645,37.90794],[-86.74282,37.90133],[-86.81217,37.99717],[-87.04357,37.89971],[-87.05387,37.82002],[-87.09301,37.78313],[-87.13078,37.7853],[-87.16442,37.84334],[-87.23309,37.84768],[-87.41093,37.94683],[-87.51049,37.90567],[-87.5771,37.94629],[-87.59014,37.97336],[-87.62447,37.92463],[-87.58328,37.87912],[-87.60662,37.82761],[-87.67735,37.82273],[-87.67666,37.90079],[-87.83527,37.87478],[-87.89089,37.92842],[-87.94102,37.88427],[-87.90222,37.82273],[-87.95578,37.76983],[-88.03356,37.80181],[-88.15716,37.66279],[-88.06652,37.47121],[-88.30822,37.44286],[-88.35491,37.40142],[-88.40984,37.4276],[-88.47301,37.39487],[-88.51696,37.27476],[-88.42357,37.15884],[-88.46477,37.06247],[-88.55266,37.06247],[-88.62682,37.11505],[-88.95916,37.23323],[-89.09649,37.1676],[-89.19536,37.01862],[-89.19146,36.9678],[-89.10907,36.98097],[-89.22168,36.56737],[-89.36175,36.63352],[-89.41668,36.50778]]]}},{"type":"Feature","properties":{"id":"US-LA"},"geometry":{"type":"Polygon","coordinates":[[[-94.04467,32.00379],[-93.92932,31.91524],[-93.52008,31.03684],[-93.76452,30.33771],[-93.70959,30.28791],[-93.71508,30.05521],[-93.92382,29.81005],[-93.77551,29.43998],[-88.93054,28.25639],[-88.37952,30.00457],[-89.58972,30.1835],[-89.69134,30.46089],[-89.77374,30.5177],[-89.85339,30.67373],[-89.73529,31.00389],[-91.63317,31.00153],[-91.44641,31.54147],[-90.90533,32.31769],[-91.16798,33.00432],[-94.04366,33.01929],[-94.04467,32.00379]]]}},{"type":"Feature","properties":{"id":"US-ME"},"geometry":{"type":"Polygon","coordinates":[[[-71.08364,45.30623],[-70.97613,43.56977],[-70.95278,43.55783],[-70.98849,43.3884],[-70.96377,43.33749],[-70.93493,43.33549],[-70.89648,43.29052],[-70.81271,43.23052],[-70.83331,43.13238],[-70.73786,43.07272],[-70.70422,43.07623],[-70.70216,43.04463],[-70.04999,42.81005],[-67.16117,44.20069],[-66.93432,44.82597],[-66.96824,44.83078],[-66.98249,44.87071],[-66.96824,44.90965],[-67.0216,44.95333],[-67.11316,45.11176],[-67.15965,45.16179],[-67.19603,45.16771],[-67.20349,45.1722],[-67.22751,45.16344],[-67.27039,45.1934],[-67.29748,45.18173],[-67.29754,45.14865],[-67.34927,45.122],[-67.48201,45.27351],[-67.42394,45.37969],[-67.50578,45.48971],[-67.42144,45.50584],[-67.43815,45.59162],[-67.6049,45.60725],[-67.80705,45.69528],[-67.80653,45.80022],[-67.75654,45.82324],[-67.80961,45.87531],[-67.75196,45.91814],[-67.78111,45.9392],[-67.78578,47.06473],[-67.87993,47.10377],[-67.94843,47.1925],[-68.23244,47.35712],[-68.37458,47.35851],[-68.38332,47.28723],[-68.57914,47.28431],[-68.60575,47.24659],[-68.70125,47.24399],[-68.89222,47.1807],[-69.05039,47.2456],[-69.05073,47.30076],[-69.05148,47.42012],[-69.22119,47.46461],[-69.99966,46.69543],[-70.05812,46.41768],[-70.18547,46.35357],[-70.29078,46.18832],[-70.23855,46.1453],[-70.31025,45.96424],[-70.24694,45.95138],[-70.25976,45.89675],[-70.41523,45.79497],[-70.38934,45.73215],[-70.54019,45.67291],[-70.68516,45.56964],[-70.72651,45.49771],[-70.62518,45.42286],[-70.65383,45.37592],[-70.78372,45.43269],[-70.82638,45.39828],[-70.80236,45.37444],[-70.84816,45.22698],[-70.89864,45.2398],[-70.91169,45.29849],[-70.95193,45.33895],[-71.0107,45.34819],[-71.01866,45.31573],[-71.08364,45.30623]]]}},{"type":"Feature","properties":{"id":"US-MD"},"geometry":{"type":"Polygon","coordinates":[[[-79.48702,39.20187],[-79.42831,39.22448],[-79.37853,39.27261],[-79.35999,39.27526],[-79.33801,39.29652],[-79.31158,39.30502],[-79.29235,39.29865],[-79.25321,39.35575],[-79.21579,39.36424],[-79.19657,39.38733],[-79.06885,39.47643],[-79.0455,39.4804],[-78.96688,39.43958],[-78.83951,39.5678],[-78.81925,39.56065],[-78.79659,39.63472],[-78.76501,39.64715],[-78.77702,39.62177],[-78.73789,39.62388],[-78.73892,39.60775],[-78.77771,39.60457],[-78.76364,39.58262],[-78.73789,39.58632],[-78.72621,39.56356],[-78.66167,39.53576],[-78.46872,39.5167],[-78.40658,39.617],[-78.31732,39.59479],[-78.18411,39.69524],[-78.10789,39.68203],[-78.05021,39.64768],[-78.01107,39.60113],[-77.87512,39.617],[-77.83392,39.60431],[-77.83392,39.56621],[-77.88885,39.55774],[-77.84216,39.49842],[-77.78036,39.49312],[-77.79821,39.43587],[-77.75289,39.42632],[-77.73135,39.32349],[-77.68054,39.32667],[-77.61462,39.3033],[-77.56655,39.30861],[-77.54596,39.27247],[-77.49102,39.25227],[-77.45532,39.22462],[-77.47729,39.18844],[-77.51162,39.18311],[-77.5281,39.14691],[-77.51849,39.12135],[-77.48416,39.11282],[-77.46081,39.07872],[-77.30975,39.05846],[-77.23971,39.02006],[-77.25619,39.00192],[-77.22186,38.97417],[-77.1477,38.9699],[-77.11962,38.93441],[-77.04117,38.99552],[-76.90939,38.89301],[-77.03906,38.79153],[-77.04196,38.70568],[-77.08041,38.70568],[-77.12023,38.68103],[-77.12161,38.63385],[-77.21225,38.6038],[-77.28915,38.50178],[-77.28778,38.38454],[-77.20813,38.35223],[-77.03784,38.42973],[-76.92248,38.23475],[-76.61074,38.15704],[-76.23034,37.8985],[-75.88153,37.90934],[-75.65768,37.94509],[-75.62472,37.99597],[-75.16879,38.02735],[-74.98718,38.4507],[-75.69382,38.46017],[-75.78918,39.65388],[-75.78987,39.72204],[-79.47663,39.72086],[-79.48702,39.20187]]]}},{"type":"Feature","properties":{"id":"IN-DD"},"geometry":{"type":"Polygon","coordinates":[[[70.8467,20.44438],[72.47526,20.38318],[72.89291,20.36748],[72.90801,20.43087],[72.83901,20.48555],[71.00154,20.74648],[70.87331,20.73203],[70.8467,20.44438]]]}},{"type":"Feature","properties":{"id":"US-MA"},"geometry":{"type":"Polygon","coordinates":[[[-73.50942,42.0867],[-73.48746,42.0497],[-72.81369,42.03654],[-72.81712,41.9993],[-72.76837,42.00491],[-72.75464,42.03756],[-71.80067,42.0236],[-71.8001,42.00779],[-71.38117,42.0194],[-71.3822,41.89277],[-71.33894,41.89916],[-71.341,41.79814],[-71.32898,41.7815],[-71.26135,41.75231],[-71.19577,41.67465],[-71.13432,41.65952],[-71.14153,41.60717],[-71.13123,41.591],[-71.10101,41.43444],[-69.97282,40.56828],[-69.42513,41.52748],[-70.04999,42.81005],[-70.81606,42.8739],[-70.84627,42.86182],[-70.88541,42.88446],[-70.92592,42.88698],[-70.96781,42.86887],[-71.04196,42.85981],[-71.06531,42.80744],[-71.13878,42.82305],[-71.18616,42.79484],[-71.18273,42.7399],[-71.25139,42.74343],[-71.29465,42.69651],[-72.45969,42.72515],[-73.26498,42.74494],[-73.50942,42.0867]]]}},{"type":"Feature","properties":{"id":"CN-QH"},"geometry":{"type":"Polygon","coordinates":[[[89.40811,36.01522],[89.42802,35.91602],[89.80224,35.859],[89.68482,35.42207],[89.45274,35.22991],[89.57908,34.90113],[89.81941,34.90395],[89.73358,34.65862],[89.87708,34.2277],[89.63882,34.04583],[89.93751,33.80083],[89.99656,33.55913],[90.24993,33.42857],[90.38177,33.2605],[90.51567,33.2651],[90.70175,33.13985],[91.51405,33.11339],[91.97891,32.86113],[92.20275,32.88766],[92.22335,32.72144],[93.02398,32.73646],[93.48953,32.4947],[93.72161,32.57343],[94.14733,32.43561],[94.61254,32.67001],[94.91981,32.413],[95.22571,32.3872],[95.51032,31.74685],[95.61881,31.77896],[95.7891,31.75327],[96.14822,31.69078],[96.20109,31.53816],[96.25053,31.55396],[96.21963,31.76145],[96.13929,31.82623],[96.24435,31.9341],[96.33636,31.95682],[96.37069,31.85539],[96.5657,31.7194],[96.8431,31.7083],[96.725,32.02612],[96.9564,31.99351],[97.00309,32.06628],[97.16583,32.03049],[97.22557,32.10962],[97.30865,32.07501],[97.37663,32.5306],[97.66399,32.47704],[97.72544,32.52886],[97.66296,32.55781],[97.54417,32.62332],[97.5325,32.64241],[97.48168,32.65556],[97.4271,32.7122],[97.37766,32.80718],[97.37834,32.86978],[97.33989,32.9038],[97.4319,32.9813],[97.53078,32.99167],[97.49061,33.11512],[97.4858,33.166],[97.59841,33.25964],[97.62348,33.33769],[97.7584,33.40536],[97.40409,33.63062],[97.39517,33.89492],[97.65266,33.93538],[97.66158,34.12431],[98.41689,34.09816],[98.42651,33.85217],[98.73962,33.43717],[98.85497,33.14675],[99.36035,32.90092],[99.73388,32.72375],[99.8822,33.04781],[100.49554,32.65671],[100.54687,32.5714],[100.66463,32.52481],[100.71819,32.67492],[100.94032,32.60756],[101.1185,32.63619],[101.22665,32.76071],[101.1621,33.22835],[101.64001,33.09844],[101.76223,33.46925],[101.61254,33.51506],[101.58782,33.67349],[101.17034,33.65463],[101.19232,33.79455],[100.7611,34.17545],[100.94581,34.37404],[101.76841,34.06233],[102.25318,34.36441],[102.15499,34.51221],[101.72996,34.70436],[102.40218,35.18503],[102.3191,35.34369],[102.50381,35.58808],[102.75169,35.49533],[102.80456,35.5758],[102.70568,35.86011],[102.9467,35.83507],[102.97004,36.03299],[103.02394,36.25562],[102.92026,36.30073],[102.88936,36.33338],[102.83168,36.33531],[102.82859,36.37098],[102.71598,36.60009],[102.59651,36.71081],[102.72319,36.76886],[102.47325,36.97238],[102.64594,37.10447],[101.9878,37.73108],[101.3578,37.7916],[100.97019,38.01293],[100.93105,38.16749],[100.09815,38.45735],[100.17677,38.2112],[98.74923,39.08743],[98.28643,39.03358],[98.24867,38.88515],[98.08937,38.78513],[97.3368,39.16733],[96.97769,39.20884],[96.9358,38.9108],[97.05459,38.6284],[96.66595,38.48665],[96.65702,38.22901],[96.29859,38.15669],[95.65658,38.36857],[95.24459,38.30502],[94.99053,38.43638],[94.5346,38.35781],[94.35607,38.76265],[93.42086,38.9092],[93.11599,39.17372],[92.40874,39.03625],[90.44975,38.49928],[90.09406,38.49014],[90.18127,38.39764],[90.14076,38.33734],[90.31585,38.22955],[90.52322,38.31903],[90.5136,37.74465],[91.06567,37.48575],[91.31149,37.02887],[90.84869,36.93342],[90.7196,36.59347],[91.02035,36.54053],[91.10961,36.10792],[90.86379,36.02577],[90.01922,36.2631],[89.95056,36.08018],[89.691,36.0935],[89.40811,36.01522]]]}},{"type":"Feature","properties":{"id":"US-MI"},"geometry":{"type":"Polygon","coordinates":[[[-90.42047,46.56636],[-90.39026,46.53331],[-90.33396,46.5522],[-90.2186,46.50212],[-90.11148,46.3355],[-89.09387,46.14078],[-88.8096,46.02457],[-88.64618,45.98832],[-88.51846,46.02362],[-88.30835,45.95587],[-88.10098,45.9234],[-88.07901,45.87371],[-88.13669,45.82205],[-88.0845,45.78088],[-88.01172,45.79333],[-87.86752,45.75023],[-87.77826,45.67639],[-87.83182,45.65912],[-87.77414,45.6063],[-87.79474,45.56209],[-87.84143,45.57074],[-87.80435,45.53805],[-87.8071,45.47067],[-87.85791,45.43888],[-87.87027,45.35499],[-87.75903,45.35209],[-87.69724,45.38972],[-87.64368,45.34534],[-87.74118,45.19554],[-87.65741,45.10643],[-87.44318,45.07735],[-87.41022,45.20134],[-87.09574,45.44563],[-86.7428,45.44467],[-86.25116,45.23713],[-87.02282,42.49706],[-87.20959,41.75764],[-84.80614,41.761],[-84.80645,41.69747],[-83.42355,41.73233],[-83.11184,41.95671],[-83.14962,42.04089],[-83.12724,42.2376],[-83.09837,42.28877],[-83.07837,42.30978],[-83.02253,42.33045],[-82.82964,42.37355],[-82.64242,42.55594],[-82.58873,42.54984],[-82.57583,42.5718],[-82.51858,42.611],[-82.51063,42.66025],[-82.46613,42.76615],[-82.4826,42.8068],[-82.45331,42.93139],[-82.4253,42.95423],[-82.4146,42.97626],[-82.42469,42.992],[-82.48419,45.30225],[-83.59589,45.82131],[-83.43746,45.99749],[-83.57017,46.105],[-83.83329,46.12169],[-83.90453,46.05922],[-83.95399,46.05634],[-84.1096,46.23987],[-84.09756,46.25512],[-84.11615,46.2681],[-84.11254,46.32329],[-84.13451,46.39218],[-84.11196,46.50248],[-84.12885,46.53068],[-84.17723,46.52753],[-84.1945,46.54061],[-84.2264,46.53337],[-84.26351,46.49508],[-84.29893,46.49127],[-84.34174,46.50683],[-84.42101,46.49853],[-84.4481,46.48972],[-84.47607,46.45225],[-84.55635,46.45974],[-84.85871,46.88881],[-88.37033,48.30586],[-89.48837,48.01412],[-90.42047,46.56636]]]}},{"type":"Feature","properties":{"id":"US-MN"},"geometry":{"type":"Polygon","coordinates":[[[-97.24024,48.99952],[-97.09604,48.68275],[-97.15372,48.59745],[-97.14685,48.17245],[-97.05484,47.9485],[-97.01639,47.91905],[-97.02738,47.89144],[-96.85983,47.60148],[-96.83511,47.0083],[-96.76233,46.92114],[-96.79666,46.81035],[-96.7898,46.63902],[-96.72525,46.45011],[-96.60303,46.32981],[-96.56732,45.93486],[-96.58106,45.82588],[-96.65109,45.74735],[-96.86258,45.62263],[-96.68405,45.41382],[-96.49591,45.36367],[-96.45334,45.29706],[-96.45334,43.50083],[-91.22537,43.4989],[-91.24582,43.77649],[-91.42572,43.99227],[-91.65094,44.06533],[-91.9874,44.3832],[-92.82511,44.74132],[-92.77017,44.82953],[-92.76056,45.28643],[-92.65207,45.40804],[-92.76056,45.56786],[-92.88416,45.56978],[-92.8718,45.72051],[-92.78803,45.76364],[-92.72348,45.889],[-92.29639,46.07794],[-92.29227,46.66258],[-92.2085,46.65221],[-92.203,46.69744],[-92.1055,46.75016],[-92.02448,46.70498],[-89.48837,48.01412],[-89.57972,48.00023],[-89.77248,48.02607],[-89.89974,47.98109],[-90.07418,48.11043],[-90.56312,48.09488],[-90.56444,48.12184],[-90.75045,48.09143],[-90.87588,48.2484],[-91.08016,48.18096],[-91.25025,48.08522],[-91.43248,48.04912],[-91.45829,48.07454],[-91.58025,48.04339],[-91.55649,48.10611],[-91.70451,48.11805],[-91.71231,48.19875],[-91.86125,48.21278],[-91.98929,48.25409],[-92.05339,48.35958],[-92.14732,48.36578],[-92.202,48.35252],[-92.26662,48.35651],[-92.30939,48.31251],[-92.27167,48.25046],[-92.37185,48.22259],[-92.48147,48.36609],[-92.45588,48.40624],[-92.50712,48.44921],[-92.65606,48.43471],[-92.71323,48.46081],[-92.69927,48.49573],[-92.62747,48.50278],[-92.6342,48.54133],[-92.7287,48.54005],[-92.94973,48.60866],[-93.25391,48.64266],[-93.33946,48.62787],[-93.3712,48.60599],[-93.39758,48.60364],[-93.40693,48.60948],[-93.44472,48.59147],[-93.47022,48.54357],[-93.66382,48.51845],[-93.79267,48.51631],[-93.80939,48.52439],[-93.80676,48.58232],[-93.83288,48.62745],[-93.85769,48.63284],[-94.23215,48.65202],[-94.25104,48.65729],[-94.25172,48.68404],[-94.27153,48.70232],[-94.4174,48.71049],[-94.44258,48.69223],[-94.53826,48.70216],[-94.54885,48.71543],[-94.58903,48.71803],[-94.69335,48.77883],[-94.69669,48.80918],[-94.70486,48.82365],[-94.70087,48.8339],[-94.687,48.84077],[-94.75017,49.09931],[-94.77355,49.11998],[-94.82487,49.29483],[-94.8159,49.32299],[-94.85381,49.32492],[-94.95681,49.37035],[-94.99532,49.36579],[-95.01419,49.35647],[-95.05825,49.35311],[-95.12903,49.37056],[-95.15357,49.384],[-95.15355,48.9996],[-97.24024,48.99952]]]}},{"type":"Feature","properties":{"id":"IN-AR"},"geometry":{"type":"Polygon","coordinates":[[[91.55819,27.6144],[91.65007,27.48287],[92.01132,27.47352],[92.12019,27.27829],[92.04702,27.26861],[92.03457,27.07334],[92.11863,26.893],[92.6441,26.98495],[92.64289,27.03894],[92.90313,27.00591],[93.03291,26.919],[93.38035,26.96308],[93.50257,26.93859],[93.68385,26.97838],[93.83354,27.07746],[93.80882,27.15142],[94.15489,27.4839],[94.26269,27.52471],[94.216,27.62331],[94.46937,27.5728],[94.86968,27.74036],[95.316,27.87125],[95.51994,27.88157],[95.63117,27.96105],[95.97518,27.9665],[95.76335,27.73519],[95.88523,27.52836],[95.86189,27.43333],[95.99647,27.37481],[95.89279,27.27294],[95.49041,27.2473],[95.46295,27.12209],[95.19515,27.02915],[95.23513,26.68499],[95.30339,26.65372],[95.437,26.7083],[95.81603,27.01335],[95.93002,27.04149],[96.04949,27.19428],[96.15591,27.24572],[96.40779,27.29818],[96.55761,27.29928],[96.73888,27.36638],[96.88445,27.25046],[96.85287,27.2065],[96.89132,27.17474],[97.14675,27.09041],[97.17422,27.14052],[96.91431,27.45752],[96.90112,27.62149],[97.29919,27.92233],[97.35824,27.87256],[97.38845,28.01329],[97.35412,28.06663],[97.31292,28.06784],[97.34547,28.21385],[97.1289,28.3619],[96.98882,28.32564],[96.88445,28.39452],[96.85561,28.4875],[96.6455,28.61657],[96.48895,28.42955],[96.40929,28.51526],[96.61391,28.72742],[96.3626,29.10607],[96.20467,29.02325],[96.18682,29.11087],[96.31316,29.18643],[96.05361,29.38167],[95.84899,29.31464],[95.75149,29.32063],[95.72086,29.20797],[95.50842,29.13487],[95.41091,29.13007],[95.3038,29.13847],[95.26122,29.07727],[95.2214,29.10727],[95.11291,29.09527],[95.0978,29.14446],[94.81353,29.17804],[94.69318,29.31739],[94.2752,29.11687],[94.35897,29.01965],[93.72797,28.68821],[93.44621,28.67189],[93.18069,28.50319],[93.14635,28.37035],[92.93075,28.25671],[92.67486,28.15018],[92.65472,28.07632],[92.73025,28.05814],[92.7275,27.98662],[92.42538,27.80092],[92.32101,27.79363],[92.27432,27.89077],[91.87057,27.7195],[91.84722,27.76325],[91.6469,27.76358],[91.55819,27.6144]]]}},{"type":"Feature","properties":{"id":"US-WI"},"geometry":{"type":"Polygon","coordinates":[[[-92.88416,45.56978],[-92.76056,45.56786],[-92.65207,45.40804],[-92.76056,45.28643],[-92.77017,44.82953],[-92.82511,44.74132],[-91.9874,44.3832],[-91.65094,44.06533],[-91.42572,43.99227],[-91.24582,43.77649],[-91.22537,43.4989],[-91.21439,43.38123],[-91.09628,43.31932],[-91.07706,43.27334],[-91.16769,43.17528],[-91.15121,43.02085],[-91.1622,42.93646],[-91.09354,42.8761],[-91.08804,42.7774],[-91.02487,42.7068],[-90.70901,42.65026],[-90.64245,42.50785],[-87.02282,42.49706],[-86.25116,45.23713],[-86.7428,45.44467],[-87.09574,45.44563],[-87.41022,45.20134],[-87.44318,45.07735],[-87.65741,45.10643],[-87.74118,45.19554],[-87.64368,45.34534],[-87.69724,45.38972],[-87.75903,45.35209],[-87.87027,45.35499],[-87.85791,45.43888],[-87.8071,45.47067],[-87.80435,45.53805],[-87.84143,45.57074],[-87.79474,45.56209],[-87.77414,45.6063],[-87.83182,45.65912],[-87.77826,45.67639],[-87.86752,45.75023],[-88.01172,45.79333],[-88.0845,45.78088],[-88.13669,45.82205],[-88.07901,45.87371],[-88.10098,45.9234],[-88.30835,45.95587],[-88.51846,46.02362],[-88.64618,45.98832],[-88.8096,46.02457],[-89.09387,46.14078],[-90.11148,46.3355],[-90.2186,46.50212],[-90.33396,46.5522],[-90.39026,46.53331],[-90.42047,46.56636],[-89.48837,48.01412],[-92.02448,46.70498],[-92.1055,46.75016],[-92.203,46.69744],[-92.2085,46.65221],[-92.29227,46.66258],[-92.29639,46.07794],[-92.72348,45.889],[-92.78803,45.76364],[-92.8718,45.72051],[-92.88416,45.56978]]]}},{"type":"Feature","properties":{"id":"US-WY"},"geometry":{"type":"Polygon","coordinates":[[[-111.05503,44.99947],[-111.04897,44.47412],[-111.04628,42.00049],[-111.04675,40.99766],[-109.05003,41.00069],[-104.0521,41.00188],[-104.05548,43.00258],[-104.05897,44.99972],[-111.05503,44.99947]]]}},{"type":"Feature","properties":{"id":"US-MS"},"geometry":{"type":"Polygon","coordinates":[[[-91.63317,31.00153],[-89.73529,31.00389],[-89.85339,30.67373],[-89.77374,30.5177],[-89.69134,30.46089],[-89.58972,30.1835],[-88.37952,30.00457],[-88.47496,31.89065],[-88.09868,34.89407],[-88.14949,34.9211],[-88.20029,34.99532],[-90.31242,34.99989],[-90.24925,34.93349],[-90.56236,34.72946],[-90.58846,34.49776],[-91.08696,33.96299],[-91.14052,33.29866],[-91.16798,33.00432],[-90.90533,32.31769],[-91.44641,31.54147],[-91.63317,31.00153]]]}},{"type":"Feature","properties":{"id":"US-MO"},"geometry":{"type":"Polygon","coordinates":[[[-95.77211,40.58647],[-95.65168,40.39775],[-95.31497,40.00166],[-94.87654,39.82391],[-94.88272,39.79542],[-94.93251,39.78804],[-94.93491,39.77221],[-94.90779,39.75875],[-94.86865,39.773],[-94.85903,39.75769],[-94.86247,39.74133],[-95.02177,39.67371],[-95.10279,39.57851],[-95.10348,39.53404],[-94.92839,39.38561],[-94.89405,39.39622],[-94.87895,39.37446],[-94.91122,39.35216],[-94.90298,39.30383],[-94.77664,39.20174],[-94.77011,39.18684],[-94.75157,39.17194],[-94.72239,39.16874],[-94.67845,39.18498],[-94.66094,39.17673],[-94.66128,39.15863],[-94.64686,39.1533],[-94.60601,39.16129],[-94.58953,39.15384],[-94.5909,39.13759],[-94.60772,39.11895],[-94.61795,36.9986],[-94.61906,36.49995],[-90.1545,36.49885],[-90.13939,36.41711],[-90.07347,36.39833],[-90.07759,36.27442],[-90.11467,36.26446],[-90.37834,35.99826],[-89.73701,36.00048],[-89.61332,36.10897],[-89.58997,36.1478],[-89.6916,36.24089],[-89.57212,36.24754],[-89.5474,36.43117],[-89.52268,36.46762],[-89.57212,36.56144],[-89.52268,36.5846],[-89.47187,36.55813],[-89.48972,36.46541],[-89.45127,36.46431],[-89.41668,36.50778],[-89.36175,36.63352],[-89.22168,36.56737],[-89.10907,36.98097],[-89.19146,36.9678],[-89.19536,37.01862],[-89.286,37.09314],[-89.28325,36.99011],[-89.38488,37.04274],[-89.46728,37.20698],[-89.52495,37.28788],[-89.49199,37.3403],[-89.42882,37.35559],[-89.43706,37.4385],[-89.52221,37.52786],[-89.52221,37.69322],[-89.83806,37.90374],[-90.18139,38.07258],[-90.35168,38.20436],[-90.37914,38.32728],[-90.29674,38.43278],[-90.26104,38.54027],[-90.19031,38.60094],[-90.17795,38.64385],[-90.18894,38.68138],[-90.21366,38.70604],[-90.2116,38.73015],[-90.16079,38.7778],[-90.12234,38.79761],[-90.1086,38.84789],[-90.25554,38.91951],[-90.41141,38.96438],[-90.46429,38.96705],[-90.50342,38.90616],[-90.55767,38.87088],[-90.59475,38.87302],[-90.66822,38.94035],[-90.71491,39.05828],[-90.67989,39.09612],[-90.72933,39.25847],[-91.04656,39.45756],[-91.37615,39.73481],[-91.36242,39.80026],[-91.44756,39.8551],[-91.52996,40.18533],[-91.44307,40.37471],[-91.73074,40.61201],[-95.77211,40.58647]]]}},{"type":"Feature","properties":{"id":"US-MT"},"geometry":{"type":"Polygon","coordinates":[[[-116.04938,48.99999],[-116.04835,47.97742],[-115.68992,47.60746],[-115.75859,47.55002],[-115.63225,47.47953],[-115.75859,47.43311],[-115.33562,47.25631],[-114.61052,46.64322],[-114.31938,46.64887],[-114.49516,46.04407],[-114.39628,45.88752],[-114.55559,45.77653],[-114.54735,45.5731],[-114.33861,45.46148],[-113.98155,45.70752],[-113.82225,45.59809],[-113.75084,45.34385],[-113.45421,45.05742],[-113.44047,44.97005],[-113.5009,44.93506],[-113.3361,44.7871],[-113.25645,44.82802],[-113.13286,44.7754],[-113.00926,44.45476],[-112.82249,44.36255],[-112.83897,44.43712],[-112.71812,44.50571],[-112.39403,44.44888],[-112.31163,44.55662],[-111.48765,44.539],[-111.51237,44.64267],[-111.38328,44.75395],[-111.04897,44.47412],[-111.05503,44.99947],[-104.05897,44.99972],[-104.05691,45.94728],[-104.05004,48.99925],[-110.0051,48.99901],[-114.0683,48.99885],[-116.04938,48.99999]]]}},{"type":"Feature","properties":{"id":"US-SD"},"geometry":{"type":"Polygon","coordinates":[[[-104.05897,44.99972],[-104.05548,43.00258],[-98.50401,43.00058],[-98.44908,42.93275],[-97.99383,42.76612],[-97.95057,42.77065],[-97.84826,42.86685],[-97.44314,42.84773],[-97.40125,42.86736],[-97.25019,42.85729],[-97.11836,42.76813],[-97.00575,42.76561],[-96.94875,42.71922],[-96.88627,42.73536],[-96.69264,42.64805],[-96.71461,42.60561],[-96.60475,42.50344],[-96.55187,42.51963],[-96.47134,42.49249],[-96.49057,42.57547],[-96.63614,42.74513],[-96.43838,43.11516],[-96.48233,43.22133],[-96.54275,43.22733],[-96.58121,43.28334],[-96.52902,43.31333],[-96.60043,43.50089],[-96.45334,43.50083],[-96.45334,45.29706],[-96.49591,45.36367],[-96.68405,45.41382],[-96.86258,45.62263],[-96.65109,45.74735],[-96.58106,45.82588],[-96.56732,45.93486],[-104.05691,45.94728],[-104.05897,44.99972]]]}},{"type":"Feature","properties":{"id":"US-NE"},"geometry":{"type":"Polygon","coordinates":[[[-104.05548,43.00258],[-104.0521,41.00188],[-102.05165,41.00235],[-102.04923,40.00324],[-95.31497,40.00166],[-95.65168,40.39775],[-95.77211,40.58647],[-95.84238,40.67557],[-95.88495,41.05568],[-95.86298,41.08829],[-95.88426,41.14985],[-95.87534,41.16587],[-95.84581,41.16484],[-95.84512,41.18035],[-95.86092,41.18861],[-95.92203,41.18655],[-95.93095,41.20566],[-95.91173,41.23046],[-95.92203,41.26917],[-95.87602,41.28569],[-95.8719,41.30426],[-95.88701,41.31922],[-95.93507,41.32489],[-95.95224,41.34603],[-95.91928,41.45728],[-96.08682,41.53956],[-96.14999,41.9678],[-96.25162,42.02699],[-96.41641,42.40737],[-96.3862,42.4317],[-96.38071,42.46616],[-96.40268,42.49249],[-96.47134,42.49249],[-96.55187,42.51963],[-96.60475,42.50344],[-96.71461,42.60561],[-96.69264,42.64805],[-96.88627,42.73536],[-96.94875,42.71922],[-97.00575,42.76561],[-97.11836,42.76813],[-97.25019,42.85729],[-97.40125,42.86736],[-97.44314,42.84773],[-97.84826,42.86685],[-97.95057,42.77065],[-97.99383,42.76612],[-98.44908,42.93275],[-98.50401,43.00058],[-104.05548,43.00258]]]}},{"type":"Feature","properties":{"id":"US-NV"},"geometry":{"type":"Polygon","coordinates":[[[-120.0016,41.99495],[-120.00023,38.99862],[-114.64165,35.01451],[-114.60732,35.07635],[-114.64577,35.10444],[-114.62791,35.12129],[-114.5826,35.12803],[-114.57024,35.15498],[-114.59633,35.33331],[-114.68147,35.49783],[-114.65263,35.60956],[-114.68971,35.65197],[-114.70482,35.85592],[-114.66774,35.87039],[-114.74602,35.98271],[-114.74052,36.0127],[-114.72404,36.03159],[-114.75014,36.09486],[-114.63066,36.14367],[-114.61281,36.13036],[-114.57298,36.15254],[-114.37523,36.147],[-114.30931,36.06379],[-114.2379,36.01715],[-114.14864,36.02936],[-114.12254,36.11372],[-114.04564,36.1991],[-114.05113,37.00171],[-114.04073,42.00031],[-117.02619,42.00013],[-120.0016,41.99495]]]}},{"type":"Feature","properties":{"id":"US-UT"},"geometry":{"type":"Polygon","coordinates":[[[-114.05113,37.00171],[-109.04686,37.00061],[-109.05003,41.00069],[-111.04675,40.99766],[-111.04628,42.00049],[-114.04073,42.00031],[-114.05113,37.00171]]]}},{"type":"Feature","properties":{"id":"US-ND"},"geometry":{"type":"Polygon","coordinates":[[[-104.05691,45.94728],[-96.56732,45.93486],[-96.60303,46.32981],[-96.72525,46.45011],[-96.7898,46.63902],[-96.79666,46.81035],[-96.76233,46.92114],[-96.83511,47.0083],[-96.85983,47.60148],[-97.02738,47.89144],[-97.01639,47.91905],[-97.05484,47.9485],[-97.14685,48.17245],[-97.15372,48.59745],[-97.09604,48.68275],[-97.24024,48.99952],[-101.36198,48.99935],[-104.05004,48.99925],[-104.05691,45.94728]]]}},{"type":"Feature","properties":{"id":"US-NH"},"geometry":{"type":"Polygon","coordinates":[[[-72.55705,42.85427],[-72.54331,42.81147],[-72.51173,42.78174],[-72.51722,42.7636],[-72.49456,42.77368],[-72.45969,42.72515],[-71.29465,42.69651],[-71.25139,42.74343],[-71.18273,42.7399],[-71.18616,42.79484],[-71.13878,42.82305],[-71.06531,42.80744],[-71.04196,42.85981],[-70.96781,42.86887],[-70.92592,42.88698],[-70.88541,42.88446],[-70.84627,42.86182],[-70.81606,42.8739],[-70.04999,42.81005],[-70.70216,43.04463],[-70.70422,43.07623],[-70.73786,43.07272],[-70.83331,43.13238],[-70.81271,43.23052],[-70.89648,43.29052],[-70.93493,43.33549],[-70.96377,43.33749],[-70.98849,43.3884],[-70.95278,43.55783],[-70.97613,43.56977],[-71.08364,45.30623],[-71.14568,45.24128],[-71.19723,45.25438],[-71.22338,45.25184],[-71.29371,45.29996],[-71.37133,45.24624],[-71.44252,45.2361],[-71.40364,45.21382],[-71.42778,45.12624],[-71.48735,45.07784],[-71.50067,45.01357],[-71.54287,44.98758],[-71.49618,44.90788],[-71.55386,44.86214],[-71.57583,44.79592],[-71.63351,44.74912],[-71.54287,44.58601],[-71.56347,44.56351],[-71.59231,44.56351],[-71.59368,44.49302],[-71.639,44.47343],[-71.7008,44.41558],[-71.79693,44.39891],[-71.81753,44.35866],[-71.86834,44.33706],[-71.90679,44.34688],[-71.9782,44.33411],[-72.0249,44.31741],[-72.06335,44.27514],[-72.04,44.08408],[-72.11141,43.9977],[-72.12309,43.9201],[-72.16291,43.8919],[-72.20617,43.77302],[-72.30093,43.70754],[-72.32702,43.63553],[-72.40049,43.51265],[-72.38127,43.49472],[-72.41491,43.36557],[-72.39362,43.35659],[-72.45611,43.14654],[-72.441,43.13702],[-72.43688,43.08388],[-72.46092,43.05479],[-72.46504,42.98099],[-72.53233,42.95134],[-72.52546,42.93626],[-72.53301,42.89553],[-72.55361,42.88497],[-72.55705,42.85427]]]}},{"type":"Feature","properties":{"id":"US-NJ"},"geometry":{"type":"Polygon","coordinates":[[[-75.56053,39.45773],[-75.38063,39.30382],[-75.01808,38.79724],[-74.98718,38.4507],[-73.81773,39.66512],[-73.9166,40.514],[-74.23109,40.47954],[-74.2613,40.49625],[-74.25615,40.51427],[-74.24722,40.52236],[-74.25134,40.54532],[-74.23418,40.55914],[-74.21839,40.55836],[-74.19985,40.59956],[-74.20397,40.63162],[-74.18577,40.64647],[-74.12775,40.6436],[-74.05668,40.65402],[-74.02612,40.69959],[-74.01445,40.7589],[-73.95197,40.8509],[-73.92072,40.91268],[-73.89463,40.99461],[-74.32825,41.18583],[-74.6956,41.35872],[-74.76152,41.33913],[-74.83431,41.28136],[-74.88237,41.1848],[-75.02931,41.03995],[-75.13849,40.98347],[-75.05266,40.8657],[-75.06777,40.84804],[-75.09935,40.84804],[-75.08219,40.82726],[-75.133,40.77373],[-75.17076,40.77893],[-75.19617,40.75084],[-75.18175,40.73107],[-75.20372,40.691],[-75.18003,40.66939],[-75.20029,40.64881],[-75.19068,40.63865],[-75.19102,40.62093],[-75.19994,40.61259],[-75.19068,40.59435],[-75.1948,40.57844],[-75.18106,40.56619],[-75.16458,40.56332],[-75.14776,40.57453],[-75.12682,40.57453],[-75.10347,40.56984],[-75.06708,40.5388],[-75.06365,40.48581],[-75.07017,40.45525],[-75.06124,40.4218],[-75.03137,40.40534],[-74.98743,40.40664],[-74.96477,40.39592],[-74.94966,40.36611],[-74.94451,40.34152],[-74.91396,40.3177],[-74.89198,40.31246],[-74.86315,40.28837],[-74.84426,40.25013],[-74.82504,40.24069],[-74.78349,40.2234],[-74.76701,40.2095],[-74.75843,40.18774],[-74.73852,40.17855],[-74.72273,40.16045],[-74.72341,40.14864],[-74.74127,40.13473],[-74.75843,40.13447],[-74.7907,40.12187],[-74.81542,40.1287],[-74.82641,40.12633],[-74.83774,40.10244],[-74.8628,40.08432],[-74.91224,40.06987],[-74.9246,40.07224],[-74.97164,40.05279],[-75.01352,40.0202],[-75.04682,40.01099],[-75.0712,39.97969],[-75.09901,39.97443],[-75.13334,39.95786],[-75.13815,39.93627],[-75.12785,39.91073],[-75.13986,39.88716],[-75.16905,39.88294],[-75.26809,39.85014],[-75.33745,39.84842],[-75.41621,39.80165],[-75.40672,39.7962],[-75.46131,39.77457],[-75.55641,39.63352],[-75.56053,39.45773]]]}},{"type":"Feature","properties":{"id":"US-NM"},"geometry":{"type":"Polygon","coordinates":[[[-109.05235,31.3333],[-108.20979,31.33316],[-108.20899,31.78534],[-106.529,31.784],[-106.5436,31.80546],[-106.60333,31.82938],[-106.64522,31.89178],[-106.62187,31.92151],[-106.61981,32.00074],[-103.06402,31.99986],[-103.04239,36.49992],[-103.00325,36.50047],[-103.00462,36.99417],[-109.04686,37.00061],[-109.05235,31.3333]]]}},{"type":"Feature","properties":{"id":"CN-HA"},"geometry":{"type":"Polygon","coordinates":[[[110.35388,34.519],[110.6385,34.18056],[110.587,33.89093],[110.84106,33.67978],[111.0189,33.56771],[110.9801,33.2605],[111.18163,33.10534],[111.29665,32.85622],[111.46488,32.73732],[111.57474,32.59455],[111.67293,32.62636],[112.0008,32.45864],[112.31323,32.32862],[112.55149,32.39851],[113.2505,32.39213],[113.41804,32.27784],[113.71467,32.43329],[113.75038,32.26855],[113.7284,32.08432],[113.84582,31.84314],[113.9859,31.75736],[114.18708,31.85452],[114.58465,31.71648],[114.83184,31.45092],[115.21018,31.58204],[115.36165,31.40228],[115.4718,31.65045],[115.64002,31.76145],[115.87005,31.77195],[115.93872,32.06861],[115.86181,32.45705],[115.91812,32.57922],[115.56312,32.38634],[115.44982,32.53813],[115.1889,32.59946],[115.20675,32.84844],[114.88128,32.97295],[114.91287,33.14387],[115.13465,33.08348],[115.30769,33.20709],[115.34957,33.5185],[115.62286,33.57115],[115.54801,33.8821],[115.59059,34.02563],[115.76431,34.07598],[115.99845,33.97439],[115.96034,33.90376],[116.05545,33.85787],[116.03176,33.83563],[116.14986,33.71148],[116.22951,33.72148],[116.63806,33.8858],[116.64974,33.96585],[116.53266,34.09588],[116.57867,34.27537],[116.2429,34.37177],[116.19792,34.51759],[116.09596,34.60665],[115.67916,34.55577],[115.45394,34.63659],[115.42545,34.8014],[115.19439,34.90817],[115.21465,34.94814],[115.13122,35.00187],[114.82429,34.994],[114.91218,35.19962],[115.07903,35.40416],[115.32966,35.47744],[115.41206,35.64111],[115.67985,35.76211],[115.87005,35.91185],[116.03073,35.963],[116.0939,36.11069],[115.64414,35.91936],[115.49171,35.92297],[115.35644,35.77771],[115.35026,35.95021],[115.43197,36.01078],[115.48072,36.15506],[115.31936,36.07518],[115.19714,36.22544],[114.91493,36.04354],[114.91287,36.13066],[114.61418,36.12345],[114.02435,36.33172],[113.72909,36.36103],[113.65287,35.83507],[113.57597,35.81614],[113.60961,35.67626],[113.48945,35.52943],[113.02802,35.35937],[112.76916,35.20635],[112.05505,35.27981],[112.03994,35.04517],[111.82228,35.07159],[111.57508,34.84649],[111.22695,34.79294],[111.1576,34.81831],[110.8905,34.65354],[110.41122,34.58432],[110.35388,34.519]]]}},{"type":"Feature","properties":{"id":"US-NY"},"geometry":{"type":"Polygon","coordinates":[[[-79.77073,42.55308],[-79.76349,42.00107],[-75.3772,42.00515],[-75.08057,41.80278],[-75.0531,41.59155],[-74.98718,41.48258],[-74.74274,41.42288],[-74.6956,41.35872],[-73.89463,40.99461],[-73.92072,40.91268],[-73.95197,40.8509],[-74.01445,40.7589],[-74.02612,40.69959],[-74.05668,40.65402],[-74.12775,40.6436],[-74.18577,40.64647],[-74.20397,40.63162],[-74.19985,40.59956],[-74.21839,40.55836],[-74.23418,40.55914],[-74.25134,40.54532],[-74.24722,40.52236],[-74.25615,40.51427],[-74.2613,40.49625],[-74.23109,40.47954],[-73.9166,40.514],[-73.81773,39.66512],[-71.6391,40.94332],[-71.85736,41.32188],[-73.62136,40.9494],[-73.65981,40.98854],[-73.65723,40.99062],[-73.65947,40.99373],[-73.66067,41.00098],[-73.65535,41.01225],[-73.72761,41.10079],[-73.48283,41.21298],[-73.5508,41.2957],[-73.48746,42.0497],[-73.50942,42.0867],[-73.26498,42.74494],[-73.25409,43.57117],[-73.33649,43.62686],[-73.43811,43.57117],[-73.35571,43.77182],[-73.4436,44.07055],[-73.3255,44.25969],[-73.35025,45.00942],[-74.32699,44.99029],[-74.66689,45.00646],[-74.8447,45.00606],[-74.99101,44.98051],[-75.01363,44.95608],[-75.2193,44.87821],[-75.41441,44.76614],[-75.76813,44.51537],[-75.8217,44.43176],[-75.95947,44.34463],[-76.00018,44.34896],[-76.16285,44.28262],[-76.1664,44.23051],[-76.244,44.19643],[-76.31222,44.19894],[-76.35324,44.13493],[-76.43859,44.09393],[-76.79706,43.63099],[-79.25796,43.54052],[-79.06921,43.26183],[-79.05512,43.25375],[-79.05544,43.21224],[-79.05002,43.20133],[-79.05384,43.17418],[-79.04652,43.16396],[-79.0427,43.13934],[-79.06881,43.12029],[-79.05671,43.10937],[-79.07486,43.07845],[-79.01055,43.06659],[-78.99941,43.05612],[-79.02424,43.01983],[-79.02074,42.98444],[-78.98126,42.97],[-78.96312,42.95509],[-78.93224,42.95229],[-78.90905,42.93022],[-78.90712,42.89733],[-78.93684,42.82887],[-79.77073,42.55308]]]}},{"type":"Feature","properties":{"id":"US-NC"},"geometry":{"type":"Polygon","coordinates":[[[-84.32551,34.99393],[-83.10796,35.0011],[-82.39746,35.20044],[-81.04889,35.15105],[-81.04889,35.04993],[-80.9198,35.08815],[-80.79346,34.94193],[-80.78796,34.82252],[-79.68109,34.81124],[-77.99552,33.38485],[-74.86753,35.41538],[-75.79776,36.55091],[-80.30148,36.54837],[-81.66962,36.58987],[-81.72455,36.33806],[-81.82617,36.36682],[-82.06238,36.11872],[-82.22992,36.16086],[-82.57324,35.96103],[-82.64191,36.06989],[-82.97424,35.78744],[-83.13904,35.76961],[-83.50159,35.56433],[-83.74603,35.56209],[-84.0097,35.4324],[-84.03717,35.29129],[-84.1333,35.24419],[-84.22943,35.27335],[-84.28711,35.224],[-84.32551,34.99393]]]}},{"type":"Feature","properties":{"id":"US-PA"},"geometry":{"type":"Polygon","coordinates":[[[-80.53581,42.29896],[-80.51902,40.63803],[-80.52292,39.72222],[-79.47663,39.72086],[-75.78987,39.72204],[-75.77476,39.7223],[-75.76,39.75002],[-75.74043,39.77378],[-75.72532,39.78644],[-75.71434,39.79515],[-75.68172,39.81387],[-75.65975,39.82337],[-75.62713,39.83259],[-75.59898,39.83734],[-75.57632,39.83945],[-75.53959,39.83945],[-75.49942,39.83365],[-75.46783,39.82548],[-75.43796,39.81414],[-75.41621,39.80165],[-75.33745,39.84842],[-75.26809,39.85014],[-75.16905,39.88294],[-75.13986,39.88716],[-75.12785,39.91073],[-75.13815,39.93627],[-75.13334,39.95786],[-75.09901,39.97443],[-75.0712,39.97969],[-75.04682,40.01099],[-75.01352,40.0202],[-74.97164,40.05279],[-74.9246,40.07224],[-74.91224,40.06987],[-74.8628,40.08432],[-74.83774,40.10244],[-74.82641,40.12633],[-74.81542,40.1287],[-74.7907,40.12187],[-74.75843,40.13447],[-74.74127,40.13473],[-74.72341,40.14864],[-74.72273,40.16045],[-74.73852,40.17855],[-74.75843,40.18774],[-74.76701,40.2095],[-74.78349,40.2234],[-74.82504,40.24069],[-74.84426,40.25013],[-74.86315,40.28837],[-74.89198,40.31246],[-74.91396,40.3177],[-74.94451,40.34152],[-74.94966,40.36611],[-74.96477,40.39592],[-74.98743,40.40664],[-75.03137,40.40534],[-75.06124,40.4218],[-75.07017,40.45525],[-75.06365,40.48581],[-75.06708,40.5388],[-75.10347,40.56984],[-75.12682,40.57453],[-75.14776,40.57453],[-75.16458,40.56332],[-75.18106,40.56619],[-75.1948,40.57844],[-75.19068,40.59435],[-75.19994,40.61259],[-75.19102,40.62093],[-75.19068,40.63865],[-75.20029,40.64881],[-75.18003,40.66939],[-75.20372,40.691],[-75.18175,40.73107],[-75.19617,40.75084],[-75.17076,40.77893],[-75.133,40.77373],[-75.08219,40.82726],[-75.09935,40.84804],[-75.06777,40.84804],[-75.05266,40.8657],[-75.13849,40.98347],[-75.02931,41.03995],[-74.88237,41.1848],[-74.83431,41.28136],[-74.76152,41.33913],[-74.6956,41.35872],[-74.74274,41.42288],[-74.98718,41.48258],[-75.0531,41.59155],[-75.08057,41.80278],[-75.3772,42.00515],[-79.76349,42.00107],[-79.77073,42.55308],[-80.53581,42.29896]]]}},{"type":"Feature","properties":{"id":"US-OR"},"geometry":{"type":"Polygon","coordinates":[[[-125.69978,42.00605],[-120.0016,41.99495],[-117.02619,42.00013],[-117.02923,43.83121],[-116.99215,43.8629],[-116.96194,43.91734],[-116.97704,43.96282],[-116.93859,43.98654],[-116.93722,44.03198],[-116.97704,44.05172],[-116.97429,44.08921],[-116.94271,44.09513],[-116.89602,44.15526],[-116.90151,44.17792],[-116.97155,44.19565],[-116.97841,44.24387],[-117.18304,44.26453],[-117.22149,44.30238],[-117.18921,44.34266],[-117.24003,44.37408],[-117.22492,44.48392],[-117.15626,44.53093],[-117.05051,44.74298],[-116.9379,44.78588],[-116.83353,44.92995],[-116.85825,44.97563],[-116.84864,45.02321],[-116.75388,45.11342],[-116.67972,45.3185],[-116.46274,45.60746],[-116.54789,45.7533],[-116.77585,45.82129],[-116.91799,45.99567],[-118.98743,46.00052],[-119.1378,45.92797],[-119.26826,45.94086],[-119.4928,45.90647],[-119.6109,45.92654],[-119.67064,45.85772],[-119.96658,45.82375],[-120.16502,45.7663],[-120.21103,45.72701],[-120.50079,45.69537],[-120.56053,45.74043],[-120.63538,45.74714],[-120.89493,45.65219],[-121.08307,45.65075],[-121.14899,45.60609],[-121.19156,45.61282],[-121.21284,45.66802],[-121.34674,45.70592],[-121.41266,45.69489],[-121.53008,45.7227],[-121.71478,45.69489],[-121.81366,45.71215],[-121.90097,45.67502],[-121.9891,45.62074],[-122.14899,45.58514],[-122.23595,45.55275],[-122.32384,45.54697],[-122.38014,45.5739],[-122.43919,45.5638],[-122.47456,45.57942],[-122.67609,45.61786],[-122.76501,45.65747],[-122.77668,45.68745],[-122.76157,45.7378],[-122.76501,45.76654],[-122.79591,45.81203],[-122.78492,45.86704],[-122.81445,45.91627],[-122.81033,45.96068],[-122.87762,46.03414],[-122.8941,46.07797],[-122.96688,46.10654],[-123.00945,46.13605],[-123.13442,46.18647],[-123.17837,46.18694],[-123.28754,46.14367],[-123.38093,46.14842],[-123.43243,46.18219],[-123.42968,46.23351],[-123.47431,46.26864],[-123.58349,46.25583],[-123.87806,46.23588],[-123.92818,46.23968],[-124.02981,46.30281],[-124.03873,46.26295],[-124.14997,46.26295],[-125.2772,46.2631],[-125.69978,42.00605]]]}},{"type":"Feature","properties":{"id":"CN-SH"},"geometry":{"type":"Polygon","coordinates":[[[120.85475,31.10938],[120.89836,31.09028],[120.89424,31.01822],[120.98659,31.01939],[120.98865,30.89603],[121.03122,30.82265],[121.12529,30.86509],[121.12152,30.78018],[121.21456,30.78726],[121.26434,30.68516],[123.5458,31.01942],[122.29378,31.76513],[121.76147,31.63818],[121.44286,31.76086],[121.30554,31.88338],[121.09954,31.75853],[121.3821,31.54723],[121.25335,31.47933],[121.23722,31.49704],[121.14246,31.44492],[121.15447,31.41108],[121.11173,31.37459],[121.12581,31.30348],[121.14057,31.31038],[121.15722,31.28515],[121.1495,31.27752],[121.11808,31.28529],[121.06006,31.27356],[121.05903,31.23658],[121.07276,31.16345],[121.03671,31.14171],[120.88325,31.14083],[120.85475,31.10938]]]}},{"type":"Feature","properties":{"id":"US-WA"},"geometry":{"type":"Polygon","coordinates":[[[-125.2772,46.2631],[-124.14997,46.26295],[-124.03873,46.26295],[-124.02981,46.30281],[-123.92818,46.23968],[-123.87806,46.23588],[-123.58349,46.25583],[-123.47431,46.26864],[-123.42968,46.23351],[-123.43243,46.18219],[-123.38093,46.14842],[-123.28754,46.14367],[-123.17837,46.18694],[-123.13442,46.18647],[-123.00945,46.13605],[-122.96688,46.10654],[-122.8941,46.07797],[-122.87762,46.03414],[-122.81033,45.96068],[-122.81445,45.91627],[-122.78492,45.86704],[-122.79591,45.81203],[-122.76501,45.76654],[-122.76157,45.7378],[-122.77668,45.68745],[-122.76501,45.65747],[-122.67609,45.61786],[-122.47456,45.57942],[-122.43919,45.5638],[-122.38014,45.5739],[-122.32384,45.54697],[-122.23595,45.55275],[-122.14899,45.58514],[-121.9891,45.62074],[-121.90097,45.67502],[-121.81366,45.71215],[-121.71478,45.69489],[-121.53008,45.7227],[-121.41266,45.69489],[-121.34674,45.70592],[-121.21284,45.66802],[-121.19156,45.61282],[-121.14899,45.60609],[-121.08307,45.65075],[-120.89493,45.65219],[-120.63538,45.74714],[-120.56053,45.74043],[-120.50079,45.69537],[-120.21103,45.72701],[-120.16502,45.7663],[-119.96658,45.82375],[-119.67064,45.85772],[-119.6109,45.92654],[-119.4928,45.90647],[-119.26826,45.94086],[-119.1378,45.92797],[-118.98743,46.00052],[-116.91799,45.99567],[-116.94958,46.07004],[-116.98116,46.08242],[-116.92348,46.16048],[-117.03472,46.34138],[-117.04811,46.34281],[-117.06184,46.34873],[-117.06287,46.3665],[-117.04914,46.37787],[-117.03575,46.40794],[-117.03644,46.42309],[-117.04021,46.4257],[-117.03266,49.00056],[-123.32163,49.00419],[-123.0093,48.83186],[-123.0093,48.76586],[-123.26565,48.6959],[-123.15614,48.35395],[-123.50039,48.21223],[-125.03842,48.53282],[-125.2772,46.2631]]]}},{"type":"Feature","properties":{"id":"US-OK"},"geometry":{"type":"Polygon","coordinates":[[[-103.00462,36.99417],[-103.00325,36.50047],[-100.00134,36.50078],[-99.99928,34.56197],[-99.9725,34.56197],[-99.95464,34.5778],[-99.92443,34.57836],[-99.76444,34.42841],[-99.71638,34.40462],[-99.71226,34.38932],[-99.66557,34.37515],[-99.59965,34.37629],[-99.58523,34.38989],[-99.58111,34.41821],[-99.50489,34.41198],[-99.43554,34.37515],[-99.39915,34.37799],[-99.39434,34.44257],[-99.37717,34.45899],[-99.23916,34.36439],[-99.18354,34.22029],[-99.04415,34.20042],[-98.98579,34.22313],[-98.75164,34.1277],[-98.64452,34.1635],[-98.58616,34.15384],[-98.49277,34.06572],[-98.409,34.09074],[-98.37879,34.15384],[-98.16662,34.11462],[-98.12061,34.15725],[-98.08834,34.13111],[-98.12061,34.07653],[-98.08697,34.00483],[-97.95033,33.99459],[-97.98191,33.89547],[-97.87067,33.85043],[-97.81368,33.87552],[-97.68116,33.99117],[-97.59258,33.95701],[-97.59327,33.90687],[-97.55138,33.89832],[-97.49783,33.92169],[-97.45251,33.89718],[-97.45731,33.83218],[-97.40513,33.82135],[-97.3605,33.82648],[-97.30762,33.88521],[-97.26849,33.85899],[-97.23553,33.91713],[-97.1854,33.90402],[-97.16686,33.84473],[-97.20394,33.81735],[-97.18334,33.75115],[-97.15038,33.72317],[-97.09888,33.72603],[-97.08515,33.75857],[-97.09614,33.80252],[-97.05221,33.82252],[-97.08515,33.85614],[-97.02691,33.84657],[-96.98215,33.89376],[-96.99245,33.93365],[-96.93958,33.95871],[-96.90113,33.94163],[-96.86954,33.85386],[-96.81118,33.87267],[-96.75762,33.82648],[-96.70887,33.8396],[-96.6663,33.91599],[-96.58733,33.89262],[-96.62441,33.85157],[-96.57497,33.82021],[-96.52622,33.82591],[-96.507,33.77342],[-96.42735,33.78026],[-96.35044,33.68661],[-96.32023,33.7049],[-96.29002,33.7757],[-96.22959,33.75743],[-96.18565,33.75743],[-96.16367,33.82135],[-95.93296,33.88749],[-95.84232,33.84416],[-95.57041,33.93992],[-95.54295,33.89661],[-95.43034,33.87381],[-95.28477,33.88521],[-95.2216,33.96726],[-95.10349,33.92397],[-94.88651,33.76657],[-94.48448,33.64004],[-94.43092,35.38371],[-94.61906,36.49995],[-94.61795,36.9986],[-102.04214,36.99314],[-103.00462,36.99417]]]}},{"type":"Feature","properties":{"id":"US-TX"},"geometry":{"type":"Polygon","coordinates":[[[-106.64522,31.89178],[-106.60333,31.82938],[-106.5436,31.80546],[-106.529,31.784],[-106.52266,31.77509],[-106.51251,31.76922],[-106.50962,31.76155],[-106.50111,31.75714],[-106.48815,31.74769],[-106.47298,31.75054],[-106.46726,31.75998],[-106.45244,31.76523],[-106.43419,31.75478],[-106.41773,31.75196],[-106.38003,31.73151],[-106.3718,31.71165],[-106.34864,31.69663],[-106.33419,31.66303],[-106.30305,31.62154],[-106.28084,31.56173],[-106.24612,31.54193],[-106.23711,31.51262],[-106.20346,31.46305],[-106.09025,31.40569],[-106.00363,31.39181],[-104.77674,30.4236],[-104.5171,29.64671],[-104.3969,29.57105],[-104.39363,29.55396],[-104.37752,29.54255],[-103.15787,28.93865],[-102.60596,29.8192],[-101.47277,29.7744],[-101.05686,29.44738],[-101.01128,29.36947],[-100.96725,29.3477],[-100.94579,29.34523],[-100.94056,29.33371],[-100.87982,29.296],[-100.79696,29.24688],[-100.67294,29.09744],[-100.63689,28.90812],[-100.59809,28.88197],[-100.52313,28.75598],[-100.5075,28.74066],[-100.51222,28.70679],[-100.50029,28.66117],[-99.55409,27.61314],[-99.51478,27.55836],[-99.52955,27.49747],[-99.50208,27.50021],[-99.48045,27.49016],[-99.482,27.47128],[-99.49744,27.43746],[-99.53573,27.30926],[-99.08477,26.39849],[-99.03053,26.41249],[-99.00546,26.3925],[-98.35126,26.15129],[-98.30491,26.10475],[-98.27075,26.09457],[-98.24603,26.07191],[-97.97017,26.05232],[-97.95155,26.0625],[-97.66511,26.01708],[-97.52025,25.88518],[-97.49828,25.89877],[-97.45669,25.86874],[-97.42511,25.83969],[-97.37332,25.83854],[-97.35946,25.92189],[-97.13927,25.96583],[-96.92418,25.97377],[-93.77551,29.43998],[-93.92382,29.81005],[-93.71508,30.05521],[-93.70959,30.28791],[-93.76452,30.33771],[-93.52008,31.03684],[-93.92932,31.91524],[-94.04467,32.00379],[-94.04366,33.01929],[-94.0464,33.55539],[-94.07661,33.57828],[-94.38423,33.56455],[-94.48448,33.64004],[-94.88651,33.76657],[-95.10349,33.92397],[-95.2216,33.96726],[-95.28477,33.88521],[-95.43034,33.87381],[-95.54295,33.89661],[-95.57041,33.93992],[-95.84232,33.84416],[-95.93296,33.88749],[-96.16367,33.82135],[-96.18565,33.75743],[-96.22959,33.75743],[-96.29002,33.7757],[-96.32023,33.7049],[-96.35044,33.68661],[-96.42735,33.78026],[-96.507,33.77342],[-96.52622,33.82591],[-96.57497,33.82021],[-96.62441,33.85157],[-96.58733,33.89262],[-96.6663,33.91599],[-96.70887,33.8396],[-96.75762,33.82648],[-96.81118,33.87267],[-96.86954,33.85386],[-96.90113,33.94163],[-96.93958,33.95871],[-96.99245,33.93365],[-96.98215,33.89376],[-97.02691,33.84657],[-97.08515,33.85614],[-97.05221,33.82252],[-97.09614,33.80252],[-97.08515,33.75857],[-97.09888,33.72603],[-97.15038,33.72317],[-97.18334,33.75115],[-97.20394,33.81735],[-97.16686,33.84473],[-97.1854,33.90402],[-97.23553,33.91713],[-97.26849,33.85899],[-97.30762,33.88521],[-97.3605,33.82648],[-97.40513,33.82135],[-97.45731,33.83218],[-97.45251,33.89718],[-97.49783,33.92169],[-97.55138,33.89832],[-97.59327,33.90687],[-97.59258,33.95701],[-97.68116,33.99117],[-97.81368,33.87552],[-97.87067,33.85043],[-97.98191,33.89547],[-97.95033,33.99459],[-98.08697,34.00483],[-98.12061,34.07653],[-98.08834,34.13111],[-98.12061,34.15725],[-98.16662,34.11462],[-98.37879,34.15384],[-98.409,34.09074],[-98.49277,34.06572],[-98.58616,34.15384],[-98.64452,34.1635],[-98.75164,34.1277],[-98.98579,34.22313],[-99.04415,34.20042],[-99.18354,34.22029],[-99.23916,34.36439],[-99.37717,34.45899],[-99.39434,34.44257],[-99.39915,34.37799],[-99.43554,34.37515],[-99.50489,34.41198],[-99.58111,34.41821],[-99.58523,34.38989],[-99.59965,34.37629],[-99.66557,34.37515],[-99.71226,34.38932],[-99.71638,34.40462],[-99.76444,34.42841],[-99.92443,34.57836],[-99.95464,34.5778],[-99.9725,34.56197],[-99.99928,34.56197],[-100.00134,36.50078],[-103.00325,36.50047],[-103.04239,36.49992],[-103.06402,31.99986],[-106.61981,32.00074],[-106.62187,31.92151],[-106.64522,31.89178]]]}},{"type":"Feature","properties":{"id":"US-OH"},"geometry":{"type":"Polygon","coordinates":[[[-84.81884,39.10708],[-84.74887,39.14851],[-84.68432,39.09844],[-84.62252,39.07392],[-84.56622,39.08671],[-84.54631,39.10163],[-84.51747,39.09151],[-84.49893,39.0995],[-84.47695,39.12188],[-84.4488,39.11922],[-84.4337,39.09577],[-84.43026,39.05739],[-84.41035,39.0446],[-84.34924,39.0382],[-84.30117,38.99445],[-84.29293,38.95334],[-84.23388,38.88176],[-84.23388,38.81331],[-84.07183,38.77263],[-83.95648,38.78762],[-83.79443,38.69765],[-83.7752,38.65047],[-83.66534,38.62902],[-83.62414,38.67621],[-83.52801,38.70408],[-83.33575,38.64618],[-83.31652,38.60112],[-83.27533,38.59897],[-83.24511,38.63116],[-83.20117,38.61614],[-83.14898,38.62258],[-83.10778,38.67621],[-83.0556,38.69336],[-83.02951,38.72872],[-82.97869,38.72765],[-82.89492,38.7555],[-82.8702,38.73943],[-82.87844,38.69121],[-82.84549,38.58502],[-82.79879,38.56355],[-82.72601,38.55603],[-82.61203,38.47329],[-82.59692,38.42382],[-82.54406,38.39937],[-82.31884,38.45101],[-82.28588,38.59283],[-82.17876,38.59713],[-82.21722,38.80933],[-82.14306,38.83714],[-82.1513,38.89488],[-82.08813,38.9782],[-82.02496,39.02943],[-81.93707,38.98888],[-81.90136,38.92694],[-81.93157,38.89702],[-81.89587,38.8735],[-81.84368,38.9013],[-81.83544,38.94831],[-81.76403,38.91839],[-81.74755,38.93762],[-81.786,38.96966],[-81.76128,39.01876],[-81.81622,39.05716],[-81.81622,39.08915],[-81.76952,39.07635],[-81.74206,39.1062],[-81.7503,39.1914],[-81.68987,39.2297],[-81.69537,39.26161],[-81.65417,39.28287],[-81.56902,39.27649],[-81.55529,39.35724],[-81.5086,39.36573],[-81.4674,39.41243],[-81.41796,39.39758],[-81.39874,39.35087],[-81.36303,39.34025],[-81.26141,39.39121],[-81.22021,39.38909],[-81.1845,39.43153],[-81.13232,39.4485],[-81.05541,39.53116],[-80.91534,39.61796],[-80.87139,39.62854],[-80.86384,39.68801],[-80.82813,39.71337],[-80.86555,39.77013],[-80.82092,39.80891],[-80.82436,39.84477],[-80.78899,39.87323],[-80.8065,39.90985],[-80.79655,39.91933],[-80.76702,39.90853],[-80.75329,39.91222],[-80.7605,39.95539],[-80.73818,39.97749],[-80.74265,40.00564],[-80.73097,40.03824],[-80.73681,40.07792],[-80.70591,40.10445],[-80.70763,40.14645],[-80.66917,40.19918],[-80.65475,40.24374],[-80.61871,40.26627],[-80.61733,40.28828],[-80.60017,40.31708],[-80.61253,40.3409],[-80.60944,40.37491],[-80.63313,40.39243],[-80.61356,40.40655],[-80.61424,40.43216],[-80.59776,40.46195],[-80.59639,40.47971],[-80.61287,40.49485],[-80.62935,40.53452],[-80.66608,40.58043],[-80.6345,40.61458],[-80.59948,40.6237],[-80.57837,40.6125],[-80.51902,40.63803],[-80.53581,42.29896],[-82.67862,41.67615],[-83.11184,41.95671],[-83.42355,41.73233],[-84.80645,41.69747],[-84.81884,39.10708]]]}},{"type":"Feature","properties":{"id":"US-RI"},"geometry":{"type":"Polygon","coordinates":[[[-71.85736,41.32188],[-71.6391,40.94332],[-71.10101,41.43444],[-71.13123,41.591],[-71.14153,41.60717],[-71.13432,41.65952],[-71.19577,41.67465],[-71.26135,41.75231],[-71.32898,41.7815],[-71.341,41.79814],[-71.33894,41.89916],[-71.3822,41.89277],[-71.38117,42.0194],[-71.8001,42.00779],[-71.79866,41.41592],[-71.81926,41.41952],[-71.84363,41.40948],[-71.84191,41.39455],[-71.83367,41.38837],[-71.83333,41.37033],[-71.83917,41.3626],[-71.82955,41.34199],[-71.85736,41.32188]]]}},{"type":"Feature","properties":{"id":"US-SC"},"geometry":{"type":"Polygon","coordinates":[[[-83.35447,34.72814],[-83.34829,34.69455],[-83.22916,34.61096],[-83.17148,34.60728],[-83.16873,34.59259],[-83.03655,34.48625],[-83.00085,34.47238],[-82.90231,34.48625],[-82.87519,34.47408],[-82.83365,34.36419],[-82.79657,34.34039],[-82.78043,34.29672],[-82.75057,34.2709],[-82.74095,34.20789],[-82.71658,34.14882],[-82.64311,34.0951],[-82.64105,34.06809],[-82.59538,34.02855],[-82.56414,33.95567],[-82.39008,33.85651],[-82.3015,33.80062],[-82.20022,33.66214],[-82.19747,33.63013],[-82.1343,33.59095],[-82.10752,33.59782],[-82.05019,33.56464],[-81.99766,33.51342],[-81.9877,33.48794],[-81.92968,33.46674],[-81.91354,33.43953],[-81.93964,33.34609],[-81.85587,33.30248],[-81.85037,33.24622],[-81.78858,33.20716],[-81.77553,33.2198],[-81.75974,33.19912],[-81.7721,33.18303],[-81.76248,33.15947],[-81.70824,33.11807],[-81.64163,33.09276],[-81.62103,33.09564],[-81.49538,33.00988],[-81.50087,32.93557],[-81.45555,32.84851],[-81.42809,32.84101],[-81.39581,32.65101],[-81.41847,32.63193],[-81.38277,32.59086],[-81.3244,32.55788],[-81.28595,32.55904],[-81.27771,32.53531],[-81.19257,32.46292],[-81.20767,32.42409],[-81.11772,32.29127],[-81.15823,32.24017],[-81.11978,32.1937],[-81.11635,32.11638],[-81.05386,32.08497],[-81.00511,32.1001],[-80.92066,32.03667],[-80.49837,32.0326],[-77.99552,33.38485],[-79.68109,34.81124],[-80.78796,34.82252],[-80.79346,34.94193],[-80.9198,35.08815],[-81.04889,35.04993],[-81.04889,35.15105],[-82.39746,35.20044],[-83.10796,35.0011],[-83.09869,34.99098],[-83.12616,34.9544],[-83.11689,34.94033],[-83.2374,34.87417],[-83.32357,34.78878],[-83.32048,34.75861],[-83.35447,34.72814]]]}},{"type":"Feature","properties":{"id":"US-TN"},"geometry":{"type":"Polygon","coordinates":[[[-90.31242,34.99989],[-88.20029,34.99532],[-88.20305,35.00664],[-85.60478,34.98639],[-84.32551,34.99393],[-84.28711,35.224],[-84.22943,35.27335],[-84.1333,35.24419],[-84.03717,35.29129],[-84.0097,35.4324],[-83.74603,35.56209],[-83.50159,35.56433],[-83.13904,35.76961],[-82.97424,35.78744],[-82.64191,36.06989],[-82.57324,35.96103],[-82.22992,36.16086],[-82.06238,36.11872],[-81.82617,36.36682],[-81.72455,36.33806],[-81.66962,36.58987],[-81.64833,36.61206],[-81.92299,36.61647],[-81.93466,36.5947],[-83.67455,36.60056],[-83.69109,36.58281],[-86.51355,36.65555],[-86.56848,36.63572],[-86.5932,36.65555],[-87.80993,36.63792],[-88.06536,36.67979],[-88.05987,36.49674],[-89.41668,36.50778],[-89.45127,36.46431],[-89.48972,36.46541],[-89.47187,36.55813],[-89.52268,36.5846],[-89.57212,36.56144],[-89.52268,36.46762],[-89.5474,36.43117],[-89.57212,36.24754],[-89.6916,36.24089],[-89.58997,36.1478],[-89.61332,36.10897],[-89.73701,36.00048],[-89.64638,35.91489],[-89.67384,35.8804],[-89.73564,35.91044],[-89.77409,35.87261],[-89.70131,35.83366],[-89.72878,35.8047],[-89.95399,35.73228],[-89.94301,35.66871],[-89.89357,35.64528],[-90.11604,35.38483],[-90.07072,35.1314],[-90.16136,35.13252],[-90.31242,34.99989]]]}},{"type":"Feature","properties":{"id":"US-VT"},"geometry":{"type":"Polygon","coordinates":[[[-73.4436,44.07055],[-73.35571,43.77182],[-73.43811,43.57117],[-73.33649,43.62686],[-73.25409,43.57117],[-73.26498,42.74494],[-72.45969,42.72515],[-72.49456,42.77368],[-72.51722,42.7636],[-72.51173,42.78174],[-72.54331,42.81147],[-72.55705,42.85427],[-72.55361,42.88497],[-72.53301,42.89553],[-72.52546,42.93626],[-72.53233,42.95134],[-72.46504,42.98099],[-72.46092,43.05479],[-72.43688,43.08388],[-72.441,43.13702],[-72.45611,43.14654],[-72.39362,43.35659],[-72.41491,43.36557],[-72.38127,43.49472],[-72.40049,43.51265],[-72.32702,43.63553],[-72.30093,43.70754],[-72.20617,43.77302],[-72.16291,43.8919],[-72.12309,43.9201],[-72.11141,43.9977],[-72.04,44.08408],[-72.06335,44.27514],[-72.0249,44.31741],[-71.9782,44.33411],[-71.90679,44.34688],[-71.86834,44.33706],[-71.81753,44.35866],[-71.79693,44.39891],[-71.7008,44.41558],[-71.639,44.47343],[-71.59368,44.49302],[-71.59231,44.56351],[-71.56347,44.56351],[-71.54287,44.58601],[-71.63351,44.74912],[-71.57583,44.79592],[-71.55386,44.86214],[-71.49618,44.90788],[-71.54287,44.98758],[-71.50067,45.01357],[-73.35025,45.00942],[-73.3255,44.25969],[-73.4436,44.07055]]]}},{"type":"Feature","properties":{"id":"US-VA"},"geometry":{"type":"Polygon","coordinates":[[[-83.67455,36.60056],[-81.93466,36.5947],[-81.92299,36.61647],[-81.64833,36.61206],[-81.66962,36.58987],[-80.30148,36.54837],[-75.79776,36.55091],[-75.16879,38.02735],[-75.62472,37.99597],[-75.65768,37.94509],[-75.88153,37.90934],[-76.23034,37.8985],[-76.61074,38.15704],[-76.92248,38.23475],[-77.03784,38.42973],[-77.20813,38.35223],[-77.28778,38.38454],[-77.28915,38.50178],[-77.21225,38.6038],[-77.12161,38.63385],[-77.12023,38.68103],[-77.08041,38.70568],[-77.04196,38.70568],[-77.03906,38.79153],[-77.03021,38.86133],[-77.04592,38.87557],[-77.0491,38.87343],[-77.05493,38.87964],[-77.05957,38.88152],[-77.06759,38.89895],[-77.07047,38.90106],[-77.08897,38.90436],[-77.10201,38.91264],[-77.10592,38.91912],[-77.11536,38.92787],[-77.11962,38.93441],[-77.1477,38.9699],[-77.22186,38.97417],[-77.25619,39.00192],[-77.23971,39.02006],[-77.30975,39.05846],[-77.46081,39.07872],[-77.48416,39.11282],[-77.51849,39.12135],[-77.5281,39.14691],[-77.51162,39.18311],[-77.47729,39.18844],[-77.45532,39.22462],[-77.49102,39.25227],[-77.54596,39.27247],[-77.56655,39.30861],[-77.61462,39.3033],[-77.68054,39.32667],[-77.73135,39.32349],[-77.82818,39.13337],[-78.34728,39.46705],[-78.34934,39.42676],[-78.3617,39.40872],[-78.34385,39.38909],[-78.3672,39.35883],[-78.33973,39.35352],[-78.42075,39.25736],[-78.40084,39.24566],[-78.43792,39.19725],[-78.40496,39.16851],[-78.5725,39.03156],[-78.55396,39.01716],[-78.6034,38.96539],[-78.62743,38.98408],[-78.69198,38.91519],[-78.71944,38.90557],[-78.71807,38.93602],[-78.7421,38.92748],[-78.75858,38.90183],[-78.78742,38.88794],[-78.86982,38.7633],[-78.99479,38.84998],[-79.09504,38.7092],[-79.08543,38.68133],[-79.10191,38.65345],[-79.12663,38.66418],[-79.21864,38.48918],[-79.30515,38.41282],[-79.47681,38.458],[-79.53587,38.55257],[-79.6471,38.59015],[-79.67319,38.53646],[-79.66221,38.51175],[-79.70066,38.49133],[-79.68967,38.45693],[-79.69517,38.42358],[-79.73362,38.37838],[-79.72538,38.36115],[-79.73911,38.35146],[-79.76383,38.35792],[-79.80915,38.30837],[-79.7858,38.26849],[-79.91901,38.18326],[-79.93412,38.10334],[-80.00278,37.99519],[-80.17994,37.85762],[-80.29667,37.68719],[-80.22251,37.62522],[-80.32413,37.56646],[-80.2953,37.51746],[-80.47245,37.42373],[-80.51228,37.48042],[-80.76633,37.37573],[-80.79243,37.39973],[-80.85835,37.43136],[-80.88306,37.38337],[-80.84873,37.34735],[-80.91602,37.30913],[-80.97782,37.29056],[-80.98606,37.30148],[-81.12339,37.27526],[-81.17695,37.26214],[-81.22776,37.23591],[-81.36372,37.33643],[-81.42002,37.27089],[-81.50242,37.2534],[-81.55735,37.20966],[-81.6782,37.20201],[-81.76334,37.27744],[-81.8581,37.28509],[-81.87595,37.32988],[-81.92814,37.36154],[-81.93775,37.43791],[-81.99268,37.4608],[-81.99543,37.4826],[-81.9405,37.50766],[-81.9707,37.53839],[-82.34698,37.2744],[-82.72326,37.12564],[-82.73425,37.04018],[-82.86059,36.98316],[-82.89904,36.88437],[-83.08032,36.84701],[-83.14074,36.75244],[-83.42125,36.66798],[-83.5239,36.66716],[-83.67455,36.60056]]]}},{"type":"Feature","properties":{"id":"US-WV"},"geometry":{"type":"Polygon","coordinates":[[[-82.64361,38.1673],[-82.63263,38.13922],[-82.46646,37.98569],[-82.49392,37.93372],[-82.41702,37.84593],[-82.33462,37.77758],[-82.29754,37.67656],[-82.17669,37.63416],[-82.13961,37.56235],[-81.9707,37.53839],[-81.9405,37.50766],[-81.99543,37.4826],[-81.99268,37.4608],[-81.93775,37.43791],[-81.92814,37.36154],[-81.87595,37.32988],[-81.8581,37.28509],[-81.76334,37.27744],[-81.6782,37.20201],[-81.55735,37.20966],[-81.50242,37.2534],[-81.42002,37.27089],[-81.36372,37.33643],[-81.22776,37.23591],[-81.17695,37.26214],[-81.12339,37.27526],[-80.98606,37.30148],[-80.97782,37.29056],[-80.91602,37.30913],[-80.84873,37.34735],[-80.88306,37.38337],[-80.85835,37.43136],[-80.79243,37.39973],[-80.76633,37.37573],[-80.51228,37.48042],[-80.47245,37.42373],[-80.2953,37.51746],[-80.32413,37.56646],[-80.22251,37.62522],[-80.29667,37.68719],[-80.17994,37.85762],[-80.00278,37.99519],[-79.93412,38.10334],[-79.91901,38.18326],[-79.7858,38.26849],[-79.80915,38.30837],[-79.76383,38.35792],[-79.73911,38.35146],[-79.72538,38.36115],[-79.73362,38.37838],[-79.69517,38.42358],[-79.68967,38.45693],[-79.70066,38.49133],[-79.66221,38.51175],[-79.67319,38.53646],[-79.6471,38.59015],[-79.53587,38.55257],[-79.47681,38.458],[-79.30515,38.41282],[-79.21864,38.48918],[-79.12663,38.66418],[-79.10191,38.65345],[-79.08543,38.68133],[-79.09504,38.7092],[-78.99479,38.84998],[-78.86982,38.7633],[-78.78742,38.88794],[-78.75858,38.90183],[-78.7421,38.92748],[-78.71807,38.93602],[-78.71944,38.90557],[-78.69198,38.91519],[-78.62743,38.98408],[-78.6034,38.96539],[-78.55396,39.01716],[-78.5725,39.03156],[-78.40496,39.16851],[-78.43792,39.19725],[-78.40084,39.24566],[-78.42075,39.25736],[-78.33973,39.35352],[-78.3672,39.35883],[-78.34385,39.38909],[-78.3617,39.40872],[-78.34934,39.42676],[-78.34728,39.46705],[-77.82818,39.13337],[-77.73135,39.32349],[-77.75289,39.42632],[-77.79821,39.43587],[-77.78036,39.49312],[-77.84216,39.49842],[-77.88885,39.55774],[-77.83392,39.56621],[-77.83392,39.60431],[-77.87512,39.617],[-78.01107,39.60113],[-78.05021,39.64768],[-78.10789,39.68203],[-78.18411,39.69524],[-78.31732,39.59479],[-78.40658,39.617],[-78.46872,39.5167],[-78.66167,39.53576],[-78.72621,39.56356],[-78.73789,39.58632],[-78.76364,39.58262],[-78.77771,39.60457],[-78.73892,39.60775],[-78.73789,39.62388],[-78.77702,39.62177],[-78.76501,39.64715],[-78.79659,39.63472],[-78.81925,39.56065],[-78.83951,39.5678],[-78.96688,39.43958],[-79.0455,39.4804],[-79.06885,39.47643],[-79.19657,39.38733],[-79.21579,39.36424],[-79.25321,39.35575],[-79.29235,39.29865],[-79.31158,39.30502],[-79.33801,39.29652],[-79.35999,39.27526],[-79.37853,39.27261],[-79.42831,39.22448],[-79.48702,39.20187],[-79.47663,39.72086],[-80.52292,39.72222],[-80.51902,40.63803],[-80.57837,40.6125],[-80.59948,40.6237],[-80.6345,40.61458],[-80.66608,40.58043],[-80.62935,40.53452],[-80.61287,40.49485],[-80.59639,40.47971],[-80.59776,40.46195],[-80.61424,40.43216],[-80.61356,40.40655],[-80.63313,40.39243],[-80.60944,40.37491],[-80.61253,40.3409],[-80.60017,40.31708],[-80.61733,40.28828],[-80.61871,40.26627],[-80.65475,40.24374],[-80.66917,40.19918],[-80.70763,40.14645],[-80.70591,40.10445],[-80.73681,40.07792],[-80.73097,40.03824],[-80.74265,40.00564],[-80.73818,39.97749],[-80.7605,39.95539],[-80.75329,39.91222],[-80.76702,39.90853],[-80.79655,39.91933],[-80.8065,39.90985],[-80.78899,39.87323],[-80.82436,39.84477],[-80.82092,39.80891],[-80.86555,39.77013],[-80.82813,39.71337],[-80.86384,39.68801],[-80.87139,39.62854],[-80.91534,39.61796],[-81.05541,39.53116],[-81.13232,39.4485],[-81.1845,39.43153],[-81.22021,39.38909],[-81.26141,39.39121],[-81.36303,39.34025],[-81.39874,39.35087],[-81.41796,39.39758],[-81.4674,39.41243],[-81.5086,39.36573],[-81.55529,39.35724],[-81.56902,39.27649],[-81.65417,39.28287],[-81.69537,39.26161],[-81.68987,39.2297],[-81.7503,39.1914],[-81.74206,39.1062],[-81.76952,39.07635],[-81.81622,39.08915],[-81.81622,39.05716],[-81.76128,39.01876],[-81.786,38.96966],[-81.74755,38.93762],[-81.76403,38.91839],[-81.83544,38.94831],[-81.84368,38.9013],[-81.89587,38.8735],[-81.93157,38.89702],[-81.90136,38.92694],[-81.93707,38.98888],[-82.02496,39.02943],[-82.08813,38.9782],[-82.1513,38.89488],[-82.14306,38.83714],[-82.21722,38.80933],[-82.17876,38.59713],[-82.28588,38.59283],[-82.31884,38.45101],[-82.54406,38.39937],[-82.59692,38.42382],[-82.59692,38.342],[-82.57495,38.32261],[-82.58319,38.25039],[-82.61203,38.24176],[-82.59692,38.21156],[-82.60791,38.17378],[-82.64361,38.1673]]]}},{"type":"Feature","properties":{"id":"UA-43"},"geometry":{"type":"Polygon","coordinates":[[[31.62627,45.50633],[32.99857,44.48323],[33.28621,44.94345],[33.5643,44.84057],[33.5849,44.80794],[33.60275,44.81086],[33.6776,44.78577],[33.68172,44.77017],[33.61305,44.75018],[33.61649,44.71237],[33.72772,44.71579],[33.7751,44.68968],[33.71502,44.62081],[33.73528,44.60199],[33.77853,44.6125],[33.92616,44.42082],[33.85784,44.41886],[33.76171,44.38918],[33.66142,43.9825],[36.61884,44.89556],[36.52546,45.20215],[36.68476,45.40306],[36.66828,45.63016],[35.23066,45.79231],[34.96015,45.75634],[34.79905,45.81009],[34.80153,45.90047],[34.75479,45.90705],[34.66679,45.97136],[34.60861,45.99347],[34.55889,45.99347],[34.52011,45.95097],[34.48729,45.94267],[34.44155,45.95995],[34.41221,46.00245],[34.33912,46.06114],[34.25111,46.0532],[34.181,46.06804],[34.12929,46.10494],[34.07311,46.11769],[34.05272,46.10838],[33.91549,46.15938],[33.85234,46.19863],[33.79715,46.20482],[33.74047,46.18555],[33.646,46.23028],[33.61517,46.22615],[33.63854,46.14147],[33.61467,46.13561],[33.57318,46.10317],[33.59087,46.06013],[33.54017,46.0123],[31.62627,45.50633]]]}},{"type":"Feature","properties":{"id":"UA-40"},"geometry":{"type":"Polygon","coordinates":[[[32.99857,44.48323],[33.66142,43.9825],[33.76171,44.38918],[33.85784,44.41886],[33.92616,44.42082],[33.77853,44.6125],[33.73528,44.60199],[33.71502,44.62081],[33.7751,44.68968],[33.72772,44.71579],[33.61649,44.71237],[33.61305,44.75018],[33.68172,44.77017],[33.6776,44.78577],[33.60275,44.81086],[33.5849,44.80794],[33.5643,44.84057],[33.28621,44.94345],[32.99857,44.48323]]]}},{"type":"Feature","properties":{"id":"NL-BQ1"},"geometry":{"type":"Polygon","coordinates":[[[-68.90012,12.62309],[-68.33524,11.78151],[-68.01417,11.77722],[-67.89186,12.4116],[-68.90012,12.62309]]]}},{"type":"Feature","properties":{"id":"CN-GS"},"geometry":{"type":"Polygon","coordinates":[[[92.40874,39.03625],[93.11599,39.17372],[93.42086,38.9092],[94.35607,38.76265],[94.5346,38.35781],[94.99053,38.43638],[95.24459,38.30502],[95.65658,38.36857],[96.29859,38.15669],[96.65702,38.22901],[96.66595,38.48665],[97.05459,38.6284],[96.9358,38.9108],[96.97769,39.20884],[97.3368,39.16733],[98.08937,38.78513],[98.24867,38.88515],[98.28643,39.03358],[98.74923,39.08743],[100.17677,38.2112],[100.09815,38.45735],[100.93105,38.16749],[100.97019,38.01293],[101.3578,37.7916],[101.9878,37.73108],[102.64594,37.10447],[102.47325,36.97238],[102.72319,36.76886],[102.59651,36.71081],[102.71598,36.60009],[102.82859,36.37098],[102.83168,36.33531],[102.88936,36.33338],[102.92026,36.30073],[103.02394,36.25562],[102.97004,36.03299],[102.9467,35.83507],[102.70568,35.86011],[102.80456,35.5758],[102.75169,35.49533],[102.50381,35.58808],[102.3191,35.34369],[102.40218,35.18503],[101.72996,34.70436],[102.15499,34.51221],[102.25318,34.36441],[101.76841,34.06233],[100.94581,34.37404],[100.7611,34.17545],[101.19232,33.79455],[101.17034,33.65463],[101.58782,33.67349],[101.61254,33.51506],[101.76223,33.46925],[101.94625,33.58773],[101.81579,33.10937],[102.46879,33.47211],[102.14332,33.98379],[102.3912,33.97753],[102.45849,34.09929],[102.66792,34.07541],[102.89039,34.33266],[103.17672,34.07484],[103.16162,33.7974],[103.77891,33.66606],[104.10026,33.68435],[104.28634,33.35978],[104.45526,33.32938],[104.33921,33.1979],[104.4326,33.00636],[104.40238,32.79189],[105.11032,32.60004],[105.39321,32.72433],[105.43647,32.94875],[105.47878,32.89406],[105.85945,32.93896],[105.96244,33.15652],[105.72624,33.36322],[105.95764,33.61061],[106.36688,33.61347],[106.51519,33.50246],[106.58523,33.57],[106.41357,33.89777],[106.71295,34.37092],[106.64188,34.38651],[106.6175,34.44797],[106.47399,34.52183],[106.3322,34.51532],[106.33186,34.55972],[106.5612,34.74443],[106.48635,35.05754],[106.76788,35.09238],[107.05833,35.02887],[107.18604,34.9062],[107.8466,34.97487],[107.7079,35.30896],[107.84248,35.26524],[108.58886,35.31176],[108.64654,35.95021],[108.6589,36.41023],[107.34878,36.90378],[107.30346,37.0979],[106.66076,37.19751],[106.49047,36.30848],[106.9313,36.12456],[106.921,35.76824],[106.44241,35.69466],[106.4994,35.35993],[106.36344,35.23889],[106.05857,35.48639],[105.48454,35.72756],[105.32592,35.99911],[105.51544,36.0996],[105.18997,36.95208],[104.29321,37.4367],[103.83865,37.65773],[103.39507,37.88352],[103.36074,38.08809],[103.54476,38.15615],[104.18884,39.12047],[103.9389,39.46482],[102.96798,39.10981],[102.45712,39.23757],[101.8872,39.06931],[101.7279,38.64154],[100.84075,39.18224],[99.70229,39.98659],[100.28045,40.67439],[99.76958,40.97575],[98.3139,40.56806],[97.1777,42.7964],[96.37926,42.72055],[96.04934,42.38796],[96.18324,41.97225],[95.35171,41.54559],[95.19103,41.7498],[94.80789,41.53428],[93.76556,40.66605],[92.92785,40.58058],[92.40874,39.03625]]]}},{"type":"Feature","properties":{"id":"NL-BQ2"},"geometry":{"type":"Polygon","coordinates":[[[-63.58819,17.61311],[-63.22932,17.32592],[-63.07669,17.79659],[-63.29212,17.90532],[-63.58819,17.61311]]]}},{"type":"Feature","properties":{"id":"IN-DL"},"geometry":{"type":"Polygon","coordinates":[[[76.83915,28.58301],[76.84584,28.55037],[76.86249,28.54487],[76.87391,28.5282],[76.88738,28.51998],[76.88043,28.50543],[76.89116,28.50037],[76.89657,28.50686],[76.90206,28.50671],[76.90635,28.51395],[76.92034,28.50678],[76.95334,28.50509],[76.97845,28.5213],[76.99111,28.51365],[76.9969,28.51949],[77.00982,28.51466],[77.01703,28.52104],[77.01476,28.52398],[77.00098,28.53114],[77.00544,28.53947],[77.0139,28.54068],[77.02424,28.5328],[77.03209,28.53118],[77.04344,28.52513],[77.0434,28.52409],[77.04862,28.52107],[77.0463,28.5167],[77.05226,28.51512],[77.05746,28.51297],[77.06093,28.51225],[77.06428,28.51285],[77.06703,28.51199],[77.07153,28.51787],[77.07235,28.52025],[77.07505,28.51877],[77.08003,28.51815],[77.09265,28.51434],[77.09863,28.51146],[77.09575,28.50713],[77.09775,28.50493],[77.11973,28.4952],[77.11277,28.4731],[77.13076,28.43984],[77.14043,28.43848],[77.14651,28.43692],[77.16161,28.42922],[77.17208,28.40559],[77.17389,28.40446],[77.17818,28.40921],[77.22058,28.41344],[77.24169,28.42763],[77.24628,28.4496],[77.24101,28.45616],[77.23156,28.45609],[77.23483,28.46982],[77.24298,28.47917],[77.26238,28.48762],[77.26991,28.48791],[77.27527,28.49358],[77.28832,28.49673],[77.30053,28.49419],[77.30053,28.49007],[77.30855,28.48823],[77.31413,28.4837],[77.32563,28.49004],[77.34615,28.51651],[77.29886,28.55723],[77.29293,28.57634],[77.29916,28.58772],[77.30422,28.58587],[77.31049,28.59085],[77.31332,28.59661],[77.3246,28.59789],[77.33066,28.60098],[77.33645,28.60174],[77.3419,28.60524],[77.34087,28.62299],[77.31594,28.64152],[77.31988,28.65188],[77.32027,28.66234],[77.32551,28.67827],[77.32997,28.67861],[77.33345,28.68147],[77.32409,28.69864],[77.33207,28.71317],[77.3134,28.71366],[77.29971,28.71008],[77.29628,28.70526],[77.29036,28.70602],[77.2865,28.7143],[77.29083,28.72273],[77.28688,28.7248],[77.27667,28.73564],[77.26057,28.73564],[77.25547,28.73861],[77.25658,28.7444],[77.26006,28.75039],[77.25512,28.7558],[77.24886,28.75524],[77.23839,28.75908],[77.20659,28.78451],[77.20418,28.80527],[77.20985,28.81429],[77.2229,28.82091],[77.21157,28.8573],[77.17457,28.85865],[77.15681,28.8367],[77.14282,28.83858],[77.14616,28.85572],[77.13406,28.86301],[77.12265,28.8573],[77.11063,28.86918],[77.09166,28.87098],[77.08316,28.88315],[77.07939,28.87135],[77.06171,28.86963],[77.04282,28.8355],[76.99398,28.84068],[76.98077,28.82113],[76.97064,28.82783],[76.96146,28.81474],[76.95116,28.81798],[76.94292,28.79955],[76.95433,28.79045],[76.94807,28.78097],[76.95579,28.76841],[76.94403,28.75419],[76.95811,28.7432],[76.96068,28.73161],[76.94832,28.71264],[76.96781,28.69917],[76.95776,28.68448],[76.95502,28.66988],[76.93751,28.66942],[76.92378,28.64999],[76.94601,28.63289],[76.93528,28.61865],[76.91725,28.63395],[76.90738,28.62393],[76.8903,28.63274],[76.86429,28.58602],[76.83915,28.58301]]]}},{"type":"Feature","properties":{"id":"NO-21"},"geometry":{"type":"Polygon","coordinates":[[[-3.52068,82.6752],[16.4353,73.61229],[33.12005,75.46568],[35.22046,80.57056],[-3.52068,82.6752]]]}},{"type":"Feature","properties":{"id":"NO-22"},"geometry":{"type":"Polygon","coordinates":[[[-10.71459,70.09565],[-5.93364,70.76368],[-9.68082,72.73731],[-10.71459,70.09565]]]}},{"type":"Feature","properties":{"id":"IN-GJ"},"geometry":{"type":"Polygon","coordinates":[[[68.11329,23.53945],[68.83233,21.42207],[70.8467,20.44438],[70.87331,20.73203],[71.00154,20.74648],[72.83901,20.48555],[72.90801,20.43087],[72.89291,20.36748],[72.47526,20.38318],[72.4768,20.16425],[72.80021,20.12622],[72.8754,20.22869],[72.9808,20.21323],[72.92346,20.26348],[72.94578,20.35331],[73.12156,20.36909],[73.18508,20.29407],[73.06766,20.21806],[73.06354,20.18487],[73.171,20.19744],[73.23383,20.14266],[73.29048,20.1549],[73.29769,20.20453],[73.4333,20.2055],[73.44978,20.71726],[73.6695,20.56208],[73.7495,20.5624],[73.88854,20.72946],[73.93901,20.73588],[73.91635,20.92232],[73.7325,21.10163],[73.58573,21.15591],[73.74538,21.14279],[73.74315,21.16568],[73.83447,21.19337],[73.83619,21.26953],[73.94897,21.29737],[74.01712,21.42047],[74.05265,21.41983],[74.06776,21.48118],[74.11085,21.44492],[74.26328,21.46265],[74.33332,21.50945],[74.30911,21.5655],[74.21161,21.53101],[74.10724,21.5639],[73.85662,21.49939],[73.79379,21.62041],[73.83636,21.84684],[74.14947,21.95323],[74.17282,22.06846],[74.07909,22.24652],[74.08149,22.35896],[74.27787,22.38373],[74.05677,22.48115],[74.26929,22.64633],[74.36714,22.62858],[74.47769,22.86004],[74.3201,23.0573],[74.24182,23.19244],[73.99017,23.33405],[73.89953,23.33248],[73.83172,23.44749],[73.64135,23.4393],[73.6211,23.66024],[73.35639,23.77591],[73.42231,23.92601],[73.37425,24.13359],[73.2431,24.00319],[73.0783,24.20829],[73.2328,24.36476],[73.00277,24.48777],[72.97084,24.34866],[72.74116,24.35491],[72.69996,24.44527],[72.50083,24.40088],[72.44144,24.49214],[72.18292,24.60894],[71.09405,24.69017],[70.97594,24.60904],[71.00341,24.46038],[71.12838,24.42662],[71.04461,24.34657],[70.94985,24.3791],[70.85784,24.30903],[70.88393,24.27398],[70.71502,24.23517],[70.57906,24.27774],[70.5667,24.43787],[70.11712,24.30915],[70.03428,24.172],[69.73335,24.17007],[69.59579,24.29777],[69.29778,24.28712],[69.19341,24.25646],[69.07806,24.29777],[68.97781,24.26021],[68.90914,24.33156],[68.7416,24.31904],[68.74643,23.97027],[68.39339,23.96838],[68.20763,23.85849],[68.11329,23.53945]]]}},{"type":"Feature","properties":{"id":"SO"},"geometry":{"type":"Polygon","coordinates":[[[40.98767,2.82959],[41.00099,-0.83068],[41.56,-1.59812],[41.56362,-1.66375],[41.75542,-1.85308],[49.16337,2.78611],[52.253,11.68582],[51.12877,12.56479],[48.95249,11.56816],[43.42425,11.70983],[42.95776,10.98533],[42.69452,10.62672],[42.87643,10.18441],[43.0937,9.90579],[43.23518,9.84605],[43.32613,9.59205],[44.19222,8.93028],[46.99339,7.9989],[47.92477,8.00111],[47.97917,8.00124],[44.98104,4.91821],[44.02436,4.9451],[43.40263,4.79289],[43.04177,4.57923],[42.97746,4.44032],[42.84526,4.28357],[42.55853,4.20518],[42.07619,4.17667],[41.89488,3.97375],[41.31368,3.14314],[40.98767,2.82959]]]}},{"type":"Feature","properties":{"id":"CN-SX"},"geometry":{"type":"Polygon","coordinates":[[[110.2272,34.90733],[110.23921,34.62784],[110.41122,34.58432],[110.8905,34.65354],[111.1576,34.81831],[111.22695,34.79294],[111.57508,34.84649],[111.82228,35.07159],[112.03994,35.04517],[112.05505,35.27981],[112.76916,35.20635],[113.02802,35.35937],[113.48945,35.52943],[113.60961,35.67626],[113.57597,35.81614],[113.65287,35.83507],[113.72909,36.36103],[113.59554,36.4616],[113.47297,36.6976],[113.78917,36.88071],[113.74488,37.0738],[114.09851,37.58594],[114.127,37.69387],[114.02984,37.72972],[113.82797,38.16263],[113.55194,38.23871],[113.53683,38.50787],[113.84101,38.76854],[113.75518,38.94499],[113.94676,39.09489],[114.3402,39.07997],[114.5613,39.55276],[114.39376,39.60568],[114.41093,39.83121],[113.89114,40.0192],[114.54482,40.3366],[114.30519,40.36695],[114.28527,40.51327],[114.1246,40.74569],[114.0652,40.67634],[114.07001,40.54093],[113.93783,40.50544],[113.85234,40.44511],[113.6721,40.4425],[113.53443,40.3345],[113.31504,40.31304],[113.24809,40.41349],[112.88761,40.32822],[112.84572,40.20169],[112.73963,40.1626],[112.61947,40.23891],[112.45399,40.29995],[112.30293,40.25463],[112.10758,39.97527],[111.97059,39.78822],[111.91909,39.61468],[111.72615,39.59537],[111.67121,39.62525],[111.53217,39.65698],[111.43295,39.64006],[111.4199,39.50245],[111.36188,39.47489],[111.33235,39.42081],[111.21288,39.42638],[111.12945,39.4025],[111.11881,39.36403],[111.19228,39.30508],[111.23897,39.30003],[111.1576,39.10741],[111.09134,39.02985],[111.04637,39.02158],[110.97495,38.97836],[111.00963,38.90706],[110.95745,38.75836],[110.88775,38.65522],[110.87333,38.45842],[110.80192,38.44713],[110.5149,38.20905],[110.49636,38.02862],[110.58357,37.92578],[110.77377,37.62946],[110.74665,37.45169],[110.39474,36.99816],[110.4895,36.56039],[110.43594,36.1606],[110.61035,35.64948],[110.40572,35.30728],[110.36041,35.139],[110.2272,34.90733]]]}},{"type":"Feature","properties":{"id":"IN-ML"},"geometry":{"type":"Polygon","coordinates":[[[89.81208,25.37244],[89.84086,25.31854],[89.83371,25.29548],[89.87629,25.28337],[89.90478,25.31038],[90.1155,25.22686],[90.40034,25.1534],[90.65042,25.17788],[90.87427,25.15799],[91.25517,25.20677],[91.63648,25.12846],[92.0316,25.1834],[92.33957,25.07593],[92.39147,25.01471],[92.79464,25.21612],[92.6477,25.57465],[92.13958,25.69846],[92.30438,26.06788],[91.94732,25.99755],[91.84432,26.10982],[91.24969,25.71887],[90.95443,25.95001],[90.61729,25.87714],[90.48065,26.0031],[90.10642,25.96113],[89.89906,25.73867],[90.01922,25.60314],[89.89562,25.5635],[89.81208,25.37244]]]}},{"type":"Feature","properties":{"id":"IN-TN"},"geometry":{"type":"Polygon","coordinates":[[[76.23344,11.51871],[76.53934,11.35079],[76.43531,11.19456],[76.7237,11.20736],[76.6492,10.924],[76.81777,10.86163],[76.84112,10.81138],[76.8988,10.77327],[76.85691,10.68051],[76.87236,10.63226],[76.80679,10.63159],[76.82327,10.3237],[76.96403,10.221],[77.21465,10.36423],[77.27645,10.13382],[77.20298,10.11759],[77.25997,10.02971],[77.24693,9.80447],[77.16865,9.61632],[77.42065,9.51543],[77.15045,9.01496],[77.26135,8.843],[77.17655,8.7385],[77.27954,8.52296],[77.20024,8.50734],[77.22358,8.44758],[76.72283,7.82138],[77.66782,7.85769],[79.37385,8.98767],[79.45362,9.159],[79.42124,9.80115],[80.48418,10.20786],[80.42198,10.81981],[79.8088,10.81374],[79.68658,10.99107],[80.41717,10.96613],[80.35262,11.6751],[79.59525,11.86735],[79.70031,12.10378],[80.31898,12.0091],[80.67259,13.46443],[80.32104,13.44372],[80.29632,13.37626],[80.2153,13.48512],[80.02784,13.52718],[79.92484,13.33884],[79.77996,13.21254],[79.53414,13.30944],[79.36832,13.30711],[79.40025,13.142],[79.2152,13.13063],[79.14997,13.00422],[78.84681,13.07613],[78.63292,12.97143],[78.46401,12.61454],[78.2151,12.68991],[78.23295,12.76526],[78.12309,12.76861],[78.08678,12.83146],[78.03322,12.85406],[78.00215,12.80359],[77.97005,12.83105],[77.95349,12.85966],[77.94782,12.8354],[77.91975,12.82828],[77.93683,12.88192],[77.83281,12.86151],[77.79247,12.84092],[77.81032,12.82987],[77.78062,12.76928],[77.79384,12.74768],[77.7662,12.73663],[77.76277,12.72658],[77.77582,12.72273],[77.76329,12.6956],[77.73994,12.69962],[77.74114,12.67065],[77.71196,12.6817],[77.71265,12.66395],[77.67943,12.65625],[77.67514,12.68363],[77.60089,12.66579],[77.58853,12.51803],[77.63523,12.49088],[77.61806,12.36649],[77.48931,12.2766],[77.45738,12.20681],[77.725,12.17963],[77.77925,12.112],[77.72724,12.05409],[77.67917,11.94898],[77.49704,11.9426],[77.46665,11.84887],[77.42906,11.76199],[77.25465,11.81241],[77.12059,11.71863],[76.98772,11.81291],[76.97193,11.77628],[76.91013,11.79308],[76.84249,11.66938],[76.85623,11.59506],[76.61281,11.60717],[76.539,11.69123],[76.42948,11.66568],[76.37145,11.59136],[76.23722,11.58699],[76.23344,11.51871]]]}},{"type":"Feature","properties":{"id":"TJ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[67.33226,39.23739],[67.67833,39.14479],[67.68915,39.00775],[68.09704,39.02589],[68.19743,38.85985],[68.06948,38.82115],[68.12877,38.73677],[68.05598,38.71641],[68.0807,38.64136],[68.05873,38.56087],[68.11366,38.47169],[68.06274,38.39435],[68.13289,38.40822],[68.40343,38.19484],[68.27159,37.91477],[68.12635,37.93],[67.81566,37.43107],[67.8474,37.31594],[67.78329,37.1834],[67.7803,37.08978],[67.87917,37.0591],[68.02194,36.91923],[68.18542,37.02074],[68.27605,37.00977],[68.29253,37.10621],[68.41201,37.10402],[68.41888,37.13906],[68.61851,37.19815],[68.6798,37.27906],[68.81438,37.23862],[68.80889,37.32494],[68.91189,37.26704],[68.88168,37.33368],[68.96407,37.32603],[69.03274,37.25174],[69.25152,37.09426],[69.39529,37.16752],[69.45022,37.23315],[69.36645,37.40462],[69.44954,37.4869],[69.51888,37.5844],[69.80041,37.5746],[69.84435,37.60616],[69.93362,37.61378],[69.95971,37.5659],[70.15015,37.52519],[70.28243,37.66706],[70.27694,37.81258],[70.1863,37.84296],[70.17206,37.93276],[70.4898,38.12546],[70.54673,38.24541],[70.60407,38.28046],[70.61526,38.34774],[70.64966,38.34999],[70.69189,38.37031],[70.6761,38.39144],[70.67438,38.40597],[70.69807,38.41861],[70.72485,38.4131],[70.75455,38.4252],[70.77132,38.45548],[70.78581,38.45502],[70.78702,38.45031],[70.79766,38.44944],[70.80521,38.44447],[70.81697,38.44507],[70.82538,38.45394],[70.84376,38.44688],[70.88719,38.46826],[70.92728,38.43021],[70.98693,38.48862],[71.03545,38.44779],[71.0556,38.40176],[71.09542,38.42517],[71.10592,38.42077],[71.10957,38.40671],[71.1451,38.40106],[71.21291,38.32797],[71.33114,38.30339],[71.33869,38.27335],[71.37803,38.25641],[71.36444,38.15358],[71.29878,38.04429],[71.28922,38.01272],[71.27622,37.99946],[71.27278,37.96496],[71.24969,37.93031],[71.2809,37.91995],[71.296,37.93403],[71.32871,37.88564],[71.51565,37.95349],[71.58843,37.92425],[71.59255,37.79956],[71.55752,37.78677],[71.54324,37.77104],[71.53053,37.76534],[71.55234,37.73209],[71.54186,37.69691],[71.51972,37.61945],[71.5065,37.60912],[71.49693,37.53527],[71.50616,37.50733],[71.5256,37.47971],[71.49612,37.4279],[71.47685,37.40281],[71.4862,37.33405],[71.49821,37.31975],[71.50674,37.31502],[71.48536,37.26017],[71.4824,37.24921],[71.48339,37.23937],[71.47386,37.2269],[71.4555,37.21418],[71.4494,37.18137],[71.44127,37.11856],[71.43097,37.05855],[71.45578,37.03094],[71.46923,36.99925],[71.48481,36.93218],[71.51502,36.89128],[71.57195,36.74943],[71.67083,36.67346],[71.83229,36.68084],[72.31676,36.98115],[72.54095,37.00007],[72.66381,37.02014],[72.79693,37.22222],[73.06884,37.31729],[73.29633,37.46495],[73.77197,37.4417],[73.76647,37.33913],[73.61129,37.27469],[73.64974,37.23643],[73.82552,37.22659],[73.8564,37.26158],[74.20308,37.34208],[74.23339,37.41116],[74.41055,37.3948],[74.56161,37.37734],[74.68383,37.3948],[74.8294,37.3435],[74.88887,37.23275],[75.12328,37.31839],[75.09719,37.37297],[75.15899,37.41443],[75.06011,37.52779],[74.94338,37.55501],[74.8912,37.67576],[75.00935,37.77486],[74.92416,37.83428],[74.9063,38.03033],[74.82665,38.07359],[74.80331,38.19889],[74.69894,38.22155],[74.69619,38.42947],[74.51217,38.47034],[74.17022,38.65504],[73.97933,38.52945],[73.79806,38.61106],[73.80656,38.66449],[73.7033,38.84782],[73.7445,38.93867],[73.82964,38.91517],[73.81728,39.04007],[73.75823,39.023],[73.60638,39.24534],[73.54572,39.27567],[73.55396,39.3543],[73.5004,39.38402],[73.59241,39.40843],[73.59831,39.46425],[73.45096,39.46677],[73.31912,39.38615],[73.18454,39.35536],[72.85934,39.35116],[72.62027,39.39696],[72.33173,39.33093],[72.23834,39.17248],[72.17242,39.2661],[72.09689,39.26823],[72.04059,39.36704],[71.90601,39.27674],[71.79202,39.27355],[71.7522,39.32031],[71.80164,39.40631],[71.76816,39.45456],[71.62688,39.44056],[71.5517,39.45722],[71.55856,39.57588],[71.49814,39.61397],[71.08752,39.50704],[71.06418,39.41586],[70.7854,39.38933],[70.64087,39.58792],[70.44757,39.60128],[70.2869,39.53141],[70.11111,39.58223],[69.87491,39.53882],[69.68677,39.59281],[69.3594,39.52516],[69.26938,39.8127],[69.35649,40.01994],[69.43134,39.98431],[69.43557,39.92877],[69.53615,39.93991],[69.5057,40.03277],[69.53855,40.0887],[69.53794,40.11833],[69.55555,40.12296],[69.57615,40.10524],[69.64704,40.12165],[69.67001,40.10639],[70.01283,40.23288],[70.58297,40.00891],[70.57384,39.99394],[70.47557,39.93216],[70.55033,39.96619],[70.58912,39.95211],[70.65946,39.9878],[70.65827,40.0981],[70.7928,40.12797],[70.80495,40.16813],[70.9818,40.22392],[70.8607,40.217],[70.62342,40.17396],[70.56394,40.26421],[70.57149,40.3442],[70.37511,40.38605],[70.32626,40.45174],[70.49871,40.52503],[70.80009,40.72825],[70.45251,41.04438],[70.38028,41.02014],[70.36655,40.90296],[69.69434,40.62615],[69.59441,40.70181],[69.53021,40.77621],[69.38327,40.7918],[69.32834,40.70233],[69.3455,40.57988],[69.2643,40.57506],[69.21063,40.54469],[69.27066,40.49274],[69.28525,40.41894],[69.30774,40.36102],[69.33794,40.34819],[69.32833,40.29794],[69.30808,40.2821],[69.24817,40.30357],[69.25229,40.26362],[69.30104,40.24502],[69.30448,40.18774],[69.2074,40.21488],[69.15659,40.2162],[69.04544,40.22904],[68.85832,40.20885],[68.84357,40.18604],[68.79276,40.17555],[68.77902,40.20492],[68.5332,40.14826],[68.52771,40.11676],[68.62796,40.07789],[69.01523,40.15771],[69.01935,40.11466],[68.96579,40.06949],[68.84906,40.04952],[68.93695,39.91167],[68.88889,39.87163],[68.63071,39.85265],[68.61972,39.68905],[68.54166,39.53929],[68.12053,39.56317],[67.70992,39.66156],[67.62889,39.60234],[67.44899,39.57799],[67.46547,39.53564],[67.39681,39.52505],[67.46822,39.46146],[67.45998,39.315],[67.36522,39.31287],[67.33226,39.23739]]],[[[70.52631,39.86989],[70.54998,39.85137],[70.59667,39.83542],[70.63105,39.77923],[70.74189,39.86319],[70.53651,39.89155],[70.52631,39.86989]]],[[[70.54223,40.98787],[70.57501,40.98941],[70.6721,40.90555],[70.68112,40.90612],[70.6158,40.97661],[70.56077,41.00642],[70.54223,40.98787]]]]}},{"type":"Feature","properties":{"id":"US"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-179.55295,50.81807],[-133.92876,54.62289],[-130.61931,54.70835],[-130.64499,54.76912],[-130.44184,54.85377],[-130.27203,54.97174],[-130.18765,55.07744],[-130.08035,55.21556],[-129.97513,55.28029],[-130.15373,55.74895],[-130.00857,55.91344],[-130.00093,56.00325],[-130.10173,56.12178],[-130.33965,56.10849],[-130.77769,56.36185],[-131.8271,56.62247],[-133.38523,58.42773],[-133.84645,58.73543],[-134.27175,58.8634],[-134.48059,59.13231],[-134.55699,59.1297],[-134.7047,59.2458],[-135.00267,59.28745],[-135.03069,59.56208],[-135.48007,59.79937],[-136.31566,59.59083],[-136.22381,59.55526],[-136.33727,59.44466],[-136.47323,59.46617],[-136.52365,59.16752],[-136.82619,59.16198],[-137.4925,58.89415],[-137.60623,59.24465],[-138.62145,59.76431],[-138.71149,59.90728],[-139.05365,59.99655],[-139.20603,60.08896],[-139.05831,60.35205],[-139.68991,60.33693],[-139.98024,60.18027],[-140.45648,60.30919],[-140.5227,60.22077],[-141.00116,60.30648],[-141.00555,72.20369],[-168.25765,71.99091],[-168.95635,65.98512],[-169.03888,65.48473],[-172.76104,63.77445],[-179.55295,57.62081],[-179.55295,50.81807]]],[[[-179.2458,29.18869],[-179.23433,18.15359],[-154.13058,18.17333],[-154.14205,29.20682],[-176.83456,29.19028],[-177.8563,29.18961],[-179.2458,29.18869]]],[[[-177.43928,1.65656],[-177.43039,-1.43294],[-175.33482,-1.40631],[-175.33167,1.67574],[-177.43928,1.65656]]],[[[-174.18596,-12.48057],[-171.14953,-12.4725],[-171.14262,-14.93704],[-167.73854,-14.92809],[-167.75195,-10.12005],[-174.17993,-10.13616],[-174.18596,-12.48057]]],[[[-169.97341,16.32808],[-169.02347,16.32808],[-169.02347,17.13856],[-169.97341,17.13856],[-169.97341,16.32808]]],[[[-163.24994,7.12322],[-163.24478,5.24198],[-161.06795,5.2462],[-161.0731,7.1291],[-163.24994,7.12322]]],[[[-161.05669,1.11722],[-161.04969,-1.36251],[-158.62058,-1.35506],[-158.62734,1.1296],[-161.05669,1.11722]]],[[[-125.69978,42.00605],[-122.18305,33.57011],[-118.48109,32.5991],[-117.1243,32.53427],[-115.88053,32.63624],[-114.71871,32.71894],[-114.76736,32.64094],[-114.80584,32.62028],[-114.81141,32.55543],[-114.79524,32.55731],[-114.82011,32.49609],[-112.34553,31.7357],[-111.07523,31.33232],[-109.05235,31.3333],[-108.20979,31.33316],[-108.20899,31.78534],[-106.529,31.784],[-106.52266,31.77509],[-106.51251,31.76922],[-106.50962,31.76155],[-106.50111,31.75714],[-106.48815,31.74769],[-106.47298,31.75054],[-106.46726,31.75998],[-106.45244,31.76523],[-106.43419,31.75478],[-106.41773,31.75196],[-106.38003,31.73151],[-106.3718,31.71165],[-106.34864,31.69663],[-106.33419,31.66303],[-106.30305,31.62154],[-106.28084,31.56173],[-106.24612,31.54193],[-106.23711,31.51262],[-106.20346,31.46305],[-106.09025,31.40569],[-106.00363,31.39181],[-104.77674,30.4236],[-104.5171,29.64671],[-104.3969,29.57105],[-104.39363,29.55396],[-104.37752,29.54255],[-103.15787,28.93865],[-102.60596,29.8192],[-101.47277,29.7744],[-101.05686,29.44738],[-101.01128,29.36947],[-100.96725,29.3477],[-100.94579,29.34523],[-100.94056,29.33371],[-100.87982,29.296],[-100.79696,29.24688],[-100.67294,29.09744],[-100.63689,28.90812],[-100.59809,28.88197],[-100.52313,28.75598],[-100.5075,28.74066],[-100.51222,28.70679],[-100.50029,28.66117],[-99.55409,27.61314],[-99.51478,27.55836],[-99.52955,27.49747],[-99.50208,27.50021],[-99.48045,27.49016],[-99.482,27.47128],[-99.49744,27.43746],[-99.53573,27.30926],[-99.08477,26.39849],[-99.03053,26.41249],[-99.00546,26.3925],[-98.35126,26.15129],[-98.30491,26.10475],[-98.27075,26.09457],[-98.24603,26.07191],[-97.97017,26.05232],[-97.95155,26.0625],[-97.66511,26.01708],[-97.52025,25.88518],[-97.49828,25.89877],[-97.45669,25.86874],[-97.42511,25.83969],[-97.37332,25.83854],[-97.35946,25.92189],[-97.13927,25.96583],[-96.92418,25.97377],[-93.77551,29.43998],[-88.93054,28.25639],[-88.37952,30.00457],[-87.51915,30.07055],[-83.18732,24.36791],[-82.02215,24.23074],[-80.16442,23.44484],[-79.36558,27.02964],[-81.34929,30.71298],[-80.49837,32.0326],[-77.99552,33.38485],[-74.86753,35.41538],[-75.79776,36.55091],[-75.16879,38.02735],[-74.98718,38.4507],[-73.81773,39.66512],[-71.6391,40.94332],[-71.10101,41.43444],[-69.97282,40.56828],[-69.42513,41.52748],[-70.04999,42.81005],[-67.16117,44.20069],[-66.93432,44.82597],[-66.96824,44.83078],[-66.98249,44.87071],[-66.96824,44.90965],[-67.0216,44.95333],[-67.11316,45.11176],[-67.15965,45.16179],[-67.19603,45.16771],[-67.20349,45.1722],[-67.22751,45.16344],[-67.27039,45.1934],[-67.29748,45.18173],[-67.29754,45.14865],[-67.34927,45.122],[-67.48201,45.27351],[-67.42394,45.37969],[-67.50578,45.48971],[-67.42144,45.50584],[-67.43815,45.59162],[-67.6049,45.60725],[-67.80705,45.69528],[-67.80653,45.80022],[-67.75654,45.82324],[-67.80961,45.87531],[-67.75196,45.91814],[-67.78111,45.9392],[-67.78578,47.06473],[-67.87993,47.10377],[-67.94843,47.1925],[-68.23244,47.35712],[-68.37458,47.35851],[-68.38332,47.28723],[-68.57914,47.28431],[-68.60575,47.24659],[-68.70125,47.24399],[-68.89222,47.1807],[-69.05039,47.2456],[-69.05073,47.30076],[-69.05148,47.42012],[-69.22119,47.46461],[-69.99966,46.69543],[-70.05812,46.41768],[-70.18547,46.35357],[-70.29078,46.18832],[-70.23855,46.1453],[-70.31025,45.96424],[-70.24694,45.95138],[-70.25976,45.89675],[-70.41523,45.79497],[-70.38934,45.73215],[-70.54019,45.67291],[-70.68516,45.56964],[-70.72651,45.49771],[-70.62518,45.42286],[-70.65383,45.37592],[-70.78372,45.43269],[-70.82638,45.39828],[-70.80236,45.37444],[-70.84816,45.22698],[-70.89864,45.2398],[-70.91169,45.29849],[-70.95193,45.33895],[-71.0107,45.34819],[-71.01866,45.31573],[-71.08364,45.30623],[-71.14568,45.24128],[-71.19723,45.25438],[-71.22338,45.25184],[-71.29371,45.29996],[-71.37133,45.24624],[-71.44252,45.2361],[-71.40364,45.21382],[-71.42778,45.12624],[-71.48735,45.07784],[-71.50067,45.01357],[-73.35025,45.00942],[-74.32699,44.99029],[-74.66689,45.00646],[-74.8447,45.00606],[-74.99101,44.98051],[-75.01363,44.95608],[-75.2193,44.87821],[-75.41441,44.76614],[-75.76813,44.51537],[-75.8217,44.43176],[-75.95947,44.34463],[-76.00018,44.34896],[-76.16285,44.28262],[-76.1664,44.23051],[-76.244,44.19643],[-76.31222,44.19894],[-76.35324,44.13493],[-76.43859,44.09393],[-76.79706,43.63099],[-79.25796,43.54052],[-79.06921,43.26183],[-79.05512,43.25375],[-79.05544,43.21224],[-79.05002,43.20133],[-79.05384,43.17418],[-79.04652,43.16396],[-79.0427,43.13934],[-79.06881,43.12029],[-79.05671,43.10937],[-79.07486,43.07845],[-79.01055,43.06659],[-78.99941,43.05612],[-79.02424,43.01983],[-79.02074,42.98444],[-78.98126,42.97],[-78.96312,42.95509],[-78.93224,42.95229],[-78.90905,42.93022],[-78.90712,42.89733],[-78.93684,42.82887],[-79.77073,42.55308],[-80.53581,42.29896],[-82.67862,41.67615],[-83.11184,41.95671],[-83.14962,42.04089],[-83.12724,42.2376],[-83.09837,42.28877],[-83.07837,42.30978],[-83.02253,42.33045],[-82.82964,42.37355],[-82.64242,42.55594],[-82.58873,42.54984],[-82.57583,42.5718],[-82.51858,42.611],[-82.51063,42.66025],[-82.46613,42.76615],[-82.4826,42.8068],[-82.45331,42.93139],[-82.4253,42.95423],[-82.4146,42.97626],[-82.42469,42.992],[-82.48419,45.30225],[-83.59589,45.82131],[-83.43746,45.99749],[-83.57017,46.105],[-83.83329,46.12169],[-83.90453,46.05922],[-83.95399,46.05634],[-84.1096,46.23987],[-84.09756,46.25512],[-84.11615,46.2681],[-84.11254,46.32329],[-84.13451,46.39218],[-84.11196,46.50248],[-84.12885,46.53068],[-84.17723,46.52753],[-84.1945,46.54061],[-84.2264,46.53337],[-84.26351,46.49508],[-84.29893,46.49127],[-84.34174,46.50683],[-84.42101,46.49853],[-84.4481,46.48972],[-84.47607,46.45225],[-84.55635,46.45974],[-84.85871,46.88881],[-88.37033,48.30586],[-89.48837,48.01412],[-89.57972,48.00023],[-89.77248,48.02607],[-89.89974,47.98109],[-90.07418,48.11043],[-90.56312,48.09488],[-90.56444,48.12184],[-90.75045,48.09143],[-90.87588,48.2484],[-91.08016,48.18096],[-91.25025,48.08522],[-91.43248,48.04912],[-91.45829,48.07454],[-91.58025,48.04339],[-91.55649,48.10611],[-91.70451,48.11805],[-91.71231,48.19875],[-91.86125,48.21278],[-91.98929,48.25409],[-92.05339,48.35958],[-92.14732,48.36578],[-92.202,48.35252],[-92.26662,48.35651],[-92.30939,48.31251],[-92.27167,48.25046],[-92.37185,48.22259],[-92.48147,48.36609],[-92.45588,48.40624],[-92.50712,48.44921],[-92.65606,48.43471],[-92.71323,48.46081],[-92.69927,48.49573],[-92.62747,48.50278],[-92.6342,48.54133],[-92.7287,48.54005],[-92.94973,48.60866],[-93.25391,48.64266],[-93.33946,48.62787],[-93.3712,48.60599],[-93.39758,48.60364],[-93.40693,48.60948],[-93.44472,48.59147],[-93.47022,48.54357],[-93.66382,48.51845],[-93.79267,48.51631],[-93.80939,48.52439],[-93.80676,48.58232],[-93.83288,48.62745],[-93.85769,48.63284],[-94.23215,48.65202],[-94.25104,48.65729],[-94.25172,48.68404],[-94.27153,48.70232],[-94.4174,48.71049],[-94.44258,48.69223],[-94.53826,48.70216],[-94.54885,48.71543],[-94.58903,48.71803],[-94.69335,48.77883],[-94.69669,48.80918],[-94.70486,48.82365],[-94.70087,48.8339],[-94.687,48.84077],[-94.75017,49.09931],[-94.77355,49.11998],[-94.82487,49.29483],[-94.8159,49.32299],[-94.85381,49.32492],[-94.95681,49.37035],[-94.99532,49.36579],[-95.01419,49.35647],[-95.05825,49.35311],[-95.12903,49.37056],[-95.15357,49.384],[-95.15355,48.9996],[-97.24024,48.99952],[-101.36198,48.99935],[-104.05004,48.99925],[-110.0051,48.99901],[-114.0683,48.99885],[-116.04938,48.99999],[-117.03266,49.00056],[-123.32163,49.00419],[-123.0093,48.83186],[-123.0093,48.76586],[-123.26565,48.6959],[-123.15614,48.35395],[-123.50039,48.21223],[-125.03842,48.53282],[-125.2772,46.2631],[-125.69978,42.00605]]],[[[-75.27909,18.17213],[-74.76465,18.06252],[-74.7289,18.71009],[-75.24866,18.6531],[-75.27909,18.17213]]],[[[-68.20301,17.83927],[-65.27974,17.56928],[-64.35558,17.48384],[-64.646,18.10286],[-64.64067,18.36478],[-64.86049,18.39954],[-65.02435,18.73231],[-67.99519,18.97186],[-68.20301,17.83927]]],[[[143.82485,13.92273],[144.61642,12.82462],[146.25931,13.85876],[146.6755,21.00809],[144.18594,21.03576],[143.82485,13.92273]]],[[[166.27257,19.60026],[166.27567,19.02484],[166.94111,19.02804],[166.93801,19.60345],[166.27257,19.60026]]],[[[171.97544,51.06331],[180,51.0171],[180,53.34113],[172.01045,53.385],[171.97544,51.06331]]]]}},{"type":"Feature","properties":{"id":"UZ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[55.97584,44.99322],[56.00314,41.32584],[57.03423,41.25435],[57.13796,41.36625],[57.03359,41.41777],[56.96218,41.80383],[57.03633,41.92043],[57.30275,42.14076],[57.6296,42.16519],[57.84932,42.18555],[57.92897,42.24047],[57.90975,42.4374],[57.99214,42.50021],[58.3492,42.43335],[58.40688,42.29535],[58.51674,42.30348],[58.29427,42.56497],[58.14321,42.62159],[58.27504,42.69632],[58.57991,42.64988],[58.6266,42.79314],[58.93422,42.5407],[59.17317,42.52248],[59.2955,42.37064],[59.4341,42.29738],[59.94633,42.27655],[60.00539,42.212],[59.96419,42.1428],[60.04659,42.08982],[60.0356,42.01028],[59.95046,41.97966],[60.33223,41.75058],[60.08504,41.80997],[60.06032,41.76287],[60.18117,41.60082],[60.06581,41.4363],[60.5078,41.21694],[61.03261,41.25691],[61.22212,41.14946],[61.33199,41.14946],[61.39732,41.19873],[61.4446,41.29407],[61.87856,41.12257],[62.11751,40.58242],[62.34273,40.43206],[62.43337,39.98528],[63.6913,39.27666],[63.70778,39.22349],[64.19086,38.95561],[64.32576,38.98691],[65.55873,38.29052],[65.83913,38.25733],[66.24013,38.16238],[66.41042,38.02403],[66.56697,38.0435],[66.67684,37.96776],[66.53676,37.80084],[66.52852,37.58568],[66.65761,37.45497],[66.52303,37.39827],[66.55743,37.35409],[66.64699,37.32958],[66.95598,37.40162],[67.08232,37.35469],[67.13039,37.27168],[67.2224,37.24545],[67.2581,37.17216],[67.51868,37.26102],[67.78329,37.1834],[67.8474,37.31594],[67.81566,37.43107],[68.12635,37.93],[68.27159,37.91477],[68.40343,38.19484],[68.13289,38.40822],[68.06274,38.39435],[68.11366,38.47169],[68.05873,38.56087],[68.0807,38.64136],[68.05598,38.71641],[68.12877,38.73677],[68.06948,38.82115],[68.19743,38.85985],[68.09704,39.02589],[67.68915,39.00775],[67.67833,39.14479],[67.33226,39.23739],[67.36522,39.31287],[67.45998,39.315],[67.46822,39.46146],[67.39681,39.52505],[67.46547,39.53564],[67.44899,39.57799],[67.62889,39.60234],[67.70992,39.66156],[68.12053,39.56317],[68.54166,39.53929],[68.61972,39.68905],[68.63071,39.85265],[68.88889,39.87163],[68.93695,39.91167],[68.84906,40.04952],[68.96579,40.06949],[69.01935,40.11466],[69.01523,40.15771],[68.62796,40.07789],[68.52771,40.11676],[68.5332,40.14826],[68.77902,40.20492],[68.79276,40.17555],[68.84357,40.18604],[68.85832,40.20885],[69.04544,40.22904],[69.15659,40.2162],[69.2074,40.21488],[69.30448,40.18774],[69.30104,40.24502],[69.25229,40.26362],[69.24817,40.30357],[69.30808,40.2821],[69.32833,40.29794],[69.33794,40.34819],[69.30774,40.36102],[69.28525,40.41894],[69.27066,40.49274],[69.21063,40.54469],[69.2643,40.57506],[69.3455,40.57988],[69.32834,40.70233],[69.38327,40.7918],[69.53021,40.77621],[69.59441,40.70181],[69.69434,40.62615],[70.36655,40.90296],[70.38028,41.02014],[70.45251,41.04438],[70.80009,40.72825],[70.49871,40.52503],[70.32626,40.45174],[70.37511,40.38605],[70.57149,40.3442],[70.56394,40.26421],[70.62342,40.17396],[70.8607,40.217],[70.9818,40.22392],[70.95789,40.28761],[71.05901,40.28765],[71.13042,40.34106],[71.36663,40.31593],[71.4246,40.28619],[71.51215,40.26943],[71.51549,40.22986],[71.61725,40.20615],[71.61931,40.26775],[71.68386,40.26984],[71.70569,40.20391],[71.69621,40.18492],[71.71719,40.17886],[71.73054,40.14818],[71.82646,40.21872],[71.85002,40.25647],[72.05464,40.27586],[71.96401,40.31907],[72.18648,40.49893],[72.24368,40.46091],[72.40346,40.4007],[72.44191,40.48222],[72.41513,40.50856],[72.38384,40.51535],[72.41714,40.55736],[72.34406,40.60144],[72.40517,40.61917],[72.47795,40.5532],[72.66713,40.5219],[72.66713,40.59076],[72.69579,40.59778],[72.73995,40.58409],[72.74768,40.58051],[72.74862,40.57131],[72.75982,40.57273],[72.74894,40.59592],[72.74866,40.60873],[72.80137,40.67856],[72.84754,40.67229],[72.85372,40.7116],[72.8722,40.71111],[72.93296,40.73089],[72.99133,40.76457],[73.0612,40.76678],[73.13412,40.79122],[73.13267,40.83512],[73.01869,40.84681],[72.94454,40.8094],[72.84291,40.85512],[72.68157,40.84942],[72.59136,40.86947],[72.55109,40.96046],[72.48742,40.97136],[72.45206,41.03018],[72.38511,41.02785],[72.36138,41.04384],[72.34757,41.06104],[72.34026,41.04539],[72.324,41.03381],[72.18339,40.99571],[72.17594,41.02377],[72.21061,41.05607],[72.1792,41.10621],[72.14864,41.13363],[72.17594,41.15522],[72.16433,41.16483],[72.10745,41.15483],[72.07249,41.11739],[71.85964,41.19081],[71.91457,41.2982],[71.83914,41.3546],[71.76625,41.4466],[71.71132,41.43012],[71.73054,41.54713],[71.65914,41.49599],[71.6787,41.42111],[71.57227,41.29175],[71.46688,41.31883],[71.43814,41.19644],[71.46148,41.13958],[71.40198,41.09436],[71.34877,41.16807],[71.27187,41.11015],[71.25813,41.18796],[71.11806,41.15359],[71.02193,41.19494],[70.9615,41.16393],[70.86263,41.23833],[70.77885,41.24813],[70.78572,41.36419],[70.67586,41.47953],[70.48909,41.40335],[70.17682,41.5455],[70.69777,41.92554],[71.28719,42.18033],[71.13263,42.28356],[70.94483,42.26238],[69.49545,41.545],[69.45751,41.56863],[69.39485,41.51518],[69.45081,41.46246],[69.37468,41.46555],[69.35554,41.47211],[69.29778,41.43673],[69.25059,41.46693],[69.23332,41.45847],[69.22671,41.46298],[69.20439,41.45391],[69.18528,41.45175],[69.17701,41.43769],[69.15137,41.43078],[69.05006,41.36183],[69.01308,41.22804],[68.7217,41.05025],[68.73945,40.96989],[68.65662,40.93861],[68.62221,41.03019],[68.49983,40.99669],[68.58444,40.91447],[68.63,40.59358],[68.49983,40.56437],[67.96736,40.83798],[68.1271,41.0324],[68.08273,41.08148],[67.98511,41.02794],[67.9644,41.14611],[66.69129,41.1311],[66.53302,41.87388],[66.00546,41.94455],[66.09482,42.93426],[65.85194,42.85481],[65.53277,43.31856],[65.18666,43.48835],[64.96464,43.74748],[64.53885,43.56941],[63.34656,43.64003],[62.01711,43.51008],[61.01475,44.41383],[58.59711,45.58671],[55.97842,44.99622],[55.97832,44.99622],[55.97822,44.99617],[55.97811,44.99617],[55.97801,44.99612],[55.97801,44.99607],[55.97791,44.99607],[55.9778,44.99607],[55.9777,44.99601],[55.9777,44.99596],[55.9776,44.99591],[55.97749,44.99591],[55.97739,44.99591],[55.97739,44.99586],[55.97729,44.99586],[55.97718,44.99581],[55.97708,44.99576],[55.97698,44.9957],[55.97698,44.99565],[55.97687,44.9956],[55.97677,44.9956],[55.97677,44.99555],[55.97677,44.9955],[55.97667,44.99545],[55.97656,44.99539],[55.97646,44.99534],[55.97646,44.99529],[55.97636,44.99524],[55.97636,44.99519],[55.97625,44.99514],[55.97615,44.99508],[55.97615,44.99503],[55.97615,44.99498],[55.97615,44.99493],[55.97615,44.99483],[55.97615,44.99477],[55.97605,44.99477],[55.97605,44.99467],[55.97605,44.99462],[55.97605,44.99457],[55.97605,44.99452],[55.97594,44.99446],[55.97584,44.99441],[55.97584,44.99436],[55.97584,44.99431],[55.97584,44.99426],[55.97584,44.99421],[55.97584,44.99415],[55.97584,44.99405],[55.97584,44.994],[55.97584,44.9939],[55.97584,44.99384],[55.97584,44.99374],[55.97584,44.99369],[55.97584,44.99359],[55.97584,44.99353],[55.97584,44.99348],[55.97584,44.99343],[55.97584,44.99338],[55.97584,44.99328],[55.97584,44.99322]],[[70.54223,40.98787],[70.56077,41.00642],[70.6158,40.97661],[70.68112,40.90612],[70.6721,40.90555],[70.57501,40.98941],[70.54223,40.98787]]],[[[71.00236,40.18154],[71.01035,40.05481],[71.11037,40.01984],[71.11668,39.99291],[71.09063,39.99],[71.10501,39.95568],[71.04979,39.89808],[71.10531,39.91354],[71.16101,39.88423],[71.23067,39.93581],[71.1427,39.95026],[71.21139,40.03369],[71.12218,40.03052],[71.06305,40.1771],[71.00236,40.18154]]],[[[71.71511,39.96348],[71.7504,39.93701],[71.84316,39.95582],[71.86463,39.98598],[71.78838,40.01404],[71.71511,39.96348]]]]}},{"type":"Feature","properties":{"id":"ZA"},"geometry":{"type":"Polygon","coordinates":[[[15.70388,-29.23989],[16.22632,-35.03863],[38.88176,-48.03306],[33.10054,-26.92273],[32.89816,-26.8579],[32.35222,-26.86027],[32.29584,-26.852],[32.22302,-26.84136],[32.19409,-26.84032],[32.13315,-26.84345],[32.09664,-26.80721],[32.00893,-26.8096],[31.97463,-27.11057],[31.97592,-27.31675],[31.49834,-27.31549],[31.15027,-27.20151],[30.96088,-27.0245],[30.97757,-26.92706],[30.88826,-26.79622],[30.81101,-26.84722],[30.78927,-26.48271],[30.95819,-26.26303],[31.13073,-25.91558],[31.31237,-25.7431],[31.4175,-25.71886],[31.86881,-25.99973],[31.974,-25.95387],[31.92649,-25.84216],[32.00631,-25.65044],[31.97875,-25.46356],[32.01676,-25.38117],[32.03196,-25.10785],[31.9835,-24.29983],[31.90368,-24.18892],[31.87707,-23.95293],[31.77445,-23.90082],[31.70223,-23.72695],[31.67942,-23.60858],[31.56539,-23.47268],[31.55779,-23.176],[31.30611,-22.422],[31.16344,-22.32599],[31.08932,-22.34884],[30.86696,-22.28907],[30.6294,-22.32599],[30.48686,-22.31368],[30.38614,-22.34533],[30.28351,-22.35587],[30.2265,-22.2961],[30.13147,-22.30841],[29.92242,-22.19408],[29.76848,-22.14128],[29.64609,-22.12917],[29.37703,-22.19581],[29.21955,-22.17771],[29.18974,-22.18599],[29.15268,-22.21399],[29.10881,-22.21202],[29.0151,-22.22907],[28.91889,-22.44299],[28.63287,-22.55887],[28.34874,-22.5694],[28.04562,-22.8394],[28.04752,-22.90243],[27.93729,-22.96194],[27.93539,-23.04941],[27.74154,-23.2137],[27.6066,-23.21894],[27.52393,-23.37952],[27.33768,-23.40917],[26.99749,-23.65486],[26.84165,-24.24885],[26.51667,-24.47219],[26.46346,-24.60358],[26.39409,-24.63468],[25.8515,-24.75727],[25.84295,-24.78661],[25.88571,-24.87802],[25.72702,-25.25503],[25.69661,-25.29284],[25.6643,-25.4491],[25.58543,-25.6343],[25.33076,-25.76616],[25.12266,-25.75931],[25.01718,-25.72507],[24.8946,-25.80723],[24.67319,-25.81749],[24.44703,-25.73021],[24.36531,-25.773],[24.18287,-25.62916],[23.9244,-25.64286],[23.47588,-25.29971],[23.03497,-25.29971],[22.86012,-25.50572],[22.70808,-25.99186],[22.56365,-26.19668],[22.41921,-26.23078],[22.21206,-26.3773],[22.06192,-26.61882],[21.90703,-26.66808],[21.83291,-26.65959],[21.77114,-26.69015],[21.7854,-26.79199],[21.69322,-26.86152],[21.37869,-26.82083],[21.13353,-26.86661],[20.87031,-26.80047],[20.68596,-26.9039],[20.63275,-26.78181],[20.61754,-26.4692],[20.86081,-26.14892],[20.64795,-25.47827],[20.29826,-24.94869],[20.03678,-24.81004],[20.02809,-24.78725],[19.99817,-24.76768],[19.99882,-28.42622],[18.99885,-28.89165],[17.4579,-28.68718],[17.15405,-28.08573],[16.90446,-28.057],[16.59922,-28.53246],[16.46592,-28.57126],[16.45332,-28.63117],[15.70388,-29.23989]],[[27.01016,-29.65439],[27.33464,-29.48161],[27.4358,-29.33465],[27.47254,-29.31968],[27.45125,-29.29708],[27.48679,-29.29349],[27.54258,-29.25575],[27.5158,-29.2261],[27.55974,-29.18954],[27.75458,-28.89839],[27.8907,-28.91612],[27.88933,-28.88156],[27.9392,-28.84864],[27.98675,-28.8787],[28.02503,-28.85991],[28.1317,-28.7293],[28.2348,-28.69471],[28.30518,-28.69531],[28.40612,-28.6215],[28.65091,-28.57025],[28.68043,-28.58744],[29.40524,-29.21246],[29.44883,-29.3772],[29.33204,-29.45598],[29.28545,-29.58456],[29.12553,-29.76266],[29.16548,-29.91706],[28.9338,-30.05072],[28.80222,-30.10579],[28.68627,-30.12885],[28.399,-30.1592],[28.2319,-30.28476],[28.12073,-30.68072],[27.74814,-30.60635],[27.69467,-30.55862],[27.67819,-30.53437],[27.6521,-30.51707],[27.62137,-30.50509],[27.56781,-30.44562],[27.56901,-30.42504],[27.45452,-30.32239],[27.38108,-30.33456],[27.36649,-30.27246],[27.37293,-30.19401],[27.40778,-30.14577],[27.32555,-30.14785],[27.29603,-30.05473],[27.22719,-30.00718],[27.09489,-29.72796],[27.01016,-29.65439]]]}},{"type":"Feature","properties":{"id":"EU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-63.35989,18.06012],[-63.33064,17.9615],[-63.13584,18.0541],[-63.11096,18.05368],[-63.09686,18.04608],[-63.07759,18.04943],[-63.0579,18.06614],[-63.04039,18.05619],[-63.02323,18.05757],[-62.93924,18.02904],[-62.75637,18.13489],[-62.86666,18.19278],[-63.35989,18.06012]]],[[[-62.17275,16.35721],[-61.81728,15.58058],[-61.44899,15.79571],[-60.95725,15.70997],[-60.71337,16.48911],[-61.44461,16.81958],[-61.83929,16.66647],[-62.17275,16.35721]]],[[[-61.51867,14.96709],[-61.26561,14.25664],[-60.5958,14.23076],[-60.69955,15.22234],[-61.51867,14.96709]]],[[[-54.6084,2.32856],[-54.16286,2.10779],[-53.78743,2.34412],[-52.96539,2.1881],[-52.6906,2.37298],[-52.31787,3.17896],[-51.85573,3.83427],[-51.82312,3.85825],[-51.79599,3.89336],[-51.61983,4.14596],[-51.63798,4.51394],[-51.35485,4.8383],[-53.7094,6.2264],[-54.01074,5.68785],[-54.01877,5.52789],[-54.26916,5.26909],[-54.4717,4.91964],[-54.38444,4.13222],[-54.19367,3.84387],[-54.05128,3.63557],[-53.98914,3.627],[-53.9849,3.58697],[-54.28534,2.67798],[-54.42864,2.42442],[-54.6084,2.32856]]],[[[-32.42346,39.07068],[-15.92339,29.50503],[-18.67893,29.62861],[-18.8556,26.96222],[-14.43883,27.02969],[-12.42686,29.61659],[-14.33337,30.94071],[-7.37282,36.96896],[-7.27694,35.93599],[-5.64962,35.93752],[-5.10878,36.05227],[-2.85819,35.63219],[-2.27707,35.35051],[2.46645,37.97429],[5.18061,39.43581],[3.4481,42.4358],[7.52234,41.54558],[7.89009,38.19924],[11.2718,37.6713],[12.02012,35.25036],[12.80065,35.1178],[13.4634,35.88474],[14.74801,35.36688],[15.10171,36.26215],[18.75365,39.82496],[18.83516,40.36999],[16.15283,42.18525],[18.45131,42.21682],[18.54128,42.39171],[18.52152,42.42302],[18.43588,42.48556],[18.44307,42.51077],[18.43735,42.55921],[18.36197,42.61423],[18.24318,42.6112],[17.88201,42.83668],[17.80854,42.9182],[17.7948,42.89556],[17.68151,42.92725],[17.6444,42.88641],[17.5392,42.92787],[17.70879,42.97223],[17.64268,43.08595],[17.46986,43.16559],[17.286,43.33065],[17.25579,43.40353],[17.29699,43.44542],[17.24411,43.49376],[17.15828,43.49376],[17.00585,43.58037],[16.80736,43.76011],[16.75316,43.77157],[16.70922,43.84887],[16.55472,43.95326],[16.50528,44.0244],[16.43629,44.02826],[16.43662,44.07523],[16.36864,44.08263],[16.18688,44.27012],[16.21346,44.35231],[16.12969,44.38275],[16.16814,44.40679],[16.10566,44.52586],[16.03012,44.55572],[16.00884,44.58605],[16.05828,44.61538],[15.89348,44.74964],[15.8255,44.71501],[15.72584,44.82334],[15.79472,44.8455],[15.76096,44.87045],[15.74723,44.96818],[15.78568,44.97401],[15.74585,45.0638],[15.78842,45.11519],[15.76371,45.16508],[15.83512,45.22459],[15.98412,45.23088],[16.12153,45.09616],[16.29036,44.99732],[16.35404,45.00241],[16.35863,45.03529],[16.3749,45.05206],[16.38219,45.05139],[16.38309,45.05955],[16.40023,45.1147],[16.4634,45.14522],[16.49155,45.21153],[16.52982,45.22713],[16.5501,45.2212],[16.56559,45.22307],[16.60194,45.23042],[16.64962,45.20714],[16.74845,45.20393],[16.78219,45.19002],[16.81137,45.18434],[16.83804,45.18951],[16.92405,45.27607],[16.9385,45.22742],[17.0415,45.20759],[17.18438,45.14764],[17.24325,45.146],[17.25131,45.14957],[17.26815,45.18444],[17.32092,45.16246],[17.33573,45.14521],[17.41229,45.13335],[17.4498,45.16119],[17.45615,45.12523],[17.47589,45.12656],[17.51469,45.10791],[17.59104,45.10816],[17.66571,45.13408],[17.84826,45.04489],[17.87148,45.04645],[17.93706,45.08016],[17.97336,45.12245],[17.97834,45.13831],[17.99479,45.14958],[18.01594,45.15163],[18.03121,45.12632],[18.1624,45.07654],[18.24387,45.13699],[18.32077,45.1021],[18.41896,45.11083],[18.47939,45.05871],[18.65723,45.07544],[18.78357,44.97741],[18.80661,44.93561],[18.76369,44.93707],[18.76347,44.90669],[18.8704,44.85097],[19.01994,44.85493],[18.98957,44.90645],[19.02871,44.92541],[19.06853,44.89915],[19.15573,44.95409],[19.05205,44.97692],[19.1011,45.01191],[19.07952,45.14668],[19.14063,45.12972],[19.19144,45.17863],[19.43589,45.17137],[19.41941,45.23475],[19.28208,45.23813],[19.10774,45.29547],[18.97446,45.37528],[18.99918,45.49333],[19.08364,45.48804],[19.07471,45.53086],[18.94562,45.53712],[18.88776,45.57253],[18.96691,45.66731],[18.90305,45.71863],[18.85783,45.85493],[18.81394,45.91329],[18.99712,45.93537],[19.01284,45.96529],[19.0791,45.96458],[19.10388,46.04015],[19.14543,45.9998],[19.28826,45.99694],[19.52473,46.1171],[19.56113,46.16824],[19.66007,46.19005],[19.81491,46.1313],[19.93508,46.17553],[20.01816,46.17696],[20.03533,46.14509],[20.09713,46.17315],[20.26068,46.12332],[20.35862,45.99356],[20.54818,45.89939],[20.65645,45.82801],[20.70069,45.7493],[20.77416,45.75601],[20.78446,45.78522],[20.82364,45.77738],[20.80361,45.65875],[20.76798,45.60969],[20.83321,45.53567],[20.77217,45.49788],[20.86026,45.47295],[20.87948,45.42743],[21.09894,45.30144],[21.17612,45.32566],[21.20392,45.2677],[21.29398,45.24148],[21.48278,45.19557],[21.51299,45.15345],[21.4505,45.04294],[21.35855,45.01941],[21.54938,44.9327],[21.56328,44.89502],[21.48202,44.87199],[21.44013,44.87613],[21.35643,44.86364],[21.38802,44.78133],[21.55007,44.77304],[21.60019,44.75208],[21.61942,44.67059],[21.67504,44.67107],[21.71692,44.65349],[21.7795,44.66165],[21.99364,44.63395],[22.08016,44.49844],[22.13234,44.47444],[22.18315,44.48179],[22.30844,44.6619],[22.45301,44.7194],[22.61917,44.61489],[22.69196,44.61587],[22.76749,44.54446],[22.70981,44.51852],[22.61368,44.55719],[22.56493,44.53419],[22.54021,44.47836],[22.45436,44.47258],[22.56012,44.30712],[22.68166,44.28206],[22.67173,44.21564],[22.61711,44.16938],[22.61688,44.06534],[22.41449,44.00514],[22.35558,43.81281],[22.41043,43.69566],[22.47582,43.6558],[22.53397,43.47225],[22.82036,43.33665],[22.89727,43.22417],[23.00806,43.19279],[22.98104,43.11199],[22.89521,43.03625],[22.78397,42.98253],[22.74826,42.88701],[22.54302,42.87774],[22.43309,42.82057],[22.4997,42.74144],[22.43983,42.56851],[22.55669,42.50144],[22.51961,42.3991],[22.47498,42.3915],[22.45919,42.33822],[22.34773,42.31725],[22.38136,42.30339],[22.47251,42.20393],[22.50289,42.19527],[22.51224,42.15457],[22.67701,42.06614],[22.86749,42.02275],[22.90254,41.87587],[22.96682,41.77137],[23.01239,41.76527],[23.03342,41.71034],[22.95513,41.63265],[22.96331,41.35782],[22.93334,41.34104],[22.81199,41.3398],[22.76408,41.32225],[22.74538,41.16321],[22.71266,41.13945],[22.65306,41.18168],[22.62852,41.14385],[22.58295,41.11568],[22.5549,41.13065],[22.42285,41.11921],[22.26744,41.16409],[22.17629,41.15969],[22.1424,41.12449],[22.06527,41.15617],[21.90869,41.09191],[21.91102,41.04786],[21.7556,40.92525],[21.69601,40.9429],[21.57448,40.86076],[21.53007,40.90759],[21.41555,40.9173],[21.35595,40.87578],[21.25779,40.86165],[21.21105,40.8855],[21.15262,40.85546],[20.97887,40.85475],[20.98396,40.79109],[20.95752,40.76982],[20.98134,40.76046],[21.05833,40.66586],[21.03932,40.56299],[20.96908,40.51526],[20.94925,40.46625],[20.83688,40.47882],[20.7906,40.42726],[20.78234,40.35803],[20.71789,40.27739],[20.67162,40.09433],[20.62566,40.0897],[20.61081,40.07866],[20.55593,40.06524],[20.51297,40.08168],[20.48487,40.06271],[20.42373,40.06777],[20.37911,39.99058],[20.31135,39.99438],[20.41546,39.82832],[20.41475,39.81437],[20.38572,39.78516],[20.30804,39.81563],[20.29152,39.80421],[20.31961,39.72799],[20.27412,39.69884],[20.22707,39.67459],[20.22376,39.64532],[20.15988,39.652],[20.12956,39.65805],[20.05189,39.69112],[20.00957,39.69227],[19.98042,39.6504],[19.92466,39.69533],[19.97622,39.78684],[19.95905,39.82857],[19.0384,40.35325],[19.20409,39.7532],[22.5213,33.45682],[29.73302,35.92555],[29.69611,36.10365],[29.61805,36.14179],[29.61002,36.1731],[29.48192,36.18377],[29.30783,36.01033],[28.23708,36.56812],[27.95037,36.46155],[27.89482,36.69898],[27.46117,36.53789],[27.24613,36.71622],[27.45627,36.9008],[27.20312,36.94571],[27.14757,37.32],[26.95583,37.64989],[26.99377,37.69034],[27.16428,37.72343],[27.05537,37.9131],[26.21136,38.17558],[26.24183,38.44695],[26.32173,38.48731],[26.21136,38.65436],[26.61814,38.81372],[26.70773,39.0312],[26.43357,39.43096],[25.94257,39.39358],[25.61285,40.17161],[26.04292,40.3958],[25.94795,40.72797],[26.03489,40.73051],[26.0754,40.72772],[26.08638,40.73214],[26.12495,40.74283],[26.12854,40.77339],[26.15685,40.80709],[26.21351,40.83298],[26.20856,40.86048],[26.26169,40.9168],[26.29441,40.89119],[26.28623,40.93005],[26.32259,40.94042],[26.35894,40.94292],[26.33297,40.98388],[26.3606,41.02027],[26.31928,41.07386],[26.32259,41.24929],[26.39861,41.25053],[26.5209,41.33993],[26.5837,41.32131],[26.62997,41.34613],[26.61767,41.42281],[26.59742,41.48058],[26.59196,41.60491],[26.5209,41.62592],[26.47958,41.67037],[26.35957,41.71149],[26.32952,41.73637],[26.33589,41.76802],[26.36952,41.82265],[26.53968,41.82653],[26.57961,41.90024],[26.56051,41.92995],[26.62996,41.97644],[26.79143,41.97386],[26.95638,42.00741],[27.03277,42.0809],[27.08486,42.08735],[27.19251,42.06028],[27.22376,42.10152],[27.27411,42.10409],[27.45478,41.96591],[27.52379,41.93756],[27.55191,41.90928],[27.69949,41.97515],[27.81235,41.94803],[27.83492,41.99709],[27.91479,41.97902],[28.02971,41.98066],[28.32297,41.98371],[29.24336,43.70874],[30.04414,45.08461],[29.69272,45.19227],[29.65428,45.25629],[29.68175,45.26885],[29.59798,45.38857],[29.42632,45.44545],[29.24779,45.43388],[28.96077,45.33164],[28.94292,45.28045],[28.81383,45.3384],[28.78911,45.24179],[28.71358,45.22631],[28.5735,45.24759],[28.34554,45.32102],[28.28504,45.43907],[28.21139,45.46895],[28.18741,45.47358],[28.08927,45.6051],[28.16568,45.6421],[28.13111,45.92819],[28.08612,46.01105],[28.13684,46.18099],[28.10937,46.22852],[28.19864,46.31869],[28.18902,46.35283],[28.25769,46.43334],[28.22281,46.50481],[28.24808,46.64305],[28.12173,46.82283],[28.09095,46.97621],[27.81892,47.1381],[27.73172,47.29248],[27.68706,47.28962],[27.60263,47.32507],[27.55731,47.46637],[27.47942,47.48113],[27.3979,47.59473],[27.32202,47.64009],[27.25519,47.71366],[27.29069,47.73722],[27.1618,47.92391],[27.15622,47.98538],[27.02985,48.09083],[27.04118,48.12522],[26.96119,48.13003],[26.98042,48.15752],[26.94265,48.1969],[26.87708,48.19919],[26.81161,48.25049],[26.62823,48.25804],[26.55202,48.22445],[26.33504,48.18418],[26.17711,47.99246],[26.05901,47.9897],[25.77723,47.93919],[25.63878,47.94924],[25.23778,47.89403],[25.11144,47.75203],[24.88896,47.7234],[24.81893,47.82031],[24.70632,47.84428],[24.61994,47.95062],[24.43578,47.97131],[24.34926,47.9244],[24.22566,47.90231],[24.11281,47.91487],[24.06466,47.95317],[24.02999,47.95087],[24.00801,47.968],[23.98553,47.96076],[23.96337,47.96672],[23.94192,47.94868],[23.89352,47.94512],[23.8602,47.9329],[23.80904,47.98142],[23.75188,47.99705],[23.66262,47.98786],[23.63894,48.00293],[23.5653,48.00499],[23.52803,48.01818],[23.4979,47.96858],[23.33577,48.0237],[23.27397,48.08245],[23.15999,48.12188],[23.1133,48.08061],[23.08858,48.00716],[23.0158,47.99338],[22.92241,48.02002],[22.94301,47.96672],[22.89849,47.95851],[22.84276,47.98602],[22.87847,48.04665],[22.81804,48.11363],[22.73427,48.12005],[22.66835,48.09162],[22.58733,48.10813],[22.59007,48.15121],[22.49806,48.25189],[22.38133,48.23726],[22.2083,48.42534],[22.14689,48.4005],[22.16023,48.56548],[22.21379,48.6218],[22.34151,48.68893],[22.42934,48.92857],[22.48296,48.99172],[22.54338,49.01424],[22.56155,49.08865],[22.89122,49.00725],[22.86336,49.10513],[22.72009,49.20288],[22.748,49.32759],[22.69444,49.49378],[22.64534,49.53094],[22.78304,49.65543],[22.80261,49.69098],[22.83179,49.69875],[22.99329,49.84249],[23.28221,50.0957],[23.67635,50.33385],[23.71382,50.38248],[23.79445,50.40481],[23.99563,50.41289],[24.03668,50.44507],[24.07048,50.5071],[24.0996,50.60752],[24.0595,50.71625],[23.95925,50.79271],[23.99254,50.83847],[24.0952,50.83262],[24.14524,50.86128],[24.04576,50.90196],[23.92217,51.00836],[23.90376,51.07697],[23.80678,51.18405],[23.63858,51.32182],[23.69905,51.40871],[23.62751,51.50512],[23.56236,51.53673],[23.57053,51.55938],[23.53198,51.74298],[23.62691,51.78208],[23.61523,51.92066],[23.68733,51.9906],[23.64066,52.07626],[23.61,52.11264],[23.54314,52.12148],[23.47859,52.18215],[23.20071,52.22848],[23.18196,52.28812],[23.34141,52.44845],[23.45112,52.53774],[23.58296,52.59868],[23.73615,52.6149],[23.93763,52.71332],[23.91805,52.94016],[23.94689,52.95919],[23.92184,53.02079],[23.87548,53.0831],[23.91393,53.16469],[23.85657,53.22923],[23.81995,53.24131],[23.62004,53.60942],[23.51284,53.95052],[23.61677,53.92691],[23.71726,53.93379],[23.80543,53.89558],[23.81309,53.94205],[23.95098,53.9613],[23.98837,53.92554],[24.19638,53.96405],[24.34128,53.90076],[24.44411,53.90076],[24.62275,54.00217],[24.69652,54.01901],[24.69185,53.96543],[24.74279,53.96663],[24.85311,54.02862],[24.77131,54.11091],[24.96894,54.17589],[24.991,54.14241],[25.0728,54.13419],[25.19199,54.219],[25.22705,54.26271],[25.35559,54.26544],[25.509,54.30267],[25.56823,54.25212],[25.51452,54.17799],[25.54724,54.14925],[25.64875,54.1259],[25.71084,54.16704],[25.78563,54.15747],[25.78553,54.23327],[25.68513,54.31727],[25.55425,54.31591],[25.5376,54.33158],[25.63371,54.42075],[25.62203,54.4656],[25.64813,54.48704],[25.68045,54.5321],[25.75977,54.57252],[25.74122,54.80108],[25.89462,54.93438],[25.99129,54.95705],[26.05907,54.94631],[26.13386,54.98924],[26.20397,54.99729],[26.26941,55.08032],[26.23202,55.10439],[26.30628,55.12536],[26.35121,55.1525],[26.46249,55.12814],[26.51481,55.16051],[26.54753,55.14181],[26.69243,55.16718],[26.68075,55.19787],[26.72983,55.21788],[26.73017,55.24226],[26.835,55.28182],[26.83266,55.30444],[26.80929,55.31642],[26.6714,55.33902],[26.5709,55.32572],[26.44937,55.34832],[26.5522,55.40277],[26.55094,55.5093],[26.63167,55.57887],[26.63231,55.67968],[26.64888,55.70515],[26.71802,55.70645],[26.76872,55.67658],[26.87448,55.7172],[26.97153,55.8102],[27.1559,55.85032],[27.27804,55.78299],[27.3541,55.8089],[27.61683,55.78558],[27.63065,55.89687],[27.97865,56.11849],[28.15217,56.16964],[28.23716,56.27588],[28.16599,56.37806],[28.19057,56.44637],[28.10069,56.524],[28.13526,56.57989],[28.04768,56.59004],[27.86101,56.88204],[27.66511,56.83921],[27.86101,57.29402],[27.52453,57.42826],[27.56832,57.53728],[27.34698,57.52242],[27.31919,57.57672],[27.40393,57.62125],[27.3746,57.66834],[27.52615,57.72843],[27.50171,57.78842],[27.56689,57.83356],[27.78526,57.83963],[27.81841,57.89244],[27.67282,57.92627],[27.62393,58.09462],[27.48541,58.22615],[27.55489,58.39525],[27.36366,58.78381],[27.74429,58.98351],[27.80482,59.1116],[27.87978,59.18097],[27.90911,59.24353],[28.00689,59.28351],[28.14215,59.28934],[28.19284,59.35791],[28.20537,59.36491],[28.21137,59.38058],[28.19061,59.39962],[28.04187,59.47017],[27.85643,59.58538],[26.90044,59.63819],[26.32936,60.00121],[27.44953,60.22766],[27.71177,60.3893],[27.77352,60.52722],[28.47974,60.93365],[28.82816,61.1233],[29.01829,61.17448],[31.10136,62.43042],[31.38369,62.66284],[31.58535,62.91642],[31.29294,63.09035],[31.23244,63.22239],[30.49637,63.46666],[29.98213,63.75795],[30.25437,63.83364],[30.55687,64.09036],[30.4762,64.25728],[30.06279,64.35782],[30.01238,64.57513],[30.12329,64.64862],[30.05271,64.79072],[29.68972,64.80789],[29.61914,65.05993],[29.84096,65.1109],[29.8813,65.22101],[29.61914,65.23791],[29.68972,65.31803],[29.84096,65.56945],[29.74013,65.64025],[29.97205,65.70256],[30.16363,65.66935],[29.91155,66.13863],[28.9839,66.94139],[29.91155,67.51507],[30.02041,67.67523],[29.66955,67.79872],[29.34179,68.06655],[28.62982,68.19816],[28.43941,68.53366],[28.78224,68.86696],[28.45957,68.91417],[28.91738,69.04774],[28.81248,69.11997],[28.8629,69.22395],[29.31664,69.47994],[29.12697,69.69193],[28.36883,69.81658],[28.32849,69.88605],[27.97558,69.99671],[27.95542,70.0965],[27.57226,70.06215],[27.05802,69.92069],[26.64461,69.96565],[26.40261,69.91377],[25.96904,69.68397],[25.69679,69.27039],[25.75729,68.99383],[25.61613,68.89602],[25.42455,68.90328],[25.12206,68.78684],[25.10189,68.63307],[24.93048,68.61102],[24.90023,68.55579],[24.74898,68.65143],[24.18432,68.73936],[24.02299,68.81601],[23.781,68.84514],[23.68017,68.70276],[23.13064,68.64684],[22.53321,68.74393],[22.38367,68.71561],[22.27276,68.89514],[21.63833,69.27485],[21.27827,69.31281],[21.00732,69.22755],[20.98641,69.18809],[21.11099,69.10291],[21.05775,69.0356],[20.72171,69.11874],[20.55258,69.06069],[20.0695,69.04469],[20.28444,68.93283],[20.33435,68.80174],[20.22027,68.67246],[19.95647,68.55546],[20.22027,68.48759],[19.93508,68.35911],[18.97255,68.52416],[18.63032,68.50849],[18.39503,68.58672],[18.1241,68.53721],[18.13836,68.20874],[17.90787,67.96537],[17.30416,68.11591],[16.7409,67.91037],[16.38441,67.52923],[16.12774,67.52106],[16.09922,67.4364],[16.39154,67.21653],[16.35589,67.06419],[15.37197,66.48217],[15.49318,66.28509],[15.05113,66.15572],[14.53778,66.12399],[14.50926,65.31786],[13.64276,64.58402],[14.11117,64.46674],[14.16051,64.18725],[13.98222,64.00953],[13.23411,64.09087],[12.74105,64.02171],[12.14928,63.59373],[12.19919,63.47935],[11.98529,63.27487],[12.19919,63.00104],[12.07085,62.6297],[12.29187,62.25699],[12.14746,61.7147],[12.40595,61.57226],[12.57707,61.56547],[12.86939,61.35427],[12.69115,61.06584],[12.2277,61.02442],[12.59133,60.50559],[12.52003,60.13846],[12.36317,59.99259],[12.15641,59.8926],[11.87121,59.86039],[11.92112,59.69531],[11.69297,59.59442],[11.8213,59.24985],[11.65732,58.90177],[11.45199,58.89604],[11.4601,58.99022],[11.34459,59.11672],[11.15367,59.07862],[11.08911,58.98745],[10.64958,58.89391],[10.40861,58.38489],[7.28637,57.35913],[8.02459,55.09613],[5.45168,54.20039],[2.56575,51.85301],[2.18458,51.52087],[1.17405,50.74239],[-2.02963,49.91866],[-2.09454,49.46288],[-1.83944,49.23037],[-2.00491,48.86706],[-2.5234,48.91595],[-2.56423,49.22209],[-2.9511,49.31141],[-5.81385,48.52441],[-1.81005,43.59738],[-10.14298,44.17365],[-9.14112,41.86623],[-30.18705,41.4962],[-32.42346,39.07068]],[[-5.40134,36.14896],[-5.38545,36.15481],[-5.36494,36.15496],[-5.34536,36.15501],[-5.33822,36.15272],[-5.27801,36.14942],[-5.28217,36.09907],[-5.3004,36.07439],[-5.32837,36.05935],[-5.36503,36.06205],[-5.39074,36.10278],[-5.40134,36.14896]],[[1.41245,42.53539],[1.4234,42.55959],[1.44529,42.56722],[1.42512,42.58292],[1.44197,42.60217],[1.47986,42.61346],[1.46718,42.63296],[1.48043,42.65203],[1.50867,42.64483],[1.55418,42.65669],[1.60085,42.62703],[1.63485,42.62957],[1.6625,42.61982],[1.68267,42.62533],[1.73452,42.61515],[1.72588,42.59098],[1.7858,42.57698],[1.73683,42.55492],[1.72515,42.50338],[1.70571,42.48867],[1.66826,42.50779],[1.65674,42.47125],[1.58933,42.46275],[1.57953,42.44957],[1.55937,42.45808],[1.55073,42.43299],[1.5127,42.42959],[1.44529,42.43724],[1.43838,42.47848],[1.41648,42.48315],[1.46661,42.50949],[1.44759,42.54431],[1.41245,42.53539]],[[5.95781,46.12925],[5.9641,46.14412],[5.97508,46.15863],[5.98188,46.17392],[5.98846,46.17046],[5.99573,46.18587],[5.96515,46.19638],[5.97542,46.21525],[6.02461,46.23313],[6.03342,46.2383],[6.04602,46.23127],[6.05029,46.23518],[6.0633,46.24583],[6.07072,46.24085],[6.08563,46.24651],[6.10071,46.23772],[6.12446,46.25059],[6.11926,46.2634],[6.1013,46.28512],[6.11697,46.29547],[6.1198,46.31157],[6.13876,46.33844],[6.15738,46.3491],[6.16987,46.36759],[6.15985,46.37721],[6.15016,46.3778],[6.09926,46.40768],[6.06407,46.41676],[6.08427,46.44305],[6.07269,46.46244],[6.1567,46.54402],[6.11084,46.57649],[6.27135,46.68251],[6.38351,46.73171],[6.45209,46.77502],[6.43216,46.80336],[6.46456,46.88865],[6.43341,46.92703],[6.71531,47.0494],[6.68823,47.06616],[6.76788,47.1208],[6.8489,47.15933],[6.9508,47.24338],[6.95108,47.26428],[6.94316,47.28747],[7.05305,47.33304],[7.0564,47.35134],[7.03125,47.36996],[6.87959,47.35335],[6.88542,47.37262],[6.93744,47.40714],[6.93953,47.43388],[7.0024,47.45264],[6.98425,47.49432],[7.0231,47.50522],[7.07425,47.48863],[7.12781,47.50371],[7.16249,47.49025],[7.19583,47.49455],[7.17026,47.44312],[7.24669,47.4205],[7.33526,47.44186],[7.35603,47.43432],[7.40308,47.43638],[7.43088,47.45846],[7.4462,47.46264],[7.4583,47.47216],[7.42923,47.48628],[7.43356,47.49712],[7.47534,47.47932],[7.51076,47.49651],[7.49804,47.51798],[7.5229,47.51644],[7.53199,47.5284],[7.51904,47.53515],[7.50588,47.52856],[7.49691,47.53821],[7.50873,47.54546],[7.51723,47.54578],[7.52831,47.55347],[7.53634,47.55553],[7.55652,47.56779],[7.55689,47.57232],[7.56548,47.57617],[7.56684,47.57785],[7.58386,47.57536],[7.58945,47.59017],[7.60523,47.58519],[7.60459,47.57869],[7.61929,47.57683],[7.64309,47.59151],[7.64213,47.5944],[7.64599,47.59695],[7.67395,47.59212],[7.68229,47.59905],[7.69385,47.60099],[7.68486,47.59601],[7.67115,47.5871],[7.68904,47.57133],[7.67655,47.56435],[7.63338,47.56256],[7.65083,47.54662],[7.66174,47.54554],[7.6656,47.53752],[7.68101,47.53232],[7.69642,47.53297],[7.71961,47.54219],[7.75261,47.54599],[7.79486,47.55691],[7.80098,47.56335],[7.811279,47.56946],[7.81901,47.58798],[7.833466,47.58663],[7.84167,47.58196],[7.862692,47.58808],[7.88664,47.58854],[7.898354,47.58408],[7.90673,47.57674],[7.911615,47.56686],[7.906809,47.56037],[7.91251,47.55031],[7.920585,47.5469],[7.932644,47.54704],[7.94614,47.5436],[7.95682,47.55789],[7.97581,47.55493],[8.00113,47.55616],[8.02136,47.55096],[8.04383,47.55443],[8.06663,47.56374],[8.08557,47.55768],[8.10002,47.56504],[8.10395,47.57918],[8.11543,47.5841],[8.13662,47.58432],[8.13823,47.59147],[8.14947,47.59558],[8.1652,47.5945],[8.19378,47.61636],[8.20617,47.62141],[8.22011,47.6181],[8.22577,47.60385],[8.23809,47.61204],[8.25863,47.61571],[8.26313,47.6103],[8.2824,47.61225],[8.29722,47.60603],[8.29524,47.5919],[8.30277,47.58607],[8.32735,47.57133],[8.38273,47.56608],[8.39477,47.57826],[8.43235,47.56617],[8.49431,47.58107],[8.48949,47.588],[8.46637,47.58389],[8.45578,47.60121],[8.50747,47.61897],[8.51686,47.63476],[8.55756,47.62394],[8.57586,47.59537],[8.60348,47.61204],[8.59545,47.64298],[8.60701,47.65271],[8.61471,47.64514],[8.60412,47.63735],[8.62049,47.63757],[8.62884,47.65098],[8.61113,47.66332],[8.6052,47.67258],[8.57683,47.66158],[8.56141,47.67088],[8.52801,47.66059],[8.5322,47.64687],[8.49656,47.64709],[8.46605,47.64103],[8.4667,47.65747],[8.44711,47.65379],[8.42264,47.66667],[8.41346,47.66676],[8.40473,47.67499],[8.4211,47.68407],[8.40569,47.69855],[8.44807,47.72426],[8.45771,47.7493],[8.48868,47.77215],[8.56814,47.78001],[8.56415,47.80633],[8.61657,47.79998],[8.62408,47.7626],[8.64425,47.76398],[8.65292,47.80066],[8.68022,47.78599],[8.68985,47.75686],[8.71778,47.76571],[8.74251,47.75168],[8.70543,47.73121],[8.73671,47.7169],[8.72617,47.69651],[8.72809,47.69282],[8.75856,47.68969],[8.79511,47.67462],[8.79966,47.70222],[8.76965,47.7075],[8.77309,47.72059],[8.80663,47.73821],[8.82002,47.71458],[8.86989,47.70504],[8.85065,47.68209],[8.87383,47.67045],[8.87625,47.65441],[8.89946,47.64769],[8.94093,47.65596],[9.02093,47.6868],[9.09891,47.67801],[9.13845,47.66389],[9.15181,47.66904],[9.1705,47.65513],[9.1755,47.65584],[9.17593,47.65399],[9.18203,47.65598],[9.25619,47.65939],[9.55125,47.53629],[9.56312,47.49495],[9.58208,47.48344],[9.59482,47.46305],[9.60205,47.46165],[9.60484,47.46358],[9.60841,47.47178],[9.62158,47.45858],[9.62475,47.45685],[9.6423,47.45599],[9.65728,47.45383],[9.65863,47.44847],[9.64483,47.43842],[9.6446,47.43233],[9.65043,47.41937],[9.65136,47.40504],[9.6629,47.39591],[9.67334,47.39191],[9.67445,47.38429],[9.6711,47.37824],[9.66243,47.37136],[9.65427,47.36824],[9.62476,47.36639],[9.59978,47.34671],[9.58513,47.31334],[9.55857,47.29919],[9.54773,47.2809],[9.53116,47.27029],[9.56766,47.24281],[9.55176,47.22585],[9.56981,47.21926],[9.58264,47.20673],[9.56539,47.17124],[9.62623,47.14685],[9.63395,47.08443],[9.61216,47.07732],[9.60717,47.06091],[9.87935,47.01337],[9.88266,46.93343],[9.98058,46.91434],[10.10715,46.84296],[10.22675,46.86942],[10.24128,46.93147],[10.30031,46.92093],[10.36933,47.00212],[10.48376,46.93891],[10.47197,46.85698],[10.38659,46.67847],[10.40475,46.63671],[10.44686,46.64162],[10.49375,46.62049],[10.46136,46.53164],[10.25309,46.57432],[10.23674,46.63484],[10.10307,46.61003],[10.03715,46.44479],[10.165,46.41051],[10.10506,46.3372],[10.17862,46.25626],[10.14439,46.22992],[10.07055,46.21668],[9.95249,46.38045],[9.73086,46.35071],[9.71273,46.29266],[9.57015,46.2958],[9.46117,46.37481],[9.45936,46.50873],[9.40487,46.46621],[9.36128,46.5081],[9.28136,46.49685],[9.25502,46.43743],[9.29226,46.32717],[9.24503,46.23616],[9.01618,46.04928],[8.99257,45.9698],[9.09065,45.89906],[9.06642,45.8761],[9.04546,45.84968],[9.04059,45.8464],[9.03505,45.83976],[9.03793,45.83548],[9.03279,45.82865],[9.0298,45.82127],[9.00324,45.82055],[8.99663,45.83466],[8.9621,45.83707],[8.94737,45.84285],[8.91129,45.8388],[8.93504,45.86245],[8.94372,45.86587],[8.93649,45.86775],[8.88904,45.95465],[8.86688,45.96135],[8.85121,45.97239],[8.8319,45.9879],[8.79362,45.99207],[8.78585,45.98973],[8.79414,46.00913],[8.85617,46.0748],[8.80778,46.10085],[8.75697,46.10395],[8.62242,46.12112],[8.45032,46.26869],[8.46317,46.43712],[8.42464,46.46367],[8.30648,46.41587],[8.31162,46.38044],[8.08814,46.26692],[8.16866,46.17817],[8.11383,46.11577],[8.02906,46.10331],[7.98881,45.99867],[7.9049,45.99945],[7.85949,45.91485],[7.56343,45.97421],[7.10685,45.85653],[7.04151,45.92435],[7.00946,45.9944],[6.93862,46.06502],[6.87868,46.03855],[6.89321,46.12548],[6.78968,46.14058],[6.86052,46.28512],[6.77152,46.34784],[6.8024,46.39171],[6.82312,46.42661],[6.53358,46.45431],[6.25432,46.3632],[6.21981,46.31304],[6.24826,46.30175],[6.25137,46.29014],[6.23775,46.27822],[6.24952,46.26255],[6.26749,46.24745],[6.29474,46.26221],[6.31041,46.24417],[6.29663,46.22688],[6.27694,46.21566],[6.26007,46.21165],[6.24821,46.20531],[6.23913,46.20511],[6.23544,46.20714],[6.22175,46.20045],[6.22222,46.19888],[6.21844,46.19837],[6.21603,46.19507],[6.21273,46.19409],[6.21114,46.1927],[6.20539,46.19163],[6.19807,46.18369],[6.19552,46.18401],[6.18707,46.17999],[6.18871,46.16644],[6.18116,46.16187],[6.15305,46.15194],[6.13397,46.1406],[6.09926,46.14373],[6.09199,46.15191],[6.07491,46.14879],[6.05203,46.15191],[6.04564,46.14031],[6.03614,46.13712],[6.01791,46.14228],[5.9871,46.14499],[5.97893,46.13303],[5.95781,46.12925]],[[7.40903,43.7296],[7.41113,43.73156],[7.41291,43.73168],[7.41298,43.73311],[7.41233,43.73439],[7.42062,43.73977],[7.42299,43.74176],[7.42443,43.74087],[7.42809,43.74396],[7.43013,43.74895],[7.43624,43.75014],[7.43708,43.75197],[7.4389,43.75151],[7.4379,43.74963],[7.45448,43.7432],[7.53358,43.53609],[7.50102,43.51859],[7.41855,43.72479],[7.40903,43.7296]],[[12.40415,43.95485],[12.41414,43.95273],[12.42005,43.9578],[12.43662,43.95698],[12.44684,43.96597],[12.46205,43.97463],[12.47853,43.98052],[12.49406,43.98492],[12.50678,43.99113],[12.51463,43.99122],[12.5154,43.98508],[12.51064,43.98165],[12.51109,43.97201],[12.50622,43.97131],[12.50875,43.96198],[12.50655,43.95796],[12.51427,43.94897],[12.51553,43.94096],[12.50496,43.93017],[12.50269,43.92363],[12.49724,43.92248],[12.49247,43.91774],[12.49429,43.90973],[12.48771,43.89706],[12.45648,43.89369],[12.44184,43.90498],[12.41641,43.89991],[12.40935,43.9024],[12.41233,43.90956],[12.40733,43.92379],[12.41551,43.92984],[12.41165,43.93769],[12.40506,43.94325],[12.40415,43.95485]],[[12.44582,41.90194],[12.44815,41.90326],[12.44984,41.90545],[12.45091,41.90625],[12.45543,41.90738],[12.45561,41.90629],[12.45762,41.9058],[12.45755,41.9033],[12.45826,41.90281],[12.45834,41.90174],[12.4577,41.90115],[12.45691,41.90125],[12.45626,41.90172],[12.45435,41.90143],[12.45446,41.90028],[12.45181,41.90056],[12.44834,41.90095],[12.44582,41.90194]],[[18.57853,55.25302],[20.60454,55.40986],[20.95181,55.27994],[21.26425,55.24456],[21.35465,55.28427],[21.38446,55.29348],[21.46766,55.21115],[21.51095,55.18507],[21.55605,55.20311],[21.64954,55.1791],[21.85521,55.09493],[21.96505,55.07353],[21.99543,55.08691],[22.03984,55.07888],[22.02582,55.05078],[22.06087,55.02935],[22.11697,55.02131],[22.14267,55.05345],[22.31562,55.0655],[22.47688,55.04408],[22.58907,55.07085],[22.60075,55.01863],[22.65451,54.97037],[22.68723,54.9811],[22.76422,54.92521],[22.85083,54.88711],[22.87317,54.79492],[22.73631,54.72952],[22.73397,54.66604],[22.75467,54.6483],[22.74225,54.64339],[22.7522,54.63525],[22.68021,54.58486],[22.71293,54.56454],[22.67788,54.532],[22.70208,54.45312],[22.7253,54.41732],[22.79705,54.36264],[21.41123,54.32395],[20.63871,54.3706],[19.8038,54.44203],[19.64312,54.45423],[18.57853,55.25302]]],[[[-13.3292,54.24486],[-10.17712,50.85267],[-5.79914,52.03902],[-5.37267,53.63269],[-5.83481,53.87749],[-6.26218,54.09785],[-6.29003,54.11278],[-6.32694,54.09337],[-6.36279,54.11248],[-6.36605,54.07234],[-6.47849,54.06947],[-6.62842,54.03503],[-6.66264,54.0666],[-6.6382,54.17071],[-6.70175,54.20218],[-6.74575,54.18788],[-6.81583,54.22791],[-6.85179,54.29176],[-6.87775,54.34682],[-7.02034,54.4212],[-7.19145,54.31296],[-7.14908,54.22732],[-7.25012,54.20063],[-7.26316,54.13863],[-7.29493,54.12013],[-7.29687,54.1354],[-7.28017,54.16714],[-7.29157,54.17191],[-7.34005,54.14698],[-7.30553,54.11869],[-7.32834,54.11475],[-7.44567,54.1539],[-7.4799,54.12239],[-7.55812,54.12239],[-7.69501,54.20731],[-7.81397,54.20159],[-7.8596,54.21779],[-7.87101,54.29299],[-8.04555,54.36292],[-8.179,54.46763],[-8.04538,54.48941],[-7.99812,54.54427],[-7.8596,54.53671],[-7.70315,54.62077],[-7.93293,54.66603],[-7.83352,54.73854],[-7.75041,54.7103],[-7.64449,54.75265],[-7.54671,54.74606],[-7.54508,54.79401],[-7.47626,54.83084],[-7.4473,54.87003],[-7.44404,54.9403],[-7.40004,54.94498],[-7.4033,55.00391],[-7.34464,55.04688],[-7.2471,55.06933],[-6.9734,55.19878],[-6.71944,55.27952],[-6.79943,55.54107],[-7.93366,55.84142],[-13.3292,54.24486]]],[[[-5.38491,35.92591],[-5.37338,35.88417],[-5.35844,35.87375],[-5.34379,35.8711],[-5.27056,35.88794],[-5.27635,35.91222],[-5.38491,35.92591]]],[[[-2.97035,35.28852],[-2.96507,35.28801],[-2.96826,35.28296],[-2.96516,35.27967],[-2.95431,35.2728],[-2.95065,35.26576],[-2.93893,35.26737],[-2.92674,35.27313],[-2.92181,35.28599],[-2.92224,35.3401],[-2.96038,35.31609],[-2.96648,35.30475],[-2.96978,35.29459],[-2.97035,35.28852]]],[[[8.65769,47.68928],[8.66837,47.68437],[8.68985,47.69552],[8.70847,47.68904],[8.71773,47.69088],[8.70237,47.71453],[8.66416,47.71367],[8.67508,47.6979],[8.65769,47.68928]]],[[[8.95861,45.96485],[8.97604,45.96151],[8.97741,45.98317],[8.96668,45.98436],[8.95861,45.96485]]],[[[31.71872,35.1606],[32.10341,34.37973],[32.74412,34.43926],[32.75515,34.64985],[32.76136,34.68318],[32.79433,34.67883],[32.82717,34.70622],[32.86014,34.70585],[32.86167,34.68734],[32.9068,34.66102],[32.91398,34.67343],[32.93043,34.67091],[32.92807,34.66736],[32.93449,34.66241],[32.93693,34.67027],[32.94379,34.67111],[32.94683,34.67907],[32.95539,34.68471],[32.99135,34.68061],[32.98668,34.67268],[32.99014,34.65518],[32.97736,34.65277],[32.97079,34.66112],[32.95325,34.66462],[32.94796,34.6587],[32.94976,34.65204],[32.95471,34.64528],[32.95323,34.64075],[32.95891,34.62919],[32.96718,34.63446],[32.96968,34.64046],[33.0138,34.64424],[33.26744,34.49942],[33.83531,34.73974],[33.70575,34.97947],[33.70639,34.99303],[33.71514,35.00294],[33.69731,35.01754],[33.69938,35.03123],[33.67678,35.03866],[33.67742,35.05963],[33.68474,35.06602],[33.69095,35.06237],[33.70861,35.07644],[33.7161,35.07279],[33.70209,35.04882],[33.71482,35.03722],[33.73824,35.05321],[33.76106,35.04253],[33.78581,35.05104],[33.82067,35.07826],[33.84168,35.06823],[33.8541,35.07201],[33.87479,35.08881],[33.87097,35.09389],[33.87622,35.10457],[33.87224,35.12293],[33.88561,35.12449],[33.88943,35.12007],[33.88737,35.11408],[33.89853,35.11377],[33.91789,35.08688],[33.91299,35.07579],[33.90247,35.07686],[33.89485,35.06873],[33.88367,35.07877],[33.85261,35.0574],[33.8355,35.05777],[33.82051,35.0667],[33.8012,35.04786],[33.81524,35.04192],[33.83055,35.02865],[33.82875,35.01685],[33.84045,35.00616],[33.85216,35.00579],[33.85891,35.001],[33.85621,34.98956],[33.83505,34.98108],[33.84811,34.97075],[33.86432,34.97592],[33.90075,34.96623],[33.98684,34.76642],[35.48515,34.70851],[35.51152,36.10954],[32.82353,35.70297],[31.71872,35.1606]]],[[[33.7343,35.01178],[33.74144,35.01053],[33.7492,35.01319],[33.74983,35.02274],[33.74265,35.02329],[33.73781,35.02181],[33.7343,35.01178]]],[[[33.75682,34.99916],[33.76605,34.99543],[33.76738,34.99188],[33.7778,34.98981],[33.77843,34.988],[33.78149,34.98854],[33.78318,34.98699],[33.78571,34.98951],[33.78917,34.98854],[33.79191,34.98914],[33.78516,34.99582],[33.77553,34.99518],[33.77312,34.9976],[33.75994,35.00113],[33.75682,34.99916]]],[[[44.75722,-12.58368],[44.82644,-13.30845],[45.54824,-13.22353],[45.45962,-12.30345],[44.75722,-12.58368]]],[[[54.32269,-20.37973],[54.43368,-22.02482],[56.73473,-21.9174],[56.62373,-20.2711],[54.32269,-20.37973]]]]}},{"type":"Feature","properties":{"id":"UM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-177.8563,29.18961],[-177.84531,27.68616],[-176.81808,27.68129],[-176.83456,29.19028],[-177.8563,29.18961]]],[[[-177.43928,1.65656],[-177.43039,-1.43294],[-175.33482,-1.40631],[-175.33167,1.67574],[-177.43928,1.65656]]],[[[-169.97341,16.32808],[-169.02347,16.32808],[-169.02347,17.13856],[-169.97341,17.13856],[-169.97341,16.32808]]],[[[-163.24994,7.12322],[-163.24478,5.24198],[-161.06795,5.2462],[-161.0731,7.1291],[-163.24994,7.12322]]],[[[-161.05669,1.11722],[-161.04969,-1.36251],[-158.62058,-1.35506],[-158.62734,1.1296],[-161.05669,1.11722]]],[[[-75.27909,18.17213],[-74.76465,18.06252],[-74.7289,18.71009],[-75.24866,18.6531],[-75.27909,18.17213]]],[[[166.27257,19.60026],[166.27567,19.02484],[166.94111,19.02804],[166.93801,19.60345],[166.27257,19.60026]]]]}},{"type":"Feature","properties":{"id":"PS"},"geometry":{"type":"MultiPolygon","coordinates":[[[[34.052,31.46619],[34.21853,31.32363],[34.23572,31.2966],[34.24012,31.29591],[34.26742,31.21998],[34.29417,31.24194],[34.36523,31.28963],[34.37381,31.30598],[34.36505,31.36404],[34.40077,31.40926],[34.48892,31.48365],[34.56797,31.54197],[34.48681,31.59711],[34.29262,31.70393],[34.052,31.46619]]],[[[34.87833,31.39321],[34.88932,31.37093],[34.92571,31.34337],[35.02459,31.35979],[35.13033,31.3551],[35.22921,31.37445],[35.39675,31.49572],[35.47672,31.49578],[35.55941,31.76535],[35.52758,31.9131],[35.54375,31.96587],[35.52012,32.04076],[35.57111,32.21877],[35.55807,32.38674],[35.42078,32.41562],[35.41048,32.43706],[35.41598,32.45593],[35.42034,32.46009],[35.40224,32.50136],[35.35212,32.52047],[35.30685,32.51024],[35.29306,32.50947],[35.25049,32.52453],[35.2244,32.55289],[35.15937,32.50466],[35.10882,32.4757],[35.10024,32.47856],[35.09236,32.47614],[35.08564,32.46948],[35.07059,32.4585],[35.05423,32.41754],[35.05311,32.4024],[35.0421,32.38242],[35.05142,32.3667],[35.04243,32.35008],[35.01772,32.33863],[35.01119,32.28684],[35.02939,32.2671],[35.01841,32.23981],[34.98885,32.20758],[34.95703,32.19522],[34.96009,32.17503],[34.99039,32.14626],[34.98507,32.12606],[34.99437,32.10962],[34.9863,32.09551],[35.00261,32.027],[34.98682,31.96935],[35.00124,31.93264],[35.03489,31.92448],[35.03978,31.89276],[35.03489,31.85919],[34.99712,31.85569],[34.9724,31.83352],[35.01978,31.82944],[35.05617,31.85685],[35.07677,31.85627],[35.14174,31.81325],[35.18603,31.80901],[35.18169,31.82542],[35.19461,31.82687],[35.21469,31.81835],[35.216,31.83894],[35.21128,31.863],[35.20381,31.86716],[35.20673,31.88151],[35.20791,31.8821],[35.20945,31.8815],[35.21016,31.88237],[35.21276,31.88153],[35.2136,31.88241],[35.22014,31.88264],[35.22294,31.87889],[35.22567,31.86745],[35.22817,31.8638],[35.2249,31.85433],[35.2304,31.84222],[35.24816,31.8458],[35.25753,31.8387],[35.251,31.83085],[35.26404,31.82567],[35.25573,31.81362],[35.26058,31.79064],[35.25225,31.7678],[35.26319,31.74846],[35.25182,31.73945],[35.24981,31.72543],[35.2438,31.7201],[35.24315,31.71244],[35.23972,31.70896],[35.22392,31.71899],[35.21937,31.71578],[35.20538,31.72388],[35.18023,31.72067],[35.16478,31.73242],[35.15474,31.73352],[35.15119,31.73634],[35.13931,31.73012],[35.12933,31.7325],[35.11895,31.71454],[35.10782,31.71594],[35.08226,31.69107],[35.00879,31.65426],[34.95249,31.59813],[34.9415,31.55601],[34.94356,31.50743],[34.93258,31.47816],[34.89756,31.43891],[34.87833,31.39321]]]]}},{"type":"Feature","properties":{"id":"TF"},"geometry":{"type":"MultiPolygon","coordinates":[[[[39.10324,-21.48967],[40.40841,-23.17181],[43.72277,-16.09877],[41.06663,-17.08802],[39.10324,-21.48967]]],[[[46.31615,-46.28749],[70.67507,-51.14192],[80.15867,-36.04977],[46.31615,-46.28749]]],[[[46.52682,-10.83678],[47.29063,-12.45583],[48.86266,-10.8109],[46.52682,-10.83678]]],[[[54.08717,-15.5001],[54.13761,-16.33002],[54.96649,-16.28353],[54.91606,-15.45342],[54.08717,-15.5001]]]]}},{"type":"Feature","properties":{"id":"EA"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-5.38491,35.92591],[-5.37338,35.88417],[-5.35844,35.87375],[-5.34379,35.8711],[-5.27056,35.88794],[-5.27635,35.91222],[-5.38491,35.92591]]],[[[-2.97035,35.28852],[-2.96507,35.28801],[-2.96826,35.28296],[-2.96516,35.27967],[-2.95431,35.2728],[-2.95065,35.26576],[-2.93893,35.26737],[-2.92674,35.27313],[-2.92181,35.28599],[-2.92224,35.3401],[-2.96038,35.31609],[-2.96648,35.30475],[-2.96978,35.29459],[-2.97035,35.28852]]]]}},{"type":"Feature","properties":{"id":"MA"},"geometry":{"type":"Polygon","coordinates":[[[-17.27295,21.93519],[-17.21511,21.34226],[-17.02707,21.34022],[-16.9978,21.36239],[-16.44269,21.39745],[-14.78487,21.36587],[-14.47329,21.63839],[-14.48112,22.00886],[-14.1291,22.41636],[-14.10361,22.75501],[-13.75627,23.77231],[-13.00628,24.01923],[-12.92147,24.39502],[-12.12281,25.13682],[-12.06001,26.04442],[-11.62052,26.05229],[-11.38635,26.611],[-11.23622,26.72023],[-11.35695,26.8505],[-10.68417,26.90984],[-9.81998,26.71379],[-9.56957,26.90042],[-9.08698,26.98639],[-8.71787,26.9898],[-8.77527,27.66663],[-8.66879,27.6666],[-8.6715,28.71194],[-7.61585,29.36252],[-6.95824,29.50924],[-6.78351,29.44634],[-6.69965,29.51623],[-5.75616,29.61407],[-5.72121,29.52322],[-5.58831,29.48103],[-5.21671,29.95253],[-4.6058,30.28343],[-4.31774,30.53229],[-3.64735,30.67539],[-3.65418,30.85566],[-3.54944,31.0503],[-3.77103,31.14984],[-3.77647,31.31912],[-3.66386,31.39202],[-3.66314,31.6339],[-2.82784,31.79459],[-2.93873,32.06557],[-2.46166,32.16603],[-1.22829,32.07832],[-1.15735,32.12096],[-1.24453,32.1917],[-1.24998,32.32993],[-0.9912,32.52467],[-1.37794,32.73628],[-1.54244,32.95499],[-1.46249,33.0499],[-1.67067,33.27084],[-1.59508,33.59929],[-1.73494,33.71721],[-1.64666,34.10405],[-1.78042,34.39018],[-1.69788,34.48056],[-1.84569,34.61907],[-1.73707,34.74226],[-1.97469,34.886],[-1.97833,34.93218],[-2.04734,34.93218],[-2.21445,35.04378],[-2.21248,35.08532],[-2.27707,35.35051],[-2.85819,35.63219],[-5.10878,36.05227],[-5.64962,35.93752],[-7.27694,35.93599],[-12.42686,29.61659],[-14.43883,27.02969],[-17.27295,21.93519]],[[-5.38491,35.92591],[-5.27635,35.91222],[-5.27056,35.88794],[-5.34379,35.8711],[-5.35844,35.87375],[-5.37338,35.88417],[-5.38491,35.92591]],[[-4.30191,35.17419],[-4.29436,35.17149],[-4.30112,35.17058],[-4.30191,35.17419]],[[-3.90602,35.21494],[-3.90288,35.22024],[-3.88617,35.21406],[-3.88926,35.20841],[-3.90602,35.21494]],[[-2.97035,35.28852],[-2.96978,35.29459],[-2.96648,35.30475],[-2.96038,35.31609],[-2.92224,35.3401],[-2.92181,35.28599],[-2.92674,35.27313],[-2.93893,35.26737],[-2.95065,35.26576],[-2.95431,35.2728],[-2.96516,35.27967],[-2.96826,35.28296],[-2.96507,35.28801],[-2.97035,35.28852]],[[-2.44896,35.18777],[-2.41265,35.1877],[-2.41312,35.17111],[-2.44887,35.17075],[-2.44896,35.18777]]]}},{"type":"Feature","properties":{"id":"AU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[71.08716,-53.87687],[75.44182,-53.99822],[72.87012,-51.48322],[71.08716,-53.87687]]],[[[96.53724,-12.46709],[97.24513,-12.47233],[97.25212,-11.57036],[96.54423,-11.5651],[96.53724,-12.46709]]],[[[99.6403,-26.70736],[129,-43.08851],[137.66184,-47.26522],[158.89388,-55.66823],[159.92772,-54.25538],[152.57175,-39.16128],[155.3142,-27.34698],[159.35793,-33.24807],[165.46901,-28.32101],[169.35326,-30.60259],[169.6687,-29.09191],[166.75333,-27.25416],[158.4748,-21.86428],[157.46481,-18.93777],[158.60851,-15.7108],[155.22803,-12.9001],[144.30183,-9.48146],[142.81927,-9.31709],[142.5723,-9.35994],[142.31447,-9.24611],[142.23304,-9.19253],[142.1462,-9.19923],[142.0953,-9.23534],[142.0601,-9.56571],[140.88922,-9.34945],[139.41724,-8.97063],[127.55165,-9.05052],[125.68138,-9.85176],[122.91521,-11.65621],[99.6403,-26.70736]]],[[[105.29647,-10.80676],[105.9699,-10.81333],[105.97626,-10.18257],[105.30283,-10.176],[105.29647,-10.80676]]]]}},{"type":"Feature","properties":{"id":"CH"},"geometry":{"type":"Polygon","coordinates":[[[5.95781,46.12925],[5.97893,46.13303],[5.9871,46.14499],[6.01791,46.14228],[6.03614,46.13712],[6.04564,46.14031],[6.05203,46.15191],[6.07491,46.14879],[6.09199,46.15191],[6.09926,46.14373],[6.13397,46.1406],[6.15305,46.15194],[6.18116,46.16187],[6.18871,46.16644],[6.18707,46.17999],[6.19552,46.18401],[6.19807,46.18369],[6.20539,46.19163],[6.21114,46.1927],[6.21273,46.19409],[6.21603,46.19507],[6.21844,46.19837],[6.22222,46.19888],[6.22175,46.20045],[6.23544,46.20714],[6.23913,46.20511],[6.24821,46.20531],[6.26007,46.21165],[6.27694,46.21566],[6.29663,46.22688],[6.31041,46.24417],[6.29474,46.26221],[6.26749,46.24745],[6.24952,46.26255],[6.23775,46.27822],[6.25137,46.29014],[6.24826,46.30175],[6.21981,46.31304],[6.25432,46.3632],[6.53358,46.45431],[6.82312,46.42661],[6.8024,46.39171],[6.77152,46.34784],[6.86052,46.28512],[6.78968,46.14058],[6.89321,46.12548],[6.87868,46.03855],[6.93862,46.06502],[7.00946,45.9944],[7.04151,45.92435],[7.10685,45.85653],[7.56343,45.97421],[7.85949,45.91485],[7.9049,45.99945],[7.98881,45.99867],[8.02906,46.10331],[8.11383,46.11577],[8.16866,46.17817],[8.08814,46.26692],[8.31162,46.38044],[8.30648,46.41587],[8.42464,46.46367],[8.46317,46.43712],[8.45032,46.26869],[8.62242,46.12112],[8.75697,46.10395],[8.80778,46.10085],[8.85617,46.0748],[8.79414,46.00913],[8.78585,45.98973],[8.79362,45.99207],[8.8319,45.9879],[8.85121,45.97239],[8.86688,45.96135],[8.88904,45.95465],[8.93649,45.86775],[8.94372,45.86587],[8.93504,45.86245],[8.91129,45.8388],[8.94737,45.84285],[8.9621,45.83707],[8.99663,45.83466],[9.00324,45.82055],[9.0298,45.82127],[9.03279,45.82865],[9.03793,45.83548],[9.03505,45.83976],[9.04059,45.8464],[9.04546,45.84968],[9.06642,45.8761],[9.09065,45.89906],[8.99257,45.9698],[9.01618,46.04928],[9.24503,46.23616],[9.29226,46.32717],[9.25502,46.43743],[9.28136,46.49685],[9.36128,46.5081],[9.40487,46.46621],[9.45936,46.50873],[9.46117,46.37481],[9.57015,46.2958],[9.71273,46.29266],[9.73086,46.35071],[9.95249,46.38045],[10.07055,46.21668],[10.14439,46.22992],[10.17862,46.25626],[10.10506,46.3372],[10.165,46.41051],[10.03715,46.44479],[10.10307,46.61003],[10.23674,46.63484],[10.25309,46.57432],[10.46136,46.53164],[10.49375,46.62049],[10.44686,46.64162],[10.40475,46.63671],[10.38659,46.67847],[10.47197,46.85698],[10.48376,46.93891],[10.36933,47.00212],[10.30031,46.92093],[10.24128,46.93147],[10.22675,46.86942],[10.10715,46.84296],[9.98058,46.91434],[9.88266,46.93343],[9.87935,47.01337],[9.60717,47.06091],[9.55721,47.04762],[9.54041,47.06495],[9.47548,47.05257],[9.47139,47.06402],[9.51362,47.08505],[9.52089,47.10019],[9.51044,47.13727],[9.48774,47.17402],[9.4891,47.19346],[9.50318,47.22153],[9.52406,47.24959],[9.53116,47.27029],[9.54773,47.2809],[9.55857,47.29919],[9.58513,47.31334],[9.59978,47.34671],[9.62476,47.36639],[9.65427,47.36824],[9.66243,47.37136],[9.6711,47.37824],[9.67445,47.38429],[9.67334,47.39191],[9.6629,47.39591],[9.65136,47.40504],[9.65043,47.41937],[9.6446,47.43233],[9.64483,47.43842],[9.65863,47.44847],[9.65728,47.45383],[9.6423,47.45599],[9.62475,47.45685],[9.62158,47.45858],[9.60841,47.47178],[9.60484,47.46358],[9.60205,47.46165],[9.59482,47.46305],[9.58208,47.48344],[9.56312,47.49495],[9.55125,47.53629],[9.25619,47.65939],[9.18203,47.65598],[9.17593,47.65399],[9.1755,47.65584],[9.1705,47.65513],[9.15181,47.66904],[9.13845,47.66389],[9.09891,47.67801],[9.02093,47.6868],[8.94093,47.65596],[8.89946,47.64769],[8.87625,47.65441],[8.87383,47.67045],[8.85065,47.68209],[8.86989,47.70504],[8.82002,47.71458],[8.80663,47.73821],[8.77309,47.72059],[8.76965,47.7075],[8.79966,47.70222],[8.79511,47.67462],[8.75856,47.68969],[8.72809,47.69282],[8.72617,47.69651],[8.73671,47.7169],[8.70543,47.73121],[8.74251,47.75168],[8.71778,47.76571],[8.68985,47.75686],[8.68022,47.78599],[8.65292,47.80066],[8.64425,47.76398],[8.62408,47.7626],[8.61657,47.79998],[8.56415,47.80633],[8.56814,47.78001],[8.48868,47.77215],[8.45771,47.7493],[8.44807,47.72426],[8.40569,47.69855],[8.4211,47.68407],[8.40473,47.67499],[8.41346,47.66676],[8.42264,47.66667],[8.44711,47.65379],[8.4667,47.65747],[8.46605,47.64103],[8.49656,47.64709],[8.5322,47.64687],[8.52801,47.66059],[8.56141,47.67088],[8.57683,47.66158],[8.6052,47.67258],[8.61113,47.66332],[8.62884,47.65098],[8.62049,47.63757],[8.60412,47.63735],[8.61471,47.64514],[8.60701,47.65271],[8.59545,47.64298],[8.60348,47.61204],[8.57586,47.59537],[8.55756,47.62394],[8.51686,47.63476],[8.50747,47.61897],[8.45578,47.60121],[8.46637,47.58389],[8.48949,47.588],[8.49431,47.58107],[8.43235,47.56617],[8.39477,47.57826],[8.38273,47.56608],[8.32735,47.57133],[8.30277,47.58607],[8.29524,47.5919],[8.29722,47.60603],[8.2824,47.61225],[8.26313,47.6103],[8.25863,47.61571],[8.23809,47.61204],[8.22577,47.60385],[8.22011,47.6181],[8.20617,47.62141],[8.19378,47.61636],[8.1652,47.5945],[8.14947,47.59558],[8.13823,47.59147],[8.13662,47.58432],[8.11543,47.5841],[8.10395,47.57918],[8.10002,47.56504],[8.08557,47.55768],[8.06663,47.56374],[8.04383,47.55443],[8.02136,47.55096],[8.00113,47.55616],[7.97581,47.55493],[7.95682,47.55789],[7.94614,47.5436],[7.932644,47.54704],[7.920585,47.5469],[7.91251,47.55031],[7.906809,47.56037],[7.911615,47.56686],[7.90673,47.57674],[7.898354,47.58408],[7.88664,47.58854],[7.862692,47.58808],[7.84167,47.58196],[7.833466,47.58663],[7.81901,47.58798],[7.811279,47.56946],[7.80098,47.56335],[7.79486,47.55691],[7.75261,47.54599],[7.71961,47.54219],[7.69642,47.53297],[7.68101,47.53232],[7.6656,47.53752],[7.66174,47.54554],[7.65083,47.54662],[7.63338,47.56256],[7.67655,47.56435],[7.68904,47.57133],[7.67115,47.5871],[7.68486,47.59601],[7.69385,47.60099],[7.68229,47.59905],[7.67395,47.59212],[7.64599,47.59695],[7.64213,47.5944],[7.64309,47.59151],[7.61929,47.57683],[7.60459,47.57869],[7.60523,47.58519],[7.58945,47.59017],[7.58386,47.57536],[7.56684,47.57785],[7.56548,47.57617],[7.55689,47.57232],[7.55652,47.56779],[7.53634,47.55553],[7.52831,47.55347],[7.51723,47.54578],[7.50873,47.54546],[7.49691,47.53821],[7.50588,47.52856],[7.51904,47.53515],[7.53199,47.5284],[7.5229,47.51644],[7.49804,47.51798],[7.51076,47.49651],[7.47534,47.47932],[7.43356,47.49712],[7.42923,47.48628],[7.4583,47.47216],[7.4462,47.46264],[7.43088,47.45846],[7.40308,47.43638],[7.35603,47.43432],[7.33526,47.44186],[7.24669,47.4205],[7.17026,47.44312],[7.19583,47.49455],[7.16249,47.49025],[7.12781,47.50371],[7.07425,47.48863],[7.0231,47.50522],[6.98425,47.49432],[7.0024,47.45264],[6.93953,47.43388],[6.93744,47.40714],[6.88542,47.37262],[6.87959,47.35335],[7.03125,47.36996],[7.0564,47.35134],[7.05305,47.33304],[6.94316,47.28747],[6.95108,47.26428],[6.9508,47.24338],[6.8489,47.15933],[6.76788,47.1208],[6.68823,47.06616],[6.71531,47.0494],[6.43341,46.92703],[6.46456,46.88865],[6.43216,46.80336],[6.45209,46.77502],[6.38351,46.73171],[6.27135,46.68251],[6.11084,46.57649],[6.1567,46.54402],[6.07269,46.46244],[6.08427,46.44305],[6.06407,46.41676],[6.09926,46.40768],[6.15016,46.3778],[6.15985,46.37721],[6.16987,46.36759],[6.15738,46.3491],[6.13876,46.33844],[6.1198,46.31157],[6.11697,46.29547],[6.1013,46.28512],[6.11926,46.2634],[6.12446,46.25059],[6.10071,46.23772],[6.08563,46.24651],[6.07072,46.24085],[6.0633,46.24583],[6.05029,46.23518],[6.04602,46.23127],[6.03342,46.2383],[6.02461,46.23313],[5.97542,46.21525],[5.96515,46.19638],[5.99573,46.18587],[5.98846,46.17046],[5.98188,46.17392],[5.97508,46.15863],[5.9641,46.14412],[5.95781,46.12925]],[[8.65769,47.68928],[8.67508,47.6979],[8.66416,47.71367],[8.70237,47.71453],[8.71773,47.69088],[8.70847,47.68904],[8.68985,47.69552],[8.66837,47.68437],[8.65769,47.68928]],[[8.95861,45.96485],[8.96668,45.98436],[8.97741,45.98317],[8.97604,45.96151],[8.95861,45.96485]]]}},{"type":"Feature","properties":{"id":"DE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[5.45168,54.20039],[6.91025,53.44221],[7.00198,53.32672],[7.19052,53.31866],[7.21679,53.20058],[7.22681,53.18165],[7.17898,53.13817],[7.21694,53.00742],[7.07253,52.81083],[7.04557,52.63318],[6.77307,52.65375],[6.71641,52.62905],[6.69507,52.488],[6.94293,52.43597],[6.99041,52.47235],[7.03417,52.40237],[7.07044,52.37805],[7.02703,52.27941],[7.06365,52.23789],[7.03729,52.22695],[6.9897,52.2271],[6.97189,52.20329],[6.83984,52.11728],[6.76117,52.11895],[6.68128,52.05052],[6.83035,51.9905],[6.82357,51.96711],[6.72319,51.89518],[6.68386,51.91861],[6.58556,51.89386],[6.50231,51.86313],[6.47179,51.85395],[6.38815,51.87257],[6.40704,51.82771],[6.30593,51.84998],[6.29872,51.86801],[6.21443,51.86801],[6.15349,51.90439],[6.11551,51.89769],[6.16902,51.84094],[6.10337,51.84829],[6.06705,51.86136],[5.99848,51.83195],[5.94568,51.82786],[5.98665,51.76944],[5.95003,51.7493],[6.04091,51.71821],[6.02767,51.6742],[6.11759,51.65609],[6.09055,51.60564],[6.18017,51.54096],[6.21724,51.48568],[6.20654,51.40049],[6.22641,51.39948],[6.22674,51.36135],[6.16977,51.33169],[6.07889,51.24432],[6.07889,51.17038],[6.17384,51.19589],[6.16706,51.15677],[5.98292,51.07469],[5.9541,51.03496],[5.9134,51.06736],[5.86735,51.05182],[5.87849,51.01969],[5.90493,51.00198],[5.90296,50.97356],[5.95282,50.98728],[6.02697,50.98303],[6.01615,50.93367],[6.09297,50.92066],[6.07486,50.89307],[6.08805,50.87223],[6.07693,50.86025],[6.07431,50.84674],[6.05702,50.85179],[6.05623,50.8572],[6.01921,50.84435],[6.02328,50.81694],[6.00462,50.80065],[5.98404,50.80988],[5.97497,50.79992],[6.02624,50.77453],[6.01976,50.75398],[6.03889,50.74618],[6.0326,50.72647],[6.0406,50.71848],[6.04428,50.72861],[6.11707,50.72231],[6.17852,50.6245],[6.26957,50.62444],[6.2476,50.60392],[6.24888,50.59869],[6.24005,50.58732],[6.22581,50.5907],[6.20281,50.56952],[6.17739,50.55875],[6.17802,50.54179],[6.19735,50.53576],[6.19579,50.5313],[6.18716,50.52653],[6.19193,50.5212],[6.20599,50.52089],[6.22335,50.49578],[6.26637,50.50272],[6.30809,50.50058],[6.3465,50.48833],[6.34005,50.46083],[6.37219,50.45397],[6.36852,50.40776],[6.34406,50.37994],[6.3688,50.35898],[6.40785,50.33557],[6.40641,50.32425],[6.35701,50.31139],[6.32488,50.32333],[6.29949,50.30887],[6.28797,50.27458],[6.208,50.25179],[6.16853,50.2234],[6.18364,50.20815],[6.18739,50.1822],[6.14588,50.17106],[6.14132,50.14971],[6.15298,50.14126],[6.1379,50.12964],[6.12055,50.09171],[6.11274,50.05916],[6.13458,50.04141],[6.13044,50.02929],[6.14666,50.02207],[6.13794,50.01466],[6.13273,50.02019],[6.1295,50.01849],[6.13806,50.01056],[6.14948,50.00908],[6.14147,49.99563],[6.1701,49.98518],[6.16466,49.97086],[6.17872,49.9537],[6.18554,49.95622],[6.18045,49.96611],[6.19089,49.96991],[6.19856,49.95053],[6.22094,49.94955],[6.22608,49.929],[6.21882,49.92403],[6.22926,49.92096],[6.23496,49.89972],[6.26146,49.88203],[6.28874,49.87592],[6.29692,49.86685],[6.30963,49.87021],[6.32303,49.85133],[6.32098,49.83728],[6.33585,49.83785],[6.34267,49.84974],[6.36576,49.85032],[6.40022,49.82029],[6.42521,49.81591],[6.42905,49.81091],[6.44131,49.81443],[6.45425,49.81164],[6.47111,49.82263],[6.48718,49.81267],[6.50647,49.80916],[6.51215,49.80124],[6.52121,49.81338],[6.53122,49.80666],[6.52169,49.79787],[6.50534,49.78952],[6.51669,49.78336],[6.51056,49.77515],[6.51828,49.76855],[6.51646,49.75961],[6.50174,49.75292],[6.50193,49.73291],[6.51805,49.72425],[6.51397,49.72058],[6.50261,49.72718],[6.49535,49.72645],[6.49694,49.72205],[6.5042,49.71808],[6.50647,49.71353],[6.49785,49.71118],[6.48014,49.69767],[6.46048,49.69092],[6.44654,49.67799],[6.42937,49.66857],[6.42726,49.66078],[6.43768,49.66021],[6.4413,49.65722],[6.41861,49.61723],[6.39822,49.60081],[6.385,49.59946],[6.37464,49.58886],[6.38342,49.5799],[6.38024,49.57593],[6.36676,49.57813],[6.35825,49.57053],[6.38228,49.55855],[6.38072,49.55171],[6.35666,49.52931],[6.36788,49.50377],[6.36907,49.48931],[6.36778,49.46937],[6.38352,49.46463],[6.39168,49.4667],[6.40274,49.46546],[6.42432,49.47683],[6.55404,49.42464],[6.533,49.40748],[6.60091,49.36864],[6.58807,49.35358],[6.572,49.35027],[6.60186,49.31055],[6.66583,49.28065],[6.69274,49.21661],[6.71843,49.2208],[6.73256,49.20486],[6.71137,49.18808],[6.73765,49.16375],[6.78265,49.16793],[6.83385,49.15162],[6.84703,49.15734],[6.86225,49.18185],[6.85016,49.19354],[6.85119,49.20038],[6.83555,49.21249],[6.85939,49.22376],[6.89298,49.20863],[6.91875,49.22261],[6.93831,49.2223],[6.94028,49.21641],[6.95963,49.203],[6.97273,49.2099],[7.01318,49.19018],[7.03459,49.19096],[7.0274,49.17042],[7.03178,49.15734],[7.04662,49.13724],[7.04409,49.12123],[7.04843,49.11422],[7.05548,49.11185],[7.06642,49.11415],[7.07162,49.1255],[7.09007,49.13094],[7.07859,49.15031],[7.10715,49.15631],[7.10384,49.13787],[7.12504,49.14253],[7.1358,49.1282],[7.1593,49.1204],[7.23473,49.12971],[7.29514,49.11426],[7.3195,49.14231],[7.35995,49.14399],[7.3662,49.17308],[7.44052,49.18354],[7.44455,49.16765],[7.49473,49.17],[7.49172,49.13915],[7.53012,49.09818],[7.56416,49.08136],[7.62575,49.07654],[7.63618,49.05428],[7.75948,49.04562],[7.79557,49.06583],[7.86386,49.03499],[7.93641,49.05544],[7.97783,49.03161],[8.14189,48.97833],[8.22604,48.97352],[8.20031,48.95856],[8.19989,48.95825],[8.12813,48.87985],[8.10253,48.81829],[8.06802,48.78957],[8.0326,48.79017],[8.01534,48.76085],[7.96994,48.75606],[7.96812,48.72491],[7.89002,48.66317],[7.84098,48.64217],[7.80057,48.5857],[7.80167,48.54758],[7.80647,48.51239],[7.76833,48.48945],[7.73109,48.39192],[7.74562,48.32736],[7.69022,48.30018],[7.6648,48.22219],[7.57137,48.12292],[7.56966,48.03265],[7.62302,47.97898],[7.55673,47.87371],[7.52921,47.77747],[7.54761,47.72912],[7.53722,47.71635],[7.51266,47.70197],[7.51915,47.68335],[7.52067,47.66437],[7.53384,47.65115],[7.5591,47.63849],[7.57423,47.61628],[7.58851,47.60794],[7.59301,47.60058],[7.58945,47.59017],[7.60523,47.58519],[7.60459,47.57869],[7.61929,47.57683],[7.64309,47.59151],[7.64213,47.5944],[7.64599,47.59695],[7.67395,47.59212],[7.68229,47.59905],[7.69385,47.60099],[7.68486,47.59601],[7.67115,47.5871],[7.68904,47.57133],[7.67655,47.56435],[7.63338,47.56256],[7.65083,47.54662],[7.66174,47.54554],[7.6656,47.53752],[7.68101,47.53232],[7.69642,47.53297],[7.71961,47.54219],[7.75261,47.54599],[7.79486,47.55691],[7.80098,47.56335],[7.811279,47.56946],[7.81901,47.58798],[7.833466,47.58663],[7.84167,47.58196],[7.862692,47.58808],[7.88664,47.58854],[7.898354,47.58408],[7.90673,47.57674],[7.911615,47.56686],[7.906809,47.56037],[7.91251,47.55031],[7.920585,47.5469],[7.932644,47.54704],[7.94614,47.5436],[7.95682,47.55789],[7.97581,47.55493],[8.00113,47.55616],[8.02136,47.55096],[8.04383,47.55443],[8.06663,47.56374],[8.08557,47.55768],[8.10002,47.56504],[8.10395,47.57918],[8.11543,47.5841],[8.13662,47.58432],[8.13823,47.59147],[8.14947,47.59558],[8.1652,47.5945],[8.19378,47.61636],[8.20617,47.62141],[8.22011,47.6181],[8.22577,47.60385],[8.23809,47.61204],[8.25863,47.61571],[8.26313,47.6103],[8.2824,47.61225],[8.29722,47.60603],[8.29524,47.5919],[8.30277,47.58607],[8.32735,47.57133],[8.35512,47.57014],[8.38273,47.56608],[8.39477,47.57826],[8.43235,47.56617],[8.49431,47.58107],[8.48949,47.588],[8.46637,47.58389],[8.45578,47.60121],[8.50747,47.61897],[8.51686,47.63476],[8.55756,47.62394],[8.57586,47.59537],[8.60348,47.61204],[8.59545,47.64298],[8.60701,47.65271],[8.61471,47.64514],[8.60412,47.63735],[8.62049,47.63757],[8.62884,47.65098],[8.61113,47.66332],[8.6052,47.67258],[8.57683,47.66158],[8.56141,47.67088],[8.52801,47.66059],[8.5322,47.64687],[8.49656,47.64709],[8.46605,47.64103],[8.4667,47.65747],[8.44711,47.65379],[8.42264,47.66667],[8.41346,47.66676],[8.40473,47.67499],[8.4211,47.68407],[8.40569,47.69855],[8.44807,47.72426],[8.45771,47.7493],[8.48868,47.77215],[8.56814,47.78001],[8.56415,47.80633],[8.61657,47.79998],[8.62408,47.7626],[8.64425,47.76398],[8.65292,47.80066],[8.68022,47.78599],[8.68985,47.75686],[8.71778,47.76571],[8.74251,47.75168],[8.70543,47.73121],[8.73671,47.7169],[8.72617,47.69651],[8.72809,47.69282],[8.75856,47.68969],[8.79511,47.67462],[8.79966,47.70222],[8.76965,47.7075],[8.77309,47.72059],[8.80663,47.73821],[8.82002,47.71458],[8.86989,47.70504],[8.85065,47.68209],[8.87383,47.67045],[8.87625,47.65441],[8.89946,47.64769],[8.94093,47.65596],[9.02093,47.6868],[9.09891,47.67801],[9.13845,47.66389],[9.15181,47.66904],[9.1705,47.65513],[9.1755,47.65584],[9.17593,47.65399],[9.18203,47.65598],[9.25619,47.65939],[9.55125,47.53629],[9.72736,47.53457],[9.76748,47.5934],[9.80254,47.59419],[9.82591,47.58158],[9.8189,47.54688],[9.87499,47.52953],[9.87733,47.54688],[9.92407,47.53111],[9.96029,47.53899],[10.00003,47.48216],[10.03859,47.48927],[10.07131,47.45531],[10.09001,47.46005],[10.1052,47.4316],[10.06897,47.40709],[10.09819,47.35724],[10.11805,47.37228],[10.16362,47.36674],[10.17648,47.38889],[10.2127,47.38019],[10.22774,47.38904],[10.23757,47.37609],[10.19998,47.32832],[10.2147,47.31014],[10.17648,47.29149],[10.17531,47.27167],[10.23257,47.27088],[10.33424,47.30813],[10.39851,47.37623],[10.4324,47.38494],[10.4359,47.41183],[10.47446,47.43318],[10.46278,47.47901],[10.44291,47.48453],[10.4324,47.50111],[10.44992,47.5524],[10.43473,47.58394],[10.47329,47.58552],[10.48849,47.54057],[10.56912,47.53584],[10.60337,47.56755],[10.63456,47.5591],[10.68832,47.55752],[10.6965,47.54253],[10.7596,47.53228],[10.77596,47.51729],[10.88814,47.53701],[10.91268,47.51334],[10.86945,47.5015],[10.87061,47.4786],[10.90918,47.48571],[10.93839,47.48018],[10.92437,47.46991],[10.98513,47.42882],[10.97111,47.41617],[10.97111,47.39561],[11.11835,47.39719],[11.12536,47.41222],[11.20482,47.43198],[11.25157,47.43277],[11.22002,47.3964],[11.27844,47.39956],[11.29597,47.42566],[11.33804,47.44937],[11.4175,47.44621],[11.38128,47.47465],[11.4362,47.51413],[11.52618,47.50939],[11.58578,47.52281],[11.58811,47.55515],[11.60681,47.57881],[11.63934,47.59202],[11.84052,47.58354],[11.85572,47.60166],[12.0088,47.62451],[12.02282,47.61033],[12.05788,47.61742],[12.13734,47.60639],[12.17824,47.61506],[12.18145,47.61019],[12.17737,47.60121],[12.18568,47.6049],[12.20398,47.60667],[12.20801,47.61082],[12.19895,47.64085],[12.18507,47.65984],[12.18347,47.66663],[12.16769,47.68167],[12.16217,47.70105],[12.18303,47.70065],[12.22571,47.71776],[12.2542,47.7433],[12.26238,47.73544],[12.24017,47.69534],[12.26004,47.67725],[12.27991,47.68827],[12.336,47.69534],[12.37222,47.68433],[12.43883,47.6977],[12.44117,47.6741],[12.50076,47.62293],[12.53816,47.63553],[12.57438,47.63238],[12.6071,47.6741],[12.7357,47.6787],[12.77777,47.66689],[12.76492,47.64485],[12.82101,47.61493],[12.77427,47.58025],[12.80699,47.54477],[12.84672,47.54556],[12.85256,47.52741],[12.9624,47.47452],[12.98344,47.48716],[12.9998,47.46267],[13.04537,47.49426],[13.03252,47.53373],[13.05355,47.56291],[13.04537,47.58183],[13.06641,47.58577],[13.06407,47.60075],[13.09562,47.63304],[13.07692,47.68814],[13.01382,47.72116],[12.98578,47.7078],[12.92969,47.71094],[12.91333,47.7178],[12.90274,47.72513],[12.91711,47.74026],[12.9353,47.74788],[12.94371,47.76281],[12.93202,47.77302],[12.96311,47.79957],[12.98543,47.82896],[13.00588,47.84374],[12.94163,47.92927],[12.93886,47.94046],[12.93642,47.94436],[12.93419,47.94063],[12.92668,47.93879],[12.91985,47.94069],[12.9211,47.95135],[12.91683,47.95647],[12.87476,47.96195],[12.8549,48.01122],[12.76141,48.07373],[12.74973,48.10885],[12.7617,48.12796],[12.78595,48.12445],[12.80676,48.14979],[12.82673,48.15245],[12.8362,48.15876],[12.836,48.1647],[12.84475,48.16556],[12.87126,48.20318],[12.95306,48.20629],[13.02083,48.25689],[13.0851,48.27711],[13.126,48.27867],[13.18093,48.29577],[13.26039,48.29422],[13.30897,48.31575],[13.40709,48.37292],[13.43929,48.43386],[13.42527,48.45711],[13.45727,48.51092],[13.43695,48.55776],[13.45214,48.56472],[13.46967,48.55157],[13.50663,48.57506],[13.50131,48.58091],[13.51291,48.59023],[13.57535,48.55912],[13.59705,48.57013],[13.62508,48.55501],[13.65186,48.55092],[13.66113,48.53558],[13.72802,48.51208],[13.74816,48.53058],[13.7513,48.5624],[13.76921,48.55324],[13.80519,48.58026],[13.80038,48.59487],[13.82609,48.62345],[13.81901,48.6761],[13.81283,48.68426],[13.81791,48.69832],[13.79337,48.71375],[13.81863,48.73257],[13.82266,48.75544],[13.84023,48.76988],[13.8096,48.77877],[13.78977,48.83319],[13.76994,48.83537],[13.73854,48.88538],[13.67739,48.87886],[13.61624,48.9462],[13.58319,48.96899],[13.50552,48.97441],[13.50221,48.93752],[13.40802,48.98851],[13.39479,49.04812],[13.28242,49.1228],[13.23689,49.11412],[13.20405,49.12303],[13.17019,49.14339],[13.17665,49.16713],[13.05883,49.26259],[13.02957,49.27399],[13.03618,49.30417],[12.94859,49.34079],[12.88249,49.35479],[12.88414,49.33541],[12.78168,49.34618],[12.75854,49.3989],[12.71227,49.42363],[12.669,49.42935],[12.64121,49.47628],[12.64782,49.52565],[12.60155,49.52887],[12.56188,49.6146],[12.53544,49.61888],[12.52553,49.68415],[12.4462,49.70233],[12.40489,49.76321],[12.46603,49.78882],[12.48256,49.83575],[12.55197,49.92094],[12.47264,49.94222],[12.49908,49.97305],[12.30798,50.05719],[12.26111,50.06331],[12.27433,50.0771],[12.23709,50.10213],[12.2073,50.10315],[12.1917,50.13434],[12.21484,50.16399],[12.19335,50.19997],[12.09287,50.25032],[12.13716,50.27396],[12.10907,50.32041],[12.18013,50.32146],[12.20823,50.2729],[12.25119,50.27079],[12.26953,50.25189],[12.24791,50.25525],[12.23943,50.24594],[12.28755,50.22429],[12.28063,50.19544],[12.29232,50.17524],[12.32596,50.17146],[12.33847,50.19432],[12.32445,50.20442],[12.33263,50.24367],[12.35425,50.23993],[12.36594,50.28289],[12.40158,50.29521],[12.39924,50.32302],[12.43371,50.32506],[12.43722,50.33774],[12.46643,50.35527],[12.48256,50.34784],[12.49214,50.35228],[12.48747,50.37278],[12.51356,50.39694],[12.67261,50.41949],[12.70731,50.39948],[12.73044,50.42268],[12.73476,50.43237],[12.82465,50.45738],[12.94058,50.40944],[12.98433,50.42016],[13.02147,50.44763],[13.02038,50.4734],[13.0312,50.50944],[13.08301,50.50132],[13.13424,50.51709],[13.19043,50.50237],[13.25158,50.59268],[13.29454,50.57904],[13.32594,50.58009],[13.32264,50.60317],[13.37805,50.627],[13.37485,50.64931],[13.42189,50.61243],[13.46413,50.60102],[13.49742,50.63133],[13.5226,50.64721],[13.53748,50.67654],[13.52474,50.70394],[13.65977,50.73096],[13.70204,50.71771],[13.76316,50.73487],[13.82942,50.7251],[13.89444,50.74142],[13.89113,50.78533],[13.98864,50.8177],[14.02982,50.80662],[14.22331,50.86049],[14.24314,50.88761],[14.27123,50.89386],[14.30098,50.88448],[14.38691,50.89907],[14.39848,50.93866],[14.31422,50.95243],[14.30251,50.96606],[14.32793,50.97379],[14.32353,50.98556],[14.28776,50.97718],[14.25665,50.98935],[14.30098,51.05515],[14.41335,51.02086],[14.45827,51.03712],[14.49202,51.02286],[14.49154,51.04382],[14.49991,51.04692],[14.50809,51.0427],[14.49873,51.02242],[14.53321,51.01679],[14.53438,51.00374],[14.56432,51.01008],[14.58215,50.99306],[14.59908,50.98685],[14.59702,50.96148],[14.56374,50.922],[14.58024,50.91443],[14.64802,50.93241],[14.65259,50.90513],[14.63434,50.8883],[14.61993,50.86049],[14.70661,50.84096],[14.79139,50.81438],[14.82803,50.86966],[14.81664,50.88148],[14.89681,50.9422],[14.89252,50.94999],[14.92942,50.99744],[14.95529,51.04552],[14.97938,51.07742],[14.98229,51.11354],[14.99689,51.12205],[14.99079,51.14284],[14.99646,51.14365],[15.00083,51.14974],[14.99414,51.15813],[14.99311,51.16249],[15.0047,51.16874],[15.01242,51.21285],[15.04288,51.28387],[14.98008,51.33449],[14.96899,51.38367],[14.9652,51.44793],[14.94749,51.47155],[14.73219,51.52922],[14.72652,51.53902],[14.73047,51.54606],[14.71125,51.56209],[14.7727,51.61263],[14.75759,51.62318],[14.75392,51.67445],[14.69065,51.70842],[14.66386,51.73282],[14.64625,51.79472],[14.60493,51.80473],[14.59089,51.83302],[14.6588,51.88359],[14.6933,51.9044],[14.70601,51.92944],[14.7177,51.94048],[14.72163,51.95188],[14.71836,51.95606],[14.7139,51.95643],[14.70488,51.97679],[14.71339,52.00337],[14.76026,52.06624],[14.72971,52.09167],[14.6917,52.10283],[14.67683,52.13936],[14.70616,52.16927],[14.68344,52.19612],[14.71319,52.22144],[14.70139,52.25038],[14.58149,52.28007],[14.56378,52.33838],[14.55228,52.35264],[14.54423,52.42568],[14.63056,52.48993],[14.60081,52.53116],[14.6289,52.57136],[14.61073,52.59847],[14.22071,52.81175],[14.13806,52.82392],[14.12256,52.84311],[14.15873,52.87715],[14.14056,52.95786],[14.25954,53.00264],[14.35044,53.05829],[14.38679,53.13669],[14.36696,53.16444],[14.37853,53.20405],[14.40662,53.21098],[14.45125,53.26241],[14.44133,53.27427],[14.4215,53.27724],[14.35209,53.49506],[14.3273,53.50587],[14.30416,53.55499],[14.31904,53.61581],[14.2853,53.63392],[14.28477,53.65955],[14.27133,53.66613],[14.2836,53.67721],[14.26782,53.69866],[14.27249,53.74464],[14.21323,53.8664],[14.20823,53.90776],[14.18544,53.91258],[14.20647,53.91671],[14.22634,53.9291],[14.20811,54.12784],[13.93395,54.84044],[12.85844,54.82438],[11.90309,54.38543],[11.00303,54.63689],[10.31111,54.65968],[10.16755,54.73883],[9.89314,54.84171],[9.73563,54.8247],[9.61187,54.85548],[9.62734,54.88057],[9.58937,54.88785],[9.4659,54.83131],[9.43155,54.82586],[9.41213,54.84254],[9.38532,54.83968],[9.36496,54.81749],[9.33849,54.80233],[9.32771,54.80602],[9.2474,54.8112],[9.23445,54.83432],[9.24631,54.84726],[9.20571,54.85841],[9.14275,54.87421],[9.04629,54.87249],[8.92795,54.90452],[8.81178,54.90518],[8.76387,54.8948],[8.63979,54.91069],[8.55769,54.91837],[8.45719,55.06747],[8.02459,55.09613],[5.45168,54.20039]]],[[[8.65769,47.68928],[8.66837,47.68437],[8.68985,47.69552],[8.70847,47.68904],[8.71773,47.69088],[8.70237,47.71453],[8.66416,47.71367],[8.67508,47.6979],[8.65769,47.68928]]]]}},{"type":"Feature","properties":{"id":"BE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[2.18458,51.52087],[2.55904,51.07014],[2.57551,51.00326],[2.63074,50.94746],[2.59093,50.91751],[2.63331,50.81457],[2.71165,50.81295],[2.81056,50.71773],[2.8483,50.72276],[2.86985,50.7033],[2.87937,50.70298],[2.88504,50.70656],[2.90069,50.69263],[2.91036,50.6939],[2.90873,50.702],[2.95019,50.75138],[2.96778,50.75242],[3.00537,50.76588],[3.04314,50.77674],[3.09163,50.77717],[3.10614,50.78303],[3.11206,50.79416],[3.11987,50.79188],[3.1257,50.78603],[3.15017,50.79031],[3.16476,50.76843],[3.18339,50.74981],[3.18811,50.74025],[3.20064,50.73547],[3.19017,50.72569],[3.20845,50.71662],[3.22042,50.71019],[3.24593,50.71389],[3.26063,50.70086],[3.26141,50.69151],[3.2536,50.68977],[3.264,50.67668],[3.23951,50.6585],[3.2729,50.60718],[3.28575,50.52724],[3.37693,50.49538],[3.44629,50.51009],[3.47385,50.53397],[3.51564,50.5256],[3.49509,50.48885],[3.5683,50.50192],[3.58361,50.49049],[3.61014,50.49568],[3.64426,50.46275],[3.66153,50.45165],[3.67494,50.40239],[3.67262,50.38663],[3.65709,50.36873],[3.66976,50.34563],[3.71009,50.30305],[3.70987,50.3191],[3.73911,50.34809],[3.84314,50.35219],[3.90781,50.32814],[3.96771,50.34989],[4.0268,50.35793],[4.0689,50.3254],[4.10237,50.31247],[4.10957,50.30234],[4.11954,50.30425],[4.13665,50.25609],[4.16808,50.25786],[4.15524,50.2833],[4.17347,50.28838],[4.17861,50.27443],[4.20651,50.27333],[4.21945,50.25539],[4.15524,50.21103],[4.16014,50.19239],[4.13561,50.13078],[4.20147,50.13535],[4.23101,50.06945],[4.16294,50.04719],[4.13508,50.01976],[4.14239,49.98034],[4.20532,49.95803],[4.31963,49.97043],[4.35051,49.95315],[4.43488,49.94122],[4.51098,49.94659],[4.5414,49.96911],[4.68695,49.99685],[4.70064,50.09384],[4.75237,50.11314],[4.82438,50.16878],[4.83279,50.15331],[4.88602,50.15182],[4.8382,50.06738],[4.78827,49.95609],[4.88529,49.9236],[4.85134,49.86457],[4.86965,49.82271],[4.85464,49.78995],[4.96714,49.79872],[5.09249,49.76193],[5.14545,49.70287],[5.26232,49.69456],[5.31465,49.66846],[5.33039,49.6555],[5.30214,49.63055],[5.3137,49.61225],[5.33851,49.61599],[5.34837,49.62889],[5.3974,49.61596],[5.43713,49.5707],[5.46734,49.52648],[5.46541,49.49825],[5.55001,49.52729],[5.60909,49.51228],[5.64505,49.55146],[5.75649,49.54321],[5.7577,49.55915],[5.77435,49.56298],[5.79195,49.55228],[5.81838,49.54777],[5.84143,49.5533],[5.84692,49.55663],[5.8424,49.56082],[5.87256,49.57539],[5.86986,49.58756],[5.84971,49.58674],[5.84826,49.5969],[5.8762,49.60898],[5.87609,49.62047],[5.88393,49.62802],[5.88552,49.63507],[5.90599,49.63853],[5.90164,49.6511],[5.9069,49.66377],[5.86175,49.67862],[5.86527,49.69291],[5.88677,49.70951],[5.86503,49.72739],[5.84193,49.72161],[5.82562,49.72395],[5.83149,49.74729],[5.82245,49.75048],[5.78871,49.7962],[5.75409,49.79239],[5.74953,49.81428],[5.74364,49.82058],[5.74844,49.82435],[5.7404,49.83452],[5.74076,49.83823],[5.74975,49.83933],[5.74953,49.84709],[5.75884,49.84811],[5.74567,49.85368],[5.75861,49.85631],[5.75269,49.8711],[5.78415,49.87922],[5.73621,49.89796],[5.77314,49.93646],[5.77291,49.96056],[5.80833,49.96451],[5.81163,49.97142],[5.83467,49.97823],[5.83968,49.9892],[5.82331,49.99662],[5.81866,50.01286],[5.8551,50.02683],[5.86904,50.04614],[5.85474,50.06342],[5.8857,50.07824],[5.89488,50.11476],[5.95929,50.13295],[5.96453,50.17259],[6.02488,50.18283],[6.03093,50.16362],[6.06406,50.15344],[6.08577,50.17246],[6.12028,50.16374],[6.1137,50.13668],[6.1379,50.12964],[6.15298,50.14126],[6.14132,50.14971],[6.14588,50.17106],[6.18739,50.1822],[6.18364,50.20815],[6.16853,50.2234],[6.208,50.25179],[6.28797,50.27458],[6.29949,50.30887],[6.32488,50.32333],[6.35701,50.31139],[6.40641,50.32425],[6.40785,50.33557],[6.3688,50.35898],[6.34406,50.37994],[6.36852,50.40776],[6.37219,50.45397],[6.34005,50.46083],[6.3465,50.48833],[6.30809,50.50058],[6.26637,50.50272],[6.22335,50.49578],[6.20599,50.52089],[6.19193,50.5212],[6.18716,50.52653],[6.19579,50.5313],[6.19735,50.53576],[6.17802,50.54179],[6.17739,50.55875],[6.20281,50.56952],[6.22581,50.5907],[6.24005,50.58732],[6.24888,50.59869],[6.2476,50.60392],[6.26957,50.62444],[6.17852,50.6245],[6.11707,50.72231],[6.04428,50.72861],[6.0406,50.71848],[6.0326,50.72647],[6.03889,50.74618],[6.01976,50.75398],[5.97545,50.75441],[5.95942,50.7622],[5.89132,50.75124],[5.89129,50.75125],[5.88734,50.77092],[5.84888,50.75448],[5.84548,50.76542],[5.80673,50.7558],[5.77513,50.78308],[5.76533,50.78159],[5.74356,50.7691],[5.73904,50.75674],[5.72216,50.76398],[5.69469,50.75529],[5.68091,50.75804],[5.70107,50.7827],[5.68995,50.79641],[5.70118,50.80764],[5.65259,50.82309],[5.64009,50.84742],[5.64504,50.87107],[5.67886,50.88142],[5.69858,50.91046],[5.71626,50.90796],[5.72644,50.91167],[5.72545,50.92312],[5.74644,50.94723],[5.75927,50.95601],[5.74752,50.96202],[5.72875,50.95428],[5.71864,50.96092],[5.76242,50.99703],[5.77688,51.02483],[5.75961,51.03113],[5.77258,51.06196],[5.79835,51.05834],[5.79903,51.09371],[5.82921,51.09328],[5.83226,51.10585],[5.8109,51.10861],[5.80798,51.11661],[5.85508,51.14445],[5.82564,51.16753],[5.77697,51.1522],[5.77735,51.17845],[5.74617,51.18928],[5.70344,51.1829],[5.65528,51.18736],[5.65145,51.19788],[5.5603,51.22249],[5.5569,51.26544],[5.515,51.29462],[5.48476,51.30053],[5.46519,51.2849],[5.4407,51.28169],[5.41672,51.26248],[5.347,51.27502],[5.33886,51.26314],[5.29716,51.26104],[5.26461,51.26693],[5.23814,51.26064],[5.22542,51.26888],[5.24244,51.30495],[5.2002,51.32243],[5.16222,51.31035],[5.13377,51.31592],[5.13105,51.34791],[5.07102,51.39469],[5.10456,51.43163],[5.07891,51.4715],[5.04774,51.47022],[5.03281,51.48679],[5.0106,51.47167],[5.00393,51.44406],[4.92152,51.39487],[4.90016,51.41404],[4.84988,51.41502],[4.78941,51.41102],[4.77229,51.41337],[4.76577,51.43046],[4.78314,51.43319],[4.82946,51.4213],[4.82409,51.44736],[4.84139,51.4799],[4.78803,51.50284],[4.77321,51.50529],[4.74578,51.48937],[4.72935,51.48424],[4.65442,51.42352],[4.57489,51.4324],[4.53521,51.4243],[4.52846,51.45002],[4.54675,51.47265],[4.5388,51.48184],[4.47736,51.4778],[4.38122,51.44905],[4.39747,51.43316],[4.38064,51.41965],[4.43777,51.36989],[4.39292,51.35547],[4.34086,51.35738],[4.33265,51.37687],[4.21923,51.37443],[4.24024,51.35371],[4.16721,51.29348],[4.05165,51.24171],[4.01957,51.24504],[3.97889,51.22537],[3.90125,51.20371],[3.78783,51.2151],[3.78999,51.25766],[3.58939,51.30064],[3.51502,51.28697],[3.52698,51.2458],[3.43488,51.24135],[3.41704,51.25933],[3.38289,51.27331],[3.35847,51.31572],[3.38696,51.33436],[3.36263,51.37112],[2.56575,51.85301],[2.18458,51.52087]]],[[[4.91493,51.4353],[4.92652,51.43329],[4.92952,51.42984],[4.93986,51.43064],[4.94265,51.44003],[4.93471,51.43861],[4.93416,51.44185],[4.94025,51.44193],[4.93544,51.44634],[4.92879,51.44161],[4.92815,51.43856],[4.92566,51.44273],[4.92811,51.4437],[4.92287,51.44741],[4.91811,51.44621],[4.92227,51.44252],[4.91935,51.43634],[4.91493,51.4353]]],[[[4.93295,51.44945],[4.93909,51.44632],[4.9524,51.45014],[4.95244,51.45207],[4.93295,51.44945]]]]}},{"type":"Feature","properties":{"id":"AU-NSW"},"geometry":{"type":"Polygon","coordinates":[[[140.99934,-28.99903],[141.00268,-34.02172],[141.5377,-34.18902],[141.71349,-34.0924],[142.0211,-34.12651],[142.22023,-34.18334],[142.24495,-34.3014],[142.37404,-34.34563],[142.50999,-34.74267],[142.61711,-34.77765],[142.76268,-34.56871],[143.34221,-34.79344],[143.3271,-34.99618],[143.39027,-35.18047],[143.57155,-35.20741],[143.56743,-35.33634],[144.08241,-35.57238],[144.74022,-36.11895],[144.94896,-36.05236],[144.9778,-35.86673],[145.1165,-35.81774],[145.34447,-35.86005],[145.50789,-35.80772],[145.80589,-35.98461],[146.36894,-36.03571],[146.42387,-35.96794],[146.59966,-35.97349],[146.85097,-36.08788],[147.04185,-36.09898],[147.10503,-36.00683],[147.31926,-36.05458],[147.39616,-35.94681],[147.71202,-35.94237],[147.99217,-36.0457],[148.04573,-36.39248],[148.20366,-36.59782],[148.10753,-36.79272],[148.19405,-36.79602],[150.19768,-37.59458],[152.57175,-39.16128],[155.3142,-27.34698],[153.55096,-28.16364],[153.53414,-28.17635],[153.47715,-28.15789],[153.36385,-28.242],[153.18121,-28.25289],[153.10293,-28.35445],[152.87222,-28.30852],[152.74725,-28.35929],[152.60442,-28.27466],[152.57696,-28.3327],[152.49731,-28.25168],[151.94662,-28.54282],[152.06472,-28.69351],[152.01391,-28.89449],[151.7777,-28.9606],[151.72552,-28.86683],[151.55248,-28.94858],[151.39318,-29.17186],[151.30392,-29.15627],[151.27508,-28.94017],[150.74499,-28.63446],[150.43737,-28.66098],[150.30004,-28.53558],[149.67519,-28.62723],[149.58044,-28.57056],[149.48705,-28.58202],[149.37788,-28.68628],[149.19248,-28.77479],[148.95806,-28.99906],[140.99934,-28.99903]],[[148.76247,-35.49504],[148.80951,-35.30698],[149.12159,-35.1241],[149.19746,-35.18502],[149.18956,-35.20157],[149.2469,-35.2285],[149.23488,-35.24336],[149.39418,-35.30362],[149.39796,-35.32435],[149.35058,-35.3518],[149.33719,-35.33976],[149.25136,-35.33024],[149.2057,-35.34732],[149.13429,-35.45338],[149.15283,-35.50566],[149.12983,-35.55288],[149.14219,-35.59337],[149.07936,-35.58193],[149.09549,-35.6411],[149.09824,-35.81223],[149.04811,-35.91684],[148.96194,-35.8971],[148.89602,-35.82504],[148.89431,-35.75095],[148.8768,-35.715],[148.85723,-35.76043],[148.78891,-35.69995],[148.76247,-35.49504]],[[150.59126,-35.17225],[150.60036,-35.1672],[150.60534,-35.15429],[150.59564,-35.15197],[150.59384,-35.14376],[150.66156,-35.11779],[150.70087,-35.12312],[150.78069,-35.10852],[150.7431,-35.20971],[150.59307,-35.18389],[150.59126,-35.17225]]]}},{"type":"Feature","properties":{"id":"AE"},"geometry":{"type":"MultiPolygon","coordinates":[[[[51.41644,24.39615],[51.58871,24.27256],[51.59617,24.12041],[52.56622,22.94341],[55.13599,22.63334],[55.2137,22.71065],[55.22634,23.10378],[55.57358,23.669],[55.48677,23.94946],[55.73301,24.05994],[55.8308,24.01633],[56.01799,24.07426],[55.95472,24.2172],[55.83367,24.20193],[55.77658,24.23476],[55.76558,24.23227],[55.75257,24.23466],[55.75382,24.2466],[55.75939,24.26114],[55.76781,24.26209],[55.79145,24.27914],[55.80747,24.31069],[55.83395,24.32776],[55.83271,24.41521],[55.76461,24.5287],[55.83271,24.68567],[55.83408,24.77858],[55.81348,24.80102],[55.81116,24.9116],[55.85094,24.96858],[55.90849,24.96771],[55.96316,25.00857],[56.05715,24.95727],[56.05106,24.87461],[55.97467,24.89639],[55.97836,24.87673],[56.03535,24.81161],[56.06128,24.74457],[56.13684,24.73699],[56.20062,24.78565],[56.20568,24.85063],[56.30269,24.88334],[56.34873,24.93205],[56.3227,24.97284],[56.86325,25.03856],[56.82555,25.7713],[56.26534,25.62825],[56.25341,25.61443],[56.26636,25.60643],[56.25365,25.60211],[56.20473,25.61119],[56.18363,25.65508],[56.14826,25.66351],[56.13579,25.73524],[56.17416,25.77239],[56.13963,25.82765],[56.19334,25.9795],[56.15498,26.06828],[56.08666,26.05038],[55.81777,26.18798],[55.14145,25.62624],[53.97892,24.64436],[52.82259,25.51697],[52.35509,25.00368],[52.02277,24.75635],[51.83108,24.71675],[51.58834,24.66608],[51.41644,24.39615]],[[56.20838,25.25668],[56.24465,25.27505],[56.25008,25.28843],[56.23362,25.31253],[56.26062,25.33108],[56.3005,25.31815],[56.3111,25.30107],[56.35172,25.30681],[56.34438,25.26653],[56.27628,25.23404],[56.24341,25.22867],[56.20872,25.24104],[56.20838,25.25668]]],[[[56.27086,25.26128],[56.28423,25.26344],[56.29379,25.2754],[56.28102,25.28486],[56.2716,25.27916],[56.27086,25.26128]]]]}},{"type":"Feature","properties":{"id":"BQ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-68.90012,12.62309],[-68.33524,11.78151],[-68.01417,11.77722],[-67.89186,12.4116],[-68.90012,12.62309]]],[[[-63.58819,17.61311],[-63.22932,17.32592],[-63.11114,17.23125],[-62.76692,17.64353],[-63.07669,17.79659],[-63.29212,17.90532],[-63.58819,17.61311]]]]}},{"type":"Feature","properties":{"id":"AM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[43.44984,41.0988],[43.47319,41.02251],[43.58683,40.98961],[43.67712,40.93084],[43.67712,40.84846],[43.74872,40.7365],[43.7425,40.66805],[43.63664,40.54159],[43.54791,40.47413],[43.60862,40.43267],[43.59928,40.34019],[43.71136,40.16673],[43.65221,40.14889],[43.65688,40.11199],[43.92307,40.01787],[44.1057,40.03555],[44.1778,40.02845],[44.26973,40.04866],[44.46635,39.97733],[44.61845,39.8281],[44.75779,39.7148],[44.88354,39.74432],[44.92869,39.72157],[45.06604,39.79277],[45.18554,39.67846],[45.17464,39.58614],[45.21784,39.58074],[45.23535,39.61373],[45.30385,39.61373],[45.29606,39.57654],[45.46992,39.49888],[45.70547,39.60174],[45.80804,39.56716],[45.83,39.46487],[45.79225,39.3695],[45.99774,39.28931],[46.02303,39.09978],[46.06973,39.0744],[46.14785,38.84206],[46.20601,38.85262],[46.34059,38.92076],[46.53497,38.86548],[46.51805,38.94982],[46.54296,39.07078],[46.44022,39.19636],[46.52584,39.18912],[46.54141,39.15895],[46.58032,39.21204],[46.63481,39.23013],[46.56476,39.24942],[46.50093,39.33736],[46.43244,39.35181],[46.37795,39.42039],[46.4013,39.45405],[46.53051,39.47809],[46.51027,39.52373],[46.57721,39.54414],[46.57098,39.56694],[46.52117,39.58734],[46.42465,39.57534],[46.40286,39.63651],[46.18493,39.60533],[45.96543,39.78859],[45.82533,39.82925],[45.7833,39.9475],[45.60895,39.97733],[45.59806,40.0131],[45.78642,40.03218],[45.83779,39.98925],[45.97944,40.181],[45.95609,40.27846],[45.65098,40.37696],[45.42994,40.53804],[45.45484,40.57707],[45.35366,40.65979],[45.4206,40.7424],[45.55914,40.78366],[45.60584,40.87436],[45.40814,40.97904],[45.44083,41.01663],[45.39725,41.02603],[45.35677,40.99784],[45.28859,41.03757],[45.26162,41.0228],[45.25897,41.0027],[45.1994,41.04518],[45.16493,41.05068],[45.1634,41.08082],[45.1313,41.09369],[45.12923,41.06059],[45.06784,41.05379],[45.08028,41.10917],[45.19942,41.13299],[45.1969,41.168],[45.11811,41.19967],[45.05201,41.19211],[45.02932,41.2101],[45.05497,41.2464],[45.0133,41.29747],[44.93493,41.25685],[44.81437,41.30371],[44.80053,41.25949],[44.81749,41.23488],[44.84358,41.23088],[44.89911,41.21366],[44.87887,41.20195],[44.82084,41.21513],[44.72814,41.20338],[44.61462,41.24018],[44.59322,41.1933],[44.46791,41.18204],[44.34417,41.2382],[44.34337,41.20312],[44.32139,41.2079],[44.18148,41.24644],[44.16591,41.19141],[43.84835,41.16329],[43.74717,41.1117],[43.67712,41.13398],[43.4717,41.12611],[43.44984,41.0988]],[[44.95383,41.07553],[44.97169,41.09176],[45.00864,41.09407],[45.03406,41.07931],[45.04517,41.06653],[45.03792,41.03938],[45.00864,41.03411],[44.9903,41.05657],[44.96031,41.06345],[44.95383,41.07553]],[[45.18382,41.0066],[45.20625,41.01484],[45.23487,41.00226],[45.23095,40.97828],[45.21324,40.9817],[45.21219,40.99001],[45.20518,40.99348],[45.19312,40.98998],[45.18382,41.0066]]],[[[45.47927,40.65023],[45.50279,40.58424],[45.56071,40.64765],[45.51825,40.67382],[45.47927,40.65023]]]]}},{"type":"Feature","properties":{"id":"SJ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-10.71459,70.09565],[-5.93364,70.76368],[-9.68082,72.73731],[-10.71459,70.09565]]],[[[-3.52068,82.6752],[16.4353,73.61229],[33.12005,75.46568],[35.22046,80.57056],[-3.52068,82.6752]]]]}},{"type":"Feature","properties":{"id":"CN-GD"},"geometry":{"type":"Polygon","coordinates":[[[108.26073,20.07614],[111.04979,20.2622],[117.76968,23.10828],[117.05863,23.73884],[116.96353,23.90655],[116.97589,23.95739],[116.97933,24.00099],[116.91478,24.09097],[116.99512,24.18402],[116.93023,24.23256],[116.89693,24.40025],[116.7517,24.5415],[116.81076,24.68352],[116.51859,24.60332],[116.48735,24.67977],[116.37062,24.80231],[116.40975,24.84313],[116.34761,24.86899],[116.29886,24.79857],[116.20754,24.84718],[116.05201,24.85528],[115.96618,24.92193],[115.88859,24.94123],[115.89889,24.87833],[115.86696,24.86743],[115.82405,24.91539],[115.76362,24.79109],[115.76499,24.71221],[115.80379,24.69131],[115.78559,24.63703],[115.84327,24.5671],[115.69358,24.54056],[115.65444,24.61799],[115.56381,24.62954],[115.46699,24.76584],[115.37738,24.76803],[115.10822,24.66792],[115.06599,24.70753],[114.93415,24.6467],[114.9266,24.67478],[114.85897,24.55805],[114.8442,24.58178],[114.72576,24.6055],[114.4178,24.48464],[114.35462,24.58865],[114.17541,24.6545],[114.57092,25.08746],[114.74739,25.13036],[114.5565,25.42281],[114.19464,25.29685],[114.00924,25.28319],[113.98315,25.40916],[113.56635,25.30802],[113.26217,25.51486],[113.12725,25.47039],[113.01721,25.34976],[112.89653,25.31501],[112.84984,25.34278],[112.8713,25.24857],[112.98923,25.24857],[113.02854,25.20059],[112.96674,25.16361],[113.00571,24.93999],[112.7798,24.89328],[112.70393,25.08622],[112.65174,25.13751],[112.18963,25.18987],[112.13504,25.00535],[112.11547,24.96582],[112.17143,24.91944],[112.15015,24.82662],[112.04166,24.77987],[111.93145,24.69506],[112.05711,24.35522],[111.87171,24.10978],[111.92596,23.97339],[111.79515,23.8133],[111.65645,23.83308],[111.63276,23.64641],[111.47724,23.62313],[111.34094,23.19654],[111.42711,23.03013],[111.35158,22.96123],[111.31965,22.85086],[110.99452,22.63682],[110.74424,22.56931],[110.73738,22.46307],[110.67626,22.47576],[110.78475,22.27353],[110.64193,22.23349],[110.67317,22.17659],[110.62442,22.15274],[110.34702,22.19567],[110.36556,21.93476],[110.39234,21.91199],[110.3841,21.89096],[110.32127,21.89351],[110.28573,21.91756],[110.24642,21.88332],[110.19458,21.90148],[109.98481,21.87185],[109.94585,21.84397],[109.92216,21.71198],[109.8904,21.65008],[109.76371,21.67178],[109.73968,21.6054],[109.78912,21.47351],[108.26073,20.07614]],[[113.52659,22.18271],[113.53552,22.20607],[113.53301,22.21235],[113.53593,22.2137],[113.54093,22.21314],[113.54333,22.21688],[113.5508,22.21672],[113.56865,22.20973],[113.57123,22.20416],[113.60504,22.20464],[113.63011,22.10782],[113.57191,22.07696],[113.54839,22.10909],[113.54942,22.14519],[113.54093,22.15497],[113.52659,22.18271]],[[113.81621,22.2163],[113.86771,22.42972],[114.03113,22.5065],[114.05438,22.5026],[114.05729,22.51104],[114.06272,22.51617],[114.07267,22.51855],[114.07817,22.52997],[114.08606,22.53276],[114.09048,22.53716],[114.09692,22.53435],[114.1034,22.5352],[114.11181,22.52878],[114.11656,22.53415],[114.12665,22.54003],[114.13823,22.54319],[114.1482,22.54091],[114.15123,22.55163],[114.1597,22.56041],[114.17247,22.55944],[114.18338,22.55444],[114.20655,22.55706],[114.22185,22.55343],[114.22888,22.5436],[114.25154,22.55977],[114.44998,22.55977],[114.50148,22.15017],[113.92195,22.13873],[113.83338,22.1826],[113.81621,22.2163]]]}},{"type":"Feature","properties":{"id":"AZ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[44.75779,39.7148],[44.80977,39.65768],[44.81043,39.62677],[44.88916,39.59653],[44.96746,39.42998],[45.05932,39.36435],[45.08751,39.35052],[45.16168,39.21952],[45.30489,39.18333],[45.40148,39.09007],[45.40452,39.07224],[45.44811,39.04927],[45.44966,38.99243],[45.6131,38.964],[45.6155,38.94304],[45.65172,38.95199],[45.83883,38.90768],[45.90266,38.87739],[45.94624,38.89072],[46.00228,38.87376],[46.06766,38.87861],[46.14785,38.84206],[46.06973,39.0744],[46.02303,39.09978],[45.99774,39.28931],[45.79225,39.3695],[45.83,39.46487],[45.80804,39.56716],[45.70547,39.60174],[45.46992,39.49888],[45.29606,39.57654],[45.30385,39.61373],[45.23535,39.61373],[45.21784,39.58074],[45.17464,39.58614],[45.18554,39.67846],[45.06604,39.79277],[44.92869,39.72157],[44.88354,39.74432],[44.75779,39.7148]]],[[[44.95383,41.07553],[44.96031,41.06345],[44.9903,41.05657],[45.00864,41.03411],[45.03792,41.03938],[45.04517,41.06653],[45.03406,41.07931],[45.00864,41.09407],[44.97169,41.09176],[44.95383,41.07553]]],[[[45.0133,41.29747],[45.05497,41.2464],[45.02932,41.2101],[45.05201,41.19211],[45.11811,41.19967],[45.1969,41.168],[45.19942,41.13299],[45.08028,41.10917],[45.06784,41.05379],[45.12923,41.06059],[45.1313,41.09369],[45.1634,41.08082],[45.16493,41.05068],[45.1994,41.04518],[45.25897,41.0027],[45.26162,41.0228],[45.28859,41.03757],[45.35677,40.99784],[45.39725,41.02603],[45.44083,41.01663],[45.40814,40.97904],[45.60584,40.87436],[45.55914,40.78366],[45.4206,40.7424],[45.35366,40.65979],[45.45484,40.57707],[45.42994,40.53804],[45.65098,40.37696],[45.95609,40.27846],[45.97944,40.181],[45.83779,39.98925],[45.78642,40.03218],[45.59806,40.0131],[45.60895,39.97733],[45.7833,39.9475],[45.82533,39.82925],[45.96543,39.78859],[46.18493,39.60533],[46.40286,39.63651],[46.42465,39.57534],[46.52117,39.58734],[46.57098,39.56694],[46.57721,39.54414],[46.51027,39.52373],[46.53051,39.47809],[46.4013,39.45405],[46.37795,39.42039],[46.43244,39.35181],[46.50093,39.33736],[46.56476,39.24942],[46.63481,39.23013],[46.58032,39.21204],[46.54141,39.15895],[46.52584,39.18912],[46.44022,39.19636],[46.54296,39.07078],[46.51805,38.94982],[46.53497,38.86548],[46.75752,39.03231],[46.83822,39.13143],[46.92539,39.16644],[46.95341,39.13505],[47.05771,39.20143],[47.05927,39.24846],[47.31301,39.37492],[47.38978,39.45999],[47.50099,39.49615],[47.84774,39.66285],[47.98977,39.70999],[48.34264,39.42935],[48.37385,39.37584],[48.15984,39.30028],[48.12404,39.25208],[48.15361,39.19419],[48.31239,39.09278],[48.33884,39.03022],[48.28437,38.97186],[48.08627,38.94434],[48.07734,38.91616],[48.01409,38.90333],[48.02581,38.82705],[48.24773,38.71883],[48.3146,38.59958],[48.45084,38.61013],[48.58793,38.45076],[48.62217,38.40198],[48.70001,38.40564],[48.78979,38.45026],[48.81072,38.44853],[48.84969,38.45015],[48.88288,38.43975],[49.20805,38.40869],[51.7708,40.29239],[48.80971,41.95365],[48.5867,41.84306],[48.55078,41.77917],[48.42301,41.65444],[48.40277,41.60441],[48.2878,41.56221],[48.22064,41.51472],[48.07587,41.49957],[47.87973,41.21798],[47.75831,41.19455],[47.62288,41.22969],[47.54504,41.20275],[47.49004,41.26366],[47.34579,41.27884],[47.10762,41.59044],[47.03757,41.55434],[46.99554,41.59743],[47.00955,41.63583],[46.8134,41.76252],[46.75269,41.8623],[46.58924,41.80547],[46.5332,41.87389],[46.42738,41.91323],[46.3984,41.84399],[46.30863,41.79133],[46.23962,41.75811],[46.20538,41.77205],[46.17891,41.72094],[46.19759,41.62327],[46.24429,41.59883],[46.26531,41.63339],[46.28182,41.60089],[46.3253,41.60912],[46.34039,41.5947],[46.34126,41.57454],[46.29794,41.5724],[46.33925,41.4963],[46.40307,41.48464],[46.4669,41.43331],[46.63658,41.37727],[46.72375,41.28609],[46.66148,41.20533],[46.63969,41.09515],[46.55096,41.1104],[46.48558,41.0576],[46.456,41.09984],[46.37661,41.10805],[46.27698,41.19011],[46.13221,41.19479],[45.95786,41.17956],[45.80842,41.2229],[45.69946,41.29545],[45.75705,41.35157],[45.71035,41.36208],[45.68389,41.3539],[45.45973,41.45898],[45.4006,41.42402],[45.31352,41.47168],[45.26285,41.46433],[45.1797,41.42231],[45.09867,41.34065],[45.0133,41.29747]],[[45.47927,40.65023],[45.51825,40.67382],[45.56071,40.64765],[45.50279,40.58424],[45.47927,40.65023]]],[[[45.18382,41.0066],[45.19312,40.98998],[45.20518,40.99348],[45.21219,40.99001],[45.21324,40.9817],[45.23095,40.97828],[45.23487,41.00226],[45.20625,41.01484],[45.18382,41.0066]]]]}},{"type":"Feature","properties":{"id":"OM-MU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[55.81777,26.18798],[56.08666,26.05038],[56.15498,26.06828],[56.19334,25.9795],[56.13963,25.82765],[56.17416,25.77239],[56.13579,25.73524],[56.14826,25.66351],[56.18363,25.65508],[56.20473,25.61119],[56.25365,25.60211],[56.26636,25.60643],[56.25341,25.61443],[56.26534,25.62825],[56.82555,25.7713],[56.79239,26.41236],[56.68954,26.76645],[56.2644,26.58649],[55.81777,26.18798]]],[[[56.20838,25.25668],[56.20872,25.24104],[56.24341,25.22867],[56.27628,25.23404],[56.34438,25.26653],[56.35172,25.30681],[56.3111,25.30107],[56.3005,25.31815],[56.26062,25.33108],[56.23362,25.31253],[56.25008,25.28843],[56.24465,25.27505],[56.20838,25.25668]],[[56.27086,25.26128],[56.2716,25.27916],[56.28102,25.28486],[56.29379,25.2754],[56.28423,25.26344],[56.27086,25.26128]]]]}},{"type":"Feature","properties":{"id":"CY"},"geometry":{"type":"MultiPolygon","coordinates":[[[[31.71872,35.1606],[32.10341,34.37973],[32.74412,34.43926],[32.75515,34.64985],[32.76136,34.68318],[32.79433,34.67883],[32.82717,34.70622],[32.86014,34.70585],[32.86167,34.68734],[32.9068,34.66102],[32.91398,34.67343],[32.93043,34.67091],[32.92807,34.66736],[32.93449,34.66241],[32.93693,34.67027],[32.94379,34.67111],[32.94683,34.67907],[32.95539,34.68471],[32.99135,34.68061],[32.98668,34.67268],[32.99014,34.65518],[32.97736,34.65277],[32.97079,34.66112],[32.95325,34.66462],[32.94796,34.6587],[32.94976,34.65204],[32.95471,34.64528],[32.95323,34.64075],[32.95891,34.62919],[32.96718,34.63446],[32.96968,34.64046],[33.0138,34.64424],[33.26744,34.49942],[33.83531,34.73974],[33.70575,34.97947],[33.70639,34.99303],[33.71514,35.00294],[33.69731,35.01754],[33.69938,35.03123],[33.67678,35.03866],[33.67742,35.05963],[33.68474,35.06602],[33.69095,35.06237],[33.70861,35.07644],[33.7161,35.07279],[33.70209,35.04882],[33.71482,35.03722],[33.73824,35.05321],[33.76106,35.04253],[33.78581,35.05104],[33.82067,35.07826],[33.84168,35.06823],[33.8541,35.07201],[33.87479,35.08881],[33.87097,35.09389],[33.87622,35.10457],[33.87224,35.12293],[33.88561,35.12449],[33.88943,35.12007],[33.88737,35.11408],[33.89853,35.11377],[33.91789,35.08688],[33.91299,35.07579],[33.90247,35.07686],[33.89485,35.06873],[33.88367,35.07877],[33.85261,35.0574],[33.8355,35.05777],[33.82051,35.0667],[33.8012,35.04786],[33.81524,35.04192],[33.83055,35.02865],[33.82875,35.01685],[33.84045,35.00616],[33.85216,35.00579],[33.85891,35.001],[33.85621,34.98956],[33.83505,34.98108],[33.84811,34.97075],[33.86432,34.97592],[33.90075,34.96623],[33.98684,34.76642],[35.48515,34.70851],[35.51152,36.10954],[32.82353,35.70297],[31.71872,35.1606]]],[[[33.7343,35.01178],[33.74144,35.01053],[33.7492,35.01319],[33.74983,35.02274],[33.74265,35.02329],[33.73781,35.02181],[33.7343,35.01178]]],[[[33.75682,34.99916],[33.76605,34.99543],[33.76738,34.99188],[33.7778,34.98981],[33.77843,34.988],[33.78149,34.98854],[33.78318,34.98699],[33.78571,34.98951],[33.78917,34.98854],[33.79191,34.98914],[33.78516,34.99582],[33.77553,34.99518],[33.77312,34.9976],[33.75994,35.00113],[33.75682,34.99916]]]]}},{"type":"Feature","properties":{"id":"IN-PY"},"geometry":{"type":"MultiPolygon","coordinates":[[[[75.18012,11.478],[75.19042,11.45378],[75.53787,11.6872],[75.55864,11.72317],[75.53821,11.76384],[75.52551,11.6993],[75.18012,11.478]]],[[[79.59525,11.86735],[80.35262,11.6751],[80.31898,12.0091],[79.70031,12.10378],[79.59525,11.86735]]],[[[79.68658,10.99107],[79.8088,10.81374],[80.42198,10.81981],[80.41717,10.96613],[79.68658,10.99107]]],[[[82.19078,16.71874],[82.9708,16.27499],[83.0072,16.31915],[82.21618,16.76378],[82.19078,16.71874]]]]}},{"type":"Feature","properties":{"id":"DK"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-74.12379,75.70014],[-53.68108,62.9266],[-45.64471,55.43944],[-25.70385,67.46637],[-10.71459,70.09565],[-9.68082,72.73731],[-3.52068,82.6752],[-34.32457,84.11035],[-59.93819,82.31398],[-63.1988,81.66522],[-67.48417,80.75493],[-73.91222,78.42484],[-74.12379,75.70014]]],[[[-8.51774,62.35338],[-6.51083,60.95272],[-5.70102,62.77194],[-8.51774,62.35338]]],[[[7.28637,57.35913],[8.02459,55.09613],[8.45719,55.06747],[8.55769,54.91837],[8.63979,54.91069],[8.76387,54.8948],[8.81178,54.90518],[8.92795,54.90452],[9.04629,54.87249],[9.14275,54.87421],[9.20571,54.85841],[9.24631,54.84726],[9.23445,54.83432],[9.2474,54.8112],[9.32771,54.80602],[9.33849,54.80233],[9.36496,54.81749],[9.38532,54.83968],[9.41213,54.84254],[9.43155,54.82586],[9.4659,54.83131],[9.58937,54.88785],[9.62734,54.88057],[9.61187,54.85548],[9.73563,54.8247],[9.89314,54.84171],[10.16755,54.73883],[10.31111,54.65968],[11.00303,54.63689],[11.90309,54.38543],[12.85844,54.82438],[13.93395,54.84044],[15.36991,54.73263],[15.79951,55.54655],[14.89259,55.5623],[14.28399,55.1553],[12.84405,55.13257],[12.60345,55.42675],[12.88472,55.63369],[12.6372,55.91371],[12.65312,56.04345],[12.07466,56.29488],[12.16597,56.60205],[10.40861,58.38489],[7.28637,57.35913]]]]}},{"type":"Feature","properties":{"id":"ES"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-18.8556,26.96222],[-14.43883,27.02969],[-12.42686,29.61659],[-14.33337,30.94071],[-15.92339,29.50503],[-18.67893,29.62861],[-18.8556,26.96222]]],[[[-10.14298,44.17365],[-9.14112,41.86623],[-8.87157,41.86488],[-8.81794,41.90375],[-8.75712,41.92833],[-8.74606,41.9469],[-8.7478,41.96282],[-8.69071,41.98862],[-8.6681,41.99703],[-8.65832,42.02972],[-8.64626,42.03668],[-8.63791,42.04691],[-8.59493,42.05708],[-8.58086,42.05147],[-8.54563,42.0537],[-8.5252,42.06264],[-8.52837,42.07658],[-8.48185,42.0811],[-8.44123,42.08218],[-8.42512,42.07199],[-8.40143,42.08052],[-8.38323,42.07683],[-8.36353,42.09065],[-8.33912,42.08358],[-8.32161,42.10218],[-8.29809,42.106],[-8.2732,42.12396],[-8.24681,42.13993],[-8.22406,42.1328],[-8.1986,42.15402],[-8.18947,42.13853],[-8.19406,42.12141],[-8.18178,42.06436],[-8.11729,42.08537],[-8.08847,42.05767],[-8.08796,42.01398],[-8.16232,41.9828],[-8.2185,41.91237],[-8.19551,41.87459],[-8.16944,41.87944],[-8.16455,41.81753],[-8.0961,41.81024],[-8.01136,41.83453],[-7.9804,41.87337],[-7.92336,41.8758],[-7.90707,41.92432],[-7.88751,41.92553],[-7.88055,41.84571],[-7.84188,41.88065],[-7.69848,41.90977],[-7.65774,41.88308],[-7.58603,41.87944],[-7.62188,41.83089],[-7.52737,41.83939],[-7.49803,41.87095],[-7.45566,41.86488],[-7.44759,41.84451],[-7.42854,41.83262],[-7.42864,41.80589],[-7.37092,41.85031],[-7.32366,41.8406],[-7.18677,41.88793],[-7.18549,41.97515],[-7.14115,41.98855],[-7.08574,41.97401],[-7.07596,41.94977],[-7.01078,41.94977],[-6.98144,41.9728],[-6.95537,41.96553],[-6.94396,41.94403],[-6.82174,41.94493],[-6.81196,41.99097],[-6.76959,41.98734],[-6.75004,41.94129],[-6.61967,41.94008],[-6.58544,41.96674],[-6.5447,41.94371],[-6.56752,41.88429],[-6.51374,41.8758],[-6.56426,41.74219],[-6.54633,41.68623],[-6.49907,41.65823],[-6.44204,41.68258],[-6.29863,41.66432],[-6.19128,41.57638],[-6.26777,41.48796],[-6.3306,41.37677],[-6.38553,41.38655],[-6.38551,41.35274],[-6.55937,41.24417],[-6.65046,41.24725],[-6.68286,41.21641],[-6.69711,41.1858],[-6.77319,41.13049],[-6.75655,41.10187],[-6.79241,41.05397],[-6.80942,41.03629],[-6.84781,41.02692],[-6.88843,41.03027],[-6.913,41.03922],[-6.9357,41.02888],[-6.8527,40.93958],[-6.84292,40.89771],[-6.80707,40.88047],[-6.79892,40.84842],[-6.82337,40.84472],[-6.82826,40.74603],[-6.79567,40.65955],[-6.84292,40.56801],[-6.80218,40.55067],[-6.7973,40.51723],[-6.84944,40.46394],[-6.84618,40.42177],[-6.78426,40.36468],[-6.80218,40.33239],[-6.86085,40.2976],[-6.86085,40.26776],[-7.00426,40.23169],[-7.02544,40.18564],[-7.00589,40.12087],[-6.94233,40.10716],[-6.86737,40.01986],[-6.91463,39.86618],[-6.97492,39.81488],[-7.01613,39.66877],[-7.24707,39.66576],[-7.33507,39.64569],[-7.54121,39.66717],[-7.49477,39.58794],[-7.2927,39.45847],[-7.3149,39.34857],[-7.23403,39.27579],[-7.23566,39.20132],[-7.12811,39.17101],[-7.14929,39.11287],[-7.10692,39.10275],[-7.04011,39.11919],[-6.97004,39.07619],[-6.95211,39.0243],[-7.051,38.907],[-7.03848,38.87221],[-7.26174,38.72107],[-7.265,38.61674],[-7.32529,38.44336],[-7.15581,38.27597],[-7.09389,38.17227],[-6.93418,38.21454],[-7.00375,38.01914],[-7.05966,38.01966],[-7.10366,38.04404],[-7.12648,38.00296],[-7.24544,37.98884],[-7.27314,37.90145],[-7.33441,37.81193],[-7.41981,37.75729],[-7.51759,37.56119],[-7.46878,37.47127],[-7.43974,37.38913],[-7.43227,37.25152],[-7.41854,37.23813],[-7.41133,37.20314],[-7.39769,37.16868],[-7.37282,36.96896],[-7.27694,35.93599],[-5.64962,35.93752],[-5.10878,36.05227],[-2.85819,35.63219],[-2.27707,35.35051],[2.46645,37.97429],[5.18061,39.43581],[3.4481,42.4358],[3.17156,42.43545],[3.11379,42.43646],[3.10027,42.42621],[3.08167,42.42748],[3.03734,42.47363],[2.96518,42.46692],[2.94283,42.48174],[2.92107,42.4573],[2.88413,42.45938],[2.86983,42.46843],[2.85675,42.45444],[2.84335,42.45724],[2.77464,42.41046],[2.75497,42.42578],[2.72056,42.42298],[2.65311,42.38771],[2.6747,42.33974],[2.57934,42.35808],[2.55516,42.35351],[2.54382,42.33406],[2.48457,42.33933],[2.43508,42.37568],[2.43299,42.39423],[2.38504,42.39977],[2.25551,42.43757],[2.20578,42.41633],[2.16599,42.42314],[2.12789,42.41291],[2.11621,42.38393],[2.06241,42.35906],[2.00488,42.35399],[1.96482,42.37787],[1.9574,42.42401],[1.94084,42.43039],[1.94061,42.43333],[1.94292,42.44316],[1.93663,42.45439],[1.88853,42.4501],[1.83037,42.48395],[1.76335,42.48863],[1.72515,42.50338],[1.70571,42.48867],[1.66826,42.50779],[1.65674,42.47125],[1.58933,42.46275],[1.57953,42.44957],[1.55937,42.45808],[1.55073,42.43299],[1.5127,42.42959],[1.44529,42.43724],[1.43838,42.47848],[1.41648,42.48315],[1.46661,42.50949],[1.44759,42.54431],[1.41245,42.53539],[1.4234,42.55959],[1.44529,42.56722],[1.42512,42.58292],[1.44197,42.60217],[1.35562,42.71944],[1.15928,42.71407],[1.0804,42.78569],[0.98292,42.78754],[0.96166,42.80629],[0.93089,42.79154],[0.711,42.86372],[0.66121,42.84021],[0.65421,42.75872],[0.67873,42.69458],[0.40214,42.69779],[0.36251,42.72282],[0.29407,42.67431],[0.25336,42.7174],[0.17569,42.73424],[-0.02468,42.68513],[-0.10519,42.72761],[-0.16141,42.79535],[-0.17939,42.78974],[-0.3122,42.84788],[-0.38833,42.80132],[-0.41319,42.80776],[-0.44334,42.79939],[-0.50863,42.82713],[-0.55497,42.77846],[-0.67637,42.88303],[-0.69837,42.87945],[-0.72608,42.89318],[-0.73422,42.91228],[-0.72037,42.92541],[-0.75478,42.96916],[-0.81652,42.95166],[-0.97133,42.96239],[-1.00963,42.99279],[-1.10333,43.0059],[-1.22881,43.05534],[-1.25244,43.04164],[-1.30531,43.06859],[-1.30052,43.09581],[-1.27118,43.11961],[-1.32209,43.1127],[-1.34419,43.09665],[-1.35272,43.02658],[-1.44067,43.047],[-1.47555,43.08372],[-1.41562,43.12815],[-1.3758,43.24511],[-1.40942,43.27272],[-1.45289,43.27049],[-1.50992,43.29481],[-1.55963,43.28828],[-1.57674,43.25269],[-1.61341,43.25269],[-1.63052,43.28591],[-1.62481,43.30726],[-1.69407,43.31378],[-1.73074,43.29481],[-1.7397,43.32979],[-1.75079,43.3317],[-1.75334,43.34107],[-1.77068,43.34396],[-1.78714,43.35476],[-1.78332,43.36399],[-1.79319,43.37497],[-1.77289,43.38957],[-1.81005,43.59738],[-10.14298,44.17365]],[[-5.40134,36.14896],[-5.38545,36.15481],[-5.36494,36.15496],[-5.34536,36.15501],[-5.33822,36.15272],[-5.27801,36.14942],[-5.28217,36.09907],[-5.3004,36.07439],[-5.32837,36.05935],[-5.36503,36.06205],[-5.39074,36.10278],[-5.40134,36.14896]]],[[[-5.38491,35.92591],[-5.37338,35.88417],[-5.35844,35.87375],[-5.34379,35.8711],[-5.27056,35.88794],[-5.27635,35.91222],[-5.38491,35.92591]]],[[[-4.30191,35.17419],[-4.30112,35.17058],[-4.29436,35.17149],[-4.30191,35.17419]]],[[[-3.90602,35.21494],[-3.88926,35.20841],[-3.88617,35.21406],[-3.90288,35.22024],[-3.90602,35.21494]]],[[[-2.97035,35.28852],[-2.96507,35.28801],[-2.96826,35.28296],[-2.96516,35.27967],[-2.95431,35.2728],[-2.95065,35.26576],[-2.93893,35.26737],[-2.92674,35.27313],[-2.92181,35.28599],[-2.92224,35.3401],[-2.96038,35.31609],[-2.96648,35.30475],[-2.96978,35.29459],[-2.97035,35.28852]]],[[[-2.44896,35.18777],[-2.44887,35.17075],[-2.41312,35.17111],[-2.41265,35.1877],[-2.44896,35.18777]]],[[[1.95606,42.45785],[1.96125,42.45364],[1.98378,42.44697],[1.99838,42.44682],[2.01564,42.45171],[1.99216,42.46208],[1.98579,42.47486],[1.99766,42.4858],[1.98916,42.49351],[1.98022,42.49569],[1.97697,42.48568],[1.97227,42.48487],[1.97003,42.48081],[1.96215,42.47854],[1.95606,42.45785]]]]}},{"type":"Feature","properties":{"id":"FJ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-180,-22.90585],[-176.74538,-22.89767],[-176.76826,-14.95183],[-178.60161,-14.95666],[-180,-14.96041],[-180,-22.90585]]],[[[174,-22.5],[179.99999,-22.5],[179.99999,-11.5],[174,-11.5],[174,-22.5]]]]}},{"type":"Feature","properties":{"id":"FR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-178.60852,-12.49232],[-178.60161,-14.95666],[-176.76826,-14.95183],[-174.17905,-14.94502],[-174.18596,-12.48057],[-178.60852,-12.49232]]],[[[-156.4957,-12.32002],[-156.46451,-23.21255],[-156.44843,-28.52556],[-133.59543,-28.4709],[-133.61511,-21.93325],[-133.65593,-7.46952],[-149.6249,-7.51261],[-149.61166,-12.30171],[-156.4957,-12.32002]]],[[[-109.6462,9.84394],[-108.755,9.84085],[-108.75183,10.72712],[-109.64303,10.7302],[-109.6462,9.84394]]],[[[-63.35989,18.06012],[-63.33064,17.9615],[-63.13584,18.0541],[-63.11096,18.05368],[-63.09686,18.04608],[-63.07759,18.04943],[-63.0579,18.06614],[-63.04039,18.05619],[-63.02323,18.05757],[-62.93924,18.02904],[-63.07669,17.79659],[-62.76692,17.64353],[-62.54836,17.8636],[-62.75637,18.13489],[-62.86666,18.19278],[-63.35989,18.06012]]],[[[-62.17275,16.35721],[-61.81728,15.58058],[-61.44899,15.79571],[-60.95725,15.70997],[-60.71337,16.48911],[-61.44461,16.81958],[-61.83929,16.66647],[-62.17275,16.35721]]],[[[-61.51867,14.96709],[-61.26561,14.25664],[-60.5958,14.23076],[-60.69955,15.22234],[-61.51867,14.96709]]],[[[-56.70773,46.51478],[-55.8643,46.64935],[-56.25228,47.31192],[-56.67989,47.3339],[-56.70773,46.51478]]],[[[-54.6084,2.32856],[-54.16286,2.10779],[-53.78743,2.34412],[-52.96539,2.1881],[-52.6906,2.37298],[-52.31787,3.17896],[-51.85573,3.83427],[-51.82312,3.85825],[-51.79599,3.89336],[-51.61983,4.14596],[-51.63798,4.51394],[-51.35485,4.8383],[-53.7094,6.2264],[-54.01074,5.68785],[-54.01877,5.52789],[-54.26916,5.26909],[-54.4717,4.91964],[-54.38444,4.13222],[-54.19367,3.84387],[-54.05128,3.63557],[-53.98914,3.627],[-53.9849,3.58697],[-54.28534,2.67798],[-54.42864,2.42442],[-54.6084,2.32856]]],[[[-5.81385,48.52441],[-1.81005,43.59738],[-1.77289,43.38957],[-1.79319,43.37497],[-1.78332,43.36399],[-1.78714,43.35476],[-1.77068,43.34396],[-1.75334,43.34107],[-1.75079,43.3317],[-1.7397,43.32979],[-1.73074,43.29481],[-1.69407,43.31378],[-1.62481,43.30726],[-1.63052,43.28591],[-1.61341,43.25269],[-1.57674,43.25269],[-1.55963,43.28828],[-1.50992,43.29481],[-1.45289,43.27049],[-1.40942,43.27272],[-1.3758,43.24511],[-1.41562,43.12815],[-1.47555,43.08372],[-1.44067,43.047],[-1.35272,43.02658],[-1.34419,43.09665],[-1.32209,43.1127],[-1.27118,43.11961],[-1.30052,43.09581],[-1.30531,43.06859],[-1.25244,43.04164],[-1.22881,43.05534],[-1.10333,43.0059],[-1.00963,42.99279],[-0.97133,42.96239],[-0.81652,42.95166],[-0.75478,42.96916],[-0.72037,42.92541],[-0.73422,42.91228],[-0.72608,42.89318],[-0.69837,42.87945],[-0.67637,42.88303],[-0.55497,42.77846],[-0.50863,42.82713],[-0.44334,42.79939],[-0.41319,42.80776],[-0.38833,42.80132],[-0.3122,42.84788],[-0.17939,42.78974],[-0.16141,42.79535],[-0.10519,42.72761],[-0.02468,42.68513],[0.17569,42.73424],[0.25336,42.7174],[0.29407,42.67431],[0.36251,42.72282],[0.40214,42.69779],[0.67873,42.69458],[0.65421,42.75872],[0.66121,42.84021],[0.711,42.86372],[0.93089,42.79154],[0.96166,42.80629],[0.98292,42.78754],[1.0804,42.78569],[1.15928,42.71407],[1.35562,42.71944],[1.44197,42.60217],[1.47986,42.61346],[1.46718,42.63296],[1.48043,42.65203],[1.50867,42.64483],[1.55418,42.65669],[1.60085,42.62703],[1.63485,42.62957],[1.6625,42.61982],[1.68267,42.62533],[1.73452,42.61515],[1.72588,42.59098],[1.7858,42.57698],[1.73683,42.55492],[1.72515,42.50338],[1.76335,42.48863],[1.83037,42.48395],[1.88853,42.4501],[1.93663,42.45439],[1.94292,42.44316],[1.94061,42.43333],[1.94084,42.43039],[1.9574,42.42401],[1.96482,42.37787],[2.00488,42.35399],[2.06241,42.35906],[2.11621,42.38393],[2.12789,42.41291],[2.16599,42.42314],[2.20578,42.41633],[2.25551,42.43757],[2.38504,42.39977],[2.43299,42.39423],[2.43508,42.37568],[2.48457,42.33933],[2.54382,42.33406],[2.55516,42.35351],[2.57934,42.35808],[2.6747,42.33974],[2.65311,42.38771],[2.72056,42.42298],[2.75497,42.42578],[2.77464,42.41046],[2.84335,42.45724],[2.85675,42.45444],[2.86983,42.46843],[2.88413,42.45938],[2.92107,42.4573],[2.94283,42.48174],[2.96518,42.46692],[3.03734,42.47363],[3.08167,42.42748],[3.10027,42.42621],[3.11379,42.43646],[3.17156,42.43545],[3.4481,42.4358],[7.52234,41.54558],[8.80584,41.26173],[9.28609,41.32097],[9.62656,41.44198],[9.86526,42.21008],[9.56115,43.20816],[7.50102,43.51859],[7.41855,43.72479],[7.40903,43.7296],[7.41113,43.73156],[7.41291,43.73168],[7.41298,43.73311],[7.41233,43.73439],[7.42062,43.73977],[7.42299,43.74176],[7.42443,43.74087],[7.42809,43.74396],[7.43013,43.74895],[7.43624,43.75014],[7.43708,43.75197],[7.4389,43.75151],[7.4379,43.74963],[7.45448,43.7432],[7.53358,43.53609],[7.63035,43.57419],[7.5289,43.78887],[7.50423,43.84345],[7.49355,43.86551],[7.51162,43.88301],[7.56075,43.89932],[7.56858,43.94506],[7.60771,43.95772],[7.65266,43.9763],[7.66848,43.99943],[7.6597,44.03009],[7.72508,44.07578],[7.66878,44.12795],[7.68694,44.17487],[7.63245,44.17877],[7.62155,44.14881],[7.36364,44.11882],[7.34547,44.14359],[7.27827,44.1462],[7.16929,44.20352],[7.00764,44.23736],[6.98221,44.28289],[6.89171,44.36637],[6.88784,44.42043],[6.94504,44.43112],[6.86233,44.49834],[6.85507,44.53072],[6.96042,44.62129],[6.95133,44.66264],[7.00582,44.69364],[7.07484,44.68073],[7.00401,44.78782],[7.02217,44.82519],[6.93499,44.8664],[6.90774,44.84322],[6.75518,44.89915],[6.74519,44.93661],[6.74791,45.01939],[6.66981,45.02324],[6.62803,45.11175],[6.7697,45.16044],[6.85144,45.13226],[6.96706,45.20841],[7.07074,45.21228],[7.13115,45.25386],[7.10572,45.32924],[7.18019,45.40071],[7.00037,45.509],[6.98948,45.63869],[6.80785,45.71864],[6.80785,45.83265],[6.95315,45.85163],[7.04151,45.92435],[7.00946,45.9944],[6.93862,46.06502],[6.87868,46.03855],[6.89321,46.12548],[6.78968,46.14058],[6.86052,46.28512],[6.77152,46.34784],[6.8024,46.39171],[6.82312,46.42661],[6.53358,46.45431],[6.25432,46.3632],[6.21981,46.31304],[6.24826,46.30175],[6.25137,46.29014],[6.23775,46.27822],[6.24952,46.26255],[6.26749,46.24745],[6.29474,46.26221],[6.31041,46.24417],[6.29663,46.22688],[6.27694,46.21566],[6.26007,46.21165],[6.24821,46.20531],[6.23913,46.20511],[6.23544,46.20714],[6.22175,46.20045],[6.22222,46.19888],[6.21844,46.19837],[6.21603,46.19507],[6.21273,46.19409],[6.21114,46.1927],[6.20539,46.19163],[6.19807,46.18369],[6.19552,46.18401],[6.18707,46.17999],[6.18871,46.16644],[6.18116,46.16187],[6.15305,46.15194],[6.13397,46.1406],[6.09926,46.14373],[6.09199,46.15191],[6.07491,46.14879],[6.05203,46.15191],[6.04564,46.14031],[6.03614,46.13712],[6.01791,46.14228],[5.9871,46.14499],[5.97893,46.13303],[5.95781,46.12925],[5.9641,46.14412],[5.97508,46.15863],[5.98188,46.17392],[5.98846,46.17046],[5.99573,46.18587],[5.96515,46.19638],[5.97542,46.21525],[6.02461,46.23313],[6.03342,46.2383],[6.04602,46.23127],[6.05029,46.23518],[6.0633,46.24583],[6.07072,46.24085],[6.08563,46.24651],[6.10071,46.23772],[6.12446,46.25059],[6.11926,46.2634],[6.1013,46.28512],[6.11697,46.29547],[6.1198,46.31157],[6.13876,46.33844],[6.15738,46.3491],[6.16987,46.36759],[6.15985,46.37721],[6.15016,46.3778],[6.09926,46.40768],[6.06407,46.41676],[6.08427,46.44305],[6.07269,46.46244],[6.1567,46.54402],[6.11084,46.57649],[6.27135,46.68251],[6.38351,46.73171],[6.45209,46.77502],[6.43216,46.80336],[6.46456,46.88865],[6.43341,46.92703],[6.71531,47.0494],[6.68823,47.06616],[6.76788,47.1208],[6.8489,47.15933],[6.9508,47.24338],[6.95108,47.26428],[6.94316,47.28747],[7.05305,47.33304],[7.0564,47.35134],[7.03125,47.36996],[6.87959,47.35335],[6.88542,47.37262],[6.93744,47.40714],[6.93953,47.43388],[7.0024,47.45264],[6.98425,47.49432],[7.0231,47.50522],[7.07425,47.48863],[7.12781,47.50371],[7.16249,47.49025],[7.19583,47.49455],[7.17026,47.44312],[7.24669,47.4205],[7.33526,47.44186],[7.35603,47.43432],[7.40308,47.43638],[7.43088,47.45846],[7.4462,47.46264],[7.4583,47.47216],[7.42923,47.48628],[7.43356,47.49712],[7.47534,47.47932],[7.51076,47.49651],[7.49804,47.51798],[7.5229,47.51644],[7.53199,47.5284],[7.51904,47.53515],[7.50588,47.52856],[7.49691,47.53821],[7.50873,47.54546],[7.51723,47.54578],[7.52831,47.55347],[7.53634,47.55553],[7.55652,47.56779],[7.55689,47.57232],[7.56548,47.57617],[7.56684,47.57785],[7.58386,47.57536],[7.58945,47.59017],[7.59301,47.60058],[7.58851,47.60794],[7.57423,47.61628],[7.5591,47.63849],[7.53384,47.65115],[7.52067,47.66437],[7.51915,47.68335],[7.51266,47.70197],[7.53722,47.71635],[7.54761,47.72912],[7.52921,47.77747],[7.55673,47.87371],[7.62302,47.97898],[7.56966,48.03265],[7.57137,48.12292],[7.6648,48.22219],[7.69022,48.30018],[7.74562,48.32736],[7.73109,48.39192],[7.76833,48.48945],[7.80647,48.51239],[7.80167,48.54758],[7.80057,48.5857],[7.84098,48.64217],[7.89002,48.66317],[7.96812,48.72491],[7.96994,48.75606],[8.01534,48.76085],[8.0326,48.79017],[8.06802,48.78957],[8.10253,48.81829],[8.12813,48.87985],[8.19989,48.95825],[8.20031,48.95856],[8.22604,48.97352],[8.14189,48.97833],[7.97783,49.03161],[7.93641,49.05544],[7.86386,49.03499],[7.79557,49.06583],[7.75948,49.04562],[7.63618,49.05428],[7.62575,49.07654],[7.56416,49.08136],[7.53012,49.09818],[7.49172,49.13915],[7.49473,49.17],[7.44455,49.16765],[7.44052,49.18354],[7.3662,49.17308],[7.35995,49.14399],[7.3195,49.14231],[7.29514,49.11426],[7.23473,49.12971],[7.1593,49.1204],[7.1358,49.1282],[7.12504,49.14253],[7.10384,49.13787],[7.10715,49.15631],[7.07859,49.15031],[7.09007,49.13094],[7.07162,49.1255],[7.06642,49.11415],[7.05548,49.11185],[7.04843,49.11422],[7.04409,49.12123],[7.04662,49.13724],[7.03178,49.15734],[7.0274,49.17042],[7.03459,49.19096],[7.01318,49.19018],[6.97273,49.2099],[6.95963,49.203],[6.94028,49.21641],[6.93831,49.2223],[6.91875,49.22261],[6.89298,49.20863],[6.85939,49.22376],[6.83555,49.21249],[6.85119,49.20038],[6.85016,49.19354],[6.86225,49.18185],[6.84703,49.15734],[6.83385,49.15162],[6.78265,49.16793],[6.73765,49.16375],[6.71137,49.18808],[6.73256,49.20486],[6.71843,49.2208],[6.69274,49.21661],[6.66583,49.28065],[6.60186,49.31055],[6.572,49.35027],[6.58807,49.35358],[6.60091,49.36864],[6.533,49.40748],[6.55404,49.42464],[6.42432,49.47683],[6.40274,49.46546],[6.39168,49.4667],[6.38352,49.46463],[6.36778,49.46937],[6.3687,49.4593],[6.28818,49.48465],[6.27875,49.503],[6.25029,49.50609],[6.2409,49.51408],[6.19543,49.50536],[6.17386,49.50934],[6.15366,49.50226],[6.16115,49.49297],[6.14321,49.48796],[6.12814,49.49365],[6.12346,49.4735],[6.10325,49.4707],[6.09845,49.46351],[6.10072,49.45268],[6.08373,49.45594],[6.07887,49.46399],[6.05553,49.46663],[6.04176,49.44801],[6.02743,49.44845],[6.02648,49.45451],[5.97693,49.45513],[5.96876,49.49053],[5.94224,49.49608],[5.94128,49.50034],[5.86571,49.50015],[5.83389,49.52152],[5.83467,49.52717],[5.84466,49.53027],[5.83648,49.5425],[5.81664,49.53775],[5.80871,49.5425],[5.81838,49.54777],[5.79195,49.55228],[5.77435,49.56298],[5.7577,49.55915],[5.75649,49.54321],[5.64505,49.55146],[5.60909,49.51228],[5.55001,49.52729],[5.46541,49.49825],[5.46734,49.52648],[5.43713,49.5707],[5.3974,49.61596],[5.34837,49.62889],[5.33851,49.61599],[5.3137,49.61225],[5.30214,49.63055],[5.33039,49.6555],[5.31465,49.66846],[5.26232,49.69456],[5.14545,49.70287],[5.09249,49.76193],[4.96714,49.79872],[4.85464,49.78995],[4.86965,49.82271],[4.85134,49.86457],[4.88529,49.9236],[4.78827,49.95609],[4.8382,50.06738],[4.88602,50.15182],[4.83279,50.15331],[4.82438,50.16878],[4.75237,50.11314],[4.70064,50.09384],[4.68695,49.99685],[4.5414,49.96911],[4.51098,49.94659],[4.43488,49.94122],[4.35051,49.95315],[4.31963,49.97043],[4.20532,49.95803],[4.14239,49.98034],[4.13508,50.01976],[4.16294,50.04719],[4.23101,50.06945],[4.20147,50.13535],[4.13561,50.13078],[4.16014,50.19239],[4.15524,50.21103],[4.21945,50.25539],[4.20651,50.27333],[4.17861,50.27443],[4.17347,50.28838],[4.15524,50.2833],[4.16808,50.25786],[4.13665,50.25609],[4.11954,50.30425],[4.10957,50.30234],[4.10237,50.31247],[4.0689,50.3254],[4.0268,50.35793],[3.96771,50.34989],[3.90781,50.32814],[3.84314,50.35219],[3.73911,50.34809],[3.70987,50.3191],[3.71009,50.30305],[3.66976,50.34563],[3.65709,50.36873],[3.67262,50.38663],[3.67494,50.40239],[3.66153,50.45165],[3.64426,50.46275],[3.61014,50.49568],[3.58361,50.49049],[3.5683,50.50192],[3.49509,50.48885],[3.51564,50.5256],[3.47385,50.53397],[3.44629,50.51009],[3.37693,50.49538],[3.28575,50.52724],[3.2729,50.60718],[3.23951,50.6585],[3.264,50.67668],[3.2536,50.68977],[3.26141,50.69151],[3.26063,50.70086],[3.24593,50.71389],[3.22042,50.71019],[3.20845,50.71662],[3.19017,50.72569],[3.20064,50.73547],[3.18811,50.74025],[3.18339,50.74981],[3.16476,50.76843],[3.15017,50.79031],[3.1257,50.78603],[3.11987,50.79188],[3.11206,50.79416],[3.10614,50.78303],[3.09163,50.77717],[3.04314,50.77674],[3.00537,50.76588],[2.96778,50.75242],[2.95019,50.75138],[2.90873,50.702],[2.91036,50.6939],[2.90069,50.69263],[2.88504,50.70656],[2.87937,50.70298],[2.86985,50.7033],[2.8483,50.72276],[2.81056,50.71773],[2.71165,50.81295],[2.63331,50.81457],[2.59093,50.91751],[2.63074,50.94746],[2.57551,51.00326],[2.55904,51.07014],[2.18458,51.52087],[1.17405,50.74239],[-2.02963,49.91866],[-2.09454,49.46288],[-1.83944,49.23037],[-2.00491,48.86706],[-2.5234,48.91595],[-2.56423,49.22209],[-2.9511,49.31141],[-5.81385,48.52441]],[[1.95606,42.45785],[1.96215,42.47854],[1.97003,42.48081],[1.97227,42.48487],[1.97697,42.48568],[1.98022,42.49569],[1.98916,42.49351],[1.99766,42.4858],[1.98579,42.47486],[1.99216,42.46208],[2.01564,42.45171],[1.99838,42.44682],[1.98378,42.44697],[1.96125,42.45364],[1.95606,42.45785]]],[[[39.10324,-21.48967],[40.40841,-23.17181],[43.72277,-16.09877],[41.06663,-17.08802],[39.10324,-21.48967]]],[[[44.75722,-12.58368],[44.82644,-13.30845],[45.54824,-13.22353],[45.45962,-12.30345],[44.75722,-12.58368]]],[[[46.31615,-46.28749],[70.67507,-51.14192],[80.15867,-36.04977],[46.31615,-46.28749]]],[[[46.52682,-10.83678],[47.29063,-12.45583],[48.86266,-10.8109],[46.52682,-10.83678]]],[[[54.08717,-15.5001],[54.13761,-16.33002],[54.96649,-16.28353],[54.91606,-15.45342],[54.08717,-15.5001]]],[[[54.32269,-20.37973],[54.43368,-22.02482],[56.73473,-21.9174],[56.62373,-20.2711],[54.32269,-20.37973]]],[[[157.46481,-18.93777],[158.4748,-21.86428],[166.93331,-23.49588],[173.07304,-22.54607],[162.93363,-17.28904],[157.46481,-18.93777]]]]}},{"type":"Feature","properties":{"id":"GB"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-133.61511,-21.93325],[-133.59543,-28.4709],[-122.0366,-24.55017],[-133.61511,-21.93325]]],[[[-81.81969,19.51758],[-81.52417,18.7521],[-79.33932,19.50496],[-79.63484,20.26689],[-81.81969,19.51758]]],[[[-72.94479,20.79216],[-71.13087,20.98822],[-70.63262,21.53631],[-72.41726,22.40371],[-72.94479,20.79216]]],[[[-65.23529,32.66274],[-65.22652,31.98296],[-64.37503,31.99084],[-64.3838,32.67056],[-65.23529,32.66274]]],[[[-65.02435,18.73231],[-64.86049,18.39954],[-64.64067,18.36478],[-64.646,18.10286],[-63.95092,18.07976],[-63.35989,18.06012],[-62.86666,18.19278],[-62.75637,18.13489],[-62.64209,18.3662],[-63.3414,18.89029],[-63.90607,18.93262],[-64.62855,18.98678],[-65.02435,18.73231]]],[[[-62.78369,-53.1401],[-58.84651,-53.93403],[-55.76919,-51.15168],[-62.3754,-50.36819],[-62.78369,-53.1401]]],[[[-62.52079,16.69392],[-62.17275,16.35721],[-61.83929,16.66647],[-62.14123,17.02632],[-62.52079,16.69392]]],[[[-43.57991,-52.56305],[-40.68557,-57.40649],[-26.52505,-59.90465],[-23.50385,-54.792],[-43.57991,-52.56305]]],[[[-14.91926,-6.63386],[-14.82771,-8.70814],[-13.48367,-36.6746],[-13.41694,-37.88844],[-13.29655,-40.02846],[-9.34669,-41.00353],[-4.97086,-15.55882],[-13.33271,-8.07391],[-14.91926,-6.63386]]],[[[-14.78497,57.60709],[-7.93366,55.84142],[-6.79943,55.54107],[-6.71944,55.27952],[-6.9734,55.19878],[-7.2471,55.06933],[-7.34464,55.04688],[-7.4033,55.00391],[-7.40004,54.94498],[-7.44404,54.9403],[-7.4473,54.87003],[-7.47626,54.83084],[-7.54508,54.79401],[-7.54671,54.74606],[-7.64449,54.75265],[-7.75041,54.7103],[-7.83352,54.73854],[-7.93293,54.66603],[-7.70315,54.62077],[-7.8596,54.53671],[-7.99812,54.54427],[-8.04538,54.48941],[-8.179,54.46763],[-8.04555,54.36292],[-7.87101,54.29299],[-7.8596,54.21779],[-7.81397,54.20159],[-7.69501,54.20731],[-7.55812,54.12239],[-7.4799,54.12239],[-7.44567,54.1539],[-7.32834,54.11475],[-7.30553,54.11869],[-7.34005,54.14698],[-7.29157,54.17191],[-7.28017,54.16714],[-7.29687,54.1354],[-7.29493,54.12013],[-7.26316,54.13863],[-7.25012,54.20063],[-7.14908,54.22732],[-7.19145,54.31296],[-7.02034,54.4212],[-6.87775,54.34682],[-6.85179,54.29176],[-6.81583,54.22791],[-6.74575,54.18788],[-6.70175,54.20218],[-6.6382,54.17071],[-6.66264,54.0666],[-6.62842,54.03503],[-6.47849,54.06947],[-6.36605,54.07234],[-6.36279,54.11248],[-6.32694,54.09337],[-6.29003,54.11278],[-6.26218,54.09785],[-5.83481,53.87749],[-5.37267,53.63269],[-5.79914,52.03902],[-6.81839,49.7273],[-3.06097,49.47231],[-2.9511,49.31141],[-2.56423,49.22209],[-2.5234,48.91595],[-2.00491,48.86706],[-1.83944,49.23037],[-2.09454,49.46288],[-2.02963,49.91866],[1.17405,50.74239],[2.18458,51.52087],[2.56575,51.85301],[-0.3751,61.32236],[-14.78497,57.60709]]],[[[-5.40134,36.14896],[-5.39074,36.10278],[-5.36503,36.06205],[-5.32837,36.05935],[-5.3004,36.07439],[-5.28217,36.09907],[-5.27801,36.14942],[-5.33822,36.15272],[-5.34536,36.15501],[-5.36494,36.15496],[-5.38545,36.15481],[-5.40134,36.14896]]],[[[32.74412,34.43926],[33.26744,34.49942],[33.0138,34.64424],[32.96968,34.64046],[32.96718,34.63446],[32.95891,34.62919],[32.95323,34.64075],[32.95471,34.64528],[32.94976,34.65204],[32.94796,34.6587],[32.95325,34.66462],[32.97079,34.66112],[32.97736,34.65277],[32.99014,34.65518],[32.98668,34.67268],[32.99135,34.68061],[32.95539,34.68471],[32.94683,34.67907],[32.94379,34.67111],[32.93693,34.67027],[32.93449,34.66241],[32.92807,34.66736],[32.93043,34.67091],[32.91398,34.67343],[32.9068,34.66102],[32.86167,34.68734],[32.86014,34.70585],[32.82717,34.70622],[32.79433,34.67883],[32.76136,34.68318],[32.75515,34.64985],[32.74412,34.43926]]],[[[33.67678,35.03866],[33.69938,35.03123],[33.69731,35.01754],[33.71514,35.00294],[33.70639,34.99303],[33.70575,34.97947],[33.83531,34.73974],[33.98684,34.76642],[33.90075,34.96623],[33.86432,34.97592],[33.84811,34.97075],[33.83505,34.98108],[33.85621,34.98956],[33.85891,35.001],[33.85216,35.00579],[33.84045,35.00616],[33.82875,35.01685],[33.83055,35.02865],[33.81524,35.04192],[33.8012,35.04786],[33.82051,35.0667],[33.8355,35.05777],[33.85261,35.0574],[33.88367,35.07877],[33.89485,35.06873],[33.90247,35.07686],[33.91299,35.07579],[33.91789,35.08688],[33.89853,35.11377],[33.88737,35.11408],[33.88943,35.12007],[33.88561,35.12449],[33.87224,35.12293],[33.87622,35.10457],[33.87097,35.09389],[33.87479,35.08881],[33.8541,35.07201],[33.84168,35.06823],[33.82067,35.07826],[33.78581,35.05104],[33.76106,35.04253],[33.73824,35.05321],[33.71482,35.03722],[33.70209,35.04882],[33.7161,35.07279],[33.70861,35.07644],[33.69095,35.06237],[33.68474,35.06602],[33.67742,35.05963],[33.67678,35.03866]],[[33.7343,35.01178],[33.73781,35.02181],[33.74265,35.02329],[33.74983,35.02274],[33.7492,35.01319],[33.74144,35.01053],[33.7343,35.01178]],[[33.75682,34.99916],[33.75994,35.00113],[33.77312,34.9976],[33.77553,34.99518],[33.78516,34.99582],[33.79191,34.98914],[33.78917,34.98854],[33.78571,34.98951],[33.78318,34.98699],[33.78149,34.98854],[33.77843,34.988],[33.7778,34.98981],[33.76738,34.99188],[33.76605,34.99543],[33.75682,34.99916]]],[[[70.64391,-7.71751],[72.09053,-7.71938],[73.19616,-7.72081],[73.19718,-6.94577],[73.19979,-4.96078],[70.64754,-4.95745],[70.64391,-7.71751]]]]}},{"type":"Feature","properties":{"id":"IT"},"geometry":{"type":"MultiPolygon","coordinates":[[[[6.62803,45.11175],[6.66981,45.02324],[6.74791,45.01939],[6.74519,44.93661],[6.75518,44.89915],[6.90774,44.84322],[6.93499,44.8664],[7.02217,44.82519],[7.00401,44.78782],[7.07484,44.68073],[7.00582,44.69364],[6.95133,44.66264],[6.96042,44.62129],[6.85507,44.53072],[6.86233,44.49834],[6.94504,44.43112],[6.88784,44.42043],[6.89171,44.36637],[6.98221,44.28289],[7.00764,44.23736],[7.16929,44.20352],[7.27827,44.1462],[7.34547,44.14359],[7.36364,44.11882],[7.62155,44.14881],[7.63245,44.17877],[7.68694,44.17487],[7.66878,44.12795],[7.72508,44.07578],[7.6597,44.03009],[7.66848,43.99943],[7.65266,43.9763],[7.60771,43.95772],[7.56858,43.94506],[7.56075,43.89932],[7.51162,43.88301],[7.49355,43.86551],[7.50423,43.84345],[7.5289,43.78887],[7.63035,43.57419],[9.56115,43.20816],[9.86526,42.21008],[9.62656,41.44198],[9.28609,41.32097],[8.80584,41.26173],[7.52234,41.54558],[7.89009,38.19924],[11.2718,37.6713],[12.02012,35.25036],[12.80065,35.1178],[13.4634,35.88474],[14.02721,36.53141],[15.10171,36.26215],[18.75365,39.82496],[18.83516,40.36999],[16.15283,42.18525],[13.12821,44.48877],[13.05142,45.33128],[13.45644,45.59464],[13.6076,45.64761],[13.7198,45.59352],[13.74587,45.59811],[13.78445,45.5825],[13.84106,45.58185],[13.86771,45.59898],[13.8695,45.60835],[13.9191,45.6322],[13.87933,45.65207],[13.83422,45.68703],[13.83332,45.70855],[13.8235,45.7176],[13.66986,45.79955],[13.59784,45.8072],[13.58858,45.83503],[13.57563,45.8425],[13.58644,45.88173],[13.59565,45.89446],[13.60857,45.89907],[13.61931,45.91782],[13.63815,45.93607],[13.6329,45.94894],[13.64307,45.98326],[13.63458,45.98947],[13.62074,45.98388],[13.58903,45.99009],[13.56759,45.96991],[13.52963,45.96588],[13.50104,45.98078],[13.47474,46.00546],[13.49702,46.01832],[13.50998,46.04498],[13.49568,46.04839],[13.50104,46.05986],[13.57072,46.09022],[13.64053,46.13587],[13.66472,46.17392],[13.64451,46.18966],[13.56682,46.18703],[13.56114,46.2054],[13.47587,46.22725],[13.42218,46.20758],[13.37671,46.29668],[13.44808,46.33507],[13.43418,46.35992],[13.47019,46.3621],[13.5763,46.40915],[13.5763,46.42613],[13.59777,46.44137],[13.68684,46.43881],[13.7148,46.5222],[13.64088,46.53438],[13.27627,46.56059],[12.94445,46.60401],[12.59992,46.6595],[12.38708,46.71529],[12.27591,46.88651],[12.2006,46.88854],[12.11675,47.01241],[12.21781,47.03996],[12.19254,47.09331],[11.74789,46.98484],[11.50739,47.00644],[11.33355,46.99862],[11.10618,46.92966],[11.00764,46.76896],[10.72974,46.78972],[10.75753,46.82258],[10.66405,46.87614],[10.54783,46.84505],[10.47197,46.85698],[10.38659,46.67847],[10.40475,46.63671],[10.44686,46.64162],[10.49375,46.62049],[10.46136,46.53164],[10.25309,46.57432],[10.23674,46.63484],[10.10307,46.61003],[10.03715,46.44479],[10.165,46.41051],[10.10506,46.3372],[10.17862,46.25626],[10.14439,46.22992],[10.07055,46.21668],[9.95249,46.38045],[9.73086,46.35071],[9.71273,46.29266],[9.57015,46.2958],[9.46117,46.37481],[9.45936,46.50873],[9.40487,46.46621],[9.36128,46.5081],[9.28136,46.49685],[9.25502,46.43743],[9.29226,46.32717],[9.24503,46.23616],[9.01618,46.04928],[8.99257,45.9698],[9.09065,45.89906],[9.06642,45.8761],[9.04546,45.84968],[9.04059,45.8464],[9.03505,45.83976],[9.03793,45.83548],[9.03279,45.82865],[9.0298,45.82127],[9.00324,45.82055],[8.99663,45.83466],[8.9621,45.83707],[8.94737,45.84285],[8.91129,45.8388],[8.93504,45.86245],[8.94372,45.86587],[8.93649,45.86775],[8.88904,45.95465],[8.86688,45.96135],[8.85121,45.97239],[8.8319,45.9879],[8.79362,45.99207],[8.78585,45.98973],[8.79414,46.00913],[8.85617,46.0748],[8.80778,46.10085],[8.75697,46.10395],[8.62242,46.12112],[8.45032,46.26869],[8.46317,46.43712],[8.42464,46.46367],[8.30648,46.41587],[8.31162,46.38044],[8.08814,46.26692],[8.16866,46.17817],[8.11383,46.11577],[8.02906,46.10331],[7.98881,45.99867],[7.9049,45.99945],[7.85949,45.91485],[7.56343,45.97421],[7.10685,45.85653],[7.04151,45.92435],[6.95315,45.85163],[6.80785,45.83265],[6.80785,45.71864],[6.98948,45.63869],[7.00037,45.509],[7.18019,45.40071],[7.10572,45.32924],[7.13115,45.25386],[7.07074,45.21228],[6.96706,45.20841],[6.85144,45.13226],[6.7697,45.16044],[6.62803,45.11175]],[[12.40415,43.95485],[12.41414,43.95273],[12.42005,43.9578],[12.43662,43.95698],[12.44684,43.96597],[12.46205,43.97463],[12.47853,43.98052],[12.49406,43.98492],[12.50678,43.99113],[12.51463,43.99122],[12.5154,43.98508],[12.51064,43.98165],[12.51109,43.97201],[12.50622,43.97131],[12.50875,43.96198],[12.50655,43.95796],[12.51427,43.94897],[12.51553,43.94096],[12.50496,43.93017],[12.50269,43.92363],[12.49724,43.92248],[12.49247,43.91774],[12.49429,43.90973],[12.48771,43.89706],[12.45648,43.89369],[12.44184,43.90498],[12.41641,43.89991],[12.40935,43.9024],[12.41233,43.90956],[12.40733,43.92379],[12.41551,43.92984],[12.41165,43.93769],[12.40506,43.94325],[12.40415,43.95485]],[[12.44582,41.90194],[12.44815,41.90326],[12.44984,41.90545],[12.45091,41.90625],[12.45543,41.90738],[12.45561,41.90629],[12.45762,41.9058],[12.45755,41.9033],[12.45826,41.90281],[12.45834,41.90174],[12.4577,41.90115],[12.45691,41.90125],[12.45626,41.90172],[12.45435,41.90143],[12.45446,41.90028],[12.45181,41.90056],[12.44834,41.90095],[12.44582,41.90194]]],[[[8.95861,45.96485],[8.97604,45.96151],[8.97741,45.98317],[8.96668,45.98436],[8.95861,45.96485]]]]}},{"type":"Feature","properties":{"id":"KG"},"geometry":{"type":"Polygon","coordinates":[[[69.26938,39.8127],[69.3594,39.52516],[69.68677,39.59281],[69.87491,39.53882],[70.11111,39.58223],[70.2869,39.53141],[70.44757,39.60128],[70.64087,39.58792],[70.7854,39.38933],[71.06418,39.41586],[71.08752,39.50704],[71.49814,39.61397],[71.55856,39.57588],[71.5517,39.45722],[71.62688,39.44056],[71.76816,39.45456],[71.80164,39.40631],[71.7522,39.32031],[71.79202,39.27355],[71.90601,39.27674],[72.04059,39.36704],[72.09689,39.26823],[72.17242,39.2661],[72.23834,39.17248],[72.33173,39.33093],[72.62027,39.39696],[72.85934,39.35116],[73.18454,39.35536],[73.31912,39.38615],[73.45096,39.46677],[73.59831,39.46425],[73.87018,39.47879],[73.94683,39.60733],[73.92354,39.69565],[73.9051,39.75073],[73.83006,39.76136],[73.97049,40.04378],[74.25533,40.13191],[74.35063,40.09742],[74.69875,40.34668],[74.85996,40.32857],[74.78168,40.44886],[74.82013,40.52197],[75.08243,40.43945],[75.22834,40.45382],[75.5854,40.66874],[75.69663,40.28642],[75.91361,40.2948],[75.96168,40.38064],[76.33659,40.3482],[76.5261,40.46114],[76.75681,40.95354],[76.99302,41.0696],[77.28004,41.0033],[77.3693,41.0375],[77.52723,41.00227],[77.76206,41.01574],[77.81287,41.14307],[78.12873,41.23091],[78.15757,41.38565],[78.3732,41.39603],[79.92977,42.04113],[80.17842,42.03211],[80.17807,42.21166],[79.97364,42.42816],[79.52921,42.44778],[79.19763,42.804],[78.91502,42.76839],[78.48469,42.89649],[75.82823,42.94848],[75.72174,42.79672],[75.29966,42.86183],[75.22619,42.85528],[74.88756,42.98612],[74.75,42.99029],[74.70331,43.02519],[74.64615,43.05881],[74.57491,43.13702],[74.22489,43.24657],[73.55634,43.03071],[73.50992,42.82356],[73.44393,42.43098],[71.88792,42.83578],[71.62405,42.76613],[71.53272,42.8014],[71.2724,42.77853],[71.22785,42.69248],[71.17807,42.67381],[71.15232,42.60486],[70.97717,42.50147],[70.85973,42.30188],[70.94483,42.26238],[71.13263,42.28356],[71.28719,42.18033],[70.69777,41.92554],[70.17682,41.5455],[70.48909,41.40335],[70.67586,41.47953],[70.78572,41.36419],[70.77885,41.24813],[70.86263,41.23833],[70.9615,41.16393],[71.02193,41.19494],[71.11806,41.15359],[71.25813,41.18796],[71.27187,41.11015],[71.34877,41.16807],[71.40198,41.09436],[71.46148,41.13958],[71.43814,41.19644],[71.46688,41.31883],[71.57227,41.29175],[71.6787,41.42111],[71.65914,41.49599],[71.73054,41.54713],[71.71132,41.43012],[71.76625,41.4466],[71.83914,41.3546],[71.91457,41.2982],[71.85964,41.19081],[72.07249,41.11739],[72.10745,41.15483],[72.16433,41.16483],[72.17594,41.15522],[72.14864,41.13363],[72.1792,41.10621],[72.21061,41.05607],[72.17594,41.02377],[72.18339,40.99571],[72.324,41.03381],[72.34026,41.04539],[72.34757,41.06104],[72.36138,41.04384],[72.38511,41.02785],[72.45206,41.03018],[72.48742,40.97136],[72.55109,40.96046],[72.59136,40.86947],[72.68157,40.84942],[72.84291,40.85512],[72.94454,40.8094],[73.01869,40.84681],[73.13267,40.83512],[73.13412,40.79122],[73.0612,40.76678],[72.99133,40.76457],[72.93296,40.73089],[72.8722,40.71111],[72.85372,40.7116],[72.84754,40.67229],[72.80137,40.67856],[72.74866,40.60873],[72.74894,40.59592],[72.75982,40.57273],[72.74862,40.57131],[72.74768,40.58051],[72.73995,40.58409],[72.69579,40.59778],[72.66713,40.59076],[72.66713,40.5219],[72.47795,40.5532],[72.40517,40.61917],[72.34406,40.60144],[72.41714,40.55736],[72.38384,40.51535],[72.41513,40.50856],[72.44191,40.48222],[72.40346,40.4007],[72.24368,40.46091],[72.18648,40.49893],[71.96401,40.31907],[72.05464,40.27586],[71.85002,40.25647],[71.82646,40.21872],[71.73054,40.14818],[71.71719,40.17886],[71.69621,40.18492],[71.70569,40.20391],[71.68386,40.26984],[71.61931,40.26775],[71.61725,40.20615],[71.51549,40.22986],[71.51215,40.26943],[71.4246,40.28619],[71.36663,40.31593],[71.13042,40.34106],[71.05901,40.28765],[70.95789,40.28761],[70.9818,40.22392],[70.80495,40.16813],[70.7928,40.12797],[70.65827,40.0981],[70.65946,39.9878],[70.58912,39.95211],[70.55033,39.96619],[70.47557,39.93216],[70.57384,39.99394],[70.58297,40.00891],[70.01283,40.23288],[69.67001,40.10639],[69.64704,40.12165],[69.57615,40.10524],[69.55555,40.12296],[69.53794,40.11833],[69.53855,40.0887],[69.5057,40.03277],[69.53615,39.93991],[69.43557,39.92877],[69.43134,39.98431],[69.35649,40.01994],[69.26938,39.8127]],[[70.52631,39.86989],[70.53651,39.89155],[70.74189,39.86319],[70.63105,39.77923],[70.59667,39.83542],[70.54998,39.85137],[70.52631,39.86989]],[[71.00236,40.18154],[71.06305,40.1771],[71.12218,40.03052],[71.21139,40.03369],[71.1427,39.95026],[71.23067,39.93581],[71.16101,39.88423],[71.10531,39.91354],[71.04979,39.89808],[71.10501,39.95568],[71.09063,39.99],[71.11668,39.99291],[71.11037,40.01984],[71.01035,40.05481],[71.00236,40.18154]],[[71.71511,39.96348],[71.78838,40.01404],[71.86463,39.98598],[71.84316,39.95582],[71.7504,39.93701],[71.71511,39.96348]]]}},{"type":"Feature","properties":{"id":"KI"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-175.33482,-1.40631],[-175.31804,-7.54825],[-174.18707,-7.54408],[-167.75329,-7.52784],[-156.50903,-7.4975],[-156.4957,-12.32002],[-149.61166,-12.30171],[-149.6249,-7.51261],[-149.65979,5.27712],[-161.06795,5.2462],[-161.05669,1.11722],[-158.62734,1.1296],[-158.62058,-1.35506],[-161.04969,-1.36251],[-175.33482,-1.40631]]],[[[169,-3.5],[178,-3.5],[178,3.9],[169,3.9],[169,-3.5]]]]}},{"type":"Feature","properties":{"id":"NL"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-70.34259,12.92535],[-70.24399,12.38063],[-69.4514,12.18025],[-68.99639,11.79035],[-68.33524,11.78151],[-68.01417,11.77722],[-67.89186,12.4116],[-68.90012,12.62309],[-69.5195,12.75292],[-70.34259,12.92535]]],[[[-63.58819,17.61311],[-63.22932,17.32592],[-63.11114,17.23125],[-62.76692,17.64353],[-63.07669,17.79659],[-62.93924,18.02904],[-63.02323,18.05757],[-63.04039,18.05619],[-63.0579,18.06614],[-63.07759,18.04943],[-63.09686,18.04608],[-63.11096,18.05368],[-63.13584,18.0541],[-63.33064,17.9615],[-63.29212,17.90532],[-63.58819,17.61311]]],[[[2.56575,51.85301],[3.36263,51.37112],[3.38696,51.33436],[3.35847,51.31572],[3.38289,51.27331],[3.41704,51.25933],[3.43488,51.24135],[3.52698,51.2458],[3.51502,51.28697],[3.58939,51.30064],[3.78999,51.25766],[3.78783,51.2151],[3.90125,51.20371],[3.97889,51.22537],[4.01957,51.24504],[4.05165,51.24171],[4.16721,51.29348],[4.24024,51.35371],[4.21923,51.37443],[4.33265,51.37687],[4.34086,51.35738],[4.39292,51.35547],[4.43777,51.36989],[4.38064,51.41965],[4.39747,51.43316],[4.38122,51.44905],[4.47736,51.4778],[4.5388,51.48184],[4.54675,51.47265],[4.52846,51.45002],[4.53521,51.4243],[4.57489,51.4324],[4.65442,51.42352],[4.72935,51.48424],[4.74578,51.48937],[4.77321,51.50529],[4.78803,51.50284],[4.84139,51.4799],[4.82409,51.44736],[4.82946,51.4213],[4.78314,51.43319],[4.76577,51.43046],[4.77229,51.41337],[4.78941,51.41102],[4.84988,51.41502],[4.90016,51.41404],[4.92152,51.39487],[5.00393,51.44406],[5.0106,51.47167],[5.03281,51.48679],[5.04774,51.47022],[5.07891,51.4715],[5.10456,51.43163],[5.07102,51.39469],[5.13105,51.34791],[5.13377,51.31592],[5.16222,51.31035],[5.2002,51.32243],[5.24244,51.30495],[5.22542,51.26888],[5.23814,51.26064],[5.26461,51.26693],[5.29716,51.26104],[5.33886,51.26314],[5.347,51.27502],[5.41672,51.26248],[5.4407,51.28169],[5.46519,51.2849],[5.48476,51.30053],[5.515,51.29462],[5.5569,51.26544],[5.5603,51.22249],[5.65145,51.19788],[5.65528,51.18736],[5.70344,51.1829],[5.74617,51.18928],[5.77735,51.17845],[5.77697,51.1522],[5.82564,51.16753],[5.85508,51.14445],[5.80798,51.11661],[5.8109,51.10861],[5.83226,51.10585],[5.82921,51.09328],[5.79903,51.09371],[5.79835,51.05834],[5.77258,51.06196],[5.75961,51.03113],[5.77688,51.02483],[5.76242,50.99703],[5.71864,50.96092],[5.72875,50.95428],[5.74752,50.96202],[5.75927,50.95601],[5.74644,50.94723],[5.72545,50.92312],[5.72644,50.91167],[5.71626,50.90796],[5.69858,50.91046],[5.67886,50.88142],[5.64504,50.87107],[5.64009,50.84742],[5.65259,50.82309],[5.70118,50.80764],[5.68995,50.79641],[5.70107,50.7827],[5.68091,50.75804],[5.69469,50.75529],[5.72216,50.76398],[5.73904,50.75674],[5.74356,50.7691],[5.76533,50.78159],[5.77513,50.78308],[5.80673,50.7558],[5.84548,50.76542],[5.84888,50.75448],[5.88734,50.77092],[5.89129,50.75125],[5.89132,50.75124],[5.95942,50.7622],[5.97545,50.75441],[6.01976,50.75398],[6.02624,50.77453],[5.97497,50.79992],[5.98404,50.80988],[6.00462,50.80065],[6.02328,50.81694],[6.01921,50.84435],[6.05623,50.8572],[6.05702,50.85179],[6.07431,50.84674],[6.07693,50.86025],[6.08805,50.87223],[6.07486,50.89307],[6.09297,50.92066],[6.01615,50.93367],[6.02697,50.98303],[5.95282,50.98728],[5.90296,50.97356],[5.90493,51.00198],[5.87849,51.01969],[5.86735,51.05182],[5.9134,51.06736],[5.9541,51.03496],[5.98292,51.07469],[6.16706,51.15677],[6.17384,51.19589],[6.07889,51.17038],[6.07889,51.24432],[6.16977,51.33169],[6.22674,51.36135],[6.22641,51.39948],[6.20654,51.40049],[6.21724,51.48568],[6.18017,51.54096],[6.09055,51.60564],[6.11759,51.65609],[6.02767,51.6742],[6.04091,51.71821],[5.95003,51.7493],[5.98665,51.76944],[5.94568,51.82786],[5.99848,51.83195],[6.06705,51.86136],[6.10337,51.84829],[6.16902,51.84094],[6.11551,51.89769],[6.15349,51.90439],[6.21443,51.86801],[6.29872,51.86801],[6.30593,51.84998],[6.40704,51.82771],[6.38815,51.87257],[6.47179,51.85395],[6.50231,51.86313],[6.58556,51.89386],[6.68386,51.91861],[6.72319,51.89518],[6.82357,51.96711],[6.83035,51.9905],[6.68128,52.05052],[6.76117,52.11895],[6.83984,52.11728],[6.97189,52.20329],[6.9897,52.2271],[7.03729,52.22695],[7.06365,52.23789],[7.02703,52.27941],[7.07044,52.37805],[7.03417,52.40237],[6.99041,52.47235],[6.94293,52.43597],[6.69507,52.488],[6.71641,52.62905],[6.77307,52.65375],[7.04557,52.63318],[7.07253,52.81083],[7.21694,53.00742],[7.17898,53.13817],[7.22681,53.18165],[7.21679,53.20058],[7.19052,53.31866],[7.00198,53.32672],[6.91025,53.44221],[5.45168,54.20039],[2.56575,51.85301]],[[4.91493,51.4353],[4.91935,51.43634],[4.92227,51.44252],[4.91811,51.44621],[4.92287,51.44741],[4.92811,51.4437],[4.92566,51.44273],[4.92815,51.43856],[4.92879,51.44161],[4.93544,51.44634],[4.94025,51.44193],[4.93416,51.44185],[4.93471,51.43861],[4.94265,51.44003],[4.93986,51.43064],[4.92952,51.42984],[4.92652,51.43329],[4.91493,51.4353]],[[4.93295,51.44945],[4.95244,51.45207],[4.9524,51.45014],[4.93909,51.44632],[4.93295,51.44945]]]]}},{"type":"Feature","properties":{"id":"NO"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-10.71459,70.09565],[-5.93364,70.76368],[-9.68082,72.73731],[-10.71459,70.09565]]],[[[-3.52068,82.6752],[16.4353,73.61229],[33.12005,75.46568],[35.22046,80.57056],[-3.52068,82.6752]]],[[[-0.3751,61.32236],[7.28637,57.35913],[10.40861,58.38489],[10.64958,58.89391],[11.08911,58.98745],[11.15367,59.07862],[11.34459,59.11672],[11.4601,58.99022],[11.45199,58.89604],[11.65732,58.90177],[11.8213,59.24985],[11.69297,59.59442],[11.92112,59.69531],[11.87121,59.86039],[12.15641,59.8926],[12.36317,59.99259],[12.52003,60.13846],[12.59133,60.50559],[12.2277,61.02442],[12.69115,61.06584],[12.86939,61.35427],[12.57707,61.56547],[12.40595,61.57226],[12.14746,61.7147],[12.29187,62.25699],[12.07085,62.6297],[12.19919,63.00104],[11.98529,63.27487],[12.19919,63.47935],[12.14928,63.59373],[12.74105,64.02171],[13.23411,64.09087],[13.98222,64.00953],[14.16051,64.18725],[14.11117,64.46674],[13.64276,64.58402],[14.50926,65.31786],[14.53778,66.12399],[15.05113,66.15572],[15.49318,66.28509],[15.37197,66.48217],[16.35589,67.06419],[16.39154,67.21653],[16.09922,67.4364],[16.12774,67.52106],[16.38441,67.52923],[16.7409,67.91037],[17.30416,68.11591],[17.90787,67.96537],[18.13836,68.20874],[18.1241,68.53721],[18.39503,68.58672],[18.63032,68.50849],[18.97255,68.52416],[19.93508,68.35911],[20.22027,68.48759],[19.95647,68.55546],[20.22027,68.67246],[20.33435,68.80174],[20.28444,68.93283],[20.0695,69.04469],[20.55258,69.06069],[20.72171,69.11874],[21.05775,69.0356],[21.11099,69.10291],[20.98641,69.18809],[21.00732,69.22755],[21.27827,69.31281],[21.63833,69.27485],[22.27276,68.89514],[22.38367,68.71561],[22.53321,68.74393],[23.13064,68.64684],[23.68017,68.70276],[23.781,68.84514],[24.02299,68.81601],[24.18432,68.73936],[24.74898,68.65143],[24.90023,68.55579],[24.93048,68.61102],[25.10189,68.63307],[25.12206,68.78684],[25.42455,68.90328],[25.61613,68.89602],[25.75729,68.99383],[25.69679,69.27039],[25.96904,69.68397],[26.40261,69.91377],[26.64461,69.96565],[27.05802,69.92069],[27.57226,70.06215],[27.95542,70.0965],[27.97558,69.99671],[28.32849,69.88605],[28.36883,69.81658],[29.12697,69.69193],[29.31664,69.47994],[28.8629,69.22395],[28.81248,69.11997],[28.91738,69.04774],[29.0444,69.0119],[29.26623,69.13794],[29.27631,69.2811],[29.97205,69.41623],[30.16363,69.65244],[30.52662,69.54699],[30.95011,69.54699],[30.84095,69.80584],[31.59909,70.16571],[32.07813,72.01005],[18.46509,71.28681],[-0.3751,61.32236]]],[[[2.85578,-54.70531],[3.87126,-54.71036],[3.87947,-54.15611],[2.86398,-54.15099],[2.85578,-54.70531]]]]}},{"type":"Feature","properties":{"id":"NZ"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-180,-24.21376],[-179.93224,-45.18423],[-173.00283,-45.20102],[-173.10761,-24.19665],[-180,-24.21376]]],[[[-174.18707,-7.54408],[-174.17993,-10.13616],[-167.75195,-10.12005],[-167.73854,-14.92809],[-171.14262,-14.93704],[-173.13438,-14.94228],[-173.11048,-23.23027],[-167.73129,-23.22266],[-156.46451,-23.21255],[-156.4957,-12.32002],[-156.50903,-7.4975],[-167.75329,-7.52784],[-174.18707,-7.54408]]],[[[164.49803,-50.68404],[169.00308,-53.19756],[179.49541,-50.04657],[179.49541,-36.79303],[169.6687,-29.09191],[169.35326,-30.60259],[164.49803,-50.68404]]]]}},{"type":"Feature","properties":{"id":"OM"},"geometry":{"type":"MultiPolygon","coordinates":[[[[52.00311,19.00083],[52.78009,17.35124],[52.74267,17.29519],[52.81185,17.28568],[53.09917,16.67084],[53.32998,16.16312],[56.66759,17.24021],[61.45114,22.55394],[56.86325,25.03856],[56.3227,24.97284],[56.34873,24.93205],[56.30269,24.88334],[56.20568,24.85063],[56.20062,24.78565],[56.13684,24.73699],[56.06128,24.74457],[56.03535,24.81161],[55.97836,24.87673],[55.97467,24.89639],[56.05106,24.87461],[56.05715,24.95727],[55.96316,25.00857],[55.90849,24.96771],[55.85094,24.96858],[55.81116,24.9116],[55.81348,24.80102],[55.83408,24.77858],[55.83271,24.68567],[55.76461,24.5287],[55.83271,24.41521],[55.83395,24.32776],[55.80747,24.31069],[55.79145,24.27914],[55.76781,24.26209],[55.75939,24.26114],[55.75382,24.2466],[55.75257,24.23466],[55.76558,24.23227],[55.77658,24.23476],[55.83367,24.20193],[55.95472,24.2172],[56.01799,24.07426],[55.8308,24.01633],[55.73301,24.05994],[55.48677,23.94946],[55.57358,23.669],[55.22634,23.10378],[55.2137,22.71065],[55.66469,21.99658],[54.99756,20.00083],[52.00311,19.00083]]],[[[55.81777,26.18798],[56.08666,26.05038],[56.15498,26.06828],[56.19334,25.9795],[56.13963,25.82765],[56.17416,25.77239],[56.13579,25.73524],[56.14826,25.66351],[56.18363,25.65508],[56.20473,25.61119],[56.25365,25.60211],[56.26636,25.60643],[56.25341,25.61443],[56.26534,25.62825],[56.82555,25.7713],[56.79239,26.41236],[56.68954,26.76645],[56.2644,26.58649],[55.81777,26.18798]]],[[[56.20838,25.25668],[56.20872,25.24104],[56.24341,25.22867],[56.27628,25.23404],[56.34438,25.26653],[56.35172,25.30681],[56.3111,25.30107],[56.3005,25.31815],[56.26062,25.33108],[56.23362,25.31253],[56.25008,25.28843],[56.24465,25.27505],[56.20838,25.25668]],[[56.27086,25.26128],[56.2716,25.27916],[56.28102,25.28486],[56.29379,25.2754],[56.28423,25.26344],[56.27086,25.26128]]]]}},{"type":"Feature","properties":{"id":"RU"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-179.99933,64.74703],[-172.76104,63.77445],[-169.03888,65.48473],[-168.95635,65.98512],[-168.25765,71.99091],[-179.9843,71.90735],[-179.99933,64.74703]]],[[[18.57853,55.25302],[19.64312,54.45423],[19.8038,54.44203],[20.63871,54.3706],[21.41123,54.32395],[22.79705,54.36264],[22.7253,54.41732],[22.70208,54.45312],[22.67788,54.532],[22.71293,54.56454],[22.68021,54.58486],[22.7522,54.63525],[22.74225,54.64339],[22.75467,54.6483],[22.73397,54.66604],[22.73631,54.72952],[22.87317,54.79492],[22.85083,54.88711],[22.76422,54.92521],[22.68723,54.9811],[22.65451,54.97037],[22.60075,55.01863],[22.58907,55.07085],[22.47688,55.04408],[22.31562,55.0655],[22.14267,55.05345],[22.11697,55.02131],[22.06087,55.02935],[22.02582,55.05078],[22.03984,55.07888],[21.99543,55.08691],[21.96505,55.07353],[21.85521,55.09493],[21.64954,55.1791],[21.55605,55.20311],[21.51095,55.18507],[21.46766,55.21115],[21.38446,55.29348],[21.35465,55.28427],[21.26425,55.24456],[20.95181,55.27994],[20.60454,55.40986],[18.57853,55.25302]]],[[[26.32936,60.00121],[26.90044,59.63819],[27.85643,59.58538],[28.04187,59.47017],[28.19061,59.39962],[28.21137,59.38058],[28.20537,59.36491],[28.19284,59.35791],[28.14215,59.28934],[28.00689,59.28351],[27.90911,59.24353],[27.87978,59.18097],[27.80482,59.1116],[27.74429,58.98351],[27.36366,58.78381],[27.55489,58.39525],[27.48541,58.22615],[27.62393,58.09462],[27.67282,57.92627],[27.81841,57.89244],[27.78526,57.83963],[27.56689,57.83356],[27.50171,57.78842],[27.52615,57.72843],[27.3746,57.66834],[27.40393,57.62125],[27.31919,57.57672],[27.34698,57.52242],[27.56832,57.53728],[27.52453,57.42826],[27.86101,57.29402],[27.66511,56.83921],[27.86101,56.88204],[28.04768,56.59004],[28.13526,56.57989],[28.10069,56.524],[28.19057,56.44637],[28.16599,56.37806],[28.23716,56.27588],[28.15217,56.16964],[28.30571,56.06035],[28.36888,56.05805],[28.37987,56.11399],[28.43068,56.09407],[28.5529,56.11705],[28.68337,56.10173],[28.63668,56.07262],[28.73418,55.97131],[29.08299,56.03427],[29.21717,55.98971],[29.44692,55.95978],[29.3604,55.75862],[29.51283,55.70294],[29.61446,55.77716],[29.80672,55.79569],[29.97975,55.87281],[30.12136,55.8358],[30.27776,55.86819],[30.30987,55.83592],[30.48257,55.81066],[30.51346,55.78982],[30.51037,55.76568],[30.63344,55.73079],[30.67464,55.64176],[30.72957,55.66268],[30.7845,55.58514],[30.86003,55.63169],[30.93419,55.6185],[30.95204,55.50667],[30.90123,55.46621],[30.93144,55.3914],[30.8257,55.3313],[30.81946,55.27931],[30.87944,55.28223],[30.97369,55.17134],[31.02071,55.06167],[31.00972,55.02783],[30.94243,55.03964],[30.9081,55.02232],[30.95754,54.98609],[30.93144,54.9585],[30.81759,54.94064],[30.8264,54.90062],[30.75165,54.80699],[30.95479,54.74346],[30.97127,54.71967],[31.0262,54.70698],[30.98226,54.68872],[30.99187,54.67046],[31.19339,54.66947],[31.21399,54.63113],[31.08543,54.50361],[31.22945,54.46585],[31.3177,54.34067],[31.30791,54.25315],[31.57002,54.14535],[31.89599,54.0837],[31.88744,54.03653],[31.85019,53.91801],[31.77028,53.80015],[31.89137,53.78099],[32.12621,53.81586],[32.36663,53.7166],[32.45717,53.74039],[32.50112,53.68594],[32.40499,53.6656],[32.47777,53.5548],[32.74968,53.45597],[32.73257,53.33494],[32.51725,53.28431],[32.40773,53.18856],[32.15368,53.07594],[31.82373,53.10042],[31.787,53.18033],[31.62496,53.22886],[31.56316,53.19432],[31.40523,53.21406],[31.36403,53.13504],[31.3915,53.09712],[31.33519,53.08805],[31.32283,53.04101],[31.24147,53.031],[31.35667,52.97854],[31.592,52.79011],[31.57277,52.71613],[31.50406,52.69707],[31.63869,52.55361],[31.56316,52.51518],[31.61397,52.48843],[31.62084,52.33849],[31.57971,52.32146],[31.70735,52.26711],[31.6895,52.1973],[31.77877,52.18636],[31.7822,52.11406],[31.81722,52.09955],[31.85018,52.11305],[31.96141,52.08015],[31.92159,52.05144],[32.08813,52.03319],[32.23331,52.08085],[32.2777,52.10266],[32.34044,52.1434],[32.33083,52.23685],[32.38988,52.24946],[32.3528,52.32842],[32.54781,52.32423],[32.69475,52.25535],[32.85405,52.27888],[32.89937,52.2461],[33.18913,52.3754],[33.51323,52.35779],[33.48027,52.31499],[33.55718,52.30324],[33.78789,52.37204],[34.05239,52.20132],[34.11199,52.14087],[34.09413,52.00835],[34.41136,51.82793],[34.42922,51.72852],[34.07765,51.67065],[34.17599,51.63253],[34.30562,51.5205],[34.22048,51.4187],[34.33446,51.363],[34.23009,51.26429],[34.31661,51.23936],[34.38802,51.2746],[34.6613,51.25053],[34.6874,51.18],[34.82472,51.17483],[34.97304,51.2342],[35.14058,51.23162],[35.12685,51.16191],[35.20375,51.04723],[35.31774,51.08434],[35.40837,51.04119],[35.32598,50.94524],[35.39307,50.92145],[35.41367,50.80227],[35.47704,50.77274],[35.48116,50.66405],[35.39464,50.64751],[35.47463,50.49247],[35.58003,50.45117],[35.61711,50.35707],[35.73659,50.35489],[35.80388,50.41356],[35.8926,50.43829],[36.06893,50.45205],[36.20763,50.3943],[36.30101,50.29088],[36.47817,50.31457],[36.58371,50.28563],[36.56655,50.2413],[36.64571,50.218],[36.69377,50.26982],[36.91762,50.34963],[37.08468,50.34935],[37.48204,50.46079],[37.47243,50.36277],[37.62486,50.29966],[37.62879,50.24481],[37.61113,50.21976],[37.75807,50.07896],[37.79515,50.08425],[37.90776,50.04194],[38.02999,49.94482],[38.02999,49.90592],[38.21675,49.98104],[38.18517,50.08161],[38.32524,50.08866],[38.35408,50.00664],[38.65688,49.97176],[38.68677,50.00904],[38.73311,49.90238],[38.90477,49.86787],[38.9391,49.79524],[39.1808,49.88911],[39.27968,49.75976],[39.44496,49.76067],[39.59142,49.73758],[39.65047,49.61761],[39.84548,49.56064],[40.13249,49.61672],[40.16683,49.56865],[40.03636,49.52321],[40.03087,49.45452],[40.1141,49.38798],[40.14912,49.37681],[40.18331,49.34996],[40.22176,49.25683],[40.01988,49.1761],[39.93437,49.05709],[39.6836,49.05121],[39.6683,48.99454],[39.71353,48.98959],[39.72649,48.9754],[39.74874,48.98675],[39.78368,48.91596],[39.98967,48.86901],[40.03636,48.91957],[40.08168,48.87443],[39.97182,48.79398],[39.79466,48.83739],[39.73104,48.7325],[39.71765,48.68673],[39.67226,48.59368],[39.79764,48.58668],[39.84548,48.57821],[39.86196,48.46633],[39.88794,48.44226],[39.94847,48.35055],[39.84136,48.33321],[39.84273,48.30947],[39.90041,48.3049],[39.91465,48.26743],[39.95248,48.29972],[39.9693,48.29904],[39.97325,48.31399],[39.99241,48.31768],[40.00752,48.22445],[39.94847,48.22811],[39.83724,48.06501],[39.88256,48.04482],[39.77544,48.04206],[39.82213,47.96396],[39.73935,47.82876],[38.87979,47.87719],[38.79628,47.81109],[38.76379,47.69346],[38.35062,47.61631],[38.28679,47.53552],[38.28954,47.39255],[38.22225,47.30788],[38.33074,47.30508],[38.32112,47.2585],[38.23049,47.2324],[38.22955,47.12069],[38.3384,46.98085],[38.12112,46.86078],[37.62608,46.82615],[35.23066,45.79231],[34.96015,45.75634],[34.79905,45.81009],[34.80153,45.90047],[34.75479,45.90705],[34.66679,45.97136],[34.60861,45.99347],[34.55889,45.99347],[34.52011,45.95097],[34.48729,45.94267],[34.44155,45.95995],[34.41221,46.00245],[34.33912,46.06114],[34.25111,46.0532],[34.181,46.06804],[34.12929,46.10494],[34.07311,46.11769],[34.05272,46.10838],[33.91549,46.15938],[33.85234,46.19863],[33.79715,46.20482],[33.74047,46.18555],[33.646,46.23028],[33.61517,46.22615],[33.63854,46.14147],[33.61467,46.13561],[33.57318,46.10317],[33.59087,46.06013],[33.54017,46.0123],[31.62627,45.50633],[32.99857,44.48323],[33.66142,43.9825],[36.61884,44.89556],[39.81147,43.06294],[40.0078,43.38551],[40.00853,43.40578],[40.01552,43.42025],[40.01007,43.42411],[40.03312,43.44262],[40.04445,43.47776],[40.10657,43.57344],[40.65957,43.56212],[41.64935,43.22331],[42.40563,43.23226],[42.66667,43.13917],[42.75889,43.19651],[43.03322,43.08883],[43.0419,43.02413],[43.81453,42.74297],[43.73119,42.62043],[43.95517,42.55396],[44.54202,42.75699],[44.70002,42.74679],[44.80941,42.61277],[44.88754,42.74934],[45.15318,42.70598],[45.36501,42.55268],[45.78692,42.48358],[45.61676,42.20768],[46.42738,41.91323],[46.5332,41.87389],[46.58924,41.80547],[46.75269,41.8623],[46.8134,41.76252],[47.00955,41.63583],[46.99554,41.59743],[47.03757,41.55434],[47.10762,41.59044],[47.34579,41.27884],[47.49004,41.26366],[47.54504,41.20275],[47.62288,41.22969],[47.75831,41.19455],[47.87973,41.21798],[48.07587,41.49957],[48.22064,41.51472],[48.2878,41.56221],[48.40277,41.60441],[48.42301,41.65444],[48.55078,41.77917],[48.5867,41.84306],[48.80971,41.95365],[49.2134,44.84989],[49.88945,46.04554],[49.32259,46.26944],[49.16518,46.38542],[48.54988,46.56267],[48.51142,46.69268],[49.01136,46.72716],[48.52326,47.4102],[48.45173,47.40818],[48.15348,47.74545],[47.64973,47.76559],[47.41689,47.83687],[47.38731,47.68176],[47.12107,47.83687],[47.11516,48.27188],[46.49011,48.43019],[46.78392,48.95352],[46.91104,48.99715],[47.01458,49.07085],[47.04416,49.17152],[46.98795,49.23531],[46.78398,49.34026],[46.9078,49.86707],[47.18319,49.93721],[47.34589,50.09308],[47.30448,50.30894],[47.58551,50.47867],[48.10044,50.09242],[48.24519,49.86099],[48.42564,49.82283],[48.68352,49.89546],[48.90782,50.02281],[48.57946,50.63278],[48.86936,50.61589],[49.12673,50.78639],[49.41959,50.85927],[49.39001,51.09396],[49.76866,51.11067],[49.97277,51.2405],[50.26859,51.28677],[50.59695,51.61859],[51.26254,51.68466],[51.301,51.48799],[51.77431,51.49536],[51.8246,51.67916],[52.36119,51.74161],[52.54329,51.48444],[53.46165,51.49445],[53.69299,51.23466],[54.12248,51.11542],[54.46331,50.85554],[54.41894,50.61214],[54.55797,50.52006],[54.71476,50.61214],[54.56685,51.01958],[54.72067,51.03261],[55.67774,50.54508],[56.11398,50.7471],[56.17906,50.93204],[57.17302,51.11253],[57.44221,50.88354],[57.74986,50.93017],[57.75578,51.13852],[58.3208,51.15151],[58.87974,50.70852],[59.48928,50.64216],[59.51886,50.49937],[59.81172,50.54451],[60.01288,50.8163],[60.17262,50.83312],[60.31914,50.67705],[60.81833,50.6629],[61.4431,50.80679],[61.56889,51.23679],[61.6813,51.25716],[61.55114,51.32746],[61.50677,51.40687],[60.95655,51.48615],[60.92401,51.61124],[60.5424,51.61675],[60.36787,51.66815],[60.50986,51.7964],[60.09867,51.87135],[59.99809,51.98263],[60.19925,51.99173],[60.48915,52.15175],[60.72581,52.15538],[60.78201,52.22067],[61.05417,52.35096],[60.98021,52.50068],[60.84709,52.52228],[60.84118,52.63912],[60.71693,52.66245],[60.71989,52.75923],[61.05842,52.92217],[61.23462,53.03227],[62.0422,52.96105],[62.12799,52.99133],[62.14574,53.09626],[61.19024,53.30536],[61.14291,53.41481],[61.29082,53.50992],[61.37957,53.45887],[61.57185,53.50112],[61.55706,53.57144],[60.90626,53.62937],[61.22574,53.80268],[61.14283,53.90063],[60.99796,53.93699],[61.26863,53.92797],[61.3706,54.08464],[61.47603,54.08048],[61.56941,53.95703],[61.65318,54.02445],[62.03913,53.94768],[62.00966,54.04134],[62.38535,54.03961],[62.45931,53.90737],[62.56876,53.94047],[62.58651,54.05871],[63.80604,54.27079],[63.91224,54.20013],[64.02715,54.22679],[63.97686,54.29763],[64.97216,54.4212],[65.11033,54.33028],[65.24663,54.35721],[65.20174,54.55216],[68.21308,54.98645],[68.26661,55.09226],[68.19206,55.18823],[68.90865,55.38148],[69.34224,55.36344],[69.74917,55.35545],[70.19179,55.1476],[70.76493,55.3027],[70.96009,55.10558],[71.08288,54.71253],[71.24185,54.64965],[71.08706,54.33376],[71.10379,54.13326],[71.96141,54.17736],[72.17477,54.36303],[72.43415,53.92685],[72.71026,54.1161],[73.37963,53.96132],[73.74778,54.07194],[73.68921,53.86522],[73.25412,53.61532],[73.39218,53.44623],[75.07405,53.80831],[75.43398,53.98652],[75.3668,54.07439],[76.91052,54.4677],[76.82266,54.1798],[76.44076,54.16017],[76.54243,53.99329],[77.90383,53.29807],[79.11255,52.01171],[80.08138,50.77658],[80.4127,50.95581],[80.44819,51.20855],[80.80318,51.28262],[81.16999,51.15662],[81.06091,50.94833],[81.41248,50.97524],[81.46581,50.77658],[81.94999,50.79307],[82.55443,50.75412],[83.14607,51.00796],[83.8442,50.87375],[84.29385,50.27257],[84.99198,50.06793],[85.24047,49.60239],[86.18709,49.50259],[86.63674,49.80136],[86.79056,49.74787],[86.61307,49.60239],[86.82606,49.51796],[87.03071,49.25142],[87.31465,49.23603],[87.28386,49.11626],[87.478,49.07403],[87.48983,49.13794],[87.81333,49.17354],[87.98977,49.18147],[88.15543,49.30314],[88.17223,49.46934],[88.42449,49.48821],[88.82499,49.44808],[89.70687,49.72535],[89.59711,49.90851],[91.86048,50.73734],[92.07173,50.69585],[92.44714,50.78762],[93.01109,50.79001],[92.99595,50.63183],[94.30823,50.57498],[94.39258,50.22193],[94.49477,50.17832],[94.6121,50.04239],[94.97166,50.04725],[95.02465,49.96941],[95.74757,49.97915],[95.80056,50.04239],[96.97388,49.88413],[97.24639,49.74737],[97.56811,49.84265],[97.56432,49.92801],[97.76871,49.99861],[97.85197,49.91339],[98.29481,50.33561],[98.31373,50.4996],[98.06393,50.61262],[97.9693,50.78044],[98.01472,50.86652],[97.83305,51.00248],[98.05257,51.46696],[98.22053,51.46579],[98.33222,51.71832],[98.74142,51.8637],[98.87768,52.14563],[99.27888,51.96876],[99.75578,51.90108],[99.89203,51.74903],[100.61116,51.73028],[101.39085,51.45753],[101.5044,51.50467],[102.14032,51.35566],[102.32194,50.67982],[102.71178,50.38873],[103.70343,50.13952],[105.32528,50.4648],[106.05562,50.40582],[106.07865,50.33474],[106.47156,50.31909],[106.49628,50.32436],[106.51122,50.34408],[106.58373,50.34044],[106.80326,50.30177],[107.00007,50.1977],[107.1174,50.04239],[107.36407,49.97612],[107.96116,49.93191],[107.95387,49.66659],[108.27937,49.53167],[108.53969,49.32325],[109.18017,49.34709],[109.51325,49.22859],[110.24373,49.16676],[110.39891,49.25083],[110.64493,49.1816],[113.02647,49.60772],[113.20216,49.83356],[114.325,50.28098],[114.9703,50.19254],[115.26068,49.97367],[115.73602,49.87688],[116.22402,50.04477],[116.62502,49.92919],[116.71193,49.83813],[117.07142,49.68482],[117.27597,49.62544],[117.48208,49.62324],[117.82343,49.52696],[118.61623,49.93809],[119.11003,50.00276],[119.27996,50.13348],[119.38598,50.35162],[119.13553,50.37412],[120.10963,51.671],[120.65907,51.93544],[120.77337,52.20805],[120.61346,52.32447],[120.71673,52.54099],[120.46454,52.63811],[120.04049,52.58773],[120.0451,52.7359],[120.85633,53.28499],[121.39213,53.31888],[122.35063,53.49565],[122.85966,53.47395],[123.26989,53.54843],[123.86158,53.49391],[124.46078,53.21881],[125.17522,53.20225],[125.6131,53.07229],[126.558,52.13738],[126.44606,51.98254],[126.68349,51.70607],[126.90369,51.3238],[126.93135,51.0841],[127.14586,50.91152],[127.28165,50.72075],[127.36335,50.58306],[127.28765,50.46585],[127.36009,50.43787],[127.37384,50.28393],[127.60515,50.23503],[127.49299,50.01251],[127.53516,49.84306],[127.83476,49.5748],[128.72896,49.58676],[129.11153,49.36813],[129.23232,49.40353],[129.35317,49.3481],[129.40398,49.44194],[129.50685,49.42398],[129.67598,49.29596],[129.85416,49.11067],[130.2355,48.86741],[130.43232,48.90844],[130.66946,48.88251],[130.52147,48.61745],[130.84462,48.30942],[130.65103,48.10052],[130.90915,47.90623],[130.95985,47.6957],[131.09871,47.6852],[131.2635,47.73325],[131.90448,47.68011],[132.57309,47.71741],[132.66989,47.96491],[134.49516,48.42884],[134.75328,48.36763],[134.67098,48.1564],[134.55508,47.98651],[134.7671,47.72051],[134.50898,47.4812],[134.20016,47.33458],[134.03538,46.75668],[133.84104,46.46681],[133.91496,46.4274],[133.88097,46.25066],[133.68047,46.14697],[133.72695,46.05576],[133.67569,45.9759],[133.60442,45.90053],[133.48457,45.86203],[133.41083,45.57723],[133.19419,45.51913],[133.09279,45.25693],[133.12293,45.1332],[132.96373,45.0212],[132.83978,45.05916],[131.99417,45.2567],[131.86903,45.33636],[131.76532,45.22609],[131.66852,45.2196],[131.68466,45.12374],[131.48415,44.99513],[130.95639,44.85154],[131.1108,44.70266],[131.30365,44.04262],[131.25484,44.03131],[131.23583,43.96085],[131.26176,43.94011],[131.21105,43.82383],[131.19492,43.53047],[131.29402,43.46695],[131.30324,43.39498],[131.19031,43.21385],[131.20414,43.13654],[131.10274,43.04734],[131.135,42.94114],[131.02668,42.91246],[131.02438,42.86518],[130.66524,42.84753],[130.44361,42.76205],[130.40213,42.70788],[130.56576,42.68925],[130.62107,42.58413],[130.55143,42.52158],[130.56835,42.43281],[130.60805,42.4317],[130.64181,42.41422],[130.66367,42.38024],[130.65022,42.32281],[131.95041,41.5445],[140.9182,45.92937],[145.82343,44.571],[145.23667,43.76813],[145.76215,43.50342],[145.97944,43.07828],[169.19658,53.9242],[180,62.52334],[180,71.53642],[157.93051,77.7025],[94.09128,81.82849],[56.59649,82.16972],[35.22046,80.57056],[33.12005,75.46568],[32.07813,72.01005],[31.59909,70.16571],[30.84095,69.80584],[30.95011,69.54699],[30.52662,69.54699],[30.16363,69.65244],[29.97205,69.41623],[29.27631,69.2811],[29.26623,69.13794],[29.0444,69.0119],[28.91738,69.04774],[28.45957,68.91417],[28.78224,68.86696],[28.43941,68.53366],[28.62982,68.19816],[29.34179,68.06655],[29.66955,67.79872],[30.02041,67.67523],[29.91155,67.51507],[28.9839,66.94139],[29.91155,66.13863],[30.16363,65.66935],[29.97205,65.70256],[29.74013,65.64025],[29.84096,65.56945],[29.68972,65.31803],[29.61914,65.23791],[29.8813,65.22101],[29.84096,65.1109],[29.61914,65.05993],[29.68972,64.80789],[30.05271,64.79072],[30.12329,64.64862],[30.01238,64.57513],[30.06279,64.35782],[30.4762,64.25728],[30.55687,64.09036],[30.25437,63.83364],[29.98213,63.75795],[30.49637,63.46666],[31.23244,63.22239],[31.29294,63.09035],[31.58535,62.91642],[31.38369,62.66284],[31.10136,62.43042],[29.01829,61.17448],[28.82816,61.1233],[28.47974,60.93365],[27.77352,60.52722],[27.71177,60.3893],[27.44953,60.22766],[26.32936,60.00121]]]]}}]} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/spatialrules/AreaIndexTest.java b/core/src/test/java/com/graphhopper/routing/util/AreaIndexTest.java similarity index 92% rename from core/src/test/java/com/graphhopper/routing/util/spatialrules/AreaIndexTest.java rename to core/src/test/java/com/graphhopper/routing/util/AreaIndexTest.java index ec0a2b63cfd..1b3ddd76e55 100644 --- a/core/src/test/java/com/graphhopper/routing/util/spatialrules/AreaIndexTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/AreaIndexTest.java @@ -16,25 +16,20 @@ * limitations under the License. */ -package com.graphhopper.routing.util.spatialrules; +package com.graphhopper.routing.util; -import com.graphhopper.routing.util.AreaIndex; -import com.graphhopper.routing.util.CustomArea; -import com.graphhopper.util.StopWatch; -import org.junit.jupiter.api.Disabled; +import com.graphhopper.routing.ev.Country; import org.junit.jupiter.api.Test; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.LinearRing; import org.locationtech.jts.geom.Polygon; -import java.io.IOException; import java.util.*; import java.util.stream.Collectors; import static com.graphhopper.util.GHUtility.readCountries; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; class AreaIndexTest { @@ -140,12 +135,10 @@ public void testOverlap() { @Test public void testCountries() { AreaIndex countryIndex = createCountryIndex(); - // Berlin - assertEquals("Germany", countryIndex.query(52.5243700, 13.4105300).get(0).getProperties().get("name:en")); - // Paris - assertEquals("France", countryIndex.query(48.864716, 2.349014).get(0).getProperties().get("name:en")); - // Austria - assertEquals("Austria", countryIndex.query(48.204484, 16.107888).get(0).getProperties().get("name:en")); + assertEquals("DEU", countryIndex.query(52.52437, 13.41053).get(0).getProperties().get(Country.ISO_ALPHA3)); + assertEquals("FRA", countryIndex.query(48.86471, 2.349014).get(0).getProperties().get(Country.ISO_ALPHA3)); + assertEquals("USA", countryIndex.query(35.67514, -105.94665).get(0).getProperties().get(Country.ISO_ALPHA3)); + assertEquals("AUT", countryIndex.query(48.20448, 16.10788).get(0).getProperties().get(Country.ISO_ALPHA3)); } private AreaIndex createCountryIndex() { From 8f6b0962892fa4a6f4f5706627bfa9cb28ebb4bc Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 23 Sep 2022 10:59:20 +0200 Subject: [PATCH 172/389] github actions: JDK19 instead of 18 --- .github/workflows/push-packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push-packages.yml b/.github/workflows/push-packages.yml index 937e1b71183..8f3074ae0d8 100644 --- a/.github/workflows/push-packages.yml +++ b/.github/workflows/push-packages.yml @@ -41,7 +41,7 @@ jobs: strategy: fail-fast: false matrix: - java-version: [ 18 ] + java-version: [ 19 ] steps: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 From 439bff515c82c6b82f0aef46fe1e08887d5c9668 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 23 Sep 2022 11:13:38 +0200 Subject: [PATCH 173/389] Github is not yet ready, revert "github actions: JDK19 instead of 18" This reverts commit 8f6b0962892fa4a6f4f5706627bfa9cb28ebb4bc. --- .github/workflows/push-packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push-packages.yml b/.github/workflows/push-packages.yml index 8f3074ae0d8..937e1b71183 100644 --- a/.github/workflows/push-packages.yml +++ b/.github/workflows/push-packages.yml @@ -41,7 +41,7 @@ jobs: strategy: fail-fast: false matrix: - java-version: [ 19 ] + java-version: [ 18 ] steps: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 From 5fff1eec69d30ba1f0e3b6d99fd3ec50ff7e9ca5 Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Sat, 24 Sep 2022 16:46:28 -0700 Subject: [PATCH 174/389] mapmatching: structured and more informative logging --- .../com/graphhopper/matching/MapMatching.java | 9 ++++++++ .../resources/MapMatchingResource.java | 16 +++++++------- .../graphhopper/resources/RouteResource.java | 22 +++++++------------ 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java index 36aeb67785c..3e83bf1b18a 100644 --- a/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java +++ b/map-matching/src/main/java/com/graphhopper/matching/MapMatching.java @@ -73,6 +73,8 @@ public class MapMatching { private final DistanceCalc distanceCalc = new DistancePlaneProjection(); private QueryGraph queryGraph; + private Map statistics = new HashMap<>(); + public static MapMatching fromGraphHopper(GraphHopper graphHopper, PMap hints) { Router router = routerFromGraphHopper(graphHopper, hints); return new MapMatching(graphHopper.getBaseGraph(), (LocationIndexTree) graphHopper.getLocationIndex(), router); @@ -193,11 +195,13 @@ public void setMeasurementErrorSigma(double measurementErrorSigma) { public MatchResult match(List observations) { List filteredObservations = filterObservations(observations); + statistics.put("filteredObservations", filteredObservations.size()); // Snap observations to links. Generates multiple candidate snaps per observation. List> snapsPerObservation = filteredObservations.stream() .map(o -> findCandidateSnaps(o.getPoint().lat, o.getPoint().lon)) .collect(Collectors.toList()); + statistics.put("snapsPerObservation", snapsPerObservation.stream().mapToInt(Collection::size).toArray()); // Create the query graph, containing split edges so that all the places where an observation might have happened // are a node. This modifies the Snap objects and puts the new node numbers into them. @@ -209,6 +213,7 @@ public MatchResult match(List observations) { // Compute the most likely sequence of map matching candidates: List> seq = computeViterbiSequence(timeSteps); + statistics.put("transitionDistances", seq.stream().filter(s -> s.transitionDescriptor != null).mapToLong(s -> Math.round(s.transitionDescriptor.getDistance())).toArray()); List path = seq.stream().filter(s1 -> s1.transitionDescriptor != null).flatMap(s1 -> s1.transitionDescriptor.calcEdges().stream()).collect(Collectors.toList()); @@ -518,6 +523,10 @@ private EdgeIteratorState resolveToRealEdge(EdgeIteratorState edgeIteratorState) } } + public Map getStatistics() { + return statistics; + } + private static class MapMatchedPath extends Path { MapMatchedPath(Graph graph, Weighting weighting, List edges) { super(graph); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java index 06a7711bee5..75fee9bd22f 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java @@ -18,6 +18,7 @@ package com.graphhopper.resources; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -27,6 +28,7 @@ import com.graphhopper.gpx.GpxConversions; import com.graphhopper.http.ProfileResolver; import com.graphhopper.jackson.Gpx; +import com.graphhopper.jackson.Jackson; import com.graphhopper.jackson.ResponsePathSerializer; import com.graphhopper.matching.*; import com.graphhopper.storage.index.LocationIndexTree; @@ -35,7 +37,6 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; -import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; @@ -65,6 +66,7 @@ public interface MapMatchingRouterFactory { private final ProfileResolver profileResolver; private final TranslationMap trMap; private final MapMatchingRouterFactory mapMatchingRouterFactory; + private final ObjectMapper objectMapper = Jackson.newObjectMapper(); @Inject public MapMatchingResource(GraphHopper graphHopper, ProfileResolver profileResolver, TranslationMap trMap, MapMatchingRouterFactory mapMatchingRouterFactory) { @@ -79,7 +81,6 @@ public MapMatchingResource(GraphHopper graphHopper, ProfileResolver profileResol @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, "application/gpx+xml"}) public Response match( Gpx gpx, - @Context HttpServletRequest request, @Context UriInfo uriInfo, @QueryParam(WAY_POINT_MAX_DISTANCE) @DefaultValue("1") double minPathPrecision, @QueryParam("type") @DefaultValue("json") String outType, @@ -113,7 +114,6 @@ public Response match( // add values that are not in hints because they were explicitly listed in query params hints.putObject(MAX_VISITED_NODES, maxVisitedNodes); - String weightingVehicleLogStr = "weighting: " + hints.getString("weighting", "") + ", vehicle: " + hints.getString("vehicle", ""); // resolve profile and remove legacy vehicle/weighting parameters // we need to explicitly disable CH here because map matching does not use it @@ -130,12 +130,12 @@ public Response match( List measurements = GpxConversions.getEntries(gpx.trk.get(0)); MatchResult matchResult = matching.match(measurements); - // TODO: Request logging and timing should perhaps be done somewhere outside double took = sw.stop().getMillisDouble(); - String infoStr = request.getRemoteAddr() + " " + request.getLocale() + " " + request.getHeader("User-Agent"); - String logStr = request.getQueryString() + ", " + infoStr + ", took:" + String.format("%.1f", took) + "ms, entries:" + measurements.size() + - ", profile: " + profile + ", " + weightingVehicleLogStr; - logger.info(logStr); + logger.info(objectMapper.createObjectNode() + .put("duration", took) + .put("profile", profile) + .put("observations", measurements.size()) + .putPOJO("mapmatching", matching.getStatistics()).toString()); if ("extended_json".equals(outType)) { return Response.ok(convertToTree(matchResult, enableElevation, pointsEncoded)). diff --git a/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java b/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java index 86b2511f502..a70957bad3f 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/RouteResource.java @@ -102,7 +102,6 @@ public Response doGet( StopWatch sw = new StopWatch().start(); GHRequest request = new GHRequest(); initHints(request.getHints(), uriInfo.getQueryParameters()); - String weightingVehicleLogStr = "weighting: " + request.getHints().getString("weighting", "") + ", vehicle: " + request.getHints().getString("vehicle", ""); PMap profileResolverHints = new PMap(request.getHints()); profileResolverHints.putObject("profile", profileName); @@ -131,13 +130,12 @@ public Response doGet( GHResponse ghResponse = graphHopper.route(request); double took = sw.stop().getMillisDouble(); - String infoStr = httpReq.getRemoteAddr() + " " + httpReq.getLocale() + " " + httpReq.getHeader("User-Agent"); - String logStr = httpReq.getQueryString() + " " + infoStr + " " + points + ", took: " - + String.format("%.1f", took) + "ms, algo: " + algoStr + ", profile: " + profileName + ", " + weightingVehicleLogStr; + String logStr = (httpReq.getRemoteAddr() + " " + httpReq.getLocale() + " " + httpReq.getHeader("User-Agent")) + " " + points + ", took: " + String.format("%.1f", took) + "ms, algo: " + algoStr + ", profile: " + profileName; if (ghResponse.hasErrors()) { - logger.error(logStr + ", errors:" + ghResponse.getErrors()); - throw new MultiException(ghResponse.getErrors()); + MultiException ex = new MultiException(ghResponse.getErrors()); + logger.error(logStr, ex); + throw ex; } else { logger.info(logStr + ", alternatives: " + ghResponse.getAll().size() + ", distance0: " + ghResponse.getBest().getDistance() @@ -180,18 +178,14 @@ public Response doPost(@NotNull GHRequest request, @Context HttpServletRequest h double took = sw.stop().getMillisDouble(); String infoStr = httpReq.getRemoteAddr() + " " + httpReq.getLocale() + " " + httpReq.getHeader("User-Agent"); - String queryString = httpReq.getQueryString() == null ? "" : (httpReq.getQueryString() + " "); - // todo: vehicle/weighting will always be empty at this point... - String weightingVehicleLogStr = "weighting: " + request.getHints().getString("weighting", "") - + ", vehicle: " + request.getHints().getString("vehicle", ""); - String logStr = queryString + infoStr + " " + request.getPoints().size() + ", took: " + String logStr = infoStr + " " + request.getPoints().size() + ", took: " + String.format("%.1f", took) + " ms, algo: " + request.getAlgorithm() + ", profile: " + request.getProfile() - + ", " + weightingVehicleLogStr + ", custom_model: " + request.getCustomModel(); if (ghResponse.hasErrors()) { - logger.error(logStr + ", errors:" + ghResponse.getErrors()); - throw new MultiException(ghResponse.getErrors()); + MultiException ex = new MultiException(ghResponse.getErrors()); + logger.error(logStr, ex); + throw ex; } else { logger.info(logStr + ", alternatives: " + ghResponse.getAll().size() + ", distance0: " + ghResponse.getBest().getDistance() From a73117c4ae4fd4e677823064bcbf5fdc15f3f937 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 28 Sep 2022 07:59:07 +0200 Subject: [PATCH 175/389] /mvt: return edge details for both directions --- .../main/java/com/graphhopper/resources/MVTResource.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java index 852f26b3092..9b375664f5e 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java @@ -134,13 +134,13 @@ public Response doGetXyz( map.put("distance", edge.getDistance()); encodingManager.getEncodedValues().forEach(ev -> { if (ev instanceof EnumEncodedValue) - map.put(ev.getName(), edge.get((EnumEncodedValue) ev).toString()); + map.put(ev.getName(), edge.get((EnumEncodedValue) ev).toString() + (ev.isStoreTwoDirections() ? " | " + edge.getReverse((EnumEncodedValue) ev).toString() : "")); else if (ev instanceof DecimalEncodedValue) - map.put(ev.getName(), edge.get((DecimalEncodedValue) ev)); + map.put(ev.getName(), edge.get((DecimalEncodedValue) ev) + (ev.isStoreTwoDirections() ? " | " + edge.getReverse((DecimalEncodedValue) ev) : "")); else if (ev instanceof BooleanEncodedValue) - map.put(ev.getName(), edge.get((BooleanEncodedValue) ev)); + map.put(ev.getName(), edge.get((BooleanEncodedValue) ev) + (ev.isStoreTwoDirections() ? " | " + edge.getReverse((BooleanEncodedValue) ev) : "")); else if (ev instanceof IntEncodedValue) - map.put(ev.getName(), edge.get((IntEncodedValue) ev)); + map.put(ev.getName(), edge.get((IntEncodedValue) ev) + (ev.isStoreTwoDirections() ? " | " + edge.getReverse((IntEncodedValue) ev) : "")); }); lineString.setUserData(map); From 217603ce7c0f9db256f0de63e2e544905e70868b Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 28 Sep 2022 08:14:32 +0200 Subject: [PATCH 176/389] fix /mvt test --- .../com/graphhopper/application/resources/MvtResourceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java index cecd04201b9..b1ac51ed6b8 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java @@ -102,7 +102,7 @@ public void testDetailsInResponse() throws IOException { filter(g -> getUserData(g).get("name").equals("Avinguda de Tarragona")) .findFirst().get(); assertEquals("road", getUserData(geometry).get("road_environment")); - assertEquals(50.0, getUserData(geometry).get("max_speed")); + assertEquals("50.0 | 50.0", getUserData(geometry).get("max_speed")); assertEquals("primary", getUserData(geometry).get("road_class")); } From 992ec522e3cf8974d7ccc1761c06673e737c0892 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 27 Sep 2022 19:19:17 +0200 Subject: [PATCH 177/389] if country overlapp: pick the smaller one; no further warnings for now, fixes #2663 --- .../java/com/graphhopper/reader/osm/OSMReader.java | 10 ++++++++-- .../java/com/graphhopper/routing/util/CustomArea.java | 6 ++++++ .../java/com/graphhopper/reader/osm/OSMReaderTest.java | 8 ++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 5e33ec84e04..0a2fe13111c 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -43,6 +43,7 @@ import com.graphhopper.util.*; import com.graphhopper.util.shapes.GHPoint; import com.graphhopper.util.shapes.GHPoint3D; +import org.locationtech.jts.geom.Polygon; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -251,12 +252,17 @@ protected void setArtificialWayTags(PointList pointList, ReaderWay way, double d // special handling for countries: since they are built-in with GraphHopper they are always fed to the EncodingManager Country country = Country.MISSING; + CustomArea prevCustomArea = null; for (CustomArea customArea : customAreas) { Object alpha3 = customArea.getProperties().get(Country.ISO_ALPHA3); if (alpha3 == null) continue; - if (country != Country.MISSING) - LOGGER.warn("Multiple countries found for way {}: {}, {}", way.getId(), country, alpha3); + + // multiple countries are available -> pick the smaller one, see #2663 + if (prevCustomArea != null && prevCustomArea.getArea() < customArea.getArea()) + break; + + prevCustomArea = customArea; country = Country.valueOf((String) alpha3); } way.setTag("country", country); diff --git a/core/src/main/java/com/graphhopper/routing/util/CustomArea.java b/core/src/main/java/com/graphhopper/routing/util/CustomArea.java index fe1b3fea49b..9cc701de3b2 100644 --- a/core/src/main/java/com/graphhopper/routing/util/CustomArea.java +++ b/core/src/main/java/com/graphhopper/routing/util/CustomArea.java @@ -27,6 +27,7 @@ public class CustomArea implements AreaIndex.Area { private final Map properties; private final List borders; + private final double area; public static CustomArea fromJsonFeature(JsonFeature j) { List borders = new ArrayList<>(); @@ -44,6 +45,7 @@ public static CustomArea fromJsonFeature(JsonFeature j) { public CustomArea(Map properties, List borders) { this.properties = properties; this.borders = borders; + this.area = borders.stream().map(Polygon::getArea).reduce(0d, Double::sum); } public Map getProperties() { @@ -54,4 +56,8 @@ public Map getProperties() { public List getBorders() { return borders; } + + public double getArea() { + return area; + } } diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 796816b547b..5bf3aaebeab 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -25,6 +25,7 @@ import com.graphhopper.reader.OSMTurnRelation; import com.graphhopper.reader.ReaderElement; import com.graphhopper.reader.ReaderRelation; +import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.dem.ElevationProvider; import com.graphhopper.reader.dem.SRTMProvider; import com.graphhopper.reader.osm.conditional.DateRangeParser; @@ -47,6 +48,7 @@ import java.io.File; import java.io.IOException; import java.util.Collections; +import java.util.HashMap; import java.util.List; import static com.graphhopper.util.GHUtility.readCountries; @@ -957,6 +959,12 @@ public void testCountries() throws IOException { assertEquals(RoadAccess.DESTINATION, edgeBerlin.get(roadAccessEnc)); // for Paris there is no such rule, we just get the default RoadAccess.YES assertEquals(RoadAccess.YES, edgeParis.get(roadAccessEnc)); + + ReaderWay way = new ReaderWay(0L); + PointList list = new PointList(); + list.add(49.214906,-2.156067); + reader.setArtificialWayTags(list, way, 10, new HashMap<>()); + assertEquals("JEY", way.getTag("country", null).toString()); } @Test From a56f889ca5e8d786c12403fac2a56d2fa8375b96 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 28 Sep 2022 12:09:48 +0200 Subject: [PATCH 178/389] add test github build --- .github/workflows/test123.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/workflows/test123.yml diff --git a/.github/workflows/test123.yml b/.github/workflows/test123.yml new file mode 100644 index 00000000000..4b50c51ea06 --- /dev/null +++ b/.github/workflows/test123.yml @@ -0,0 +1,11 @@ +name: test12 + +on: push + +jobs: + run_test: + runs-on: ubuntu-20.04 + steps: + - name: test + run: | + echo hello From 8a4b65cd79b3574f9c7674c924ec989eb022b13d Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 28 Sep 2022 14:35:02 +0200 Subject: [PATCH 179/389] configurable roads vehicle --- .../util/DefaultVehicleEncodedValuesFactory.java | 2 +- .../routing/util/VehicleEncodedValues.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java index ff59913d555..069eab985b4 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java @@ -28,7 +28,7 @@ public class DefaultVehicleEncodedValuesFactory implements VehicleEncodedValuesF @Override public VehicleEncodedValues createVehicleEncodedValues(String name, PMap configuration) { if (name.equals(ROADS)) - return VehicleEncodedValues.roads(); + return VehicleEncodedValues.roads(configuration); if (name.equals(CAR)) return VehicleEncodedValues.car(configuration); diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index 1363c806e55..53c94c5946d 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -119,12 +119,12 @@ public static VehicleEncodedValues motorcycle(PMap properties) { return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, curvatureEnc, turnCostEnc); } - public static VehicleEncodedValues roads() { - String name = "roads"; - int speedBits = 7; - double speedFactor = 2; - boolean speedTwoDirections = true; - int maxTurnCosts = 3; + public static VehicleEncodedValues roads(PMap properties) { + String name = properties.getString("name", "roads"); + int speedBits = properties.getInt("speed_bits", 7); + double speedFactor = properties.getDouble("speed_factor", 2); + boolean speedTwoDirections = properties.getBool("speed_two_directions", true); + int maxTurnCosts = properties.getInt("max_turn_costs", properties.getBool("turn_costs", true) ? 1 : 0); BooleanEncodedValue accessEnc = VehicleAccess.create(name); DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; From a145855413f04c105c85d4f28018ff672fe2b678 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 28 Sep 2022 14:39:25 +0200 Subject: [PATCH 180/389] remove --- .github/workflows/test123.yml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .github/workflows/test123.yml diff --git a/.github/workflows/test123.yml b/.github/workflows/test123.yml deleted file mode 100644 index 4b50c51ea06..00000000000 --- a/.github/workflows/test123.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: test12 - -on: push - -jobs: - run_test: - runs-on: ubuntu-20.04 - steps: - - name: test - run: | - echo hello From 62e98dcfbd54a81a248d5a0446e62165f5f13654 Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 28 Sep 2022 16:00:09 +0200 Subject: [PATCH 181/389] trigger measurement --- .github/workflows/trigger_measurement.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/trigger_measurement.yml diff --git a/.github/workflows/trigger_measurement.yml b/.github/workflows/trigger_measurement.yml new file mode 100644 index 00000000000..11a68dbc6e6 --- /dev/null +++ b/.github/workflows/trigger_measurement.yml @@ -0,0 +1,15 @@ +name: trigger_measurement + +on: push + +jobs: + trigger_measurement: + runs-on: ubuntu-22.04 + environment: benchmarks + steps: + - name: trigger + run: | + curl -X POST -H "Authorization: token ${{ secrets.MEASUREMENT_TOKEN }}" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${{ secrets.MEASUREMENT_REPO }}/dispatches" \ + -d '{"event_type":"measurement_core","client_payload":{"core_commit": "${GITHUB_SHA}" }}' From 28b07fa66f23d9968ea163294e3067fd97126f0e Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 28 Sep 2022 16:42:03 +0200 Subject: [PATCH 182/389] Cleanup GitHub workflows a bit * separate file for and rename 'build-only', which really builds and tests compared to push-packages which does not test * do not run push-packages, trigger-measurement and remove-old-artifacts for forks * measurements -> benchmarks --- .github/workflows/build.yml | 38 +++++++++++++++++++ .github/workflows/push-packages.yml | 36 +----------------- .github/workflows/remove-old-artifacts.yml | 1 + ...measurement.yml => trigger-benchmarks.yml} | 9 ++--- 4 files changed, 44 insertions(+), 40 deletions(-) create mode 100644 .github/workflows/build.yml rename .github/workflows/{trigger_measurement.yml => trigger-benchmarks.yml} (54%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000000..3b9e331c9a6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,38 @@ +name: Build and Test +on: push +jobs: + build: + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + java-version: [ 18 ] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + java-version: ${{ matrix.java-version }} + distribution: temurin + - name: Cache Maven artifacts + uses: actions/cache@v3 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Cache node + uses: actions/cache@v3 + with: + path: web-bundle/node + key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os}}-node- + - name: Cache node_modules + uses: actions/cache@v3 + with: + path: web-bundle/node_modules + key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml', '**/package.json') }} + restore-keys: | + ${{ runner.os}}-node_modules- + - name: Build ${{ matrix.java-version }} + run: mvn -B clean test diff --git a/.github/workflows/push-packages.yml b/.github/workflows/push-packages.yml index 937e1b71183..a3e89ade688 100644 --- a/.github/workflows/push-packages.yml +++ b/.github/workflows/push-packages.yml @@ -2,6 +2,7 @@ name: Publish to GitHub Packages on: push jobs: publish: + if: github.repository_owner == 'graphhopper' runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 @@ -36,38 +37,3 @@ jobs: mvn -B -DskipTests -Pskip-shaded-web-jar -Pskip-tools-jar source:jar deploy env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - build-only: - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - java-version: [ 18 ] - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 - with: - java-version: ${{ matrix.java-version }} - distribution: temurin - - name: Cache Maven artifacts - uses: actions/cache@v3 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Cache node - uses: actions/cache@v3 - with: - path: web-bundle/node - key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os}}-node- - - name: Cache node_modules - uses: actions/cache@v3 - with: - path: web-bundle/node_modules - key: ${{ runner.os }}-node-${{ hashFiles('**/pom.xml', '**/package.json') }} - restore-keys: | - ${{ runner.os}}-node_modules- - - name: Build ${{ matrix.java-version }} - run: mvn -B clean test diff --git a/.github/workflows/remove-old-artifacts.yml b/.github/workflows/remove-old-artifacts.yml index e41e91991eb..a52c80c4dc4 100644 --- a/.github/workflows/remove-old-artifacts.yml +++ b/.github/workflows/remove-old-artifacts.yml @@ -5,6 +5,7 @@ on: workflow_dispatch: jobs: remove-old-artifacts: + if: github.repository_owner == 'graphhopper' name: Remove old artifacts runs-on: ubuntu-latest timeout-minutes: 10 # stop the task if it takes longer diff --git a/.github/workflows/trigger_measurement.yml b/.github/workflows/trigger-benchmarks.yml similarity index 54% rename from .github/workflows/trigger_measurement.yml rename to .github/workflows/trigger-benchmarks.yml index 11a68dbc6e6..7909040c338 100644 --- a/.github/workflows/trigger_measurement.yml +++ b/.github/workflows/trigger-benchmarks.yml @@ -1,15 +1,14 @@ -name: trigger_measurement - +name: Trigger Benchmarks on: push - jobs: trigger_measurement: + if: github.repository_owner == 'graphhopper' runs-on: ubuntu-22.04 environment: benchmarks steps: - name: trigger run: | - curl -X POST -H "Authorization: token ${{ secrets.MEASUREMENT_TOKEN }}" \ + curl -X POST -H "Authorization: token ${{ secrets.BENCHMARKS_TOKEN }}" \ -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/${{ secrets.MEASUREMENT_REPO }}/dispatches" \ + "https://api.github.com/repos/${{ secrets.BENCHMARKS_REPO }}/dispatches" \ -d '{"event_type":"measurement_core","client_payload":{"core_commit": "${GITHUB_SHA}" }}' From 7ef1e873eaae0358ee34e86d7e4305671a019f2f Mon Sep 17 00:00:00 2001 From: easbar Date: Wed, 28 Sep 2022 16:53:17 +0200 Subject: [PATCH 183/389] trigger build --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3b9e331c9a6..71cc9c69b3b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,3 +36,4 @@ jobs: ${{ runner.os}}-node_modules- - name: Build ${{ matrix.java-version }} run: mvn -B clean test + From 829753d15fb894c13af40ee43808ce1bdbf4a68d Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 29 Sep 2022 10:01:35 +0200 Subject: [PATCH 184/389] use same names for the keys in the EdgeKVStorage (#2661) * use same names for the keys in the EdgeKVStorage like we use for path details * fix minor mistakes * move from Details into KeyValue class --- CHANGELOG.md | 5 +- .../com/graphhopper/reader/osm/OSMReader.java | 17 ++- .../routing/InstructionsFromEdges.java | 28 ++-- .../querygraph/VirtualEdgeIteratorState.java | 2 +- .../com/graphhopper/search/EdgeKVStorage.java | 5 + .../com/graphhopper/storage/BaseGraph.java | 2 +- .../util/details/KVStringDetails.java | 8 +- .../details/PathDetailsBuilderFactory.java | 6 +- .../java/com/graphhopper/GraphHopperTest.java | 9 +- .../com/graphhopper/routing/PathTest.java | 137 +++++++++--------- .../util/NameSimilarityEdgeFilterTest.java | 11 +- .../storage/AbstractGraphStorageTester.java | 7 +- .../graphhopper/storage/BaseGraphTest.java | 5 +- .../storage/BaseGraphWithTurnCostsTest.java | 5 +- .../graphhopper/util/InstructionListTest.java | 57 ++++---- .../util/PathSimplificationTest.java | 21 +-- .../com/graphhopper/tools/Measurement.java | 1 + .../jackson/InstructionListSerializer.java | 4 +- .../jackson/ResponsePathDeserializer.java | 2 +- .../com/graphhopper/util/Instruction.java | 12 +- .../java/com/graphhopper/util/Parameters.java | 5 +- .../util/RoundaboutInstruction.java | 2 +- .../graphhopper/resources/MVTResource.java | 5 +- .../graphhopper/resources/SPTResource.java | 4 +- .../graphhopper/gpx/GpxConversionsTest.java | 14 +- .../resources/ExtendedJsonResponseTest.java | 2 +- .../resources/MvtResourceTest.java | 6 +- 27 files changed, 207 insertions(+), 175 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 273e34d5622..842c85d536b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ -### 6.0 [not yet released] +### 7.0 [not yet released] +- internal keys for EdgeKVStorage changed to contain the street_ prefix like the path details too. Similarly, the extra_info in the instructions of the API response, see #2661 + +### 6.0 [13 Sep 2022] - When using a DecimalEncodedValue with useMaximumAsInfinity=true and a single bit of space make sure you always use Double.POSITIVE_INFINITY to set the value, see #2646 - renamed DouglasPeucker to RamerDouglasPeucker diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 0a2fe13111c..3d7d7601119 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -53,6 +53,7 @@ import java.util.function.LongToIntFunction; import java.util.regex.Pattern; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.*; import static com.graphhopper.util.Helper.nf; import static java.util.Collections.emptyList; @@ -400,28 +401,28 @@ protected void preprocessWay(ReaderWay way, WaySegmentParser.CoordinateSupplier if (name.isEmpty()) name = fixWayName(way.getTag("name")); if (!name.isEmpty()) - list.add(new EdgeKVStorage.KeyValue("name", name)); + list.add(new EdgeKVStorage.KeyValue(STREET_NAME, name)); // http://wiki.openstreetmap.org/wiki/Key:ref String refName = fixWayName(way.getTag("ref")); if (!refName.isEmpty()) - list.add(new EdgeKVStorage.KeyValue("ref", refName)); + list.add(new EdgeKVStorage.KeyValue(STREET_REF, refName)); if (way.hasTag("destination:ref")) { - list.add(new EdgeKVStorage.KeyValue("destination_ref", fixWayName(way.getTag("destination:ref")))); + list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION_REF, fixWayName(way.getTag("destination:ref")))); } else { if (way.hasTag("destination:ref:forward")) - list.add(new EdgeKVStorage.KeyValue("destination_ref", fixWayName(way.getTag("destination:ref:forward")), true, false)); + list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION_REF, fixWayName(way.getTag("destination:ref:forward")), true, false)); if (way.hasTag("destination:ref:backward")) - list.add(new EdgeKVStorage.KeyValue("destination_ref", fixWayName(way.getTag("destination:ref:backward")), false, true)); + list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION_REF, fixWayName(way.getTag("destination:ref:backward")), false, true)); } if (way.hasTag("destination")) { - list.add(new EdgeKVStorage.KeyValue("destination", fixWayName(way.getTag("destination")))); + list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION, fixWayName(way.getTag("destination")))); } else { if (way.hasTag("destination:forward")) - list.add(new EdgeKVStorage.KeyValue("destination", fixWayName(way.getTag("destination:forward")), true, false)); + list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION, fixWayName(way.getTag("destination:forward")), true, false)); if (way.hasTag("destination:backward")) - list.add(new EdgeKVStorage.KeyValue("destination", fixWayName(way.getTag("destination:backward")), false, true)); + list.add(new EdgeKVStorage.KeyValue(STREET_DESTINATION, fixWayName(way.getTag("destination:backward")), false, true)); } } way.setTag("key_values", list); diff --git a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java index e22ba4102b9..e8cce550989 100644 --- a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java +++ b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java @@ -24,6 +24,8 @@ import com.graphhopper.util.*; import com.graphhopper.util.shapes.GHPoint; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.*; + /** * This class calculates instructions from the edges in a Path. * @@ -138,17 +140,17 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { assert Double.compare(prevLon, nodeAccess.getLon(baseNode)) == 0; } - final String name = (String) edge.getValue("name"); - final String ref = (String) edge.getValue("ref"); - final String destination = (String) edge.getValue("destination"); // getValue is fast if it does not exist in edge - final String destinationRef = (String) edge.getValue("destination_ref"); + final String name = (String) edge.getValue(STREET_NAME); + final String ref = (String) edge.getValue(STREET_REF); + final String destination = (String) edge.getValue(STREET_DESTINATION); // getValue is fast if it does not exist in edge + final String destinationRef = (String) edge.getValue(STREET_DESTINATION_REF); if ((prevInstruction == null) && (!isRoundabout)) // very first instruction (if not in Roundabout) { int sign = Instruction.CONTINUE_ON_STREET; prevInstruction = new Instruction(sign, name, new PointList(10, nodeAccess.is3D())); - prevInstruction.setExtraInfo("ref", ref); - prevInstruction.setExtraInfo("destination", destination); - prevInstruction.setExtraInfo("destination_ref", destinationRef); + prevInstruction.setExtraInfo(STREET_REF, ref); + prevInstruction.setExtraInfo(STREET_DESTINATION, destination); + prevInstruction.setExtraInfo(STREET_DESTINATION_REF, destinationRef); double startLat = nodeAccess.getLat(baseNode); double startLon = nodeAccess.getLon(baseNode); double heading = AngleCalc.ANGLE_CALC.calcAzimuth(startLat, startLon, latitude, longitude); @@ -208,9 +210,9 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { } else if (prevInRoundabout) //previously in roundabout but not anymore { prevInstruction.setName(name); - prevInstruction.setExtraInfo("ref", ref); - prevInstruction.setExtraInfo("destination", destination); - prevInstruction.setExtraInfo("destination_ref", destinationRef); + prevInstruction.setExtraInfo(STREET_REF, ref); + prevInstruction.setExtraInfo(STREET_DESTINATION, destination); + prevInstruction.setExtraInfo(STREET_DESTINATION_REF, destinationRef); // calc angle between roundabout entrance and exit double orientation = AngleCalc.ANGLE_CALC.calcOrientation(prevLat, prevLon, latitude, longitude); @@ -284,9 +286,9 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) { prevInstructionName = prevName; ways.add(prevInstruction); } - prevInstruction.setExtraInfo("ref", ref); - prevInstruction.setExtraInfo("destination", destination); - prevInstruction.setExtraInfo("destination_ref", destinationRef); + prevInstruction.setExtraInfo(STREET_REF, ref); + prevInstruction.setExtraInfo(STREET_DESTINATION, destination); + prevInstruction.setExtraInfo(STREET_DESTINATION_REF, destinationRef); } // Update the prevName, since we don't always create an instruction on name changes the previous // name can be an old name. This leads to incorrect turn instructions due to name changes diff --git a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java index cb99cadec62..0cac2260041 100644 --- a/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java +++ b/core/src/main/java/com/graphhopper/routing/querygraph/VirtualEdgeIteratorState.java @@ -310,7 +310,7 @@ public EdgeIteratorState set(StringEncodedValue property, String fwd, String bwd @Override public String getName() { - String name = (String) getValue("name"); + String name = (String) getValue(EdgeKVStorage.KeyValue.STREET_NAME); // preserve backward compatibility (returns empty string if name tag missing) return name == null ? "" : name; } diff --git a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java index 3e3e633ade6..d6338f6d880 100644 --- a/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java +++ b/core/src/main/java/com/graphhopper/search/EdgeKVStorage.java @@ -430,6 +430,11 @@ public long getCapacity() { } public static class KeyValue { + public static final String STREET_NAME = "street_name"; + public static final String STREET_REF = "street_ref"; + public static final String STREET_DESTINATION = "street_destination"; + public static final String STREET_DESTINATION_REF = "street_destination_ref"; + public String key; public Object value; public boolean fwd, bwd; diff --git a/core/src/main/java/com/graphhopper/storage/BaseGraph.java b/core/src/main/java/com/graphhopper/storage/BaseGraph.java index 491a8513d3f..fc54bf7c754 100644 --- a/core/src/main/java/com/graphhopper/storage/BaseGraph.java +++ b/core/src/main/java/com/graphhopper/storage/BaseGraph.java @@ -974,7 +974,7 @@ public Object getValue(String key) { @Override public String getName() { - String name = (String) getValue("name"); + String name = (String) getValue(EdgeKVStorage.KeyValue.STREET_NAME); // preserve backward compatibility (returns empty string if name tag missing) return name == null ? "" : name; } diff --git a/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java b/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java index 93dc42bc1eb..a599df1fde4 100644 --- a/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/KVStringDetails.java @@ -26,21 +26,19 @@ */ public class KVStringDetails extends AbstractPathDetailsBuilder { - private final String key; private String curString; - public KVStringDetails(String name, String key) { + public KVStringDetails(String name) { super(name); - this.key = key; } @Override public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { if (curString == null) { - curString = (String) edge.getValue(key); + curString = (String) edge.getValue(getName()); return true; } - String val = (String) edge.getValue(key); + String val = (String) edge.getValue(getName()); if (!curString.equals(val)) { curString = val; return true; diff --git a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java index a8f2a24a3bc..46d28a5e296 100644 --- a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java +++ b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java @@ -36,11 +36,11 @@ public List createPathDetailsBuilders(List requested List builders = new ArrayList<>(); if (requestedPathDetails.contains(STREET_NAME)) - builders.add(new KVStringDetails(STREET_NAME, "name")); + builders.add(new KVStringDetails(STREET_NAME)); if (requestedPathDetails.contains(STREET_REF)) - builders.add(new KVStringDetails(STREET_REF, "ref")); + builders.add(new KVStringDetails(STREET_REF)); if (requestedPathDetails.contains(STREET_DESTINATION)) - builders.add(new KVStringDetails(STREET_DESTINATION, "destination")); + builders.add(new KVStringDetails(STREET_DESTINATION)); if (requestedPathDetails.contains(AVERAGE_SPEED)) builders.add(new AverageSpeedDetails(weighting)); diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index 9d1d614bc50..ae4dd366e52 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -36,6 +36,7 @@ import com.graphhopper.routing.util.parsers.TagParser; import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.routing.weighting.custom.CustomProfile; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.IntsRef; import com.graphhopper.storage.index.LocationIndexTree; import com.graphhopper.storage.index.Snap; @@ -2220,7 +2221,7 @@ public void simplifyWithInstructionsAndPathDetails() { .addPoint(new GHPoint(50.016895, 11.4923)) .addPoint(new GHPoint(50.003464, 11.49157)) .setProfile(profile) - .setPathDetails(Arrays.asList("street_ref", "max_speed")); + .setPathDetails(Arrays.asList(EdgeKVStorage.KeyValue.STREET_REF, "max_speed")); req.putHint("elevation", true); GHResponse rsp = hopper.route(req); @@ -2261,8 +2262,8 @@ public void simplifyWithInstructionsAndPathDetails() { assertDetail(speeds.get(6), "50.0 [37, 38]"); assertDetail(speeds.get(7), "null [38, 40]"); - // check street_names - List streetNames = path.getPathDetails().get("street_ref"); + // check street names + List streetNames = path.getPathDetails().get(EdgeKVStorage.KeyValue.STREET_REF); assertDetail(streetNames.get(0), "KU 11 [0, 4]"); assertDetail(streetNames.get(1), "B 85 [4, 16]"); assertDetail(streetNames.get(2), "B 85 [16, 32]"); @@ -2273,7 +2274,7 @@ public void simplifyWithInstructionsAndPathDetails() { } private void assertInstruction(Instruction instruction, String expectedRef, String expectedInterval, int expectedLength, int expectedPoints) { - assertEquals(expectedRef, instruction.getExtraInfoJSON().get("ref")); + assertEquals(expectedRef, instruction.getExtraInfoJSON().get(EdgeKVStorage.KeyValue.STREET_REF)); assertEquals(expectedInterval, ((ShallowImmutablePointList) instruction.getPoints()).getIntervalString()); assertEquals(expectedLength, instruction.getLength()); assertEquals(expectedPoints, instruction.getPoints().size()); diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index 9844673ffe9..8220a204f72 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -23,6 +23,7 @@ import com.graphhopper.routing.weighting.FastestWeighting; import com.graphhopper.routing.weighting.ShortestWeighting; import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.Graph; import com.graphhopper.storage.NodeAccess; @@ -34,10 +35,10 @@ import java.util.*; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static com.graphhopper.storage.AbstractGraphStorageTester.assertPList; import static com.graphhopper.util.Parameters.Details.*; -import com.graphhopper.search.EdgeKVStorage.KeyValue; import static org.junit.jupiter.api.Assertions.*; /** @@ -105,7 +106,7 @@ public void testWayList() { assertEquals(path.calcPoints().size() - 1, acc); // force minor change for instructions - edge2.setKeyValues(createKV("name", "2")); + edge2.setKeyValues(createKV(STREET_NAME, "2")); na.setNode(3, 1.0, 1.0); g.edge(1, 3).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 10.0); @@ -172,16 +173,16 @@ public void testFindInstruction() { EdgeIteratorState edge1 = g.edge(0, 1).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge1.setWayGeometry(Helper.createPointList()); - edge1.setKeyValues(createKV("name", "Street 1")); + edge1.setKeyValues(createKV(STREET_NAME, "Street 1")); EdgeIteratorState edge2 = g.edge(1, 2).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge2.setWayGeometry(Helper.createPointList()); - edge2.setKeyValues(createKV("name", "Street 2")); + edge2.setKeyValues(createKV(STREET_NAME, "Street 2")); EdgeIteratorState edge3 = g.edge(2, 3).setDistance(1000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge3.setWayGeometry(Helper.createPointList()); - edge3.setKeyValues(createKV("name", "Street 3")); + edge3.setKeyValues(createKV(STREET_NAME, "Street 3")); EdgeIteratorState edge4 = g.edge(3, 4).setDistance(500).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); edge4.setWayGeometry(Helper.createPointList()); - edge4.setKeyValues(createKV("name", "Street 4")); + edge4.setKeyValues(createKV(STREET_NAME, "Street 4")); g.edge(1, 5).setDistance(10000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); g.edge(2, 5).setDistance(10000).set(carAccessEnc, true, true).set(carAvSpeedEnc, 50.0); @@ -500,32 +501,32 @@ public void testCalcInstructionsRoundaboutIssue353() { na.setNode(10, 52.5135, 13.348); na.setNode(11, 52.514, 13.347); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 1).setDistance(5)).setKeyValues(createKV("name", "MainStreet 2 1")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 11).setDistance(5)).setKeyValues(createKV("name", "MainStreet 1 11")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 1).setDistance(5)).setKeyValues(createKV(STREET_NAME, "MainStreet 2 1")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 11).setDistance(5)).setKeyValues(createKV(STREET_NAME, "MainStreet 1 11")); // roundabout EdgeIteratorState tmpEdge; - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 9).setDistance(2)).setKeyValues(createKV("name", "3-9")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 9).setDistance(2)).setKeyValues(createKV(STREET_NAME, "3-9")); BooleanEncodedValue carManagerRoundabout = carManager.getBooleanEncodedValue(Roundabout.KEY); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(9, 10).setDistance(2)).setKeyValues(createKV("name", "9-10")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(9, 10).setDistance(2)).setKeyValues(createKV(STREET_NAME, "9-10")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(6, 10).setDistance(2)).setKeyValues(createKV("name", "6-10")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(6, 10).setDistance(2)).setKeyValues(createKV(STREET_NAME, "6-10")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(10, 1).setDistance(2)).setKeyValues(createKV("name", "10-1")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(10, 1).setDistance(2)).setKeyValues(createKV(STREET_NAME, "10-1")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 2).setDistance(5)).setKeyValues(createKV("name", "2-3")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(3, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "2-3")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 3).setDistance(5)).setKeyValues(createKV("name", "3-4")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 3).setDistance(5)).setKeyValues(createKV(STREET_NAME, "3-4")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(5, 4).setDistance(5)).setKeyValues(createKV("name", "4-5")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(5, 4).setDistance(5)).setKeyValues(createKV(STREET_NAME, "4-5")); tmpEdge.set(carManagerRoundabout, true); - tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 5).setDistance(5)).setKeyValues(createKV("name", "5-2")); + tmpEdge = GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 5).setDistance(5)).setKeyValues(createKV(STREET_NAME, "5-2")); tmpEdge.set(carManagerRoundabout, true); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 7).setDistance(5)).setKeyValues(createKV("name", "MainStreet 4 7")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 8).setDistance(5)).setKeyValues(createKV("name", "5-8")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 6).setDistance(5)).setKeyValues(createKV("name", "3-6")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 7).setDistance(5)).setKeyValues(createKV(STREET_NAME, "MainStreet 4 7")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 8).setDistance(5)).setKeyValues(createKV(STREET_NAME, "5-8")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 6).setDistance(5)).setKeyValues(createKV(STREET_NAME, "3-6")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) @@ -601,8 +602,8 @@ public void testCalcInstructionForForkWithSameName() { na.setNode(3, 48.982611, 13.121012); na.setNode(4, 48.982336, 13.121002); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "Regener Weg")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setKeyValues(createKV("name", "Regener Weg")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Regener Weg")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Regener Weg")); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); @@ -634,8 +635,8 @@ public void testCalcInstructionForMotorwayFork() { EnumEncodedValue roadClassEnc = carManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BooleanEncodedValue roadClassLinkEnc = carManager.getBooleanEncodedValue(RoadClassLink.KEY); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "A 8")).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setKeyValues(createKV("name", "A 8")).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "A 8")).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 4).setDistance(5)).setKeyValues(createKV(STREET_NAME, "A 8")).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, false); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).set(roadClassEnc, RoadClass.MOTORWAY).set(roadClassLinkEnc, true); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); @@ -662,9 +663,9 @@ public void testCalcInstructionsEnterMotorway() { na.setNode(3, 48.630558, 9.459851); na.setNode(4, 48.63054, 9.459406); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "A 8")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "A 8")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 2).setDistance(5)).setKeyValues(createKV("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(createKV(STREET_NAME, "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, graph.edge(4, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "A 8")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(graph, weighting, TraversalMode.NODE_BASED) @@ -691,9 +692,9 @@ public void testCalcInstructionsMotorwayJunction() { na.setNode(3, 48.706805, 9.162995); na.setNode(4, 48.706705, 9.16329); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "A 8")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "A 8")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(createKV("name", "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV(STREET_NAME, "A 8")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(createKV(STREET_NAME, "A 8")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -721,9 +722,9 @@ public void testCalcInstructionsOntoOneway() { na.setNode(3, -33.824415, 151.188177); na.setNode(4, -33.824437, 151.187925); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "Pacific Highway")); - GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "Pacific Highway")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(4, 2).setDistance(5)).setKeyValues(createKV("name", "Greenwich Road")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Pacific Highway")); + GHUtility.setSpeed(60, true, false, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Pacific Highway")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(4, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Greenwich Road")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -756,9 +757,9 @@ public void testCalcInstructionIssue1047() { EnumEncodedValue roadClassEnc = carManager.getEnumEncodedValue(RoadClass.KEY, RoadClass.class); BooleanEncodedValue roadClassLinkEnc = carManager.getBooleanEncodedValue(RoadClassLink.KEY); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "B 156")).set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(createKV("name", "S 108")).set(roadClassEnc, RoadClass.SECONDARY).set(roadClassLinkEnc, false); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "B 156")).set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "B 156")).set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(createKV(STREET_NAME, "S 108")).set(roadClassEnc, RoadClass.SECONDARY).set(roadClassLinkEnc, false); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV(STREET_NAME, "B 156")).set(roadClassEnc, RoadClass.PRIMARY).set(roadClassLinkEnc, false); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -790,9 +791,9 @@ public void testCalcInstructionContinueLeavingStreet() { na.setNode(3, 48.982611, 13.121012); na.setNode(4, 48.982565, 13.121002); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "Regener Weg")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Regener Weg")); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "Regener Weg")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Regener Weg")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -820,9 +821,9 @@ public void testCalcInstructionSlightTurn() { na.setNode(3, 48.412034, 15.599411); na.setNode(4, 48.411927, 15.599197); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "Stöhrgasse")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Stöhrgasse")); GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(createKV("name", "Stöhrgasse")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 4).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Stöhrgasse")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -854,13 +855,13 @@ public void testUTurnLeft() { na.setNode(7, 48.402604, 9.994962); GHUtility.setSpeed(60, 0, carAccessEnc, carAvSpeedEnc, - g.edge(1, 2).setDistance(5).setKeyValues(createKV("name", "Olgastraße")), - g.edge(2, 3).setDistance(5).setKeyValues(createKV("name", "Olgastraße")), - g.edge(6, 5).setDistance(5).setKeyValues(createKV("name", "Olgastraße")), - g.edge(5, 4).setDistance(5).setKeyValues(createKV("name", "Olgastraße"))); + g.edge(1, 2).setDistance(5).setKeyValues(createKV(STREET_NAME, "Olgastraße")), + g.edge(2, 3).setDistance(5).setKeyValues(createKV(STREET_NAME, "Olgastraße")), + g.edge(6, 5).setDistance(5).setKeyValues(createKV(STREET_NAME, "Olgastraße")), + g.edge(5, 4).setDistance(5).setKeyValues(createKV(STREET_NAME, "Olgastraße"))); GHUtility.setSpeed(60, 60, carAccessEnc, carAvSpeedEnc, - g.edge(2, 5).setDistance(5).setKeyValues(createKV("name", "Neithardtstraße")), - g.edge(5, 7).setDistance(5).setKeyValues(createKV("name", "Neithardtstraße"))); + g.edge(2, 5).setDistance(5).setKeyValues(createKV(STREET_NAME, "Neithardtstraße")), + g.edge(5, 7).setDistance(5).setKeyValues(createKV(STREET_NAME, "Neithardtstraße"))); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -892,13 +893,13 @@ public void testUTurnRight() { na.setNode(7, -33.885692, 151.181445); GHUtility.setSpeed(60, 0, carAccessEnc, carAvSpeedEnc, - g.edge(1, 2).setDistance(5).setKeyValues(createKV("name", "Parramatta Road")), - g.edge(2, 3).setDistance(5).setKeyValues(createKV("name", "Parramatta Road")), - g.edge(4, 5).setDistance(5).setKeyValues(createKV("name", "Parramatta Road")), - g.edge(5, 6).setDistance(5).setKeyValues(createKV("name", "Parramatta Road"))); + g.edge(1, 2).setDistance(5).setKeyValues(createKV(STREET_NAME, "Parramatta Road")), + g.edge(2, 3).setDistance(5).setKeyValues(createKV(STREET_NAME, "Parramatta Road")), + g.edge(4, 5).setDistance(5).setKeyValues(createKV(STREET_NAME, "Parramatta Road")), + g.edge(5, 6).setDistance(5).setKeyValues(createKV(STREET_NAME, "Parramatta Road"))); GHUtility.setSpeed(60, 60, carAccessEnc, carAvSpeedEnc, - g.edge(2, 5).setDistance(5).setKeyValues(createKV("name", "Larkin Street")), - g.edge(5, 7).setDistance(5).setKeyValues(createKV("name", "Larkin Street"))); + g.edge(2, 5).setDistance(5).setKeyValues(createKV(STREET_NAME, "Larkin Street")), + g.edge(5, 7).setDistance(5).setKeyValues(createKV(STREET_NAME, "Larkin Street"))); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -955,9 +956,9 @@ public void testCalcInstructionsForSlightTurnOntoDifferentStreet() { na.setNode(3, 48.764149, 8.678926); na.setNode(4, 48.764085, 8.679183); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 3).setDistance(5)).setKeyValues(createKV("name", "Talstraße, K 4313")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "Calmbacher Straße, K 4312")); - GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(3, 4).setDistance(5)).setKeyValues(createKV("name", "Calmbacher Straße, K 4312")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(1, 3).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Talstraße, K 4313")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(2, 3).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Calmbacher Straße, K 4312")); + GHUtility.setSpeed(60, true, true, carAccessEnc, carAvSpeedEnc, g.edge(3, 4).setDistance(5)).setKeyValues(createKV(STREET_NAME, "Calmbacher Straße, K 4312")); ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED) @@ -1001,11 +1002,11 @@ private Graph generatePathDetailsGraph() { na.setNode(5, 52.516, 13.3452); na.setNode(6, 52.516, 13.344); - GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV("name", "1-2")); - GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 5).setDistance(5)).setKeyValues(createKV("name", "4-5")); - GHUtility.setSpeed(90, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(createKV("name", "2-3")); - GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 4).setDistance(10)).setKeyValues(createKV("name", "3-4")); - GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 6).setDistance(0.001)).setKeyValues(createKV("name", "3-4")); + GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(1, 2).setDistance(5)).setKeyValues(createKV(STREET_NAME, "1-2")); + GHUtility.setSpeed(45, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(4, 5).setDistance(5)).setKeyValues(createKV(STREET_NAME, "4-5")); + GHUtility.setSpeed(90, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(2, 3).setDistance(5)).setKeyValues(createKV(STREET_NAME, "2-3")); + GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(3, 4).setDistance(10)).setKeyValues(createKV(STREET_NAME, "3-4")); + GHUtility.setSpeed(9, true, true, carAccessEnc, carAvSpeedEnc, graph.edge(5, 6).setDistance(0.001)).setKeyValues(createKV(STREET_NAME, "3-4")); return graph; } @@ -1051,20 +1052,20 @@ private RoundaboutGraph() { na.setNode(19, 52.515, 13.368); // roundabout - roundaboutEdges.add(g.edge(3, 2).setDistance(5).setKeyValues(createKV("name", "2-3"))); - roundaboutEdges.add(g.edge(4, 3).setDistance(5).setKeyValues(createKV("name", "3-4"))); - roundaboutEdges.add(g.edge(5, 4).setDistance(5).setKeyValues(createKV("name", "4-5"))); - roundaboutEdges.add(g.edge(2, 5).setDistance(5).setKeyValues(createKV("name", "5-2"))); + roundaboutEdges.add(g.edge(3, 2).setDistance(5).setKeyValues(createKV(STREET_NAME, "2-3"))); + roundaboutEdges.add(g.edge(4, 3).setDistance(5).setKeyValues(createKV(STREET_NAME, "3-4"))); + roundaboutEdges.add(g.edge(5, 4).setDistance(5).setKeyValues(createKV(STREET_NAME, "4-5"))); + roundaboutEdges.add(g.edge(2, 5).setDistance(5).setKeyValues(createKV(STREET_NAME, "5-2"))); List bothDir = new ArrayList<>(); List oneDir = new ArrayList<>(roundaboutEdges); - bothDir.add(g.edge(1, 2).setDistance(5).setKeyValues(createKV("name", "MainStreet 1 2"))); - bothDir.add(g.edge(4, 7).setDistance(5).setKeyValues(createKV("name", "MainStreet 4 7"))); - bothDir.add(g.edge(5, 8).setDistance(5).setKeyValues(createKV("name", "5-8"))); + bothDir.add(g.edge(1, 2).setDistance(5).setKeyValues(createKV(STREET_NAME, "MainStreet 1 2"))); + bothDir.add(g.edge(4, 7).setDistance(5).setKeyValues(createKV(STREET_NAME, "MainStreet 4 7"))); + bothDir.add(g.edge(5, 8).setDistance(5).setKeyValues(createKV(STREET_NAME, "5-8"))); - bothDir.add(edge3to6 = g.edge(3, 6).setDistance(5).setKeyValues(createKV("name", "3-6"))); - oneDir.add(edge3to9 = g.edge(3, 9).setDistance(5).setKeyValues(createKV("name", "3-9"))); + bothDir.add(edge3to6 = g.edge(3, 6).setDistance(5).setKeyValues(createKV(STREET_NAME, "3-6"))); + oneDir.add(edge3to9 = g.edge(3, 9).setDistance(5).setKeyValues(createKV(STREET_NAME, "3-9"))); bothDir.add(g.edge(7, 10).setDistance(5)); bothDir.add(g.edge(10, 11).setDistance(5)); diff --git a/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java b/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java index bf1bb2cd1ad..614a0842b42 100644 --- a/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/NameSimilarityEdgeFilterTest.java @@ -29,6 +29,7 @@ import com.graphhopper.util.shapes.GHPoint; import org.junit.jupiter.api.Test; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; @@ -104,11 +105,11 @@ public void testDistanceFiltering() { na.setNode(nodeID200, point200mAway.lat, point200mAway.lon); // Check that it matches a street 50m away - EdgeIteratorState edge1 = g.edge(nodeId50, farAwayId).setKeyValues(createKV("name", "Wentworth Street")); + EdgeIteratorState edge1 = g.edge(nodeId50, farAwayId).setKeyValues(createKV(STREET_NAME, "Wentworth Street")); assertTrue(createNameSimilarityEdgeFilter("Wentworth Street").accept(edge1)); // Check that it doesn't match streets 200m away - EdgeIteratorState edge2 = g.edge(nodeID200, farAwayId).setKeyValues(createKV("name", "Wentworth Street")); + EdgeIteratorState edge2 = g.edge(nodeID200, farAwayId).setKeyValues(createKV(STREET_NAME, "Wentworth Street")); assertFalse(createNameSimilarityEdgeFilter("Wentworth Street").accept(edge2)); } @@ -311,16 +312,16 @@ public void curvedWayGeometry_issue2319() { graph.getNodeAccess().setNode(1, 43.842775, -79.264649); EdgeIteratorState doubtfire = graph.edge(0, 1).setWayGeometry(pointList).set(accessEnc, true, true). - set(speedEnc, 60, 60).setKeyValues(createKV("name", "Doubtfire Crescent")); + set(speedEnc, 60, 60).setKeyValues(createKV(STREET_NAME, "Doubtfire Crescent")); EdgeIteratorState golden = graph.edge(0, 1).set(accessEnc, true, true).set(speedEnc, 60, 60). - setKeyValues(createKV("name", "Golden Avenue")); + setKeyValues(createKV(STREET_NAME, "Golden Avenue")); graph.getNodeAccess().setNode(2, 43.841501560244744, -79.26366394602502); graph.getNodeAccess().setNode(3, 43.842247922172724, -79.2605663670726); PointList pointList2 = new PointList(1, false); pointList2.add(43.84191413615452, -79.261912128223); EdgeIteratorState denison = graph.edge(2, 3).setWayGeometry(pointList2).set(accessEnc, true, true). - set(speedEnc, 60, 60).setKeyValues(createKV("name", "Denison Street")); + set(speedEnc, 60, 60).setKeyValues(createKV(STREET_NAME, "Denison Street")); double qlat = 43.842122; double qLon = -79.262162; diff --git a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java index 78effe6318b..acad6621059 100644 --- a/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java +++ b/core/src/test/java/com/graphhopper/storage/AbstractGraphStorageTester.java @@ -32,6 +32,7 @@ import java.io.File; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; @@ -266,7 +267,7 @@ public void testUpdateUnidirectional() { public void testCopyProperties() { graph = createGHStorage(); EdgeIteratorState edge = graph.edge(1, 3).setDistance(10).set(carAccessEnc, true, false). - setKeyValues(createKV("name", "testing")).setWayGeometry(Helper.createPointList(1, 2)); + setKeyValues(createKV(STREET_NAME, "testing")).setWayGeometry(Helper.createPointList(1, 2)); EdgeIteratorState newEdge = graph.edge(1, 3).setDistance(10).set(carAccessEnc, true, false); newEdge.copyPropertiesFrom(edge); @@ -654,10 +655,10 @@ public void testGetAllEdges() { public void testEdgeKVStorage() { graph = createGHStorage(); EdgeIteratorState iter1 = graph.edge(0, 1).setDistance(10).set(carAccessEnc, true, true); - iter1.setKeyValues(createKV("name", "named street1")); + iter1.setKeyValues(createKV(STREET_NAME, "named street1")); EdgeIteratorState iter2 = graph.edge(0, 1).setDistance(10).set(carAccessEnc, true, true); - iter2.setKeyValues(createKV("name", "named street2")); + iter2.setKeyValues(createKV(STREET_NAME, "named street2")); assertEquals(graph.getEdgeIteratorState(iter1.getEdge(), iter1.getAdjNode()).getName(), "named street1"); assertEquals(graph.getEdgeIteratorState(iter2.getEdge(), iter2.getAdjNode()).getName(), "named street2"); diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java index 63d9ecd804a..35e2e58ee49 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphTest.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.List; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; import static com.graphhopper.util.EdgeIteratorState.REVERSE_STATE; import static com.graphhopper.util.FetchMode.*; import static org.junit.jupiter.api.Assertions.*; @@ -69,8 +70,8 @@ public void testSave_and_fileFormat() { graph.edge(9, 11).setDistance(200).set(carAccessEnc, true, true); graph.edge(1, 2).setDistance(120).set(carAccessEnc, true, false); - iter1.setKeyValues(KeyValue.createKV("name", "named street1")); - iter2.setKeyValues(KeyValue.createKV("name", "named street2")); + iter1.setKeyValues(KeyValue.createKV(STREET_NAME, "named street1")); + iter2.setKeyValues(KeyValue.createKV(STREET_NAME, "named street2")); List list = new ArrayList<>(); list.add(new KeyValue("keyA", "FORWARD", true, false)); diff --git a/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java index 4b1b04c87cc..d138fa8c38c 100644 --- a/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java +++ b/core/src/test/java/com/graphhopper/storage/BaseGraphWithTurnCostsTest.java @@ -27,6 +27,7 @@ import java.util.Random; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -78,8 +79,8 @@ public void testSave_and_fileFormat() { setTurnCost(iter2.getEdge(), 0, iter1.getEdge(), 666); setTurnCost(iter1.getEdge(), 1, iter2.getEdge(), 815); - iter1.setKeyValues(KeyValue.createKV("name", "named street1")); - iter2.setKeyValues(KeyValue.createKV("name", "named street2")); + iter1.setKeyValues(KeyValue.createKV(STREET_NAME, "named street1")); + iter2.setKeyValues(KeyValue.createKV(STREET_NAME, "named street2")); checkGraph(graph); graph.flush(); diff --git a/core/src/test/java/com/graphhopper/util/InstructionListTest.java b/core/src/test/java/com/graphhopper/util/InstructionListTest.java index 9bd9e529cb7..7d35d105249 100644 --- a/core/src/test/java/com/graphhopper/util/InstructionListTest.java +++ b/core/src/test/java/com/graphhopper/util/InstructionListTest.java @@ -42,6 +42,7 @@ import java.util.List; import java.util.Locale; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; @@ -95,30 +96,30 @@ Graph createTestGraph() { na.setNode(6, 1.0, 1.0); na.setNode(7, 1.0, 1.1); na.setNode(8, 1.0, 1.2); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(createKV("name", "0-1")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(createKV("name", "1-2")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "0-1")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(createKV(STREET_NAME, "1-2")); GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(11000)); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setKeyValues(createKV("name", "1-4")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setKeyValues(createKV("name", "5-2")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "1-4")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setKeyValues(createKV(STREET_NAME, "5-2")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setKeyValues(createKV("name", "3-6")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setKeyValues(createKV("name", "4-7")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setKeyValues(createKV("name", "5-8")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setKeyValues(createKV(STREET_NAME, "3-6")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "4-7")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "5-8")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setKeyValues(createKV("name", "6-7")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setKeyValues(createKV(STREET_NAME, "6-7")); EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(10000)); PointList list = new PointList(); list.add(1.0, 1.15); list.add(1.0, 1.16); iter.setWayGeometry(list); - iter.setKeyValues(createKV("name", "7-8")); + iter.setKeyValues(createKV(STREET_NAME, "7-8")); // missing edge name GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(10000)); EdgeIteratorState iter2 = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(8, 9).setDistance(20000)); list.clear(); list.add(1.0, 1.3); - iter2.setKeyValues(createKV("name", "8-9")); + iter2.setKeyValues(createKV(STREET_NAME, "8-9")); iter2.setWayGeometry(list); return g; } @@ -187,11 +188,11 @@ public void testWayList2() { na.setNode(3, 10.0, 10.08); na.setNode(4, 10.1, 10.10); na.setNode(5, 10.2, 10.13); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setKeyValues(createKV("name", "3-4")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setKeyValues(createKV("name", "4-5")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setKeyValues(createKV(STREET_NAME, "3-4")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setKeyValues(createKV(STREET_NAME, "4-5")); EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(100)); - iter.setKeyValues(createKV("name", "2-4")); + iter.setKeyValues(createKV(STREET_NAME, "2-4")); PointList list = new PointList(); list.add(10.20, 10.05); iter.setWayGeometry(list); @@ -226,11 +227,11 @@ public void testNoInstructionIfSameStreet() { na.setNode(3, 10.0, 10.05); na.setNode(4, 10.1, 10.10); na.setNode(5, 10.2, 10.15); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setKeyValues(createKV("name", "street")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setKeyValues(createKV("name", "4-5")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(100)).setKeyValues(createKV(STREET_NAME, "street")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(100)).setKeyValues(createKV(STREET_NAME, "4-5")); EdgeIteratorState iter = GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(100)); - iter.setKeyValues(createKV("name", "street")); + iter.setKeyValues(createKV(STREET_NAME, "street")); PointList list = new PointList(); list.add(10.20, 10.05); iter.setWayGeometry(list); @@ -326,9 +327,9 @@ public void testNoInstructionIfSlightTurnAndAlternativeIsSharp3() { GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(20)); GHUtility.setSpeed(4, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(20)); - g.edge(1, 2).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(createKV("name", "pfarr")); - g.edge(2, 3).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(createKV("name", "pfarr")); - g.edge(2, 4).set(rcEV, RoadClass.PEDESTRIAN).setKeyValues(createKV("name", "markt")); + g.edge(1, 2).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(createKV(STREET_NAME, "pfarr")); + g.edge(2, 3).set(rcEV, RoadClass.RESIDENTIAL).setKeyValues(createKV(STREET_NAME, "pfarr")); + g.edge(2, 4).set(rcEV, RoadClass.PEDESTRIAN).setKeyValues(createKV(STREET_NAME, "markt")); FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 3); @@ -403,13 +404,13 @@ public void testInstructionIfSlightTurnForCustomProfile() { // default is priority=0 so set it to 1 GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(20). - setKeyValues(createKV("name", "myroad")).set(priorityEnc, 1)); + setKeyValues(createKV(STREET_NAME, "myroad")).set(priorityEnc, 1)); GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(20). - setKeyValues(createKV("name", "myroad")).set(priorityEnc, 1)); + setKeyValues(createKV(STREET_NAME, "myroad")).set(priorityEnc, 1)); PointList pointList = new PointList(); pointList.add(43.729627, 7.41749); GHUtility.setSpeed(5, true, true, accessEnc, speedEnc, g.edge(2, 4).setDistance(20). - setKeyValues(createKV("name", "myroad")).set(priorityEnc, 1).setWayGeometry(pointList)); + setKeyValues(createKV(STREET_NAME, "myroad")).set(priorityEnc, 1).setWayGeometry(pointList)); Weighting weighting = CustomModelParser.createWeighting(accessEnc, speedEnc, priorityEnc, tmpEM, DefaultTurnCostProvider.NO_TURN_COST_PROVIDER, @@ -496,12 +497,12 @@ public void testFind() { na.setNode(6, 15.1, 10.1); na.setNode(7, 15.1, 9.8); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(10000)).setKeyValues(createKV("name", "1-2")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10000)).setKeyValues(createKV("name", "2-3")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000)).setKeyValues(createKV("name", "2-6")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(10000)).setKeyValues(createKV("name", "3-4")).setWayGeometry(waypoint); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000)).setKeyValues(createKV("name", "3-7")); - GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000)).setKeyValues(createKV("name", "4-5")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "1-2")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "2-3")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "2-6")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "3-4")).setWayGeometry(waypoint); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "3-7")); + GHUtility.setSpeed(60, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "4-5")); FastestWeighting weighting = new FastestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, tMode).calcPath(1, 5); diff --git a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java index 20ef9dcaec8..159cb2fe51f 100644 --- a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java +++ b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java @@ -37,6 +37,7 @@ import java.util.*; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static com.graphhopper.util.Parameters.Details.AVERAGE_SPEED; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -76,24 +77,24 @@ public void testScenario() { na.setNode(7, 1.0, 1.1); na.setNode(8, 1.0, 1.2); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(createKV("name", "0-1")); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(createKV("name", "1-2")); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(0, 1).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "0-1")); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(11000)).setKeyValues(createKV(STREET_NAME, "1-2")); GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(0, 3).setDistance(11000)); - GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setKeyValues(createKV("name", "1-4")); - GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setKeyValues(createKV("name", "5-2")); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(1, 4).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "1-4")); + GHUtility.setSpeed(18, true, true, accessEnc, speedEnc, g.edge(2, 5).setDistance(11000)).setKeyValues(createKV(STREET_NAME, "5-2")); - GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setKeyValues(createKV("name", "3-6")); - GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setKeyValues(createKV("name", "4-7")); - GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setKeyValues(createKV("name", "5-8")); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(3, 6).setDistance(11000)).setKeyValues(createKV(STREET_NAME, "3-6")); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(4, 7).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "4-7")); + GHUtility.setSpeed(27, true, true, accessEnc, speedEnc, g.edge(5, 8).setDistance(10000)).setKeyValues(createKV(STREET_NAME, "5-8")); - GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setKeyValues(createKV("name", "6-7")); + GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(6, 7).setDistance(11000)).setKeyValues(createKV(STREET_NAME, "6-7")); EdgeIteratorState tmpEdge = GHUtility.setSpeed(36, true, true, accessEnc, speedEnc, g.edge(7, 8).setDistance(10000)); PointList list = new PointList(); list.add(1.0, 1.15); list.add(1.0, 1.16); tmpEdge.setWayGeometry(list); - tmpEdge.setKeyValues(createKV("name", "7-8")); + tmpEdge.setKeyValues(createKV(STREET_NAME, "7-8")); // missing edge name GHUtility.setSpeed(45, true, true, accessEnc, speedEnc, g.edge(9, 10).setDistance(10000)); @@ -103,7 +104,7 @@ public void testScenario() { list.add(1.0, 1.3001); list.add(1.0, 1.3002); list.add(1.0, 1.3003); - tmpEdge.setKeyValues(createKV("name", "8-9")); + tmpEdge.setKeyValues(createKV(STREET_NAME, "8-9")); tmpEdge.setWayGeometry(list); // Path is: [0 0-1, 3 1-4, 6 4-7, 9 7-8, 11 8-9, 10 9-10] diff --git a/tools/src/main/java/com/graphhopper/tools/Measurement.java b/tools/src/main/java/com/graphhopper/tools/Measurement.java index 01caf87902f..920d70fad6e 100644 --- a/tools/src/main/java/com/graphhopper/tools/Measurement.java +++ b/tools/src/main/java/com/graphhopper/tools/Measurement.java @@ -38,6 +38,7 @@ import com.graphhopper.routing.weighting.Weighting; import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.routing.weighting.custom.CustomWeighting; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.*; import com.graphhopper.storage.index.LocationIndex; import com.graphhopper.util.*; diff --git a/web-api/src/main/java/com/graphhopper/jackson/InstructionListSerializer.java b/web-api/src/main/java/com/graphhopper/jackson/InstructionListSerializer.java index 4ae3353e833..df66995d043 100644 --- a/web-api/src/main/java/com/graphhopper/jackson/InstructionListSerializer.java +++ b/web-api/src/main/java/com/graphhopper/jackson/InstructionListSerializer.java @@ -31,6 +31,8 @@ import com.graphhopper.util.Instruction; import com.graphhopper.util.InstructionList; +import static com.graphhopper.util.Parameters.Details.STREET_NAME; + public class InstructionListSerializer extends JsonSerializer { @Override public void serialize(InstructionList instructions, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { @@ -42,7 +44,7 @@ public void serialize(InstructionList instructions, JsonGenerator jsonGenerator, instrJson.put("text", Helper.firstBig(instruction.getTurnDescription(instructions.getTr()))); - instrJson.put("street_name", instruction.getName()); + instrJson.put(STREET_NAME, instruction.getName()); instrJson.put("time", instruction.getTime()); instrJson.put("distance", Helper.round(instruction.getDistance(), 3)); instrJson.put("sign", instruction.getSign()); diff --git a/web-api/src/main/java/com/graphhopper/jackson/ResponsePathDeserializer.java b/web-api/src/main/java/com/graphhopper/jackson/ResponsePathDeserializer.java index 8dadf6f5c51..d8354190497 100644 --- a/web-api/src/main/java/com/graphhopper/jackson/ResponsePathDeserializer.java +++ b/web-api/src/main/java/com/graphhopper/jackson/ResponsePathDeserializer.java @@ -83,7 +83,7 @@ public static ResponsePath createResponsePath(ObjectMapper objectMapper, JsonNod int viaCount = 1; for (JsonNode jsonObj : instrArr) { double instDist = jsonObj.get("distance").asDouble(); - String text = turnDescription ? jsonObj.get("text").asText() : jsonObj.get("street_name").asText(); + String text = turnDescription ? jsonObj.get("text").asText() : jsonObj.get(Parameters.Details.STREET_NAME).asText(); long instTime = jsonObj.get("time").asLong(); int sign = jsonObj.get("sign").asInt(); JsonNode iv = jsonObj.get("interval"); diff --git a/web-api/src/main/java/com/graphhopper/util/Instruction.java b/web-api/src/main/java/com/graphhopper/util/Instruction.java index 31132064136..1e3ad721bcf 100644 --- a/web-api/src/main/java/com/graphhopper/util/Instruction.java +++ b/web-api/src/main/java/com/graphhopper/util/Instruction.java @@ -20,6 +20,8 @@ import java.util.HashMap; import java.util.Map; +import static com.graphhopper.util.Parameters.Details.*; + public class Instruction { public static final int UNKNOWN = -99; public static final int U_TURN_UNKNOWN = -98; @@ -87,8 +89,8 @@ public void setName(String name) { if (name != null) this.name = name; } - String getStreetName() { - return getName().isEmpty() && extraInfo.get("ref") instanceof String ? (String) extraInfo.get("ref") : getName(); + String _getName() { + return getName().isEmpty() && extraInfo.get(STREET_REF) instanceof String ? (String) extraInfo.get(STREET_REF) : getName(); } public Map getExtraInfoJSON() { @@ -166,7 +168,7 @@ public String getTurnDescription(Translation tr) { return getName(); String str; - String streetName = getStreetName(); + String streetName = _getName(); int indi = getSign(); if (indi == Instruction.CONTINUE_ON_STREET) { str = Helper.isEmpty(streetName) ? tr.tr("continue") : tr.tr("continue_onto", streetName); @@ -218,8 +220,8 @@ public String getTurnDescription(Translation tr) { else str = streetName.isEmpty() ? dir : tr.tr("turn_onto", dir, streetName); } - String dest = (String) extraInfo.get("destination"); - String destRef = (String) extraInfo.get("destination_ref"); + String dest = (String) extraInfo.get(STREET_DESTINATION); + String destRef = (String) extraInfo.get(STREET_DESTINATION_REF); if (dest != null) { if (destRef != null) return tr.tr("toward_destination_with_ref", str, destRef, dest); diff --git a/web-api/src/main/java/com/graphhopper/util/Parameters.java b/web-api/src/main/java/com/graphhopper/util/Parameters.java index a1a7d490e48..a6b02bf20dd 100644 --- a/web-api/src/main/java/com/graphhopper/util/Parameters.java +++ b/web-api/src/main/java/com/graphhopper/util/Parameters.java @@ -197,10 +197,13 @@ public static final class Details { public static final String PATH_DETAILS = "details"; - public static final String AVERAGE_SPEED = "average_speed"; + // these details are directly accessing the EdgeKVStorage and the names have to be identical public static final String STREET_NAME = "street_name"; public static final String STREET_REF = "street_ref"; public static final String STREET_DESTINATION = "street_destination"; + public static final String STREET_DESTINATION_REF = "street_destination_ref"; + + public static final String AVERAGE_SPEED = "average_speed"; public static final String EDGE_ID = "edge_id"; public static final String EDGE_KEY = "edge_key"; public static final String TIME = "time"; diff --git a/web-api/src/main/java/com/graphhopper/util/RoundaboutInstruction.java b/web-api/src/main/java/com/graphhopper/util/RoundaboutInstruction.java index e2991174d75..486e40cec73 100644 --- a/web-api/src/main/java/com/graphhopper/util/RoundaboutInstruction.java +++ b/web-api/src/main/java/com/graphhopper/util/RoundaboutInstruction.java @@ -114,7 +114,7 @@ public String getTurnDescription(Translation tr) { return getName(); String str; - String streetName = getStreetName(); + String streetName = _getName(); int indi = getSign(); if (indi == Instruction.USE_ROUNDABOUT) { if (!exited) { diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java index 9b375664f5e..2f945ff2723 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MVTResource.java @@ -3,6 +3,7 @@ import com.graphhopper.GraphHopper; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.NodeAccess; import com.graphhopper.storage.index.LocationIndexTree; import com.graphhopper.util.EdgeIteratorState; @@ -124,8 +125,8 @@ public Response doGetXyz( edgeCounter.incrementAndGet(); Map map = new LinkedHashMap<>(); - Stream.of("name", "ref", "destination", "destination_ref").forEach( - key -> map.put(key, Optional.ofNullable(edge.getValue(key)).orElse("")) + edge.getKeyValues().forEach( + entry -> map.put(entry.key, entry.value) ); map.put("edge_id", edge.getEdge()); map.put("edge_key", edge.getEdgeKey()); diff --git a/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java b/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java index 062cc10f10c..b672c09b96b 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/SPTResource.java @@ -13,6 +13,7 @@ import com.graphhopper.routing.util.TraversalMode; import com.graphhopper.routing.weighting.BlockAreaWeighting; import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.search.EdgeKVStorage; import com.graphhopper.storage.BaseGraph; import com.graphhopper.storage.GraphEdgeIdFinder; import com.graphhopper.storage.NodeAccess; @@ -39,6 +40,7 @@ import static com.graphhopper.resources.RouteResource.removeLegacyParameters; import static com.graphhopper.routing.util.TraversalMode.EDGE_BASED; import static com.graphhopper.routing.util.TraversalMode.NODE_BASED; +import static com.graphhopper.util.Parameters.Details.STREET_NAME; /** * This resource provides the entire shortest path tree as response. In a simple CSV format discussed at #1577. @@ -197,7 +199,7 @@ public Response doGet( if (edge == null) continue; - if (col.equals(Parameters.Details.STREET_NAME)) { + if (col.equals(STREET_NAME)) { sb.append(edge.getName().replaceAll(",", "")); continue; } diff --git a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java index 7b4e387cc23..41c342264ba 100644 --- a/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java +++ b/web-bundle/src/test/java/com/graphhopper/gpx/GpxConversionsTest.java @@ -46,6 +46,7 @@ import java.util.List; import java.util.Locale; +import static com.graphhopper.search.EdgeKVStorage.KeyValue.STREET_NAME; import static com.graphhopper.search.EdgeKVStorage.KeyValue.createKV; import static org.junit.jupiter.api.Assertions.*; @@ -81,12 +82,12 @@ public void testInstructionsWithTimeAndPlace() { na.setNode(6, 15.1, 10.1); na.setNode(7, 15.1, 9.8); - GHUtility.setSpeed(63, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(7000).setKeyValues(createKV("name", "1-2"))); - GHUtility.setSpeed(72, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(8000).setKeyValues(createKV("name", "2-3"))); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000).setKeyValues(createKV("name", "2-6"))); - GHUtility.setSpeed(81, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(9000).setKeyValues(createKV("name", "3-4"))); - GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000).setKeyValues(createKV("name", "3-7"))); - GHUtility.setSpeed(90, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000).setKeyValues(createKV("name", "4-5"))); + GHUtility.setSpeed(63, true, true, accessEnc, speedEnc, g.edge(1, 2).setDistance(7000).setKeyValues(createKV(STREET_NAME, "1-2"))); + GHUtility.setSpeed(72, true, true, accessEnc, speedEnc, g.edge(2, 3).setDistance(8000).setKeyValues(createKV(STREET_NAME, "2-3"))); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(2, 6).setDistance(10000).setKeyValues(createKV(STREET_NAME, "2-6"))); + GHUtility.setSpeed(81, true, true, accessEnc, speedEnc, g.edge(3, 4).setDistance(9000).setKeyValues(createKV(STREET_NAME, "3-4"))); + GHUtility.setSpeed(9, true, true, accessEnc, speedEnc, g.edge(3, 7).setDistance(10000).setKeyValues(createKV(STREET_NAME, "3-7"))); + GHUtility.setSpeed(90, true, true, accessEnc, speedEnc, g.edge(4, 5).setDistance(10000).setKeyValues(createKV(STREET_NAME, "4-5"))); ShortestWeighting weighting = new ShortestWeighting(accessEnc, speedEnc); Path p = new Dijkstra(g, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); @@ -100,6 +101,7 @@ public void testInstructionsWithTimeAndPlace() { assertEquals(1604121, p.getTime()); assertEquals(Instruction.CONTINUE_ON_STREET, wayList.get(0).getSign()); + assertEquals("1-2", wayList.get(0).getName()); assertEquals(15, wayList.get(0).getPoints().getLat(0), 1e-3); assertEquals(10, wayList.get(0).getPoints().getLon(0), 1e-3); diff --git a/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java b/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java index 2a870bfbde6..91123aa815c 100644 --- a/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/ExtendedJsonResponseTest.java @@ -89,7 +89,7 @@ private EdgeIteratorState getEdgeIterator() { pointList.add(-3.4445, -38.9990); pointList.add(-3.5550, -38.7990); return new VirtualEdgeIteratorState(0, 0, 0, 1, 10, new IntsRef(1), - EdgeKVStorage.KeyValue.createKV("name", "test of iterator"), pointList, false); + EdgeKVStorage.KeyValue.createKV(EdgeKVStorage.KeyValue.STREET_NAME, "test of iterator"), pointList, false); } } diff --git a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java index b1ac51ed6b8..5fe36573c98 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java @@ -22,6 +22,7 @@ import com.graphhopper.application.util.GraphHopperServerTestConfiguration; import com.graphhopper.config.Profile; import com.graphhopper.util.Helper; +import com.graphhopper.util.Parameters; import com.wdtinc.mapbox_vector_tile.adapt.jts.MvtReader; import com.wdtinc.mapbox_vector_tile.adapt.jts.TagKeyValueMapConverter; import com.wdtinc.mapbox_vector_tile.adapt.jts.model.JtsLayer; @@ -44,6 +45,7 @@ import java.util.Map; import static com.graphhopper.application.util.TestUtils.clientTarget; +import static com.graphhopper.util.Parameters.Details.STREET_NAME; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -85,7 +87,7 @@ public void testBasicMvtQuery() throws IOException { JtsLayer layer = layerValues.values().iterator().next(); MultiLineString multiLineString = (MultiLineString) layer.getGeometries().iterator().next(); assertEquals(42, multiLineString.getCoordinates().length); - assertEquals("Camì de les Pardines", getUserData(multiLineString).get("name")); + assertEquals("Camì de les Pardines", getUserData(multiLineString).get(STREET_NAME)); } @Test @@ -99,7 +101,7 @@ public void testDetailsInResponse() throws IOException { assertEquals(21, layer.getGeometries().size()); Geometry geometry = layer.getGeometries().stream(). - filter(g -> getUserData(g).get("name").equals("Avinguda de Tarragona")) + filter(g -> "Avinguda de Tarragona".equals(getUserData(g).get(STREET_NAME))) .findFirst().get(); assertEquals("road", getUserData(geometry).get("road_environment")); assertEquals("50.0 | 50.0", getUserData(geometry).get("max_speed")); From e4f67c3cea4a6c0a296e425642011991fde062ae Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 29 Sep 2022 11:05:21 +0200 Subject: [PATCH 185/389] Move curvature EncodedValue out of MotorcycleTagParser (#2665) * initial commit * minor tweaks * moved test too * changelog * fix test * reduce changes --- CHANGELOG.md | 3 + .../java/com/graphhopper/GraphHopper.java | 2 + .../routing/DefaultWeightingFactory.java | 15 ++-- .../com/graphhopper/routing/ev/Curvature.java | 11 +++ .../routing/ev/DecimalEncodedValueImpl.java | 3 +- .../ev/DefaultEncodedValueFactory.java | 2 + .../routing/util/CurvatureCalculator.java | 34 +++++++++ .../routing/util/MotorcycleTagParser.java | 64 +---------------- .../util/{parsers => }/SlopeCalculator.java | 3 +- .../routing/util/VehicleEncodedValues.java | 23 ++---- .../routing/weighting/CurvatureWeighting.java | 71 ------------------- .../graphhopper/reader/osm/OSMReaderTest.java | 17 ----- .../routing/RoutingAlgorithmWithOSMTest.java | 16 +++-- .../routing/util/CurvatureCalculatorTest.java | 54 ++++++++++++++ .../routing/util/MotorcycleTagParserTest.java | 29 -------- .../{parsers => }/SlopeCalculatorTest.java | 3 +- 16 files changed, 133 insertions(+), 217 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/routing/ev/Curvature.java create mode 100644 core/src/main/java/com/graphhopper/routing/util/CurvatureCalculator.java rename core/src/main/java/com/graphhopper/routing/util/{parsers => }/SlopeCalculator.java (98%) delete mode 100644 core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java create mode 100644 core/src/test/java/com/graphhopper/routing/util/CurvatureCalculatorTest.java rename core/src/test/java/com/graphhopper/routing/util/{parsers => }/SlopeCalculatorTest.java (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 842c85d536b..76a6ce6c239 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,10 @@ ### 7.0 [not yet released] + +- CurvatureWeighting was removed. Use a custom model with 'curvature' instead. (#2665) - internal keys for EdgeKVStorage changed to contain the street_ prefix like the path details too. Similarly, the extra_info in the instructions of the API response, see #2661 ### 6.0 [13 Sep 2022] + - When using a DecimalEncodedValue with useMaximumAsInfinity=true and a single bit of space make sure you always use Double.POSITIVE_INFINITY to set the value, see #2646 - renamed DouglasPeucker to RamerDouglasPeucker diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index 3a9f8d862d6..c8d6ca6678f 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -648,6 +648,8 @@ private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String en osmParsers.addWayTagParser(new OSMRoadAccessParser(encodingManager.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR))); if (encodingManager.hasEncodedValue(AverageSlope.KEY) || encodingManager.hasEncodedValue(MaxSlope.KEY)) osmParsers.addWayTagParser(new SlopeCalculator(encodingManager.getDecimalEncodedValue(MaxSlope.KEY), encodingManager.getDecimalEncodedValue(AverageSlope.KEY))); + if (encodingManager.hasEncodedValue(Curvature.KEY)) + osmParsers.addWayTagParser(new CurvatureCalculator(encodingManager.getDecimalEncodedValue(Curvature.KEY))); DateRangeParser dateRangeParser = DateRangeParser.createInstance(dateRangeParserString); flagEncodersMap.forEach((name, encoderStr) -> { diff --git a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java index 34ffd51866f..bb4b139041d 100644 --- a/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java +++ b/core/src/main/java/com/graphhopper/routing/DefaultWeightingFactory.java @@ -99,25 +99,18 @@ public Weighting createWeighting(Profile profile, PMap requestHints, boolean dis weighting = new ShortestWeighting(accessEnc, speedEnc, turnCostProvider); } else if ("fastest".equalsIgnoreCase(weightingStr)) { if (!encodingManager.hasEncodedValue(RoadAccess.KEY)) - throw new IllegalArgumentException("fastest weighting requires road_access"); + throw new IllegalArgumentException("The fastest weighting requires road_access"); EnumEncodedValue roadAccessEnc = encodingManager.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class); if (priorityEnc != null) weighting = new PriorityWeighting(accessEnc, speedEnc, priorityEnc, roadAccessEnc, hints, turnCostProvider); else weighting = new FastestWeighting(accessEnc, speedEnc, roadAccessEnc, hints, turnCostProvider); } else if ("curvature".equalsIgnoreCase(weightingStr)) { - DecimalEncodedValue curvatureEnc = encodingManager.hasEncodedValue(EncodingManager.getKey(vehicle, "curvature")) - ? encodingManager.getDecimalEncodedValue(EncodingManager.getKey(vehicle, "curvature")) - : null; - if (curvatureEnc == null || priorityEnc == null) - throw new IllegalArgumentException("curvature weighting requires curvature and priority, but not found for " + vehicle); - if (!encodingManager.hasEncodedValue(RoadAccess.KEY)) - throw new IllegalArgumentException("curvature weighting requires road_access"); - EnumEncodedValue roadAccessEnc = encodingManager.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class); - weighting = new CurvatureWeighting(accessEnc, speedEnc, priorityEnc, curvatureEnc, roadAccessEnc, hints, turnCostProvider); + throw new IllegalArgumentException("The curvature weighting is no longer supported since 7.0. Use a custom " + + "model with the EncodedValue 'curvature' instead"); } else if ("short_fastest".equalsIgnoreCase(weightingStr)) { if (!encodingManager.hasEncodedValue(RoadAccess.KEY)) - throw new IllegalArgumentException("curvature weighting requires road_access"); + throw new IllegalArgumentException("The short_fastest weighting requires road_access"); EnumEncodedValue roadAccessEnc = encodingManager.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class); weighting = new ShortFastestWeighting(accessEnc, speedEnc, roadAccessEnc, hints, turnCostProvider); } diff --git a/core/src/main/java/com/graphhopper/routing/ev/Curvature.java b/core/src/main/java/com/graphhopper/routing/ev/Curvature.java new file mode 100644 index 00000000000..1d3c57c26f4 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/ev/Curvature.java @@ -0,0 +1,11 @@ +package com.graphhopper.routing.ev; + +public class Curvature { + public static final String KEY = "curvature"; + + public static DecimalEncodedValue create() { + // for now save a bit: ignore all too low values and set them to the minimum value instead + return new DecimalEncodedValueImpl(KEY, 4, 0.25, 0.05, + false, false, false); + } +} diff --git a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java index 18616dc64fe..161c1e9213d 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DecimalEncodedValueImpl.java @@ -51,7 +51,8 @@ public DecimalEncodedValueImpl(String name, int bits, double minStorableValue, d boolean negateReverseDirection, boolean storeTwoDirections, boolean useMaximumAsInfinity) { super(name, bits, (int) Math.round(minStorableValue / factor), negateReverseDirection, storeTwoDirections); if (!negateReverseDirection && super.minStorableValue * factor != minStorableValue) - throw new IllegalArgumentException("minStorableValue " + minStorableValue + " is not a multiple of the specified factor " + factor); + throw new IllegalArgumentException("minStorableValue " + minStorableValue + " is not a multiple of the specified factor " + + factor + " (" + super.minStorableValue * factor + ")"); this.factor = factor; this.useMaximumAsInfinity = useMaximumAsInfinity; } diff --git a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java index ff8430563a8..b977d8e9e0a 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java +++ b/core/src/main/java/com/graphhopper/routing/ev/DefaultEncodedValueFactory.java @@ -88,6 +88,8 @@ public EncodedValue create(String string) { enc = MaxSlope.create(); } else if (AverageSlope.KEY.equals(name)) { enc = AverageSlope.create(); + } else if (Curvature.KEY.equals(name)) { + enc = Curvature.create(); } else { throw new IllegalArgumentException("DefaultEncodedValueFactory cannot find EncodedValue " + name); } diff --git a/core/src/main/java/com/graphhopper/routing/util/CurvatureCalculator.java b/core/src/main/java/com/graphhopper/routing/util/CurvatureCalculator.java new file mode 100644 index 00000000000..106817cb0f1 --- /dev/null +++ b/core/src/main/java/com/graphhopper/routing/util/CurvatureCalculator.java @@ -0,0 +1,34 @@ +package com.graphhopper.routing.util; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.util.parsers.TagParser; +import com.graphhopper.storage.IntsRef; +import com.graphhopper.util.DistanceCalcEarth; +import com.graphhopper.util.PointList; + +public class CurvatureCalculator implements TagParser { + + private final DecimalEncodedValue curvatureEnc; + + public CurvatureCalculator(DecimalEncodedValue curvatureEnc) { + this.curvatureEnc = curvatureEnc; + } + + @Override + public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) { + PointList pointList = way.getTag("point_list", null); + double edgeDistance = way.getTag("edge_distance", null); + if (pointList != null && !pointList.isEmpty()) { + double beeline = DistanceCalcEarth.DIST_EARTH.calcDist(pointList.getLat(0), pointList.getLon(0), + pointList.getLat(pointList.size() - 1), pointList.getLon(pointList.size() - 1)); + // For now keep the formula simple. Maybe later use quadratic value as it might improve the "resolution" + double curvature = beeline / edgeDistance; + curvatureEnc.setDecimal(false, edgeFlags, Math.max(curvatureEnc.getMinStorableDecimal(), Math.min(curvatureEnc.getMaxStorableDecimal(), + curvature))); + } else { + curvatureEnc.setDecimal(false, edgeFlags, 1.0); + } + return edgeFlags; + } +} diff --git a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java index 3ee9d53ca76..240b253c546 100644 --- a/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/MotorcycleTagParser.java @@ -42,7 +42,6 @@ public class MotorcycleTagParser extends CarTagParser { private final HashSet avoidSet = new HashSet<>(); private final HashSet preferSet = new HashSet<>(); private final DecimalEncodedValue priorityWayEncoder; - private final DecimalEncodedValue curvatureEncoder; public MotorcycleTagParser(EncodedValueLookup lookup, PMap properties) { this( @@ -51,7 +50,6 @@ public MotorcycleTagParser(EncodedValueLookup lookup, PMap properties) { lookup.hasEncodedValue(TurnCost.key("motorcycle")) ? lookup.getDecimalEncodedValue(TurnCost.key("motorcycle")) : null, lookup.getBooleanEncodedValue(Roundabout.KEY), lookup.getDecimalEncodedValue(VehiclePriority.key("motorcycle")), - lookup.getDecimalEncodedValue(getKey("motorcycle", "curvature")), new PMap(properties).putObject("name", "motorcycle"), TransportationMode.MOTORCYCLE ); @@ -59,10 +57,10 @@ public MotorcycleTagParser(EncodedValueLookup lookup, PMap properties) { public MotorcycleTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue turnCostEnc, BooleanEncodedValue roundaboutEnc, - DecimalEncodedValue priorityWayEncoder, DecimalEncodedValue curvatureEnc, PMap properties, TransportationMode transportationMode) { - super(accessEnc, speedEnc, turnCostEnc, roundaboutEnc, new PMap(properties).putObject("name", "motorcycle"), transportationMode, speedEnc.getNextStorableValue(MOTOR_CYCLE_MAX_SPEED)); + DecimalEncodedValue priorityWayEncoder, PMap properties, TransportationMode transportationMode) { + super(accessEnc, speedEnc, turnCostEnc, roundaboutEnc, new PMap(properties).putObject("name", "motorcycle"), + transportationMode, speedEnc.getNextStorableValue(MOTOR_CYCLE_MAX_SPEED)); this.priorityWayEncoder = priorityWayEncoder; - this.curvatureEncoder = curvatureEnc; barriers.remove("bus_trap"); barriers.remove("sump_buster"); @@ -209,7 +207,6 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { } priorityWayEncoder.setDecimal(false, edgeFlags, PriorityCode.getValue(handlePriority(way))); - curvatureEncoder.setDecimal(false, edgeFlags, 10.0 / 7.0); return edgeFlags; } @@ -223,59 +220,4 @@ private int handlePriority(ReaderWay way) { return PriorityCode.UNCHANGED.getValue(); } - - @Override - public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { - double speed = edge.get(avgSpeedEnc); - double roadDistance = edge.getDistance(); - double beelineDistance = getBeelineDistance(way); - double bendiness = beelineDistance / roadDistance; - - bendiness = discriminateSlowStreets(bendiness, speed); - bendiness = increaseBendinessImpact(bendiness); - bendiness = correctErrors(bendiness); - - edge.set(curvatureEncoder, bendiness); - } - - private double getBeelineDistance(ReaderWay way) { - PointList pointList = way.getTag("point_list", null); - if (pointList == null) - throw new IllegalStateException("The artificial 'point_list' tag is missing for way: " + way.getId()); - if (pointList.size() < 2) - throw new IllegalStateException("The artificial 'point_list' tag contained less than two points for way: " + way.getId()); - return DistanceCalcEarth.DIST_EARTH.calcDist(pointList.getLat(0), pointList.getLon(0), pointList.getLat(pointList.size() - 1), pointList.getLon(pointList.size() - 1)); - } - - /** - * Streets that slow are not fun and probably in a town. - */ - protected double discriminateSlowStreets(double bendiness, double speed) { - if (speed < 51) { - return 1; - } - return bendiness; - } - - /** - * A really small bendiness or a bendiness greater than 1 indicates an error in the calculation. - * Just ignore them. We use bendiness greater 1.2 since the beelineDistance is only - * approximated, therefore it can happen on straight roads, that the beeline is longer than the - * road. - */ - protected double correctErrors(double bendiness) { - if (bendiness < 0.01 || bendiness > 1) { - return 1; - } - return bendiness; - } - - /** - * A good bendiness should become a greater impact. A bendiness close to 1 should not be - * changed. - */ - protected double increaseBendinessImpact(double bendiness) { - return (Math.pow(bendiness, 2)); - } - } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java b/core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java similarity index 98% rename from core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java rename to core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java index 90eb3d241e3..5bc9bb9591c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/SlopeCalculator.java +++ b/core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java @@ -1,7 +1,8 @@ -package com.graphhopper.routing.util.parsers; +package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.DecimalEncodedValue; +import com.graphhopper.routing.util.parsers.TagParser; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.DistanceCalcEarth; import com.graphhopper.util.PointList; diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index 53c94c5946d..2dcf0c2167a 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -24,7 +24,6 @@ import java.util.Arrays; import java.util.List; -import static com.graphhopper.routing.util.EncodingManager.getKey; import static com.graphhopper.routing.util.VehicleEncodedValuesFactory.*; public class VehicleEncodedValues { @@ -34,7 +33,6 @@ public class VehicleEncodedValues { private final BooleanEncodedValue accessEnc; private final DecimalEncodedValue avgSpeedEnc; private final DecimalEncodedValue priorityEnc; - private final DecimalEncodedValue curvatureEnc; private final DecimalEncodedValue turnCostEnc; public static VehicleEncodedValues foot(PMap properties) { @@ -47,7 +45,7 @@ public static VehicleEncodedValues foot(PMap properties) { DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue priorityEnc = VehiclePriority.create(name, 4, PriorityCode.getFactor(1), false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, turnCostEnc); } public static VehicleEncodedValues hike(PMap properties) { @@ -73,7 +71,7 @@ public static VehicleEncodedValues bike(PMap properties) { DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue priorityEnc = VehiclePriority.create(name, 4, PriorityCode.getFactor(1), false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, null, turnCostEnc); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, turnCostEnc); } public static VehicleEncodedValues bike2(PMap properties) { @@ -102,7 +100,7 @@ public static VehicleEncodedValues car(PMap properties) { BooleanEncodedValue accessEnc = VehicleAccess.create(name); DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc); + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, turnCostEnc); } public static VehicleEncodedValues motorcycle(PMap properties) { @@ -114,9 +112,8 @@ public static VehicleEncodedValues motorcycle(PMap properties) { BooleanEncodedValue accessEnc = VehicleAccess.create(name); DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue priorityEnc = VehiclePriority.create(name, 4, PriorityCode.getFactor(1), false); - DecimalEncodedValue curvatureEnc = new DecimalEncodedValueImpl(getKey(name, "curvature"), 4, 0.1, false); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, curvatureEnc, turnCostEnc); + return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, turnCostEnc); } public static VehicleEncodedValues roads(PMap properties) { @@ -128,17 +125,15 @@ public static VehicleEncodedValues roads(PMap properties) { BooleanEncodedValue accessEnc = VehicleAccess.create(name); DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, speedTwoDirections); DecimalEncodedValue turnCostEnc = maxTurnCosts > 0 ? TurnCost.create(name, maxTurnCosts) : null; - return new VehicleEncodedValues(name, accessEnc, speedEnc, null, null, turnCostEnc); + return new VehicleEncodedValues(name, accessEnc, speedEnc, null, turnCostEnc); } public VehicleEncodedValues(String name, BooleanEncodedValue accessEnc, DecimalEncodedValue avgSpeedEnc, - DecimalEncodedValue priorityEnc, DecimalEncodedValue curvatureEnc, - DecimalEncodedValue turnCostEnc) { + DecimalEncodedValue priorityEnc, DecimalEncodedValue turnCostEnc) { this.name = name; this.accessEnc = accessEnc; this.avgSpeedEnc = avgSpeedEnc; this.priorityEnc = priorityEnc; - this.curvatureEnc = curvatureEnc; this.turnCostEnc = turnCostEnc; } @@ -149,8 +144,6 @@ public void createEncodedValues(List registerNewEncodedValue) { registerNewEncodedValue.add(avgSpeedEnc); if (priorityEnc != null) registerNewEncodedValue.add(priorityEnc); - if (curvatureEnc != null) - registerNewEncodedValue.add(curvatureEnc); } public void createTurnCostEncodedValues(List registerNewTurnCostEncodedValues) { @@ -170,10 +163,6 @@ public DecimalEncodedValue getPriorityEnc() { return priorityEnc; } - public DecimalEncodedValue getCurvatureEnc() { - return curvatureEnc; - } - public DecimalEncodedValue getTurnCostEnc() { return turnCostEnc; } diff --git a/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java b/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java deleted file mode 100644 index fdeaf63d7ad..00000000000 --- a/core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.routing.weighting; - -import com.graphhopper.routing.ev.BooleanEncodedValue; -import com.graphhopper.routing.ev.DecimalEncodedValue; -import com.graphhopper.routing.ev.EnumEncodedValue; -import com.graphhopper.routing.ev.RoadAccess; -import com.graphhopper.routing.util.PriorityCode; -import com.graphhopper.util.EdgeIteratorState; -import com.graphhopper.util.PMap; - -import static com.graphhopper.routing.util.PriorityCode.BEST; - -/** - * This Class uses bendiness parameter to prefer curvy routes. - */ -public class CurvatureWeighting extends PriorityWeighting { - private final double minFactor; - private final DecimalEncodedValue curvatureEnc; - - public CurvatureWeighting(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, DecimalEncodedValue priorityEnc, - DecimalEncodedValue curvatureEnc, EnumEncodedValue roadAccessEnc, PMap pMap, TurnCostProvider turnCostProvider) { - super(accessEnc, speedEnc, priorityEnc, roadAccessEnc, pMap, turnCostProvider); - this.curvatureEnc = curvatureEnc; - double minBendiness = 1; // see correctErrors - double maxSpeed = speedEnc.getMaxOrMaxStorableDecimal(); - minFactor = minBendiness / Math.log(maxSpeed) / PriorityCode.getValue(BEST.getValue()); - } - - @Override - public double getMinWeight(double distance) { - return minFactor * distance; - } - - @Override - public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) { - double priority = edgeState.get(priorityEnc); - double bendiness = edgeState.get(curvatureEnc); - double speed = getRoadSpeed(edgeState, reverse); - double roadDistance = edgeState.getDistance(); - - // We use the log of the speed to decrease the impact of the speed, therefore we don't use the highway - double regularWeight = roadDistance / Math.log(speed); - return (bendiness * regularWeight) / priority; - } - - protected double getRoadSpeed(EdgeIteratorState edge, boolean reverse) { - return reverse ? edge.getReverse(speedEnc) : edge.get(speedEnc); - } - - @Override - public String getName() { - return "curvature"; - } -} diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 5bf3aaebeab..56f61976b19 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -891,23 +891,6 @@ public void testCrossBoundary_issue667() { assertEquals(112, snap.getClosestEdge().getDistance() / 1000, 1); } - @Test - public void testRoutingRequestFails_issue665() { - GraphHopper hopper = new GraphHopper() - .setOSMFile(getClass().getResource(file7).getFile()) - .setProfiles( - new Profile("profile1").setVehicle("car").setWeighting("fastest"), - new Profile("profile2").setVehicle("motorcycle").setWeighting("curvature") - ) - .setGraphHopperLocation(dir); - hopper.importOrLoad(); - GHRequest req = new GHRequest(48.977277, 8.256896, 48.978876, 8.254884). - setProfile("profile2"); - - GHResponse ghRsp = hopper.route(req); - assertFalse(ghRsp.hasErrors(), ghRsp.getErrors().toString()); - } - @Test public void testRoadClassInfo() { GraphHopper gh = new GraphHopper() { diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index 3e9e1e9131c..d09d1a25c87 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -24,12 +24,11 @@ import com.graphhopper.config.CHProfile; import com.graphhopper.config.LMProfile; import com.graphhopper.config.Profile; +import com.graphhopper.json.Statement; import com.graphhopper.reader.dem.SRTMProvider; +import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.storage.Graph; -import com.graphhopper.util.DistanceCalc; -import com.graphhopper.util.DistanceCalcEarth; -import com.graphhopper.util.GHUtility; -import com.graphhopper.util.Helper; +import com.graphhopper.util.*; import com.graphhopper.util.shapes.GHPoint; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -125,12 +124,15 @@ public void testMonacoMotorcycleCurvature() { List queries = new ArrayList<>(); queries.add(new Query(43.730729, 7.42135, 43.727697, 7.419199, 2681, 119)); queries.add(new Query(43.727687, 7.418737, 43.74958, 7.436566, 3727, 170)); - queries.add(new Query(43.728677, 7.41016, 43.739213, 7.4277, 3168, 169)); + queries.add(new Query(43.728677, 7.41016, 43.739213, 7.4277, 3157, 165)); queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 2423, 141)); queries.add(new Query(43.730949, 7.412338, 43.739643, 7.424542, 2253, 120)); queries.add(new Query(43.727592, 7.419333, 43.727712, 7.419333, 0, 1)); - GraphHopper hopper = createHopper(MONACO, - new Profile("motorcycle").setVehicle("motorcycle").setWeighting("curvature")); + CustomModel model = new CustomModel().addToPriority(Statement.If("true", Statement.Op.MULTIPLY, "curvature")); + + GraphHopper hopper = createHopper(MONACO, new CustomProfile("motorcycle").setCustomModel(model). + setVehicle("motorcycle").setWeighting("custom")); + hopper.setEncodedValuesString("curvature"); hopper.setElevationProvider(new SRTMProvider(DIR)); hopper.importOrLoad(); checkQueries(hopper, queries); diff --git a/core/src/test/java/com/graphhopper/routing/util/CurvatureCalculatorTest.java b/core/src/test/java/com/graphhopper/routing/util/CurvatureCalculatorTest.java new file mode 100644 index 00000000000..48c840dfb62 --- /dev/null +++ b/core/src/test/java/com/graphhopper/routing/util/CurvatureCalculatorTest.java @@ -0,0 +1,54 @@ +package com.graphhopper.routing.util; + +import com.graphhopper.reader.ReaderWay; +import com.graphhopper.routing.ev.Curvature; +import com.graphhopper.storage.BaseGraph; +import com.graphhopper.storage.IntsRef; +import com.graphhopper.storage.NodeAccess; +import com.graphhopper.util.EdgeIteratorState; +import com.graphhopper.util.Helper; +import com.graphhopper.util.PointList; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CurvatureCalculatorTest { + + private final EncodingManager em = EncodingManager.start().add(Curvature.create()).build(); + + @Test + public void testCurvature() { + CurvatureCalculator calculator = new CurvatureCalculator(em.getDecimalEncodedValue(Curvature.KEY)); + IntsRef ints = calculator.handleWayTags(em.createEdgeFlags(), getStraightWay(), null); + double valueStraight = em.getDecimalEncodedValue(Curvature.KEY).getDecimal(false, ints); + + ints = calculator.handleWayTags(em.createEdgeFlags(), getCurvyWay(), null); + double valueCurvy = em.getDecimalEncodedValue(Curvature.KEY).getDecimal(false, ints); + + assertTrue(valueCurvy < valueStraight, "The bendiness of the straight road is smaller than the one of the curvy road"); + } + + private ReaderWay getStraightWay() { + ReaderWay way = new ReaderWay(1); + way.setTag("highway", "primary"); + PointList pointList = new PointList(); + pointList.add(50.9, 13.13); + pointList.add(50.899, 13.13); + way.setTag("point_list", pointList); + way.setTag("edge_distance", 100d); + return way; + } + + private ReaderWay getCurvyWay() { + ReaderWay way = new ReaderWay(1); + way.setTag("highway", "primary"); + PointList pointList = new PointList(); + pointList.add(50.9, 13.13); + pointList.add(50.899, 13.129); + pointList.add(50.899, 13.13); + way.setTag("point_list", pointList); + way.setTag("edge_distance", 160d); + return way; + } + +} \ No newline at end of file diff --git a/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java index 4dbb55f071e..1de0f14fad5 100644 --- a/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/MotorcycleTagParserTest.java @@ -173,33 +173,4 @@ public void testSetSpeed0_issue367() { assertFalse(motorcycleAccessEnc.getBool(false, edgeFlags)); assertTrue(motorcycleAccessEnc.getBool(true, edgeFlags)); } - - @Test - public void testCurvature() { - Graph graph = initExampleGraph(); - EdgeIteratorState edge = GHUtility.getEdge(graph, 0, 1); - - double bendinessOfStraightWay = getBendiness(edge, 100.0); - double bendinessOfCurvyWay = getBendiness(edge, 10.0); - - assertTrue(bendinessOfCurvyWay < bendinessOfStraightWay, "The bendiness of the straight road is smaller than the one of the curvy road"); - } - - private double getBendiness(EdgeIteratorState edge, double beelineDistance) { - ReaderWay way = new ReaderWay(1); - way.setTag("highway", "primary"); - // set point_list such that it yields the requested beelineDistance - GHPoint point = new GHPoint(11.3, 45.2); - GHPoint toPoint = DistanceCalcEarth.DIST_EARTH.projectCoordinate(point.lat, point.lon, beelineDistance, 90); - PointList pointList = new PointList(); - pointList.add(point); - pointList.add(toPoint); - way.setTag("point_list", pointList); - - assertTrue(parser.getAccess(way).isWay()); - IntsRef flags = parser.handleWayTags(em.createEdgeFlags(), way); - edge.setFlags(flags); - parser.applyWayTags(way, edge); - return edge.get(motorcycleCurvatureEnc); - } } diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java b/core/src/test/java/com/graphhopper/routing/util/SlopeCalculatorTest.java similarity index 97% rename from core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java rename to core/src/test/java/com/graphhopper/routing/util/SlopeCalculatorTest.java index ce732a8ab54..dd035d00717 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/SlopeCalculatorTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/SlopeCalculatorTest.java @@ -1,10 +1,9 @@ -package com.graphhopper.routing.util.parsers; +package com.graphhopper.routing.util; import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.AverageSlope; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.ev.MaxSlope; -import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.storage.IntsRef; import com.graphhopper.util.PointList; import org.junit.jupiter.api.Test; From 02046ae73cadccad04e996ca3527832b9b382a47 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 30 Sep 2022 09:57:08 +0200 Subject: [PATCH 186/389] Improve docs regarding encoded values and for now remove misleading documentation about FlagEncoders, #2659 --- docs/core/create-new-flagencoder.md | 38 -------------------------- docs/core/custom-models.md | 27 ++++++++++++++----- docs/core/elevation.md | 8 +++++- docs/core/weighting.md | 42 ++++++++--------------------- docs/index.md | 3 +-- 5 files changed, 40 insertions(+), 78 deletions(-) delete mode 100644 docs/core/create-new-flagencoder.md diff --git a/docs/core/create-new-flagencoder.md b/docs/core/create-new-flagencoder.md deleted file mode 100644 index 47e331dc16e..00000000000 --- a/docs/core/create-new-flagencoder.md +++ /dev/null @@ -1,38 +0,0 @@ -# How to create new routing profile aka a new FlagEncoder? - -Copy e.g. a simple FlagEncoder like CarFlagEncoder or extend from it. Then change the toString method to a -different desired name. - -Make sure that it supports the required speed resolution via calling the appropriate (super) constructor. -E.g. speedBits means how many bits should reserved for the speed information, -the speedFactor means by which factor the speed should be divided before storing -(e.g. 5 for car and 1 for bikes for more precision). - -As a third step you need to tune the speeds for the different road types and surfaces. Maybe -now it is time to write a first test for your new FlagEncoder. - -Use it e.g. just via `graphHopper.setEncodingManager(new EncodingManager(myEncoder));` - -## Different forward and backward weights? - -With 0.12 this is now simple. Specify speedTwoDirections = true in the constructor and overwrite handleSpeed: - -```java -protected void handleSpeed(IntsRef edgeFlags, ReaderWay way, double speed) { - speedEncoder.setDecimal(true, edgeFlags, speed); - super.handleSpeed(edgeFlags, way, speed); -} -``` - -See Bike2WeightFlagEncoder for an example that uses different weights: slower speeds uphill than downhill. - -## Elevation - -To incorporate or precalculate values based on the elevation data you can hook into applyWayTags -and call edge.fetchWayGeometry(FetchMode.ALL) or again, see Bike2WeightFlagEncoder. - -## Add to the core - -If you want to include your FlagEncoder in GraphHopper and e.g. still want to use the config.yml -you can use a subclass of DefaultFlagEncoderFactory, set it to to the GraphHopper instance -and use the configuration object to change different properties. diff --git a/docs/core/custom-models.md b/docs/core/custom-models.md index f871a704808..bd5b1b2cf7b 100644 --- a/docs/core/custom-models.md +++ b/docs/core/custom-models.md @@ -71,21 +71,36 @@ encoded values are the following (some of their possible values are given in bra - surface: (PAVED, DIRT, SAND, GRAVEL, ...) - smoothness: (EXCELLENT, GOOD, INTERMEDIATE, ...) - toll: (MISSING, NO, HGV, ALL) +- bike_network, foot_network: (MISSING, INTERNATIONAL, NATIONAL, REGIONAL, LOCAL, OTHER) +- country: (`MISSING` or the country as a `ISO3166-1:alpha3` code e.g. `DEU`) +- hazmat: (YES, NO), hazmat_tunnel: (A, B, .., E), hazmat_water: (YES, PERMISSIVE, NO) +- hgv: (MISSING, YES, DESIGNATED, ...) +- track_type: (MISSING, GRADE1, GRADE2, ..., GRADE5) +- urban_density: (RURAL, RESIDENTIAL, CITY) -To learn about all available encoded values you can query the `/info` endpoint. + +To learn about all available encoded values you can query the `/info` endpoint Besides this kind of categories, which can take multiple different string values, there are also some that represent a -boolean value (they are either true or false for a given edge), like: +boolean value (they are either true or false for a given road segment), like: - get_off_bike - road_class_link +- roundabout +- with postfix `_access` contains the access (as boolean) for a specific vehicle There are also some that take on a numeric value, like: -- max_speed -- max_weight -- max_height -- max_width +- average_slope: a decimal for "elevation change" / edge_distance for a road segment; it changes the sign in reverse direction; see also max_slope +- curvature: "beeline distance" / edge_distance (0..1) e.g. a curvy road is smaller than 1 +- hike_rating, horse_rating, mtb_rating: a number from 0 to 6 for the `sac_scale` in OSM, e.g. 0 means "missing", 1 means "hiking", 2 means "mountain_hiking" and so on +- lanes: number of lanes +- max_slope: an unsigned decimal for the maximum slope ("elevation change / distance_i") of an edge with `sum(distance_i)=edge_distance`. Important for longer road segments where ups (or downs) can be much bigger than the average_slope. +- max_speed: the speed limit from a sign (km/h) +- max_height (meter), max_width (meter), max_length (meter) +- max_weight (ton), max_axle_load (in tons) +- with postfix `_average_speed` contains the average speed (km/h) for a specific vehicle +- with postfix `_priority` contains the road preference without changing the speed for a specific vehicle (0..1) In the next section will see how we can use these encoded values to customize GraphHopper's route calculations. diff --git a/docs/core/elevation.md b/docs/core/elevation.md index 5d31ab1c2c2..0839d11313d 100644 --- a/docs/core/elevation.md +++ b/docs/core/elevation.md @@ -11,7 +11,13 @@ The default cache directory `/tmp/` will be used. For large areas use a SSD disc, thus you need to specify the cache directory: `graph.elevation.cache_dir: /myssd/ele_cache/` -## What to download and where to store it? +## Custom Models + +The `average_slope` and `max_slope` attributes of a road segment can be used to make your routing +elevation-aware, i.e. to prefer or avoid, to speed up or slow down your vehicle based on the elevation +change. See the [custom model](custom-models.md) feature. + +## What to download and where to store it? All should work automatically but you can tune certain settings like the location where the files are downloaded and e.g. if the servers are not reachable, then you set: diff --git a/docs/core/weighting.md b/docs/core/weighting.md index c3a8a75c88e..3269a11cd7d 100644 --- a/docs/core/weighting.md +++ b/docs/core/weighting.md @@ -1,17 +1,19 @@ ## Weighting -A weighting allows to create a "weight" for an edge. The weight of an edge reflects the cost of travelling along this edge. +Instead of creating a new Weighting implementation is is highly recommended to use the CustomWeighting instead, which is explained in +the [profiles](profiles.md) and [custom models](custom-models.md) section. + +A weighting allows to create a "weight" for an edge. The weight of an edge reflects the cost of travelling along this edge. All implementations of [RoutingAlgorithm](https://github.com/graphhopper/graphhopper/blob/master/core/src/main/java/com/graphhopper/routing/RoutingAlgorithm.java) -in GraphHopper calculate the shortest path, which means the path with the [lowest overall cost from A to B](https://en.wikipedia.org/wiki/Shortest_path_problem). -The definition of the cost function is up to you, so you can create a cost function (we call this weighting) for the fastest path. -GraphHopper will still calculate the path with the lowest cost, but you can define the cost as a mix of distance speed, as shown in the [FastestWeighting](https://github.com/graphhopper/graphhopper/blob/master/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java). +in GraphHopper calculate the shortest path, which means the path with the [lowest overall cost from A to B](https://en.wikipedia.org/wiki/Shortest_path_problem). +The definition of the cost function is up to you, so you can create a cost function (we call this weighting) for the fastest path. +GraphHopper will still calculate the path with the lowest cost, but you can define the cost as a mix of distance speed, as shown in the +[FastestWeighting](https://github.com/graphhopper/graphhopper/blob/master/core/src/main/java/com/graphhopper/routing/weighting/FastestWeighting.java). In order to create a custom weighting you need to do the following: - 1. Implement the Weighting class - 2. Create a subclass of GraphHopper and override `createWeighting` - -Or use the CustomWeighting feature explained in [profiles](profiles.md). + 1. Implement the Weighting class and the WeightingFactory + 2. Let the GraphHopper class know about your WeightingFactory via overriding createWeightingFactory ### Implement your own weighting @@ -23,26 +25,4 @@ a sample can be found in the [AvoidEdgesWeighting](https://github.com/graphhoppe If your weights change on a per-request base, like the [BlockAreaWeighting](https://github.com/graphhopper/graphhopper/blob/bbd62fded97be060fc09177f9fae794cea284554/core/src/main/java/com/graphhopper/routing/weighting/BlockAreaWeighting.java), you cannot use the 'speed mode', but have to use the 'hybrid mode' or 'flexible mode' (more details [here](https://github.com/graphhopper/graphhopper#technical-overview)). If you haven't disabled the 'speed mode' in your config, you have to disable it for the requests by appending `ch.disable=true` -in the request url. - -### Extend GraphHopper - -For general information on how to extend GraphHopper have a look [here](low-level-api.md). - -Extending GraphHopper is easy, just need to override the `createWeighting` method of the GraphHopper class. -We return a new instance of our custom weighting if the string `my_custom_weighting` is given. Otherwise let the super class handle it: - -```java -class MyGraphHopper extends GraphHopper { - - @Override - public Weighting createWeighting(HintsMap hintsMap, FlagEncoder encoder, Graph graph) { - String weightingStr = hintsMap.getWeighting().toLowerCase(); - if ("my_custom_weighting".equals(weightingStr)) { - return new MyCustomWeighting(encoder); - } else { - return super.createWeighting(hintsMap, encoder, graph); - } - } -} -``` +in the request url. \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 2be373c9d5d..f0798389292 100644 --- a/docs/index.md +++ b/docs/index.md @@ -49,14 +49,13 @@ Various topics are explained in more detail separately: * [Technical overview](./core/technical.md): Technical details about how GraphHopper its calculations are working. * [Custom models](./core/custom-models.md): This tutorial explains how to customize an existing vehicle profile to your needs without to know Java. + * [Create custom weighting](./core/weighting.md): Documentation regarding Weighting. In almost all situations a custom model should be created instead. * [Simple routing](./core/routing.md): Tutorial how to integrate GraphHopper in your Java application (or pick any JVM language) - * [Create custom weighting](./core/weighting.md): Documentation about how to create a custom weighting class to influence the track calculation. * [Import GTFS](../reader-gtfs): Simple steps to get GTFS import and routing done. * [LocationIndex](../example/src/main/java/com/graphhopper/example/LocationIndexExample.java): Code about how to get the location index for getting i.e. the nearest edge. * [Hybrid Mode](./core/landmarks.md): Details about speeding up the route calculation via A* and landmarks. * [Speed Mode](./core/ch.md): Details about speeding up the route calculations via [Contraction Hierarchies](http://en.wikipedia.org/wiki/Contraction_hierarchies). * [Low level API](./core/low-level-api.md): Instructions how to use GraphHopper as a Java library. - * [Create new FlagEncoder](./core/create-new-flagencoder.md): Documentation to create new routing profiles to influence which ways to favor and how the track-time is calculated. * [Custom Areas and Country Rules](./core/custom-areas-and-country-rules.md): Instructions on how to on how to use and create new SpatialRules. SpatialRules are used to enforce country-specific routing rules. * [Turn Restrictions](./core/turn-restrictions.md): Details on how to enable and use turn restrictions. * [Isochrone generation in Java](./isochrone/java.md): Instruction on how to create isochrones using the low-level Java API. From c364f052f22572a12f1d5c8d5afc760e1715697e Mon Sep 17 00:00:00 2001 From: easbar Date: Sat, 1 Oct 2022 14:22:06 +0200 Subject: [PATCH 187/389] Remove gitlab ci --- .gitlab-ci.yml | 36 ------------------------- benchmark/benchmark.sh | 61 +++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 67 deletions(-) delete mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index f65c8ef2d0a..00000000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,36 +0,0 @@ -variables: - MAVEN_CLI_OPTS: "" - MAVEN_OPTS: "-Dmaven.repo.local=cache/.m2/repository" - -cache: - paths: - - cache/.m2/repository/ - -run_measurement: - stage: test - tags: - - openjdk11 - script: - # make this script exit if a command fails, a variable is missing etc. - - set -euo pipefail - - mvn -v - - java --version - - cat /proc/meminfo - - lscpu - - export BENCHMARK_DIR=/ext_data/ - - export BENCHMARK_RESULT_DIR=${BENCHMARK_DIR}results/$(date '+%d-%m-%Y-%s%N')/ - - export BENCHMARK_SMALL_MAP_NAME=bayern-190101.osm.pbf - - export BENCHMARK_SMALL_MAP_URL=http://download.geofabrik.de/europe/germany/${BENCHMARK_SMALL_MAP_NAME} - - export BENCHMARK_SMALL_MAP_PATH=${BENCHMARK_DIR}osm/${BENCHMARK_SMALL_MAP_NAME} - - export BENCHMARK_BIG_MAP_NAME=germany-190101.osm.pbf - - export BENCHMARK_BIG_MAP_URL=http://download.geofabrik.de/europe/${BENCHMARK_BIG_MAP_NAME} - - export BENCHMARK_BIG_MAP_PATH=${BENCHMARK_DIR}osm/${BENCHMARK_BIG_MAP_NAME} - - export USE_MEASUREMENT_TIME_AS_REF_TIME=${PERIODIC_BUILD:-false} - - mkdir -p ${BENCHMARK_DIR}osm - - mvn $MAVEN_CLI_OPTS package -DskipTests -pl tools -am - - chmod +x -R benchmark - - benchmark/download_map.sh $BENCHMARK_SMALL_MAP_URL $BENCHMARK_SMALL_MAP_PATH - - benchmark/download_map.sh $BENCHMARK_BIG_MAP_URL $BENCHMARK_BIG_MAP_PATH - - benchmark/benchmark.sh $BENCHMARK_DIR $BENCHMARK_RESULT_DIR $BENCHMARK_SMALL_MAP_PATH $BENCHMARK_BIG_MAP_PATH $USE_MEASUREMENT_TIME_AS_REF_TIME - - benchmark/post_benchmark.sh $BENCHMARK_RESULT_DIR $BENCHMARK_DB_USER $BENCHMARK_DB_PWD $BENCHMARK_DB_URL - - rm -rf $BENCHMARK_RESULT_DIR diff --git a/benchmark/benchmark.sh b/benchmark/benchmark.sh index 2ceabed5a71..7f72d46d997 100755 --- a/benchmark/benchmark.sh +++ b/benchmark/benchmark.sh @@ -1,10 +1,11 @@ #!/bin/bash # usage: -# benchmark/benchmark.sh +# benchmark/benchmark.sh # # where: -# = base directory used to store results -# = name of directory where results of this run are stored (inside ) +# = name of directory used to store graphs +# = name of directory where results of this run are stored +# = name of directory where the summary file is stored # = path to osm map the measurement is run on for slow measurements # = path to osm map the measurement is run on for fast measurements # = true/false, false by default, meaning the git commit time will be used as reference @@ -14,26 +15,24 @@ set -euo pipefail # print all commands set -o xtrace -defaultDataDir=measurements/ -defaultSingleResultsDir=measurements/results/$(date '+%d-%m-%Y-%s%N')/ +defaultGraphDir=measurements/ +defaultResultsDir=measurements/results/$(date '+%d-%m-%Y-%s%N')/ +defaultSummaryDir=measurements/ defaultSmallMap=core/files/andorra.osm.pbf defaultBigMap=core/files/andorra.osm.pbf defaultUseMeasurementTimeAsRefTime=false -# this is the directory where we read/write data from/to -DATA_DIR=${1:-$defaultDataDir} -RESULTS_DIR=${DATA_DIR}results/ -TMP_DIR=${DATA_DIR}tmp/ -SINGLE_RESULTS_DIR=${2:-$defaultSingleResultsDir} -SMALL_OSM_MAP=${3:-$defaultSmallMap} -BIG_OSM_MAP=${4:-$defaultBigMap} -USE_MEASUREMENT_TIME_AS_REF_TIME=${5:-$defaultUseMeasurementTimeAsRefTime} +GRAPH_DIR=${1:-$defaultGraphDir} +RESULTS_DIR=${2:-$defaultResultsDir} +SUMMARY_DIR=${3:-$defaultSummaryDir} +SMALL_OSM_MAP=${4:-$defaultSmallMap} +BIG_OSM_MAP=${5:-$defaultBigMap} +USE_MEASUREMENT_TIME_AS_REF_TIME=${6:-$defaultUseMeasurementTimeAsRefTime} # create directories -mkdir -p ${DATA_DIR} +mkdir -p ${GRAPH_DIR} mkdir -p ${RESULTS_DIR} -mkdir -p ${TMP_DIR} -mkdir -p ${SINGLE_RESULTS_DIR} +mkdir -p ${SUMMARY_DIR} # actually run the benchmarks: echo "1 - small map: node- and edge-based CH + slow routing" @@ -43,10 +42,10 @@ com.graphhopper.tools.Measurement \ datareader.file=${SMALL_OSM_MAP} \ datareader.date_range_parser_day=2019-11-01 \ measurement.name=small_map \ -measurement.folder=${SINGLE_RESULTS_DIR} \ +measurement.folder=${RESULTS_DIR} \ measurement.clean=true \ measurement.stop_on_error=true \ -measurement.summaryfile=${RESULTS_DIR}summary_small.dat \ +measurement.summaryfile=${SUMMARY_DIR}summary_small.dat \ measurement.repeats=1 \ measurement.run_slow_routing=true \ measurement.weighting=fastest \ @@ -55,7 +54,7 @@ measurement.ch.edge=true \ measurement.lm=false \ measurement.vehicle=car \ measurement.turn_costs=true \ -graph.location=${TMP_DIR}measurement-small-gh \ +graph.location=${GRAPH_DIR}measurement-small-gh \ prepare.min_network_size=10000 \ measurement.json=true \ measurement.count=5000 \ @@ -69,10 +68,10 @@ com.graphhopper.tools.Measurement \ datareader.file=${BIG_OSM_MAP} \ datareader.date_range_parser_day=2019-11-01 \ measurement.name=big_map \ -measurement.folder=${SINGLE_RESULTS_DIR} \ +measurement.folder=${RESULTS_DIR} \ measurement.clean=true \ measurement.stop_on_error=true \ -measurement.summaryfile=${RESULTS_DIR}summary_big.dat \ +measurement.summaryfile=${SUMMARY_DIR}summary_big.dat \ measurement.repeats=1 \ measurement.run_slow_routing=false \ measurement.weighting=fastest \ @@ -83,7 +82,7 @@ measurement.lm=true \ measurement.lm.edge_based=true \ measurement.vehicle=car \ measurement.turn_costs=true \ -graph.location=${TMP_DIR}measurement-big-gh \ +graph.location=${GRAPH_DIR}measurement-big-gh \ prepare.min_network_size=10000 \ measurement.json=true \ measurement.count=5000 \ @@ -98,10 +97,10 @@ com.graphhopper.tools.Measurement \ datareader.file=${BIG_OSM_MAP} \ datareader.date_range_parser_day=2019-11-01 \ measurement.name=big_map_little_custom \ -measurement.folder=${SINGLE_RESULTS_DIR} \ +measurement.folder=${RESULTS_DIR} \ measurement.clean=true \ measurement.stop_on_error=true \ -measurement.summaryfile=${RESULTS_DIR}summary_big_little_custom.dat \ +measurement.summaryfile=${SUMMARY_DIR}summary_big_little_custom.dat \ measurement.repeats=1 \ measurement.run_slow_routing=false \ measurement.weighting=custom \ @@ -114,7 +113,7 @@ measurement.lm=true \ measurement.lm.edge_based=false \ measurement.vehicle=car \ measurement.turn_costs=true \ -graph.location=${TMP_DIR}measurement-big-little-custom-gh \ +graph.location=${GRAPH_DIR}measurement-big-little-custom-gh \ prepare.min_network_size=10000 \ measurement.json=true \ measurement.count=5000 \ @@ -129,10 +128,10 @@ com.graphhopper.tools.Measurement \ datareader.file=${BIG_OSM_MAP} \ datareader.date_range_parser_day=2019-11-01 \ measurement.name=big_map_very_custom \ -measurement.folder=${SINGLE_RESULTS_DIR} \ +measurement.folder=${RESULTS_DIR} \ measurement.clean=true \ measurement.stop_on_error=true \ -measurement.summaryfile=${RESULTS_DIR}summary_big_very_custom.dat \ +measurement.summaryfile=${SUMMARY_DIR}summary_big_very_custom.dat \ measurement.repeats=1 \ measurement.run_slow_routing=false \ measurement.weighting=custom \ @@ -145,7 +144,7 @@ measurement.lm=true \ measurement.lm.edge_based=false \ measurement.vehicle=car \ measurement.turn_costs=true \ -graph.location=${TMP_DIR}measurement-big-very-custom-gh \ +graph.location=${GRAPH_DIR}measurement-big-very-custom-gh \ prepare.min_network_size=10000 \ measurement.json=true \ measurement.count=5000 \ @@ -159,10 +158,10 @@ com.graphhopper.tools.Measurement \ datareader.file=${BIG_OSM_MAP} \ datareader.date_range_parser_day=2019-11-01 \ measurement.name=big_map_outdoor \ -measurement.folder=${SINGLE_RESULTS_DIR} \ +measurement.folder=${RESULTS_DIR} \ measurement.clean=true \ measurement.stop_on_error=true \ -measurement.summaryfile=${RESULTS_DIR}summary_big_outdoor.dat \ +measurement.summaryfile=${SUMMARY_DIR}summary_big_outdoor.dat \ measurement.repeats=1 \ measurement.run_slow_routing=false \ measurement.weighting=fastest \ @@ -173,7 +172,7 @@ measurement.lm=true \ measurement.lm.edge_based=false \ measurement.vehicle=foot \ measurement.turn_costs=false \ -graph.location=${TMP_DIR}measurement-big-outdoor-gh \ +graph.location=${GRAPH_DIR}measurement-big-outdoor-gh \ prepare.min_network_size=10000 \ measurement.json=true \ measurement.count=5000 \ From a558141121ec78256ea02d2a930e81b0fa66f4e3 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 30 Sep 2022 22:20:44 +0200 Subject: [PATCH 188/389] slope: percentage, not factor --- docs/core/custom-models.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/custom-models.md b/docs/core/custom-models.md index bd5b1b2cf7b..a931ee30260 100644 --- a/docs/core/custom-models.md +++ b/docs/core/custom-models.md @@ -91,11 +91,11 @@ boolean value (they are either true or false for a given road segment), like: There are also some that take on a numeric value, like: -- average_slope: a decimal for "elevation change" / edge_distance for a road segment; it changes the sign in reverse direction; see also max_slope +- average_slope: a number for 100 * "elevation change" / edge_distance for a road segment; it changes the sign in reverse direction; see also max_slope - curvature: "beeline distance" / edge_distance (0..1) e.g. a curvy road is smaller than 1 - hike_rating, horse_rating, mtb_rating: a number from 0 to 6 for the `sac_scale` in OSM, e.g. 0 means "missing", 1 means "hiking", 2 means "mountain_hiking" and so on - lanes: number of lanes -- max_slope: an unsigned decimal for the maximum slope ("elevation change / distance_i") of an edge with `sum(distance_i)=edge_distance`. Important for longer road segments where ups (or downs) can be much bigger than the average_slope. +- max_slope: an unsigned decimal for the maximum slope (100 * "elevation change / distance_i") of an edge with `sum(distance_i)=edge_distance`. Important for longer road segments where ups (or downs) can be much bigger than the average_slope. - max_speed: the speed limit from a sign (km/h) - max_height (meter), max_width (meter), max_length (meter) - max_weight (ton), max_axle_load (in tons) From 881058e649c7372aa9223f57cf9f2cd3503edc5d Mon Sep 17 00:00:00 2001 From: Peter Date: Sat, 1 Oct 2022 17:28:26 +0200 Subject: [PATCH 189/389] roads vehicle should ignore all barriers like fords --- .../src/main/java/com/graphhopper/reader/osm/OSMReader.java | 2 +- .../java/com/graphhopper/routing/util/RoadsTagParser.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 3d7d7601119..cc06c0d958a 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -203,7 +203,7 @@ protected boolean acceptWay(ReaderWay way) { * junction between different ways this will be ignored and no artificial edge will be created. */ protected boolean isBarrierNode(ReaderNode node) { - return node.getTags().containsKey("barrier") || node.getTags().containsKey("ford"); + return node.hasTag("barrier") || node.hasTag("ford"); } /** diff --git a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java index f21b150fbb5..f92d8f597ed 100644 --- a/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/RoadsTagParser.java @@ -1,9 +1,9 @@ package com.graphhopper.routing.util; +import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.Helper; import com.graphhopper.util.PMap; @@ -45,4 +45,8 @@ public WayAccess getAccess(ReaderWay way) { return WayAccess.WAY; } + @Override + public boolean isBarrier(ReaderNode node) { + return false; + } } From f003176aa6a07d822ca6af99fb32705215e1ede7 Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 3 Oct 2022 16:22:32 +0200 Subject: [PATCH 190/389] bug in EncodedValue for min<0 --- .../graphhopper/routing/ev/IntEncodedValueImpl.java | 2 +- .../routing/ev/DecimalEncodedValueImplTest.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java index 9434757e4f6..7558391198c 100644 --- a/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java +++ b/core/src/main/java/com/graphhopper/routing/ev/IntEncodedValueImpl.java @@ -193,7 +193,7 @@ public final int getInt(boolean reverse, IntsRef ref) { // if we do not store both directions ignore reverse == true for convenient reading if (storeTwoDirections && reverse) { flags = ref.ints[bwdDataIndex + ref.offset]; - return minStorableValue + (flags & bwdMask) >>> bwdShift; + return minStorableValue + ((flags & bwdMask) >>> bwdShift); } else { flags = ref.ints[fwdDataIndex + ref.offset]; if (negateReverseDirection && reverse) diff --git a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java index 1ecf8ad7924..66324dc1882 100644 --- a/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java +++ b/core/src/test/java/com/graphhopper/routing/ev/DecimalEncodedValueImplTest.java @@ -188,4 +188,15 @@ public void lowestUpperBound_with_negateReverseDirection() { assertEquals(0, enc.getDecimal(false, ints)); assertEquals(6, enc.getMaxOrMaxStorableDecimal()); } + + @Test + public void minStorableBug() { + DecimalEncodedValue enc = new DecimalEncodedValueImpl("test", 5, -3, 0.2, false, true, false); + enc.init(new EncodedValue.InitializerConfig()); + assertEquals(3.2, enc.getMaxStorableDecimal()); + + IntsRef flags = new IntsRef(1); + enc.setDecimal(true, flags, 1.6); + assertEquals(1.6, enc.getDecimal(true, flags)); + } } \ No newline at end of file From c6380160af6fb72fc02c2053f4411c2b416ac6dd Mon Sep 17 00:00:00 2001 From: Peter Date: Mon, 3 Oct 2022 22:32:54 +0200 Subject: [PATCH 191/389] AverageSpeedDetails: prevEdgeId is sometimes outdated --- .../java/com/graphhopper/util/details/AverageSpeedDetails.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java b/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java index 7f76fc0d707..24631412f0f 100644 --- a/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java @@ -40,6 +40,7 @@ public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { // even lead to speed=Infinity -> just ignore these cases here, see #1848 and #2620 final double distance = edge.getDistance(); if (distance < 0.01) { + prevEdgeId = edge.getEdge(); if (decimalValue != null) return false; // in case this is the first edge we return decimalValue=null return true; From 3fb47d1422ffaa726eb79a02891e7e3055985803 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 4 Oct 2022 11:15:29 +0200 Subject: [PATCH 192/389] matrix sync client: remove unnecessary and incorrect slash after endpoint name --- .../main/java/com/graphhopper/api/GHMatrixSyncRequester.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client-hc/src/main/java/com/graphhopper/api/GHMatrixSyncRequester.java b/client-hc/src/main/java/com/graphhopper/api/GHMatrixSyncRequester.java index 7f997cecd42..08cddc96538 100644 --- a/client-hc/src/main/java/com/graphhopper/api/GHMatrixSyncRequester.java +++ b/client-hc/src/main/java/com/graphhopper/api/GHMatrixSyncRequester.java @@ -39,7 +39,7 @@ public MatrixResponse route(GHMRequest ghRequest) { withTimes, withDistances, withWeights); try { - String postUrl = buildURLNoHints("/", ghRequest); + String postUrl = buildURLNoHints("", ghRequest); JsonNode responseJson = fromStringToJSON(postUrl, postJson(postUrl, requestJson)); if (responseJson.has("message")) { matrixResponse.addErrors(ResponsePathDeserializer.readErrors(objectMapper, responseJson)); From 7c2c45d5a53241445a76d89339ce3b6151d98175 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 4 Oct 2022 11:28:55 +0200 Subject: [PATCH 193/389] Fix trigger --- .github/workflows/trigger-benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trigger-benchmarks.yml b/.github/workflows/trigger-benchmarks.yml index 7909040c338..49ff5e69365 100644 --- a/.github/workflows/trigger-benchmarks.yml +++ b/.github/workflows/trigger-benchmarks.yml @@ -11,4 +11,4 @@ jobs: curl -X POST -H "Authorization: token ${{ secrets.BENCHMARKS_TOKEN }}" \ -H "Accept: application/vnd.github+json" \ "https://api.github.com/repos/${{ secrets.BENCHMARKS_REPO }}/dispatches" \ - -d '{"event_type":"measurement_core","client_payload":{"core_commit": "${GITHUB_SHA}" }}' + -d '{"event_type":"measurement_core","client_payload":{"core_commit": "${{ env.GITHUB_SHA }}" }}' From ab06d7ab09812f9ccea8221424037deb721d5a0c Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 4 Oct 2022 11:31:09 +0200 Subject: [PATCH 194/389] again --- .github/workflows/trigger-benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trigger-benchmarks.yml b/.github/workflows/trigger-benchmarks.yml index 49ff5e69365..73c9c861117 100644 --- a/.github/workflows/trigger-benchmarks.yml +++ b/.github/workflows/trigger-benchmarks.yml @@ -11,4 +11,4 @@ jobs: curl -X POST -H "Authorization: token ${{ secrets.BENCHMARKS_TOKEN }}" \ -H "Accept: application/vnd.github+json" \ "https://api.github.com/repos/${{ secrets.BENCHMARKS_REPO }}/dispatches" \ - -d '{"event_type":"measurement_core","client_payload":{"core_commit": "${{ env.GITHUB_SHA }}" }}' + -d '{"event_type":"measurement_core","client_payload":{"core_commit": "${{ GITHUB_SHA }}" }}' From 0f29560872e3e7a9780e62b61ea7e61a4eefa465 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 4 Oct 2022 11:35:01 +0200 Subject: [PATCH 195/389] again --- .github/workflows/trigger-benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trigger-benchmarks.yml b/.github/workflows/trigger-benchmarks.yml index 73c9c861117..14dd270e74b 100644 --- a/.github/workflows/trigger-benchmarks.yml +++ b/.github/workflows/trigger-benchmarks.yml @@ -11,4 +11,4 @@ jobs: curl -X POST -H "Authorization: token ${{ secrets.BENCHMARKS_TOKEN }}" \ -H "Accept: application/vnd.github+json" \ "https://api.github.com/repos/${{ secrets.BENCHMARKS_REPO }}/dispatches" \ - -d '{"event_type":"measurement_core","client_payload":{"core_commit": "${{ GITHUB_SHA }}" }}' + -d '{"event_type":"measurement_core","client_payload":{"core_commit": "${ env.GITHUB_SHA }" }}' From 8dbf494c310b239904e9684f61202e95f621cda7 Mon Sep 17 00:00:00 2001 From: easbar Date: Tue, 4 Oct 2022 12:09:16 +0200 Subject: [PATCH 196/389] again --- .github/workflows/trigger-benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trigger-benchmarks.yml b/.github/workflows/trigger-benchmarks.yml index 14dd270e74b..e15b2fa8de2 100644 --- a/.github/workflows/trigger-benchmarks.yml +++ b/.github/workflows/trigger-benchmarks.yml @@ -11,4 +11,4 @@ jobs: curl -X POST -H "Authorization: token ${{ secrets.BENCHMARKS_TOKEN }}" \ -H "Accept: application/vnd.github+json" \ "https://api.github.com/repos/${{ secrets.BENCHMARKS_REPO }}/dispatches" \ - -d '{"event_type":"measurement_core","client_payload":{"core_commit": "${ env.GITHUB_SHA }" }}' + -d '{"event_type":"measurement_core","client_payload":{"core_commit": "'$GITHUB_SHA'" }}' From a18e8112ad1a7c099adb856e2216be1cf0fcbfec Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 5 Oct 2022 11:43:32 +0200 Subject: [PATCH 197/389] deprecate graph.flag_encoders and use custom weighting in example config (#2667) * deprecate graph.flag_encoders * clean up config-example.yml * Update config-example.yml * comments from review --- README.md | 2 +- config-example.yml | 113 +++++++++--------- .../java/com/graphhopper/GraphHopper.java | 20 +++- .../java/com/graphhopper/GraphHopperTest.java | 10 +- .../reader/osm/GraphHopperOSMTest.java | 16 +-- .../graphhopper/reader/osm/OSMReaderTest.java | 2 +- docs/core/turn-restrictions.md | 2 +- .../com/graphhopper/tools/CHMeasurement.java | 4 +- .../com/graphhopper/jackson/config.yml | 2 +- .../application/GraphHopperLandmarksTest.java | 2 +- .../resources/I18nResourceTest.java | 2 +- .../resources/IsochroneResourceTest.java | 2 +- .../resources/MapMatchingResourceTest.java | 2 +- .../MapMatchingResourceTurnCostsTest.java | 2 +- .../resources/MvtResourceTest.java | 2 +- .../resources/NearestResourceTest.java | 2 +- .../resources/NearestResourceWithEleTest.java | 2 +- .../resources/PtIsochroneTest.java | 2 +- .../resources/RouteResourceClientHCTest.java | 2 +- .../RouteResourceCustomModelLMTest.java | 2 +- .../RouteResourceCustomModelTest.java | 2 +- .../resources/RouteResourceIssue1574Test.java | 2 +- .../resources/RouteResourceIssue2020Test.java | 2 +- .../RouteResourceProfileSelectionTest.java | 2 +- .../resources/RouteResourceTest.java | 2 +- .../RouteResourceTurnCostsLegacyTest.java | 2 +- .../resources/RouteResourceTurnCostsTest.java | 2 +- .../resources/RouteResourceWithEleTest.java | 2 +- .../resources/SPTResourceTest.java | 2 +- 29 files changed, 111 insertions(+), 100 deletions(-) diff --git a/README.md b/README.md index ebf3349cabc..0e5e70ed604 100644 --- a/README.md +++ b/README.md @@ -232,7 +232,7 @@ Here is a list of the more detailed features: * Memory efficient data structures, algorithms and [the low and high level API](./docs/core/low-level-api.md) is tuned towards ease of use and efficiency * Provides a simple [web API](./docs/web/api-doc.md) including JavaScript and Java clients * Multiple weightings (fastest/shortest/custom/...) and pre-built routing profiles: car, bike, racing bike, mountain bike, foot, hike, motorcycle, wheelchair, ... - * [Customization of these profiles](./docs/core/profiles.md#custom-profiles) are possible to get truck and cargo bike support or individual improvements + * [Customization of these profiles](./docs/core/profiles.md#custom-profiles) are possible and e.g. get truck routing or support for cargo bikes and [many other changes](https://www.graphhopper.com/blog/2020/05/31/examples-for-customizable-routing/) * Does [map matching](./map-matching) * Supports public transit routing and [GTFS](./reader-gtfs/README.md). * Offers turn instructions in more than 42 languages, contribute or improve [here](./docs/core/translations.md) diff --git a/config-example.yml b/config-example.yml index 677b283c95f..ef0d605cf6c 100644 --- a/config-example.yml +++ b/config-example.yml @@ -6,30 +6,17 @@ graphhopper: graph.location: graph-cache - ##### Vehicles ##### - - # More options: foot,hike,bike,bike2,mtb,racingbike,motorcycle,wheelchair (comma separated) - # bike2 takes elevation data into account (like up-hill is slower than down-hill) and requires enabling graph.elevation.provider below. - # graph.flag_encoders: car - - # Enable turn restrictions for car or motorcycle. - # graph.flag_encoders: car|turn_costs=true - - # Add additional information to every edge. Used for path details (#1548), better instructions (#1844) and tunnel/bridge interpolation (#798). - # Default values are: road_class,road_class_link,road_environment,max_speed,road_access (since #1805) - # More are: surface,smoothness,max_width,max_height,max_weight,hgv,max_axle_load,max_length,hazmat,hazmat_tunnel,hazmat_water,toll,track_type, - # mtb_rating, hike_rating,horse_rating,lanes - # graph.encoded_values: surface,toll,track_type - ##### Routing Profiles #### - # Routing can be done for the following list of profiles. Note that it is required to specify all the profiles you - # would like to use here. The fields of each profile are as follows: + # Routing can be done only for profiles listed below. For more information about profiles and custom profiles have a + # look into the documentation at docs/core/profiles.md or the examples under web/src/test/java/com/graphhopper/application/resources/ + # or the CustomWeighting class for the raw details. + # + # In general a profile consists of the following # - name (required): a unique string identifier for the profile - # - vehicle (required): refers to the `graph.flag_encoders` used for this profile - # - weighting (required): the weighting used for this profile, e.g. fastest,shortest or short_fastest + # - vehicle (required): refers to the `graph.vehicles` used for this profile + # - weighting (required): the weighting used for this profile like custom,fastest,shortest or short_fastest # - turn_costs (true/false, default: false): whether or not turn restrictions should be applied for this profile. - # this will only work if the `graph.flag_encoders` for the given `vehicle` is configured with `|turn_costs=true`. # # Depending on the above fields there are other properties that can be used, e.g. # - distance_factor: 0.1 (can be used to fine tune the time/distance trade-off of short_fastest weighting) @@ -40,23 +27,17 @@ graphhopper: # or working directory that defines the custom_model. If you want an empty model you can also set "custom_model_file: empty". # You can also use th e`custom_model` field instead and specify your custom model in the profile directly. # - # For more information about profiles and especially custom profiles have a look into the documentation - # at docs/core/profiles.md or the examples under web/src/test/java/com/graphhopper/application/resources/ or - # the CustomWeighting class for the raw details. - # # To prevent long running routing queries you should usually enable either speed or hybrid mode for all the given - # profiles (see below). Otherwise you should at least limit the number of `routing.max_visited_nodes`. + # profiles (see below). Or at least limit the number of `routing.max_visited_nodes`. + profiles: - name: car vehicle: car - weighting: fastest - - # - name: car_with_turn_costs - # vehicle: car - # weighting: short_fastest - # distance_factor: 0.1 - # turn_costs: true - # u_turn_costs: 60 + weighting: custom + custom_model: + distance_influence: 70 + # turn_costs: true + # u_turn_costs: 60 # Speed mode: # Its possible to speed up routing by doing a special graph preparation (Contraction Hierarchies, CH). This requires @@ -66,7 +47,6 @@ graphhopper: # usage) and the routing will also be slower than with `turn_costs: false`. profiles_ch: - profile: car - # - profile: car_with_turn_costs # Hybrid mode: # Similar to speed mode, the hybrid mode (Landmarks, LM) also speeds up routing by doing calculating auxiliary data @@ -79,7 +59,39 @@ graphhopper: # for the preparation (`my_other_profile`) profiles_lm: [] - ##### Elevation ##### + + #### Vehicles #### + + # The vehicle defines the base for how the routing of a profile behaves. It can be fine tuned using the options: + # name=mycustomvehicle,block_private=true,turn_costs=true,transportation_mode=MOTOR_VEHICLE (only for the roads vehicle) + # Still, it is recommended to avoid changing the vehicle settings and change the custom model instead. + # graph.vehicles: car|block_fords=true,turn_costs=true,bike|turn_costs=true + # Other standard vehicles: foot,bike,mtb,racingbike,motorcycle,wheelchair + + + #### Encoded Values #### + + # Add additional information to every edge. Used for path details (#1548) and custom models (docs/core/custom-models.md) + # Default values are: road_class,road_class_link,road_environment,max_speed,road_access + # More are: surface,smoothness,max_width,max_height,max_weight,hgv,max_axle_load,max_length,hazmat,hazmat_tunnel,hazmat_water,toll,track_type, + # mtb_rating, hike_rating,horse_rating,lanes + # graph.encoded_values: surface,toll,track_type + + #### Speed, hybrid and flexible mode #### + + # To make CH preparation faster for multiple profiles you can increase the default threads if you have enough RAM. + # Change this setting only if you know what you are doing and if the default worked for you. + # prepare.ch.threads: 1 + + # To tune the performance vs. memory usage for the hybrid mode use + # prepare.lm.landmarks: 16 + + # Make landmark preparation parallel if you have enough RAM. Change this only if you know what you are doing and if + # the default worked for you. + # prepare.lm.threads: 1 + + + #### Elevation #### # To populate your graph with elevation data use SRTM, default is noop (no elevation). Read more about it in docs/core/elevation.md # graph.elevation.provider: srtm @@ -109,8 +121,8 @@ graphhopper: # elevation and will remove the extra points that long edge sampling added # graph.elevation.way_point_max_distance: 10 - #### Urban density (built-up areas) #### + #### Urban density (built-up areas) #### # This feature allows classifying roads into 'rural', 'residential' and 'city' areas (encoded value 'urban_density') # Use 1 or more threads to enable the feature @@ -124,18 +136,7 @@ graphhopper: # graph.urban_density.city_sensitivity: 30 - #### Speed, hybrid and flexible mode #### - - # To make CH preparation faster for multiple profiles you can increase the default threads if you have enough RAM. - # Change this setting only if you know what you are doing and if the default worked for you. - # prepare.ch.threads: 1 - - # To tune the performance vs. memory usage for the hybrid mode use - # prepare.lm.landmarks: 16 - - # Make landmark preparation parallel if you have enough RAM. Change this only if you know what you are doing and if - # the default worked for you. - # prepare.lm.threads: 1 + #### Subnetworks #### # In many cases the road network consists of independent components without any routes going in between. In # the most simple case you can imagine an island without a bridge or ferry connection. The following parameter @@ -144,7 +145,7 @@ graphhopper: prepare.min_network_size: 200 - ##### Routing ##### + #### Routing #### # You can define the maximum visited nodes when routing. This may result in not found connections if there is no # connection between two points within the given visited nodes. The default is Integer.MAX_VALUE. Useful for flexibility mode @@ -158,25 +159,27 @@ graphhopper: routing.non_ch.max_waypoint_distance: 1000000 - ##### Storage ##### + #### Storage #### # configure the memory access, use RAM_STORE for well equipped servers (default and recommended) graph.dataaccess.default_type: RAM_STORE - # will write way names in the preferred language (language code as defined in ISO 639-1 or ISO 639-2): # datareader.preferred_language: en - # Sort the graph after import to make requests roughly ~10% faster. Note that this requires significantly more RAM on import. # graph.do_sort: true - ##### Country Rules ##### + + #### Custom Areas #### + # GraphHopper reads GeoJSON polygon files including their properties from this directory and makes them available - # to all tag parsers and flag encoders. Country borders (see countries.geojson) are always included automatically. + # to all tag parsers and vehicles. Country borders (see countries.geojson) are always included automatically. # custom_areas.directory: path/to/custom_areas - ##### Country Rules ##### + + #### Country Rules #### + # GraphHopper applies country-specific routing rules during import (not enabled by default). # You need to redo the import for changes to take effect. # country_rules.enabled: true diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index c8d6ca6678f..e1989f175f4 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -131,15 +131,15 @@ public class GraphHopper { private String dateRangeParserString = ""; private String encodedValuesString = ""; - private String flagEncodersString = ""; + private String vehiclesString = ""; public GraphHopper setEncodedValuesString(String encodedValuesString) { this.encodedValuesString = encodedValuesString; return this; } - public GraphHopper setFlagEncodersString(String flagEncodersString) { - this.flagEncodersString = flagEncodersString; + public GraphHopper setVehiclesString(String vehiclesString) { + this.vehiclesString = vehiclesString; return this; } @@ -531,7 +531,15 @@ public GraphHopper init(GraphHopperConfig ghConfig) { throw new IllegalArgumentException("spatial_rules.max_bbox has been deprecated. There is no replacement, all custom areas will be considered."); setProfiles(ghConfig.getProfiles()); - flagEncodersString = ghConfig.getString("graph.flag_encoders", flagEncodersString); + vehiclesString = ghConfig.getString("graph.vehicles", vehiclesString); + if (vehiclesString.isEmpty()) { + vehiclesString = ghConfig.getString("graph.flag_encoders", vehiclesString); + if (!vehiclesString.isEmpty()) + logger.warn("The option graph.flag_encoders is deprecated and will be removed. Replace with graph.vehicles"); + } else if (!ghConfig.getString("graph.flag_encoders", "").isEmpty()) { + throw new IllegalArgumentException("Remove graph.flag_encoders as it cannot be used in parallel with graph.vehicles"); + } + encodedValuesString = ghConfig.getString("graph.encoded_values", encodedValuesString); dateRangeParserString = ghConfig.getString("datareader.date_range_parser_day", dateRangeParserString); @@ -783,7 +791,7 @@ private void process(boolean closeEarly) { GHDirectory directory = new GHDirectory(ghLocation, dataAccessDefaultType); directory.configure(dataAccessConfig); boolean withUrbanDensity = urbanDensityCalculationThreads > 0; - buildEncodingManagerAndOSMParsers(flagEncodersString, encodedValuesString, dateRangeParserString, withUrbanDensity, profilesByName.values()); + buildEncodingManagerAndOSMParsers(vehiclesString, encodedValuesString, dateRangeParserString, withUrbanDensity, profilesByName.values()); baseGraph = new BaseGraph.Builder(getEncodingManager()) .setDir(directory) .set3D(hasElevation()) @@ -1012,7 +1020,7 @@ private void checkProfilesConsistency() { if (profile.isTurnCosts() && turnCostEnc == null) { throw new IllegalArgumentException("The profile '" + profile.getName() + "' was configured with " + "'turn_costs=true', but the corresponding vehicle '" + profile.getVehicle() + "' does not support turn costs." + - "\nYou need to add `|turn_costs=true` to the vehicle in `graph.flag_encoders`"); + "\nYou need to add `|turn_costs=true` to the vehicle in `graph.vehicles`"); } try { createWeighting(profile, new PMap()); diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index ae4dd366e52..adb026e5589 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -2626,7 +2626,7 @@ public void testLoadGraph_implicitEncodedValues_issue1862() { int nodes = hopper.getBaseGraph().getNodes(); hopper.close(); - // load without configured graph.flag_encoders + // load without configured graph.vehicles hopper = new GraphHopper(); hopper.setProfiles(Arrays.asList( new Profile("p_car").setVehicle("car").setWeighting("fastest"), @@ -2638,9 +2638,9 @@ public void testLoadGraph_implicitEncodedValues_issue1862() { assertEquals(nodes, hopper.getBaseGraph().getNodes()); hopper.close(); - // load via explicitly configured graph.flag_encoders + // load via explicitly configured graph.vehicles hopper = new GraphHopper(); - hopper.setFlagEncodersString("car,bike"); + hopper.setVehiclesString("car,bike"); hopper.setProfiles(Arrays.asList( new Profile("p_car").setVehicle("car").setWeighting("fastest"), new Profile("p_bike").setVehicle("bike").setWeighting("fastest")) @@ -2655,7 +2655,7 @@ public void testLoadGraph_implicitEncodedValues_issue1862() { void testLoadingWithAnotherSpeedFactorWorks() { { GraphHopper hopper = new GraphHopper() - .setFlagEncodersString("car|speed_factor=7") + .setVehiclesString("car|speed_factor=7") .setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")) .setGraphHopperLocation(GH_LOCATION) .setOSMFile(BAYREUTH); @@ -2667,7 +2667,7 @@ void testLoadingWithAnotherSpeedFactorWorks() { // during import with those that only matter when routing for some time already. At some point we should // separate the 'import' from the 'routing' config (and split the GraphHopper class). GraphHopper hopper = new GraphHopper() - .setFlagEncodersString("car|speed_factor=9") + .setVehiclesString("car|speed_factor=9") .setProfiles(new Profile("car").setVehicle("car").setWeighting("fastest")) .setGraphHopperLocation(GH_LOCATION); hopper.load(); diff --git a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java index 65d8c430015..c9366300ae3 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java @@ -461,7 +461,7 @@ public void testNothingHappensWhenFlagEncodersAreChangedForLoad() { new GraphHopperConfig(). putObject("datareader.file", testOsm3). putObject("datareader.dataaccess", "RAM"). - putObject("graph.flag_encoders", "foot,car"). + putObject("graph.vehicles", "foot,car"). setProfiles(Arrays.asList( new Profile("foot").setVehicle("foot").setWeighting("fastest"), new Profile("car").setVehicle("car").setWeighting("fastest") @@ -476,7 +476,7 @@ public void testNothingHappensWhenFlagEncodersAreChangedForLoad() { new GraphHopperConfig(). putObject("datareader.file", testOsm3). putObject("datareader.dataaccess", "RAM"). - putObject("graph.flag_encoders", "foot"). + putObject("graph.vehicles", "foot"). setProfiles(Collections.singletonList( new Profile("foot").setVehicle("foot").setWeighting("fastest") ))). @@ -485,11 +485,11 @@ public void testNothingHappensWhenFlagEncodersAreChangedForLoad() { IllegalStateException e = assertThrows(IllegalStateException.class, tmpGH::load); assertTrue(e.getMessage().contains("Profiles do not match"), e.getMessage()); - // different order of flag_encoders is also fine, but profiles must be in same order + // different order of graph.vehicles is also fine, but profiles must be in same order tmpGH = new GraphHopper().init(new GraphHopperConfig(). putObject("datareader.file", testOsm3). putObject("datareader.dataaccess", "RAM"). - putObject("graph.flag_encoders", "car,foot"). + putObject("graph.vehicles", "car,foot"). setProfiles(Arrays.asList( new Profile("car").setVehicle("car").setWeighting("fastest"), new Profile("foot").setVehicle("foot").setWeighting("fastest") @@ -505,7 +505,7 @@ public void testNothingHappensWhenFlagEncodersAreChangedForLoad() { putObject("datareader.file", testOsm3). putObject("datareader.dataaccess", "RAM"). putObject("graph.encoded_values", "road_class"). - putObject("graph.flag_encoders", "foot,car"). + putObject("graph.vehicles", "foot,car"). setProfiles(Arrays.asList( new Profile("foot").setVehicle("foot").setWeighting("fastest"), new Profile("car").setVehicle("car").setWeighting("fastest") @@ -524,7 +524,7 @@ public void testFailsForWrongEVConfig() { new GraphHopperConfig(). putObject("datareader.file", testOsm3). putObject("datareader.dataaccess", "RAM"). - putObject("graph.flag_encoders", "foot,car"). + putObject("graph.vehicles", "foot,car"). setProfiles(Arrays.asList( new Profile("foot").setVehicle("foot").setWeighting("fastest"), new Profile("car").setVehicle("car").setWeighting("fastest") @@ -544,7 +544,7 @@ public void testFailsForWrongEVConfig() { putObject("datareader.dataaccess", "RAM"). putObject("graph.location", ghLoc). putObject("graph.encoded_values", "road_environment,road_class"). - putObject("graph.flag_encoders", "foot,car"). + putObject("graph.vehicles", "foot,car"). setProfiles(Arrays.asList( new Profile("foot").setVehicle("foot").setWeighting("fastest"), new Profile("car").setVehicle("car").setWeighting("fastest") @@ -660,7 +660,7 @@ public void testVia() { init(new GraphHopperConfig(). putObject("datareader.file", testOsm3). putObject("prepare.min_network_size", 0). - putObject("graph.flag_encoders", vehicle). + putObject("graph.vehicles", vehicle). setProfiles(Collections.singletonList(new Profile(profile).setVehicle(vehicle).setWeighting(weighting))). setCHProfiles(Collections.singletonList(new CHProfile(profile))) ). diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 56f61976b19..99aa995172d 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -390,7 +390,7 @@ public void testBarrierBetweenWays() { @Test public void testFords() { GraphHopper hopper = new GraphHopper(); - hopper.setFlagEncodersString("car|block_fords=true"); + hopper.setVehiclesString("car|block_fords=true"); hopper.setOSMFile(getClass().getResource("test-barriers3.xml").getFile()). setGraphHopperLocation(dir). setProfiles( diff --git a/docs/core/turn-restrictions.md b/docs/core/turn-restrictions.md index 9ceb633730b..a7161c072b1 100644 --- a/docs/core/turn-restrictions.md +++ b/docs/core/turn-restrictions.md @@ -12,7 +12,7 @@ Turn restrictions are crucial for correct vehicle navigation and help to avoid f ![turn with turn restrictions](./images/turn-restrictions-correct.png) Turn restrictions have to be enabled on a vehicle basis. To enable it for one vehicle add -`|turn_costs=true` in the config, for example: `graph.flag_encoders=car|turn_costs=true`. +`|turn_costs=true` in the config, for example: `graph.vehicles=car|turn_costs=true`. Or when using the Java API directly you can either create the encoding manager like `EncodingManager.create("car|turn_costs=true")` or `new EncodingManager.Builder().add(new CarFlagEncoder(5, 5, 1)` where the last parameter of `CarFlagEncoder` represents the maximum turn costs (a value of 1 means the turn can either be legal or forbidden). diff --git a/tools/src/main/java/com/graphhopper/tools/CHMeasurement.java b/tools/src/main/java/com/graphhopper/tools/CHMeasurement.java index 96afb6b963e..e6404c4b78e 100644 --- a/tools/src/main/java/com/graphhopper/tools/CHMeasurement.java +++ b/tools/src/main/java/com/graphhopper/tools/CHMeasurement.java @@ -87,7 +87,7 @@ private static void testPerformanceAutomaticNodeOrdering(String[] args) { final GraphHopper graphHopper = new GraphHopper(); String profile = "car_profile"; if (withTurnCosts) { - ghConfig.putObject("graph.flag_encoders", "car|turn_costs=true"); + ghConfig.putObject("graph.vehicles", "car|turn_costs=true"); ghConfig.setProfiles(Collections.singletonList( new Profile(profile).setVehicle("car").setWeighting("fastest").setTurnCosts(true).putHint(Parameters.Routing.U_TURN_COSTS, uTurnCosts) )); @@ -101,7 +101,7 @@ private static void testPerformanceAutomaticNodeOrdering(String[] args) { ghConfig.putObject("prepare.lm.landmarks", landmarks); } } else { - ghConfig.putObject("graph.flag_encoders", "car"); + ghConfig.putObject("graph.vehicles", "car"); ghConfig.setProfiles(Collections.singletonList( new Profile(profile).setVehicle("car").setWeighting("fastest").setTurnCosts(false) )); diff --git a/web-bundle/src/test/resources/com/graphhopper/jackson/config.yml b/web-bundle/src/test/resources/com/graphhopper/jackson/config.yml index f6c04f0fc40..71d80e1816a 100644 --- a/web-bundle/src/test/resources/com/graphhopper/jackson/config.yml +++ b/web-bundle/src/test/resources/com/graphhopper/jackson/config.yml @@ -1,6 +1,6 @@ datareader.file: map-matching/files/leipzig_germany.osm.pbf graph.location: graphs/leipzig-regular/graph -graph.flag_encoders: car +graph.vehicles: car profiles: - name: car vehicle: car diff --git a/web/src/test/java/com/graphhopper/application/GraphHopperLandmarksTest.java b/web/src/test/java/com/graphhopper/application/GraphHopperLandmarksTest.java index 3d9524dd3d3..00e3525be84 100644 --- a/web/src/test/java/com/graphhopper/application/GraphHopperLandmarksTest.java +++ b/web/src/test/java/com/graphhopper/application/GraphHopperLandmarksTest.java @@ -51,7 +51,7 @@ public class GraphHopperLandmarksTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car"). + putObject("graph.vehicles", "car"). putObject("datareader.file", "../core/files/belarus-east.osm.gz"). putObject("prepare.min_network_size", 0). putObject("graph.location", DIR) diff --git a/web/src/test/java/com/graphhopper/application/resources/I18nResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/I18nResourceTest.java index f1104142370..d4c0b3b8b13 100644 --- a/web/src/test/java/com/graphhopper/application/resources/I18nResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/I18nResourceTest.java @@ -46,7 +46,7 @@ public class I18nResourceTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car"). + putObject("graph.vehicles", "car"). putObject("datareader.file", "../core/files/andorra.osm.pbf"). putObject("graph.location", DIR). setProfiles(Collections.singletonList(new Profile("car").setVehicle("car").setWeighting("fastest"))); diff --git a/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java index 969d899fc2f..40f3ceee3c2 100644 --- a/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/IsochroneResourceTest.java @@ -53,7 +53,7 @@ public class IsochroneResourceTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car|turn_costs=true"). + putObject("graph.vehicles", "car|turn_costs=true"). putObject("datareader.file", "../core/files/andorra.osm.pbf"). putObject("graph.location", DIR). setProfiles(Arrays.asList( diff --git a/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTest.java index 5f62a3d8458..9b7a0849164 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTest.java @@ -54,7 +54,7 @@ public class MapMatchingResourceTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car,bike"). + putObject("graph.vehicles", "car,bike"). putObject("datareader.file", "../map-matching/files/leipzig_germany.osm.pbf"). putObject("graph.location", DIR). setProfiles(Arrays.asList( diff --git a/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java b/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java index 46bcbdffdd6..fa5753c1e7c 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MapMatchingResourceTurnCostsTest.java @@ -58,7 +58,7 @@ public class MapMatchingResourceTurnCostsTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car|turn_costs=true,bike"). + putObject("graph.vehicles", "car|turn_costs=true,bike"). putObject("datareader.file", "../map-matching/files/leipzig_germany.osm.pbf"). putObject("graph.location", DIR). setProfiles(Arrays.asList( diff --git a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java index 5fe36573c98..9257f99067d 100644 --- a/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/MvtResourceTest.java @@ -60,7 +60,7 @@ public class MvtResourceTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car"). + putObject("graph.vehicles", "car"). putObject("graph.encoded_values", "road_class,road_environment,max_speed,surface"). putObject("prepare.min_network_size", 0). putObject("datareader.file", "../core/files/andorra.osm.pbf"). diff --git a/web/src/test/java/com/graphhopper/application/resources/NearestResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/NearestResourceTest.java index 77781733942..7711dc9e496 100644 --- a/web/src/test/java/com/graphhopper/application/resources/NearestResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/NearestResourceTest.java @@ -49,7 +49,7 @@ public class NearestResourceTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car"). + putObject("graph.vehicles", "car"). putObject("datareader.file", "../core/files/andorra.osm.pbf"). putObject("graph.location", dir). setProfiles(Collections.singletonList(new Profile("car").setVehicle("car").setWeighting("fastest"))); diff --git a/web/src/test/java/com/graphhopper/application/resources/NearestResourceWithEleTest.java b/web/src/test/java/com/graphhopper/application/resources/NearestResourceWithEleTest.java index 0bbae7121a9..dcf23433223 100644 --- a/web/src/test/java/com/graphhopper/application/resources/NearestResourceWithEleTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/NearestResourceWithEleTest.java @@ -51,7 +51,7 @@ private static GraphHopperServerConfiguration createConfig() { putObject("graph.elevation.provider", "srtm"). putObject("graph.elevation.cache_dir", "../core/files/"). putObject("prepare.min_network_size", 0). - putObject("graph.flag_encoders", "car"). + putObject("graph.vehicles", "car"). putObject("datareader.file", "../core/files/monaco.osm.gz"). putObject("graph.location", dir). setProfiles(Collections.singletonList(new Profile("car").setVehicle("car").setWeighting("fastest"))); diff --git a/web/src/test/java/com/graphhopper/application/resources/PtIsochroneTest.java b/web/src/test/java/com/graphhopper/application/resources/PtIsochroneTest.java index 0b514b02a6c..5d810e207f4 100644 --- a/web/src/test/java/com/graphhopper/application/resources/PtIsochroneTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/PtIsochroneTest.java @@ -56,7 +56,7 @@ public class PtIsochroneTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration() - .putObject("graph.flag_encoders", "foot") + .putObject("graph.vehicles", "foot") .putObject("graph.location", GRAPH_LOC) .putObject("gtfs.file", "../reader-gtfs/files/sample-feed"). setProfiles(Collections.singletonList(new Profile("foot").setVehicle("foot").setWeighting("fastest"))); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java index 1118ef29bbe..d93bde9a1cd 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java @@ -62,7 +62,7 @@ public class RouteResourceClientHCTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car,bike"). + putObject("graph.vehicles", "car,bike"). putObject("prepare.min_network_size", 0). putObject("graph.elevation.provider", "srtm"). putObject("graph.elevation.cache_dir", "../core/files/"). diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelLMTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelLMTest.java index a23acd3a708..6cd248783f6 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelLMTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelLMTest.java @@ -53,7 +53,7 @@ public class RouteResourceCustomModelLMTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car,foot"). + putObject("graph.vehicles", "car,foot"). putObject("datareader.file", "../core/files/andorra.osm.pbf"). putObject("graph.location", DIR). putObject("graph.encoded_values", "surface"). diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java index a641d7ac79f..01a5ee8cec2 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java @@ -59,7 +59,7 @@ public class RouteResourceCustomModelTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "bike,car,foot,wheelchair,roads"). + putObject("graph.vehicles", "bike,car,foot,wheelchair,roads"). putObject("prepare.min_network_size", 200). putObject("datareader.file", "../core/files/north-bayreuth.osm.gz"). putObject("graph.location", DIR). diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceIssue1574Test.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceIssue1574Test.java index 48d6832e9d9..28409ad215f 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceIssue1574Test.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceIssue1574Test.java @@ -51,7 +51,7 @@ private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); // this is the reason we put this test into an extra file: we can only reproduce the bug of issue 1574 by increasing the one-way-network size config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car"). + putObject("graph.vehicles", "car"). putObject("prepare.min_network_size", 0). putObject("datareader.file", "../core/files/andorra.osm.pbf"). putObject("graph.location", DIR) diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceIssue2020Test.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceIssue2020Test.java index 9b192f2d9b9..0c1f0a9317d 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceIssue2020Test.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceIssue2020Test.java @@ -48,7 +48,7 @@ public class RouteResourceIssue2020Test { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car"). + putObject("graph.vehicles", "car"). putObject("prepare.lm.split_area_location", "../core/files/split.geo.json"). putObject("datareader.file", "../core/files/north-bayreuth.osm.gz"). putObject("graph.encoded_values", "road_class,surface,road_environment,max_speed"). diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java index e12edd2931b..f7e3c287ba2 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceProfileSelectionTest.java @@ -50,7 +50,7 @@ public class RouteResourceProfileSelectionTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "bike,car,foot"). + putObject("graph.vehicles", "bike,car,foot"). putObject("prepare.min_network_size", 0). putObject("datareader.file", "../core/files/monaco.osm.gz"). putObject("graph.encoded_values", "road_class,surface,road_environment,max_speed"). diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java index 11426692e1a..35200b21701 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTest.java @@ -78,7 +78,7 @@ private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). putObject("profiles_mapbox", mapboxResolver). - putObject("graph.flag_encoders", "car"). + putObject("graph.vehicles", "car"). putObject("prepare.min_network_size", 0). putObject("datareader.file", "../core/files/andorra.osm.pbf"). putObject("graph.encoded_values", "road_class,surface,road_environment,max_speed"). diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsLegacyTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsLegacyTest.java index 6c33ee004f6..1406ff24816 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsLegacyTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsLegacyTest.java @@ -52,7 +52,7 @@ public class RouteResourceTurnCostsLegacyTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car|turn_costs=true"). + putObject("graph.vehicles", "car|turn_costs=true"). putObject("prepare.min_network_size", 0). putObject("datareader.file", "../core/files/moscow.osm.gz"). putObject("graph.encoded_values", "road_class,surface,road_environment,max_speed"). diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsTest.java index b65f5fa991c..8a69177d2b3 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceTurnCostsTest.java @@ -52,7 +52,7 @@ public class RouteResourceTurnCostsTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car|turn_costs=true"). + putObject("graph.vehicles", "car|turn_costs=true"). putObject("prepare.min_network_size", 0). putObject("datareader.file", "../core/files/moscow.osm.gz"). putObject("graph.encoded_values", "road_class,surface,road_environment,max_speed"). diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceWithEleTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceWithEleTest.java index 00a049e7109..2c640c95241 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceWithEleTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceWithEleTest.java @@ -51,7 +51,7 @@ private static GraphHopperServerConfiguration createConfig() { putObject("graph.elevation.provider", "srtm"). putObject("graph.elevation.cache_dir", "../core/files/"). putObject("prepare.min_network_size", 0). - putObject("graph.flag_encoders", "car"). + putObject("graph.vehicles", "car"). putObject("datareader.file", "../core/files/monaco.osm.gz"). putObject("graph.location", dir). setProfiles(Collections.singletonList( diff --git a/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java b/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java index a2fdc62a471..9cb2d0dcc6e 100644 --- a/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/SPTResourceTest.java @@ -47,7 +47,7 @@ public class SPTResourceTest { private static GraphHopperServerConfiguration createConfig() { GraphHopperServerTestConfiguration config = new GraphHopperServerTestConfiguration(); config.getGraphHopperConfiguration(). - putObject("graph.flag_encoders", "car|turn_costs=true"). + putObject("graph.vehicles", "car|turn_costs=true"). putObject("graph.encoded_values", "max_speed,road_class"). putObject("datareader.file", "../core/files/andorra.osm.pbf"). putObject("graph.location", DIR). From 51dc8ab538597d91c9a61e1e2b27720a07f2f9f6 Mon Sep 17 00:00:00 2001 From: Andi Date: Wed, 5 Oct 2022 11:46:46 +0200 Subject: [PATCH 198/389] Remove VehicleTagParser#applyWayTags (#2669) * Change the signature for easier refactoring * use point list and distance from way, now we can move up * Remove OSMParsers#applyWayTags * Remove VehicleTagParser#applyWayTags * Move point list etc. into applyWayTags * Partly fix tests * imports * fix --- .../com/graphhopper/reader/osm/OSMReader.java | 2 -- .../routing/util/Bike2WeightTagParser.java | 24 ++++++++----- .../routing/util/HikeTagParser.java | 31 +++++++++++------ .../graphhopper/routing/util/OSMParsers.java | 5 --- .../routing/util/VehicleTagParser.java | 8 ----- .../routing/util/WheelchairTagParser.java | 34 ++++++++++++------- .../util/Bike2WeightTagParserTest.java | 18 ++++++++-- .../routing/util/TagParsingTest.java | 10 +++--- .../routing/util/WheelchairTagParserTest.java | 25 +++++++++++--- 9 files changed, 98 insertions(+), 59 deletions(-) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index cc06c0d958a..41acbe77851 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -43,7 +43,6 @@ import com.graphhopper.util.*; import com.graphhopper.util.shapes.GHPoint; import com.graphhopper.util.shapes.GHPoint3D; -import org.locationtech.jts.geom.Polygon; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -357,7 +356,6 @@ else if (config.getElevationSmoothing().equals("moving_average")) checkCoordinates(toIndex, pointList.get(pointList.size() - 1)); edge.setWayGeometry(pointList.shallowCopy(1, pointList.size() - 1, false)); } - osmParsers.applyWayTags(way, edge); checkDistance(edge); if (osmWayIdSet.contains(way.getId())) { diff --git a/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java b/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java index 8797bf1ac6d..25266d540d6 100644 --- a/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java @@ -20,8 +20,6 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.EdgeIteratorState; -import com.graphhopper.util.FetchMode; import com.graphhopper.util.PMap; import com.graphhopper.util.PointList; @@ -58,16 +56,22 @@ public Bike2WeightTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue s } @Override - public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { - PointList pl = edge.fetchWayGeometry(FetchMode.ALL); + public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { + edgeFlags = super.handleWayTags(edgeFlags, way); + return applyWayTags(way, edgeFlags); + } + + public IntsRef applyWayTags(ReaderWay way, IntsRef intsRef) { + PointList pl = way.getTag("point_list", null); + if (pl == null) + throw new IllegalArgumentException("The artificial point_list tag is missing"); if (!pl.is3D()) throw new IllegalStateException(getName() + " requires elevation data to improve speed calculation based on it. Please enable it in config via e.g. graph.elevation.provider: srtm"); - IntsRef intsRef = edge.getFlags(); if (way.hasTag("tunnel", "yes") || way.hasTag("bridge", "yes") || way.hasTag("highway", "steps")) // do not change speed // note: although tunnel can have a difference in elevation it is very unlikely that the elevation data is correct for a tunnel - return; + return intsRef; // Decrease the speed for ele increase (incline), and decrease the speed for ele decrease (decline). The speed-decrease // has to be bigger (compared to the speed-increase) for the same elevation difference to simulate losing energy and avoiding hills. @@ -75,11 +79,13 @@ public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { double incEleSum = 0, incDist2DSum = 0, decEleSum = 0, decDist2DSum = 0; // double prevLat = pl.getLat(0), prevLon = pl.getLon(0); double prevEle = pl.getEle(0); - double fullDist2D = edge.getDistance(); + if (!way.hasTag("edge_distance")) + throw new IllegalArgumentException("The artificial edge_distance tag is missing"); + double fullDist2D = way.getTag("edge_distance", 0d); // for short edges an incline makes no sense and for 0 distances could lead to NaN values for speed, see #432 if (fullDist2D < 2) - return; + return intsRef; double eleDelta = pl.getEle(pl.size() - 1) - prevEle; if (eleDelta > 0.1) { @@ -117,7 +123,7 @@ public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { speedReverse = speedReverse * (bwFaster * incDist2DSum + bwSlower * decDist2DSum + 1 * restDist2D) / fullDist2D; setSpeed(true, intsRef, keepIn(speedReverse, MIN_SPEED, maxSpeed)); } - edge.setFlags(intsRef); + return intsRef; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java b/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java index 87eb5285fd1..b275f69fa1f 100644 --- a/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/HikeTagParser.java @@ -20,7 +20,9 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.*; +import com.graphhopper.util.Helper; +import com.graphhopper.util.PMap; +import com.graphhopper.util.PointList; import java.util.TreeMap; @@ -87,30 +89,37 @@ void collect(ReaderWay way, TreeMap weightToPrioMap) { weightToPrioMap.put(44d, SLIGHT_AVOID.getValue()); } - @Override - public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { - PointList pl = edge.fetchWayGeometry(FetchMode.ALL); + public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { + edgeFlags = super.handleWayTags(edgeFlags, way); + return applyWayTags(way, edgeFlags); + } + + public IntsRef applyWayTags(ReaderWay way, IntsRef edgeFlags) { + PointList pl = way.getTag("point_list", null); + if (pl == null) + throw new IllegalArgumentException("The artificial point_list tag is missing"); if (!pl.is3D()) - return; + return edgeFlags; if (way.hasTag("tunnel", "yes") || way.hasTag("bridge", "yes") || way.hasTag("highway", "steps")) // do not change speed // note: although tunnel can have a difference in elevation it is unlikely that the elevation data is correct for a tunnel - return; + return edgeFlags; // Decrease the speed for ele increase (incline), and slightly decrease the speed for ele decrease (decline) double prevEle = pl.getEle(0); - double fullDistance = edge.getDistance(); + if (!way.hasTag("edge_distance")) + throw new IllegalArgumentException("The artificial edge_distance tag is missing"); + double fullDistance = way.getTag("edge_distance", 0d); // for short edges an incline makes no sense and for 0 distances could lead to NaN values for speed, see #432 if (fullDistance < 2) - return; + return edgeFlags; double eleDelta = Math.abs(pl.getEle(pl.size() - 1) - prevEle); double slope = eleDelta / fullDistance; - IntsRef edgeFlags = edge.getFlags(); if ((accessEnc.getBool(false, edgeFlags) || accessEnc.getBool(true, edgeFlags)) && slope > 0.005) { @@ -119,8 +128,10 @@ public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { // slope=h/s_2d=~h/2_3d = sqrt(1+slope²)/(slope+1/4.5) km/h // maximum slope is 0.37 (Ffordd Pen Llech) double newSpeed = Math.sqrt(1 + slope * slope) / (slope + 1 / 5.4); - edge.set(avgSpeedEnc, Helper.keepIn(newSpeed, 1, 5)); + avgSpeedEnc.setDecimal(false, edgeFlags, Helper.keepIn(newSpeed, 1, 5)); } + + return edgeFlags; } } diff --git a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java index 680aa3ab8ea..b908a7ce234 100644 --- a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java +++ b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java @@ -28,7 +28,6 @@ import com.graphhopper.routing.util.parsers.TurnCostParser; import com.graphhopper.storage.Graph; import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.EdgeIteratorState; import java.util.ArrayList; import java.util.List; @@ -95,10 +94,6 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationF return edgeFlags; } - public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { - vehicleTagParsers.forEach(t -> t.applyWayTags(way, edge)); - } - public void handleTurnRelationTags(OSMTurnRelation turnRelation, TurnCostParser.ExternalInternalMap map, Graph graph) { turnCostParsers.forEach(t -> t.handleTurnRelationTags(turnRelation, map, graph)); } diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java index 61b66fdb5d1..c300e29a771 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java @@ -28,7 +28,6 @@ import com.graphhopper.routing.util.parsers.TagParser; import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor; import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.EdgeIteratorState; import java.util.*; @@ -199,13 +198,6 @@ protected static boolean isValidSpeed(double speed) { return !Double.isNaN(speed); } - /** - * Second parsing step. Invoked after splitting the edges. Currently used to offer a hook to - * calculate precise speed values based on elevation data stored in the specified edge. - */ - public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { - } - public final DecimalEncodedValue getAverageSpeedEnc() { return avgSpeedEnc; } diff --git a/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java b/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java index 808f6565b73..d832519e798 100644 --- a/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/WheelchairTagParser.java @@ -20,8 +20,6 @@ import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.*; import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.EdgeIteratorState; -import com.graphhopper.util.FetchMode; import com.graphhopper.util.PMap; import com.graphhopper.util.PointList; @@ -180,6 +178,8 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { Integer priorityFromRelation = routeMap.get(footRouteEnc.getEnum(false, edgeFlags)); priorityWayEncoder.setDecimal(false, edgeFlags, PriorityCode.getValue(handlePriority(way, priorityFromRelation))); + + edgeFlags = applyWayTags(way, edgeFlags); return edgeFlags; } @@ -188,16 +188,19 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { * and maxInclinePercent will reduce speed to SLOW_SPEED. In-/declines above maxInclinePercent will result in zero * speed. */ - @Override - public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { - PointList pl = edge.fetchWayGeometry(FetchMode.ALL); - double fullDist2D = edge.getDistance(); + public IntsRef applyWayTags(ReaderWay way, IntsRef edgeFlags) { + PointList pl = way.getTag("point_list", null); + if (pl == null) + throw new IllegalArgumentException("The artificial point_list tag is missing"); + if (!way.hasTag("edge_distance")) + throw new IllegalArgumentException("The artificial edge_distance tag is missing"); + double fullDist2D = way.getTag("edge_distance", 0d); if (Double.isInfinite(fullDist2D)) throw new IllegalStateException("Infinite distance should not happen due to #435. way ID=" + way.getId()); // skip elevation data adjustment for too short segments, TODO improve the elevation data handling and/or use the same mechanism as in bike2 if (fullDist2D < 20 || !pl.is3D()) - return; + return edgeFlags; double prevEle = pl.getEle(0); double eleDelta = pl.getEle(pl.size() - 1) - prevEle; @@ -213,17 +216,22 @@ public void applyWayTags(ReaderWay way, EdgeIteratorState edge) { } else if (elePercent > maxInclinePercent || elePercent < -maxInclinePercent) { // it can be problematic to exclude roads due to potential bad elevation data (e.g.delta for narrow nodes could be too high) // so exclude only when we are certain - if (fullDist2D > 50) edge.set(accessEnc, false, false); + if (fullDist2D > 50) { + accessEnc.setBool(false, edgeFlags, false); + accessEnc.setBool(true, edgeFlags, false); + } fwdSpeed = SLOW_SPEED; bwdSpeed = SLOW_SPEED; - edge.set(priorityWayEncoder, PriorityCode.getValue(PriorityCode.REACH_DESTINATION.getValue())); + priorityWayEncoder.setDecimal(false, edgeFlags, PriorityCode.getValue(PriorityCode.REACH_DESTINATION.getValue())); } - if (fwdSpeed > 0 && edge.get(accessEnc)) - setSpeed(edge.getFlags(), true, false, fwdSpeed); - if (bwdSpeed > 0 && edge.getReverse(accessEnc)) - setSpeed(edge.getFlags(), false, true, bwdSpeed); + if (fwdSpeed > 0 && accessEnc.getBool(false, edgeFlags)) + setSpeed(edgeFlags, true, false, fwdSpeed); + if (bwdSpeed > 0 && accessEnc.getBool(true, edgeFlags)) + setSpeed(edgeFlags, false, true, bwdSpeed); + + return edgeFlags; } /** diff --git a/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java index cb35eef80b7..63a147859c5 100644 --- a/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java @@ -43,7 +43,15 @@ protected EncodingManager createEncodingManager() { @Override protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup, PMap pMap) { - Bike2WeightTagParser parser = new Bike2WeightTagParser(lookup, pMap); + Bike2WeightTagParser parser = new Bike2WeightTagParser(lookup, pMap) { + @Override + public IntsRef applyWayTags(ReaderWay way, IntsRef intsRef) { + if (!way.hasTag("point_list") || !way.hasTag("edge_distance")) + return intsRef; + else + return super.applyWayTags(way, intsRef); + } + }; parser.init(new DateRangeParser()); return parser; } @@ -75,7 +83,9 @@ public void testApplyWayTags() { Graph graph = initExampleGraph(); EdgeIteratorState edge = GHUtility.getEdge(graph, 0, 1); ReaderWay way = new ReaderWay(1); - parser.applyWayTags(way, edge); + way.setTag("point_list", edge.fetchWayGeometry(FetchMode.ALL)); + way.setTag("edge_distance", edge.getDistance()); + edge.setFlags(((Bike2WeightTagParser) parser).applyWayTags(way, edge.getFlags())); IntsRef flags = edge.getFlags(); // decrease speed @@ -91,7 +101,9 @@ public void testUnchangedForStepsBridgeAndTunnel() { IntsRef oldFlags = IntsRef.deepCopyOf(edge.getFlags()); ReaderWay way = new ReaderWay(1); way.setTag("highway", "steps"); - parser.applyWayTags(way, edge); + way.setTag("point_list", edge.fetchWayGeometry(FetchMode.ALL)); + way.setTag("edge_distance", edge.getDistance()); + edge.setFlags(((Bike2WeightTagParser) parser).applyWayTags(way, edge.getFlags())); assertEquals(oldFlags, edge.getFlags()); } diff --git a/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java b/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java index 2d6f0b6d552..7ad71cbbc3f 100644 --- a/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java @@ -130,27 +130,27 @@ public void testMixBikeTypesAndRelationCombination() { @Test public void testCompatibilityBug() { - EncodingManager manager2 = EncodingManager.create("bike2"); + EncodingManager manager2 = EncodingManager.create("mtb"); ReaderWay osmWay = new ReaderWay(1); osmWay.setTag("highway", "footway"); osmWay.setTag("name", "test"); - Bike2WeightTagParser parser = new Bike2WeightTagParser(manager2, new PMap()); + MountainBikeTagParser parser = new MountainBikeTagParser(manager2, new PMap()); parser.init(new DateRangeParser()); IntsRef flags = parser.handleWayTags(manager2.createEdgeFlags(), osmWay); double singleSpeed = parser.avgSpeedEnc.getDecimal(false, flags); assertEquals(BikeCommonTagParser.PUSHING_SECTION_SPEED, singleSpeed, 1e-3); assertEquals(singleSpeed, parser.avgSpeedEnc.getDecimal(true, flags), 1e-3); - EncodingManager manager = EncodingManager.create("bike2,bike,foot"); + EncodingManager manager = EncodingManager.create("mtb,bike,foot"); FootTagParser footParser = new FootTagParser(manager, new PMap()); footParser.init(new DateRangeParser()); - Bike2WeightTagParser bikeParser = new Bike2WeightTagParser(manager, new PMap()); + MountainBikeTagParser bikeParser = new MountainBikeTagParser(manager, new PMap()); bikeParser.init(new DateRangeParser()); flags = footParser.handleWayTags(manager.createEdgeFlags(), osmWay); flags = bikeParser.handleWayTags(flags, osmWay); - DecimalEncodedValue bikeSpeedEnc = manager.getDecimalEncodedValue(VehicleSpeed.key("bike2")); + DecimalEncodedValue bikeSpeedEnc = manager.getDecimalEncodedValue(VehicleSpeed.key("mtb")); assertEquals(singleSpeed, bikeSpeedEnc.getDecimal(false, flags), 1e-2); assertEquals(singleSpeed, bikeSpeedEnc.getDecimal(true, flags), 1e-2); diff --git a/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java index 9160b98ae93..e5a0e8231b3 100644 --- a/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/WheelchairTagParserTest.java @@ -54,7 +54,15 @@ public WheelchairTagParserTest() { .add(wheelchairAccessEnc).add(wheelchairAvSpeedEnc).add(wheelchairPriorityEnc).add(new EnumEncodedValue<>(FootNetwork.KEY, RouteNetwork.class)) .add(carAccessEnc).add(carAvSpeedEnc) .build(); - wheelchairParser = new WheelchairTagParser(encodingManager, new PMap()); + wheelchairParser = new WheelchairTagParser(encodingManager, new PMap()) { + @Override + public IntsRef applyWayTags(ReaderWay way, IntsRef edgeFlags) { + if (!way.hasTag("point_list") || !way.hasTag("edge_distance")) + return edgeFlags; + else + return super.applyWayTags(way, edgeFlags); + } + }; wheelchairParser.init(new DateRangeParser()); } @@ -527,7 +535,10 @@ public void testApplyWayTags() { GHUtility.setSpeed(5, 5, wheelchairAccessEnc, wheelchairAvSpeedEnc, edge45); - wheelchairParser.applyWayTags(new ReaderWay(1), edge01); + ReaderWay way1 = new ReaderWay(1); + way1.setTag("point_list", edge01.fetchWayGeometry(FetchMode.ALL)); + way1.setTag("edge_distance", edge01.getDistance()); + edge01.setFlags(wheelchairParser.applyWayTags(way1, edge01.getFlags())); assertTrue(edge01.get(wheelchairAccessEnc)); assertTrue(edge01.getReverse(wheelchairAccessEnc)); @@ -535,7 +546,10 @@ public void testApplyWayTags() { assertEquals(5, edge01.getReverse(wheelchairParser.getAverageSpeedEnc()), 0); - wheelchairParser.applyWayTags(new ReaderWay(2), edge23); + ReaderWay way2 = new ReaderWay(2); + way2.setTag("point_list", edge23.fetchWayGeometry(FetchMode.ALL)); + way2.setTag("edge_distance", edge23.getDistance()); + edge23.setFlags(wheelchairParser.applyWayTags(way2, edge23.getFlags())); assertTrue(edge23.get(wheelchairAccessEnc)); assertTrue(edge23.getReverse(wheelchairAccessEnc)); @@ -544,7 +558,10 @@ public void testApplyWayTags() { // only exclude longer edges with too large incline: - wheelchairParser.applyWayTags(new ReaderWay(3), edge45); + ReaderWay way3 = new ReaderWay(3); + way3.setTag("point_list", edge45.fetchWayGeometry(FetchMode.ALL)); + way3.setTag("edge_distance", edge45.getDistance()); + edge45.setFlags(wheelchairParser.applyWayTags(way3, edge45.getFlags())); assertFalse(edge45.get(wheelchairAccessEnc)); assertFalse(edge45.getReverse(wheelchairAccessEnc)); From 5b1c7b2dc33bc0b29ce4e5fba50e9de080fce59b Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 5 Oct 2022 17:21:28 +0200 Subject: [PATCH 199/389] remove Bike2WeightTagParser (#2668) * slope: percentage, not factor * initial commit * make test pass and ensure that with model is similar or even better (better avoids steep slopes) * config: remove hike from flag_encoders * deprecate graph.flag_encoders * clean up config-example.yml * Revert "config: remove hike from flag_encoders" This reverts commit 7edc9615298b9d6bbfc6842fa42139f560df6ade. * Update config-example.yml * Update DefaultVehicleEncodedValuesFactory.java * throw error if only one is enabled --- CHANGELOG.md | 4 +- config-example.yml | 7 + .../java/com/graphhopper/GraphHopper.java | 8 +- .../routing/util/Bike2WeightTagParser.java | 129 -------------- .../DefaultVehicleEncodedValuesFactory.java | 4 +- .../util/DefaultVehicleTagParserFactory.java | 2 - .../routing/util/SlopeCalculator.java | 19 +-- .../routing/util/VehicleEncodedValues.java | 2 +- .../util/VehicleEncodedValuesFactory.java | 1 - .../routing/RoutingAlgorithmWithOSMTest.java | 33 ++-- .../util/Bike2WeightTagParserTest.java | 160 ------------------ .../routing/util/TagParsingTest.java | 31 ---- custom_models/bike2.yml | 7 + .../resources => custom_models}/car4wd.yml | 0 custom_models/curvature.yml | 3 + 15 files changed, 60 insertions(+), 350 deletions(-) delete mode 100644 core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java delete mode 100644 core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java create mode 100644 custom_models/bike2.yml rename {web/src/test/resources/com/graphhopper/application/resources => custom_models}/car4wd.yml (100%) create mode 100644 custom_models/curvature.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 76a6ce6c239..b17f5faadb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ### 7.0 [not yet released] -- CurvatureWeighting was removed. Use a custom model with 'curvature' instead. (#2665) +- Bike2WeightTagParser was removed. Use the bike vehicle with a custom model, see custom_models/bike2.yml +- Car4WDTagParser was removed. Use the roads vehicle with a custom model, see custom_models/car4wd.yml +- CurvatureWeighting was removed. Use a custom model with 'curvature' instead, see custom_models/curvature.yml (#2665) - internal keys for EdgeKVStorage changed to contain the street_ prefix like the path details too. Similarly, the extra_info in the instructions of the API response, see #2661 ### 6.0 [13 Sep 2022] diff --git a/config-example.yml b/config-example.yml index ef0d605cf6c..5d1b5526a14 100644 --- a/config-example.yml +++ b/config-example.yml @@ -39,6 +39,13 @@ graphhopper: # turn_costs: true # u_turn_costs: 60 + # - name: bike + # vehicle: bike + # weighting: custom + # # the custom model in bike2.yml is defined to avoid hills + # custom_model_file: bike2.yml + custom_model_folder: custom_models + # Speed mode: # Its possible to speed up routing by doing a special graph preparation (Contraction Hierarchies, CH). This requires # more RAM/disk space for holding the prepared graph but also means less memory usage per request. Using the following diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index e1989f175f4..e1ec3a58933 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -654,8 +654,12 @@ private void buildEncodingManagerAndOSMParsers(String flagEncodersStr, String en osmParsers.addWayTagParser(new OSMMaxSpeedParser(encodingManager.getDecimalEncodedValue(MaxSpeed.KEY))); if (!encodedValueStrings.contains(RoadAccess.KEY)) osmParsers.addWayTagParser(new OSMRoadAccessParser(encodingManager.getEnumEncodedValue(RoadAccess.KEY, RoadAccess.class), OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR))); - if (encodingManager.hasEncodedValue(AverageSlope.KEY) || encodingManager.hasEncodedValue(MaxSlope.KEY)) - osmParsers.addWayTagParser(new SlopeCalculator(encodingManager.getDecimalEncodedValue(MaxSlope.KEY), encodingManager.getDecimalEncodedValue(AverageSlope.KEY))); + if (encodingManager.hasEncodedValue(AverageSlope.KEY) || encodingManager.hasEncodedValue(MaxSlope.KEY)) { + if (!encodingManager.hasEncodedValue(AverageSlope.KEY) || !encodingManager.hasEncodedValue(MaxSlope.KEY)) + throw new IllegalArgumentException("Enable both, average_slope and max_slope"); + osmParsers.addWayTagParser(new SlopeCalculator(encodingManager.getDecimalEncodedValue(MaxSlope.KEY), + encodingManager.getDecimalEncodedValue(AverageSlope.KEY))); + } if (encodingManager.hasEncodedValue(Curvature.KEY)) osmParsers.addWayTagParser(new CurvatureCalculator(encodingManager.getDecimalEncodedValue(Curvature.KEY))); diff --git a/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java b/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java deleted file mode 100644 index 25266d540d6..00000000000 --- a/core/src/main/java/com/graphhopper/routing/util/Bike2WeightTagParser.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.routing.util; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.routing.ev.*; -import com.graphhopper.storage.IntsRef; -import com.graphhopper.util.PMap; -import com.graphhopper.util.PointList; - -import static com.graphhopper.util.Helper.keepIn; - -/** - * Stores two speed values into an edge to support avoiding too much incline - * - * @author Peter Karich - */ -public class Bike2WeightTagParser extends BikeTagParser { - - public Bike2WeightTagParser(EncodedValueLookup lookup, PMap properties) { - this( - lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "bike2"))), - lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "bike2"))), - lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "bike2"))), - lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), - lookup.getBooleanEncodedValue(Roundabout.KEY), - lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class), - lookup.hasEncodedValue(TurnCost.key(properties.getString("name", "bike2"))) ? lookup.getDecimalEncodedValue(TurnCost.key(properties.getString("name", "bike2"))) : null, - properties - ); - } - - public Bike2WeightTagParser(BooleanEncodedValue accessEnc, DecimalEncodedValue speedEnc, - DecimalEncodedValue priorityEnc, EnumEncodedValue bikeRouteEnc, - BooleanEncodedValue roundaboutEnc, - EnumEncodedValue smoothnessEnc, DecimalEncodedValue turnCostEnc, PMap properties) { - super(accessEnc, speedEnc, priorityEnc, bikeRouteEnc, smoothnessEnc, properties.getString("name", "bike2"), - roundaboutEnc, turnCostEnc); - blockPrivate(properties.getBool("block_private", true)); - blockFords(properties.getBool("block_fords", false)); - } - - @Override - public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way) { - edgeFlags = super.handleWayTags(edgeFlags, way); - return applyWayTags(way, edgeFlags); - } - - public IntsRef applyWayTags(ReaderWay way, IntsRef intsRef) { - PointList pl = way.getTag("point_list", null); - if (pl == null) - throw new IllegalArgumentException("The artificial point_list tag is missing"); - if (!pl.is3D()) - throw new IllegalStateException(getName() + " requires elevation data to improve speed calculation based on it. Please enable it in config via e.g. graph.elevation.provider: srtm"); - - if (way.hasTag("tunnel", "yes") || way.hasTag("bridge", "yes") || way.hasTag("highway", "steps")) - // do not change speed - // note: although tunnel can have a difference in elevation it is very unlikely that the elevation data is correct for a tunnel - return intsRef; - - // Decrease the speed for ele increase (incline), and decrease the speed for ele decrease (decline). The speed-decrease - // has to be bigger (compared to the speed-increase) for the same elevation difference to simulate losing energy and avoiding hills. - // For the reverse speed this has to be the opposite but again keeping in mind that up+down difference. - double incEleSum = 0, incDist2DSum = 0, decEleSum = 0, decDist2DSum = 0; - // double prevLat = pl.getLat(0), prevLon = pl.getLon(0); - double prevEle = pl.getEle(0); - if (!way.hasTag("edge_distance")) - throw new IllegalArgumentException("The artificial edge_distance tag is missing"); - double fullDist2D = way.getTag("edge_distance", 0d); - - // for short edges an incline makes no sense and for 0 distances could lead to NaN values for speed, see #432 - if (fullDist2D < 2) - return intsRef; - - double eleDelta = pl.getEle(pl.size() - 1) - prevEle; - if (eleDelta > 0.1) { - incEleSum = eleDelta; - incDist2DSum = fullDist2D; - } else if (eleDelta < -0.1) { - decEleSum = -eleDelta; - decDist2DSum = fullDist2D; - } - - // Calculate slop via tan(asin(height/distance)) but for rather smallish angles where we can assume tan a=a and sin a=a. - // Then calculate a factor which decreases or increases the speed. - // Do this via a simple quadratic equation where y(0)=1 and y(0.3)=1/4 for incline and y(0.3)=2 for decline - double fwdIncline = incDist2DSum > 1 ? incEleSum / incDist2DSum : 0; - double fwdDecline = decDist2DSum > 1 ? decEleSum / decDist2DSum : 0; - double restDist2D = fullDist2D - incDist2DSum - decDist2DSum; - double maxSpeed = getHighwaySpeed("cycleway"); - if (accessEnc.getBool(false, intsRef)) { - // use weighted mean so that longer incline influences speed more than shorter - double speed = avgSpeedEnc.getDecimal(false, intsRef); - double fwdFaster = 1 + 2 * keepIn(fwdDecline, 0, 0.2); - fwdFaster = fwdFaster * fwdFaster; - double fwdSlower = 1 - 5 * keepIn(fwdIncline, 0, 0.2); - fwdSlower = fwdSlower * fwdSlower; - speed = speed * (fwdSlower * incDist2DSum + fwdFaster * decDist2DSum + 1 * restDist2D) / fullDist2D; - setSpeed(false, intsRef, keepIn(speed, MIN_SPEED, maxSpeed)); - } - - if (accessEnc.getBool(true, intsRef)) { - double speedReverse = avgSpeedEnc.getDecimal(true, intsRef); - double bwFaster = 1 + 2 * keepIn(fwdIncline, 0, 0.2); - bwFaster = bwFaster * bwFaster; - double bwSlower = 1 - 5 * keepIn(fwdDecline, 0, 0.2); - bwSlower = bwSlower * bwSlower; - speedReverse = speedReverse * (bwFaster * incDist2DSum + bwSlower * decDist2DSum + 1 * restDist2D) / fullDist2D; - setSpeed(true, intsRef, keepIn(speedReverse, MIN_SPEED, maxSpeed)); - } - return intsRef; - } - -} diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java index 069eab985b4..ddc9d15432c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java @@ -39,8 +39,8 @@ public VehicleEncodedValues createVehicleEncodedValues(String name, PMap configu if (name.equals(BIKE)) return VehicleEncodedValues.bike(configuration); - if (name.equals(BIKE2)) - return VehicleEncodedValues.bike2(configuration); + if (name.equals("bike2")) + throw new IllegalArgumentException("Instead of bike2 use the bike vehicle and a custom model, see custom_models/bike2.yml and #1234"); if (name.equals(RACINGBIKE)) return VehicleEncodedValues.racingbike(configuration); diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java index a7109eedf16..ba49f702642 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleTagParserFactory.java @@ -31,8 +31,6 @@ public VehicleTagParser createParser(EncodedValueLookup lookup, String name, PMa return new CarTagParser(lookup, configuration); if (name.equals(BIKE)) return new BikeTagParser(lookup, configuration); - if (name.equals(BIKE2)) - return new Bike2WeightTagParser(lookup, configuration); if (name.equals(RACINGBIKE)) return new RacingBikeTagParser(lookup, configuration); if (name.equals(MOUNTAINBIKE)) diff --git a/core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java b/core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java index 5bc9bb9591c..628a1d1dbe8 100644 --- a/core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java +++ b/core/src/main/java/com/graphhopper/routing/util/SlopeCalculator.java @@ -23,7 +23,7 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationF PointList pointList = way.getTag("point_list", null); if (pointList != null) { if (pointList.isEmpty() || !pointList.is3D()) { - if (averageSlopeEnc != null) averageSlopeEnc.setDecimal(false, edgeFlags, 0); + averageSlopeEnc.setDecimal(false, edgeFlags, 0); return edgeFlags; } // Calculate 2d distance, although pointList might be 3D. @@ -32,7 +32,7 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationF if (distance2D < MIN_LENGTH) { // default is minimum of average_slope is negative so we have to explicitly set it to 0 - if (averageSlopeEnc != null) averageSlopeEnc.setDecimal(false, edgeFlags, 0); + averageSlopeEnc.setDecimal(false, edgeFlags, 0); return edgeFlags; } @@ -40,12 +40,12 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationF if (Double.isNaN(towerNodeSlope)) throw new IllegalArgumentException("average_slope was NaN for OSM way ID " + way.getId()); - if (averageSlopeEnc != null) { - if (towerNodeSlope >= 0) - averageSlopeEnc.setDecimal(false, edgeFlags, Math.min(towerNodeSlope, averageSlopeEnc.getMaxStorableDecimal())); - else - averageSlopeEnc.setDecimal(true, edgeFlags, Math.min(Math.abs(towerNodeSlope), averageSlopeEnc.getMaxStorableDecimal())); - } + + if (towerNodeSlope >= 0) + averageSlopeEnc.setDecimal(false, edgeFlags, Math.min(towerNodeSlope, averageSlopeEnc.getMaxStorableDecimal())); + else + averageSlopeEnc.setDecimal(true, edgeFlags, Math.min(Math.abs(towerNodeSlope), averageSlopeEnc.getMaxStorableDecimal())); + // max_slope is more error-prone as the shorter distances increase the fluctuation // so apply some more filtering (here we use the average elevation delta of the previous two points) @@ -74,8 +74,7 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationF // TODO Use two independent values for both directions to store if it is a gain or loss and not just the absolute change. // TODO To save space then it would be nice to have an encoded value that can store two different values which are swapped when the reverse direction is used - if (maxSlopeEnc != null) - maxSlopeEnc.setDecimal(false, edgeFlags, Math.min(maxSlope, maxSlopeEnc.getMaxStorableDecimal())); + maxSlopeEnc.setDecimal(false, edgeFlags, Math.min(maxSlope, maxSlopeEnc.getMaxStorableDecimal())); } return edgeFlags; } diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java index 2dcf0c2167a..3a1262fb7d6 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValues.java @@ -27,7 +27,7 @@ import static com.graphhopper.routing.util.VehicleEncodedValuesFactory.*; public class VehicleEncodedValues { - public static final List OUTDOOR_VEHICLES = Arrays.asList(BIKE, BIKE2, RACINGBIKE, MOUNTAINBIKE, FOOT, HIKE, WHEELCHAIR); + public static final List OUTDOOR_VEHICLES = Arrays.asList(BIKE, RACINGBIKE, MOUNTAINBIKE, FOOT, HIKE, WHEELCHAIR); private final String name; private final BooleanEncodedValue accessEnc; diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java index 263644e6911..85780abd813 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleEncodedValuesFactory.java @@ -26,7 +26,6 @@ public interface VehicleEncodedValuesFactory { String ROADS = "roads"; String CAR = "car"; String BIKE = "bike"; - String BIKE2 = "bike2"; String RACINGBIKE = "racingbike"; String MOUNTAINBIKE = "mtb"; String FOOT = "foot"; diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java index d09d1a25c87..8c3dbb5f6c2 100644 --- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java +++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMTest.java @@ -41,6 +41,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; +import static com.graphhopper.json.Statement.Op.LIMIT; +import static com.graphhopper.json.Statement.Op.MULTIPLY; import static com.graphhopper.util.Parameters.Algorithms.*; import static org.junit.jupiter.api.Assertions.*; @@ -128,7 +130,7 @@ public void testMonacoMotorcycleCurvature() { queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 2423, 141)); queries.add(new Query(43.730949, 7.412338, 43.739643, 7.424542, 2253, 120)); queries.add(new Query(43.727592, 7.419333, 43.727712, 7.419333, 0, 1)); - CustomModel model = new CustomModel().addToPriority(Statement.If("true", Statement.Op.MULTIPLY, "curvature")); + CustomModel model = new CustomModel().addToPriority(Statement.If("true", MULTIPLY, "curvature")); GraphHopper hopper = createHopper(MONACO, new CustomProfile("motorcycle").setCustomModel(model). setVehicle("motorcycle").setWeighting("custom")); @@ -144,8 +146,9 @@ public void testBike2_issue432() { queries.add(new Query(52.349969, 8.013813, 52.349713, 8.013293, 56, 7)); // reverse route avoids the location // list.add(new OneRun(52.349713, 8.013293, 52.349969, 8.013813, 293, 21)); + CustomModel model = new CustomModel(); GraphHopper hopper = createHopper(DIR + "/map-bug432.osm.gz", - new Profile("bike2").setVehicle("bike2").setWeighting("fastest")); + new CustomProfile("bike2").setCustomModel(model).setVehicle("bike").setWeighting("custom")); hopper.setElevationProvider(new SRTMProvider(DIR)); hopper.importOrLoad(); checkQueries(hopper, queries); @@ -322,25 +325,31 @@ public void testNorthBayreuthHikeFastestAnd3D() { } @Test - public void testMonacoBike3D_twoSpeedsPerEdge() { + public void testMonacoBike3D() { List queries = new ArrayList<>(); // 1. alternative: go over steps 'Rampe Major' => 1.7km vs. around 2.7km - queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 2689, 118)); + queries.add(new Query(43.730864, 7.420771, 43.727687, 7.418737, 1999, 101)); // 2. - queries.add(new Query(43.728499, 7.417907, 43.74958, 7.436566, 3735, 194)); + queries.add(new Query(43.728499, 7.417907, 43.74958, 7.436566, 3939, 187)); // 3. - queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2776, 167)); + queries.add(new Query(43.728677, 7.41016, 43.739213, 7.427806, 2776, 163)); // 4. queries.add(new Query(43.733802, 7.413433, 43.739662, 7.424355, 1544, 84)); // try reverse direction // 1. queries.add(new Query(43.727687, 7.418737, 43.730864, 7.420771, 2599, 115)); - queries.add(new Query(43.74958, 7.436566, 43.728499, 7.417907, 4180, 165)); - queries.add(new Query(43.739213, 7.427806, 43.728677, 7.41016, 2805, 145)); + queries.add(new Query(43.74958, 7.436566, 43.728499, 7.417907, 3902, 199)); + queries.add(new Query(43.739213, 7.427806, 43.728677, 7.41016, 2870, 154)); // 4. avoid tunnel(s)! - queries.add(new Query(43.739662, 7.424355, 43.733802, 7.413433, 2436, 112)); - GraphHopper hopper = createHopper(MONACO, new Profile("bike2").setVehicle("bike2").setWeighting("fastest")); + queries.add(new Query(43.739662, 7.424355, 43.733802, 7.413433, 1795, 96)); + CustomModel model = new CustomModel(); + model.addToSpeed(Statement.If("average_slope >= 10", LIMIT, "4")). + addToSpeed(Statement.If("average_slope >= 5", MULTIPLY, "0.45")). + addToSpeed(Statement.If("average_slope >= 3.5", MULTIPLY, "0.7")). + addToSpeed(Statement.If("average_slope >= 2", MULTIPLY, "0.9")). + addToSpeed(Statement.If("average_slope < -5", MULTIPLY, "1.25")); + GraphHopper hopper = createHopper(MONACO, new CustomProfile("bike2").setCustomModel(model).setVehicle("bike").setWeighting("custom")); hopper.setElevationProvider(new SRTMProvider(DIR)); hopper.importOrLoad(); checkQueries(hopper, queries); @@ -571,7 +580,8 @@ public void testNeudrossenfeld() { Helper.removeDir(new File(GH_LOCATION)); - hopper = createHopper(BAYREUTH, new Profile("bike2").setVehicle("bike2").setWeighting("fastest")); + CustomModel model = new CustomModel(); + hopper = createHopper(BAYREUTH, new CustomProfile("bike2").setCustomModel(model).setVehicle("bike").setWeighting("custom")); hopper.setElevationProvider(new SRTMProvider(DIR)); hopper.importOrLoad(); checkQueries(hopper, list); @@ -686,6 +696,7 @@ private GraphHopper createHopper(String osmFile, Profile... profiles) { setStoreOnFlush(true). setOSMFile(osmFile). setProfiles(profiles). + setEncodedValuesString("average_slope,max_slope"). setGraphHopperLocation(GH_LOCATION); hopper.getRouterConfig().setSimplifyResponse(false); hopper.setMinNetworkSize(0); diff --git a/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java b/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java deleted file mode 100644 index 63a147859c5..00000000000 --- a/core/src/test/java/com/graphhopper/routing/util/Bike2WeightTagParserTest.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.routing.util; - -import com.graphhopper.reader.ReaderWay; -import com.graphhopper.reader.osm.conditional.DateRangeParser; -import com.graphhopper.routing.ev.*; -import com.graphhopper.routing.util.parsers.OSMBikeNetworkTagParser; -import com.graphhopper.routing.util.parsers.OSMSmoothnessParser; -import com.graphhopper.storage.BaseGraph; -import com.graphhopper.storage.Graph; -import com.graphhopper.storage.IntsRef; -import com.graphhopper.storage.NodeAccess; -import com.graphhopper.util.*; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * @author Peter Karich - */ -public class Bike2WeightTagParserTest extends BikeTagParserTest { - - @Override - protected EncodingManager createEncodingManager() { - return EncodingManager.create("bike2"); - } - - @Override - protected BikeCommonTagParser createBikeTagParser(EncodedValueLookup lookup, PMap pMap) { - Bike2WeightTagParser parser = new Bike2WeightTagParser(lookup, pMap) { - @Override - public IntsRef applyWayTags(ReaderWay way, IntsRef intsRef) { - if (!way.hasTag("point_list") || !way.hasTag("edge_distance")) - return intsRef; - else - return super.applyWayTags(way, intsRef); - } - }; - parser.init(new DateRangeParser()); - return parser; - } - - @Override - protected OSMParsers createOSMParsers(BikeCommonTagParser parser, EncodedValueLookup lookup) { - return new OSMParsers() - .addRelationTagParser(relConfig -> new OSMBikeNetworkTagParser(lookup.getEnumEncodedValue(BikeNetwork.KEY, RouteNetwork.class), relConfig)) - .addWayTagParser(new OSMSmoothnessParser(lookup.getEnumEncodedValue(Smoothness.KEY, Smoothness.class))) - .addVehicleTagParser(parser); - } - - private Graph initExampleGraph() { - BaseGraph gs = new BaseGraph.Builder(encodingManager).set3D(true).create(); - NodeAccess na = gs.getNodeAccess(); - // 50--(0.0001)-->49--(0.0004)-->55--(0.0005)-->60 - na.setNode(0, 51.1, 12.001, 50); - na.setNode(1, 51.1, 12.002, 60); - EdgeIteratorState edge = gs.edge(0, 1). - setDistance(100). - setWayGeometry(Helper.createPointList3D(51.1, 12.0011, 49, 51.1, 12.0015, 55)); - edge.set(avgSpeedEnc, 10, 15); - edge.set(parser.getAccessEnc(), true, true); - return gs; - } - - @Test - public void testApplyWayTags() { - Graph graph = initExampleGraph(); - EdgeIteratorState edge = GHUtility.getEdge(graph, 0, 1); - ReaderWay way = new ReaderWay(1); - way.setTag("point_list", edge.fetchWayGeometry(FetchMode.ALL)); - way.setTag("edge_distance", edge.getDistance()); - edge.setFlags(((Bike2WeightTagParser) parser).applyWayTags(way, edge.getFlags())); - - IntsRef flags = edge.getFlags(); - // decrease speed - assertEquals(2, avgSpeedEnc.getDecimal(false, flags), 1e-1); - // increase speed but use maximum speed (calculated was 24) - assertEquals(18, avgSpeedEnc.getDecimal(true, flags), 1e-1); - } - - @Test - public void testUnchangedForStepsBridgeAndTunnel() { - Graph graph = initExampleGraph(); - EdgeIteratorState edge = GHUtility.getEdge(graph, 0, 1); - IntsRef oldFlags = IntsRef.deepCopyOf(edge.getFlags()); - ReaderWay way = new ReaderWay(1); - way.setTag("highway", "steps"); - way.setTag("point_list", edge.fetchWayGeometry(FetchMode.ALL)); - way.setTag("edge_distance", edge.getDistance()); - edge.setFlags(((Bike2WeightTagParser) parser).applyWayTags(way, edge.getFlags())); - - assertEquals(oldFlags, edge.getFlags()); - } - - @Test - public void testSetSpeed0_issue367() { - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - avgSpeedEnc.setDecimal(false, edgeFlags, 10); - avgSpeedEnc.setDecimal(true, edgeFlags, 10); - parser.getAccessEnc().setBool(false, edgeFlags, true); - parser.getAccessEnc().setBool(true, edgeFlags, true); - - parser.setSpeed(false, edgeFlags, 0); - - assertEquals(0, avgSpeedEnc.getDecimal(false, edgeFlags), .1); - assertEquals(10, avgSpeedEnc.getDecimal(true, edgeFlags), .1); - assertFalse(parser.getAccessEnc().getBool(false, edgeFlags)); - assertTrue(parser.getAccessEnc().getBool(true, edgeFlags)); - } - - @Test - public void testRoutingFailsWithInvalidGraph_issue665() { - BaseGraph graph = new BaseGraph.Builder(encodingManager).set3D(true).create(); - ReaderWay way = new ReaderWay(0); - way.setTag("route", "ferry"); - way.setTag("edge_distance", 500.0); - - assertNotEquals(WayAccess.CAN_SKIP, parser.getAccess(way)); - IntsRef edgeFlags = encodingManager.createEdgeFlags(); - edgeFlags = osmParsers.handleWayTags(edgeFlags, way, encodingManager.createRelationFlags()); - graph.edge(0, 1).setDistance(247).setFlags(edgeFlags); - - assertTrue(isGraphValid(graph, parser.getAccessEnc())); - } - - private boolean isGraphValid(Graph graph, BooleanEncodedValue accessEnc) { - EdgeExplorer explorer = graph.createEdgeExplorer(); - // iterator at node 0 considers the edge 0-1 to be undirected - EdgeIterator iter0 = explorer.setBaseNode(0); - iter0.next(); - boolean iter0flag - = iter0.getBaseNode() == 0 && iter0.getAdjNode() == 1 - && iter0.get(accessEnc) && iter0.getReverse(accessEnc); - - // iterator at node 1 considers the edge 1-0 to be directed - EdgeIterator iter1 = explorer.setBaseNode(1); - iter1.next(); - boolean iter1flag - = iter1.getBaseNode() == 1 && iter1.getAdjNode() == 0 - && iter1.get(accessEnc) && iter1.getReverse(accessEnc); - - return iter0flag && iter1flag; - } -} diff --git a/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java b/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java index 7ad71cbbc3f..c6b7b887897 100644 --- a/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/TagParsingTest.java @@ -128,37 +128,6 @@ public void testMixBikeTypesAndRelationCombination() { assertTrue(bikePriorityEnc.getDecimal(false, edgeFlags) > mtbPriorityEnc.getDecimal(false, edgeFlags)); } - @Test - public void testCompatibilityBug() { - EncodingManager manager2 = EncodingManager.create("mtb"); - ReaderWay osmWay = new ReaderWay(1); - osmWay.setTag("highway", "footway"); - osmWay.setTag("name", "test"); - - MountainBikeTagParser parser = new MountainBikeTagParser(manager2, new PMap()); - parser.init(new DateRangeParser()); - IntsRef flags = parser.handleWayTags(manager2.createEdgeFlags(), osmWay); - double singleSpeed = parser.avgSpeedEnc.getDecimal(false, flags); - assertEquals(BikeCommonTagParser.PUSHING_SECTION_SPEED, singleSpeed, 1e-3); - assertEquals(singleSpeed, parser.avgSpeedEnc.getDecimal(true, flags), 1e-3); - - EncodingManager manager = EncodingManager.create("mtb,bike,foot"); - FootTagParser footParser = new FootTagParser(manager, new PMap()); - footParser.init(new DateRangeParser()); - MountainBikeTagParser bikeParser = new MountainBikeTagParser(manager, new PMap()); - bikeParser.init(new DateRangeParser()); - - flags = footParser.handleWayTags(manager.createEdgeFlags(), osmWay); - flags = bikeParser.handleWayTags(flags, osmWay); - DecimalEncodedValue bikeSpeedEnc = manager.getDecimalEncodedValue(VehicleSpeed.key("mtb")); - assertEquals(singleSpeed, bikeSpeedEnc.getDecimal(false, flags), 1e-2); - assertEquals(singleSpeed, bikeSpeedEnc.getDecimal(true, flags), 1e-2); - - DecimalEncodedValue footSpeedEnc = manager.getDecimalEncodedValue(VehicleSpeed.key("foot")); - assertEquals(5, footSpeedEnc.getDecimal(false, flags), 1e-2); - assertEquals(5, footSpeedEnc.getDecimal(true, flags), 1e-2); - } - @Test public void testSharedEncodedValues() { BooleanEncodedValue carAccessEnc = VehicleAccess.create("car"); diff --git a/custom_models/bike2.yml b/custom_models/bike2.yml new file mode 100644 index 00000000000..d46a4105685 --- /dev/null +++ b/custom_models/bike2.yml @@ -0,0 +1,7 @@ +distance_influence: 10 +speed: + - if: "average_slope >= 10", limit_to: "4" + - if: "average_slope >= 5", "multiply_by": "0.45" + - if: "average_slope >= 3.5", multiply_by: "0.7" + - if: "average_slope >= 2", multiply_by: "0.9" + - if: "average_slope < -5", multiply_by: "1.25" diff --git a/web/src/test/resources/com/graphhopper/application/resources/car4wd.yml b/custom_models/car4wd.yml similarity index 100% rename from web/src/test/resources/com/graphhopper/application/resources/car4wd.yml rename to custom_models/car4wd.yml diff --git a/custom_models/curvature.yml b/custom_models/curvature.yml new file mode 100644 index 00000000000..565a24bbe70 --- /dev/null +++ b/custom_models/curvature.yml @@ -0,0 +1,3 @@ +priority: + - if: "curvature > 0.9" + multiply_by: "0.3" \ No newline at end of file From b907cdfb8b7248f276e5342515d9d08dfd8e0acf Mon Sep 17 00:00:00 2001 From: Michael Zilske Date: Mon, 26 Sep 2022 15:47:10 -0700 Subject: [PATCH 200/389] units --- .../graphhopper/resources/MapMatchingResource.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java index 75fee9bd22f..70210e47741 100644 --- a/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java +++ b/web-bundle/src/main/java/com/graphhopper/resources/MapMatchingResource.java @@ -130,16 +130,16 @@ public Response match( List measurements = GpxConversions.getEntries(gpx.trk.get(0)); MatchResult matchResult = matching.match(measurements); - double took = sw.stop().getMillisDouble(); + sw.stop(); logger.info(objectMapper.createObjectNode() - .put("duration", took) + .put("duration", sw.getNanos()) .put("profile", profile) .put("observations", measurements.size()) .putPOJO("mapmatching", matching.getStatistics()).toString()); if ("extended_json".equals(outType)) { return Response.ok(convertToTree(matchResult, enableElevation, pointsEncoded)). - header("X-GH-Took", "" + Math.round(took)). + header("X-GH-Took", "" + Math.round(sw.getMillisDouble())). build(); } else { Translation tr = trMap.getWithFallBack(Helper.getLocale(localeStr)); @@ -163,10 +163,10 @@ public Response match( .map(Date::getTime) .orElse(System.currentTimeMillis()); return Response.ok(GpxConversions.createGPX(rsp.getBest().getInstructions(), gpx.trk.get(0).name != null ? gpx.trk.get(0).name : "", time, enableElevation, withRoute, withTrack, false, Constants.VERSION, tr), "application/gpx+xml"). - header("X-GH-Took", "" + Math.round(took)). + header("X-GH-Took", "" + Math.round(sw.getMillisDouble())). build(); } else { - ObjectNode map = ResponsePathSerializer.jsonObject(rsp, instructions, calcPoints, enableElevation, pointsEncoded, took); + ObjectNode map = ResponsePathSerializer.jsonObject(rsp, instructions, calcPoints, enableElevation, pointsEncoded, sw.getMillisDouble()); Map matchStatistics = new HashMap<>(); matchStatistics.put("distance", matchResult.getMatchLength()); @@ -184,7 +184,7 @@ public Response match( map.putPOJO("traversal_keys", traversalKeylist); } return Response.ok(map). - header("X-GH-Took", "" + Math.round(took)). + header("X-GH-Took", "" + Math.round(sw.getMillisDouble())). build(); } } From f1fd1d1de2be77bedcf51329d4247a5392d58387 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 5 Oct 2022 21:53:47 +0200 Subject: [PATCH 201/389] Update custom-models.md --- docs/core/custom-models.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/core/custom-models.md b/docs/core/custom-models.md index a931ee30260..d1d088152e6 100644 --- a/docs/core/custom-models.md +++ b/docs/core/custom-models.md @@ -4,6 +4,8 @@ GraphHopper provides an easy-to-use way to customize its route calculations: Cus default routing behavior by specifying a set of rules in JSON language. Here we will first explain some theoretical background and then show how to use custom models in practice. +Try some live examples in [this blog post](https://www.graphhopper.com/blog/2020/05/31/examples-for-customizable-routing/). + ## How GraphHopper's route calculations work One of GraphHopper's most important functionality is the calculation of the 'optimal' route between two locations. To do From 92f64809e10764307a71a3b0f1a01a523257b702 Mon Sep 17 00:00:00 2001 From: easbar Date: Thu, 6 Oct 2022 06:33:27 +0200 Subject: [PATCH 202/389] Simplify graph.flag_encoders/vehicles check * sorry, I could not resist... --- core/src/main/java/com/graphhopper/GraphHopper.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java index e1ec3a58933..53380482324 100644 --- a/core/src/main/java/com/graphhopper/GraphHopper.java +++ b/core/src/main/java/com/graphhopper/GraphHopper.java @@ -531,14 +531,12 @@ public GraphHopper init(GraphHopperConfig ghConfig) { throw new IllegalArgumentException("spatial_rules.max_bbox has been deprecated. There is no replacement, all custom areas will be considered."); setProfiles(ghConfig.getProfiles()); - vehiclesString = ghConfig.getString("graph.vehicles", vehiclesString); - if (vehiclesString.isEmpty()) { - vehiclesString = ghConfig.getString("graph.flag_encoders", vehiclesString); - if (!vehiclesString.isEmpty()) - logger.warn("The option graph.flag_encoders is deprecated and will be removed. Replace with graph.vehicles"); - } else if (!ghConfig.getString("graph.flag_encoders", "").isEmpty()) { + + if (ghConfig.has("graph.vehicles") && ghConfig.has("graph.flag_encoders")) throw new IllegalArgumentException("Remove graph.flag_encoders as it cannot be used in parallel with graph.vehicles"); - } + if (ghConfig.has("graph.flag_encoders")) + logger.warn("The option graph.flag_encoders is deprecated and will be removed. Replace with graph.vehicles"); + vehiclesString = ghConfig.getString("graph.vehicles", ghConfig.getString("graph.flag_encoders", vehiclesString)); encodedValuesString = ghConfig.getString("graph.encoded_values", encodedValuesString); dateRangeParserString = ghConfig.getString("datareader.date_range_parser_day", dateRangeParserString); From fc86257123e9b85c1600f13ce703525223c21a79 Mon Sep 17 00:00:00 2001 From: Robin Date: Fri, 7 Oct 2022 11:36:31 +0200 Subject: [PATCH 203/389] Provide all intersections with additional information along a route via PathDetails (#2590) * Calculate IntersectionDetails * Add license header * Remove location array from PathDetails * Rename entry to entries in the GraphHopper PathDetails * Remove special handling for the first intersection * Handle deserializing maps in PathDetail value * Fix wayGeo.size() typo * Use FetchMode.PILLAR_AND_ADJ * Move PathDetailDeserialization * Use JsonParser --- .../java/com/graphhopper/util/PathMerger.java | 2 +- .../util/details/AverageSpeedDetails.java | 17 ++ .../util/details/IntersectionDetails.java | 154 ++++++++++++++++++ .../details/PathDetailsBuilderFactory.java | 6 +- .../util/details/PathDetailsFromEdges.java | 6 +- .../com/graphhopper/routing/PathTest.java | 47 +++++- .../util/PathSimplificationTest.java | 2 +- .../navigation/NavigateResource.java | 3 + .../navigation/NavigateResponseConverter.java | 83 ++++++++-- .../NavigateResponseConverterTest.java | 34 +++- .../com/graphhopper/gtfs/TripFromLabel.java | 2 +- .../jackson/PathDetailDeserializer.java | 7 +- .../jackson/PathDetailSerializer.java | 3 + .../java/com/graphhopper/util/Parameters.java | 1 + .../resources/RouteResourceClientHCTest.java | 11 +- 15 files changed, 338 insertions(+), 40 deletions(-) create mode 100644 core/src/main/java/com/graphhopper/util/details/IntersectionDetails.java diff --git a/core/src/main/java/com/graphhopper/util/PathMerger.java b/core/src/main/java/com/graphhopper/util/PathMerger.java index 662a759bd9f..bfb91e1fa88 100644 --- a/core/src/main/java/com/graphhopper/util/PathMerger.java +++ b/core/src/main/java/com/graphhopper/util/PathMerger.java @@ -135,7 +135,7 @@ public ResponsePath doWork(PointList waypoints, List paths, EncodedValueLo } fullPoints.add(tmpPoints); - responsePath.addPathDetails(PathDetailsFromEdges.calcDetails(path, evLookup, weighting, requestedPathDetails, pathBuilderFactory, origPoints)); + responsePath.addPathDetails(PathDetailsFromEdges.calcDetails(path, evLookup, weighting, requestedPathDetails, pathBuilderFactory, origPoints, graph)); origPoints = fullPoints.size(); } diff --git a/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java b/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java index 24631412f0f..32a56e9c72b 100644 --- a/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java +++ b/core/src/main/java/com/graphhopper/util/details/AverageSpeedDetails.java @@ -1,3 +1,20 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ package com.graphhopper.util.details; import com.graphhopper.routing.weighting.Weighting; diff --git a/core/src/main/java/com/graphhopper/util/details/IntersectionDetails.java b/core/src/main/java/com/graphhopper/util/details/IntersectionDetails.java new file mode 100644 index 00000000000..71b9310e9e3 --- /dev/null +++ b/core/src/main/java/com/graphhopper/util/details/IntersectionDetails.java @@ -0,0 +1,154 @@ +/* + * Licensed to GraphHopper GmbH under one or more contributor + * license agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + * + * GraphHopper GmbH licenses this file to you 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. + */ +package com.graphhopper.util.details; + +import com.graphhopper.routing.querygraph.VirtualEdgeIteratorState; +import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.storage.Graph; +import com.graphhopper.storage.NodeAccess; +import com.graphhopper.util.*; +import com.graphhopper.util.shapes.GHPoint; + +import java.util.*; + +import static com.graphhopper.util.Parameters.Details.INTERSECTION; + +/** + * Calculate the intersections for a route. Every change of the edge id is considered an intersection. + *

    + * The format is inspired by the format that is consumed by Maplibre Navigation SDK. + *

    + * Explanation of the format: + * - entries contain an array of the edges at that intersection. They are sorted by bearing, starting from 0 (which is 0° north) to 359. Every edge that we can turn onto is marked with “true” in the array. + * - bearings contain an array of the edges at that intersection. They are sorted by bearing, starting from 0 (which is 0° north) to 359. The array contains the bearings of each edge at that intersection. + * - in marks the index in the “bearings” edge we are coming from. + * - out the index we are going to. + * + * @author Robin Boldt + */ +public class IntersectionDetails extends AbstractPathDetailsBuilder { + + private int fromEdge = -1; + + private Map intersectionMap = new HashMap<>(); + + private final EdgeExplorer crossingExplorer; + private final NodeAccess nodeAccess; + private final Weighting weighting; + + public IntersectionDetails(Graph graph, Weighting weighting) { + super(INTERSECTION); + + crossingExplorer = graph.createEdgeExplorer(); + nodeAccess = graph.getNodeAccess(); + this.weighting = weighting; + } + + @Override + public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) { + int toEdge = edgeId(edge); + if (toEdge != fromEdge) { + // Important to create a new map and not to clean the old map! + intersectionMap = new HashMap<>(); + + List intersectingEdges = new ArrayList<>(); + + int baseNode = edge.getBaseNode(); + EdgeIteratorState tmpEdge; + + double startLat = nodeAccess.getLat(baseNode); + double startLon = nodeAccess.getLon(baseNode); + + + EdgeIterator edgeIter = crossingExplorer.setBaseNode(baseNode); + while (edgeIter.next()) { + // We need to call detach to get the edgeId, as we need to check for VirtualEdgeIteratorState in #edgeId(), see discussion in #2590 + tmpEdge = edgeIter.detach(false); + + IntersectionValues intersectionValues = new IntersectionValues(); + intersectionValues.bearing = calculateBearing(startLat, startLon, tmpEdge); + intersectionValues.in = edgeId(tmpEdge) == fromEdge; + intersectionValues.out = edgeId(tmpEdge) == edgeId(edge); + // The in edge is always false, this means that u-turns are not considered as possible turning option + intersectionValues.entry = !intersectionValues.in && Double.isFinite(weighting.calcEdgeWeightWithAccess(tmpEdge, false)); + + intersectingEdges.add(intersectionValues); + } + + intersectingEdges.sort(null); + + List bearings = new ArrayList<>(intersectingEdges.size()); + List entries = new ArrayList<>(intersectingEdges.size()); + + for (int i = 0; i < intersectingEdges.size(); i++) { + IntersectionValues intersectionValues = intersectingEdges.get(i); + bearings.add(intersectionValues.bearing); + entries.add(intersectionValues.entry); + if (intersectionValues.in) { + intersectionMap.put("in", i); + } + if (intersectionValues.out) { + intersectionMap.put("out", i); + } + } + + intersectionMap.put("bearings", bearings); + intersectionMap.put("entries", entries); + + fromEdge = toEdge; + return true; + } + return false; + } + + private int calculateBearing(double startLat, double startLon, EdgeIteratorState tmpEdge) { + PointList wayGeo = tmpEdge.fetchWayGeometry(FetchMode.PILLAR_AND_ADJ); + final double latitude = wayGeo.getLat(0); + final double longitude = wayGeo.getLon(0); + return (int) Math.round(AngleCalc.ANGLE_CALC.calcAzimuth(startLat, startLon, latitude, longitude)); + } + + private int edgeId(EdgeIteratorState edge) { + if (edge instanceof VirtualEdgeIteratorState) { + return GHUtility.getEdgeFromEdgeKey(((VirtualEdgeIteratorState) edge).getOriginalEdgeKey()); + } else { + return edge.getEdge(); + } + } + + @Override + public Object getCurrentValue() { + return this.intersectionMap; + } + + private class IntersectionValues implements Comparable { + + public int bearing; + public boolean entry; + public boolean in; + public boolean out; + + @Override + public int compareTo(Object o) { + if (o instanceof IntersectionValues) { + return Integer.compare(this.bearing, ((IntersectionValues) o).bearing); + } + return 0; + } + } +} \ No newline at end of file diff --git a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java index 46d28a5e296..80f4ba96967 100644 --- a/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java +++ b/core/src/main/java/com/graphhopper/util/details/PathDetailsBuilderFactory.java @@ -19,6 +19,7 @@ import com.graphhopper.routing.ev.*; import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.storage.Graph; import java.util.ArrayList; import java.util.List; @@ -32,7 +33,7 @@ */ public class PathDetailsBuilderFactory { - public List createPathDetailsBuilders(List requestedPathDetails, EncodedValueLookup evl, Weighting weighting) { + public List createPathDetailsBuilders(List requestedPathDetails, EncodedValueLookup evl, Weighting weighting, Graph graph) { List builders = new ArrayList<>(); if (requestedPathDetails.contains(STREET_NAME)) @@ -60,6 +61,9 @@ public List createPathDetailsBuilders(List requested if (requestedPathDetails.contains(DISTANCE)) builders.add(new DistanceDetails()); + if (requestedPathDetails.contains(INTERSECTION)) + builders.add(new IntersectionDetails(graph, weighting)); + for (String pathDetail : requestedPathDetails) { if (!evl.hasEncodedValue(pathDetail)) continue; // path details like "time" won't be found diff --git a/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java b/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java index 2e8328dff27..3a28ded8205 100644 --- a/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java +++ b/core/src/main/java/com/graphhopper/util/details/PathDetailsFromEdges.java @@ -20,6 +20,7 @@ import com.graphhopper.routing.Path; import com.graphhopper.routing.ev.EncodedValueLookup; import com.graphhopper.routing.weighting.Weighting; +import com.graphhopper.storage.Graph; import com.graphhopper.util.EdgeIteratorState; import com.graphhopper.util.FetchMode; @@ -57,10 +58,11 @@ public PathDetailsFromEdges(List calculators, int previousIn * @return List of PathDetails for this Path */ public static Map> calcDetails(Path path, EncodedValueLookup evLookup, Weighting weighting, - List requestedPathDetails, PathDetailsBuilderFactory pathBuilderFactory, int previousIndex) { + List requestedPathDetails, PathDetailsBuilderFactory pathBuilderFactory, + int previousIndex, Graph graph) { if (!path.isFound() || requestedPathDetails.isEmpty()) return Collections.emptyMap(); - List pathBuilders = pathBuilderFactory.createPathDetailsBuilders(requestedPathDetails, evLookup, weighting); + List pathBuilders = pathBuilderFactory.createPathDetailsBuilders(requestedPathDetails, evLookup, weighting, graph); if (pathBuilders.isEmpty()) return Collections.emptyMap(); diff --git a/core/src/test/java/com/graphhopper/routing/PathTest.java b/core/src/test/java/com/graphhopper/routing/PathTest.java index 8220a204f72..af9a9c36249 100644 --- a/core/src/test/java/com/graphhopper/routing/PathTest.java +++ b/core/src/test/java/com/graphhopper/routing/PathTest.java @@ -285,7 +285,7 @@ public void testCalcAverageSpeedDetails() { assertTrue(p.isFound()); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, - Arrays.asList(AVERAGE_SPEED), new PathDetailsBuilderFactory(), 0); + Arrays.asList(AVERAGE_SPEED), new PathDetailsBuilderFactory(), 0, pathDetailGraph); assertTrue(details.size() == 1); List averageSpeedDetails = details.get(AVERAGE_SPEED); @@ -308,7 +308,7 @@ public void testCalcAverageSpeedDetailsWithShortDistances_issue1848() { Path p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(1, 6); assertTrue(p.isFound()); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, - Arrays.asList(AVERAGE_SPEED), new PathDetailsBuilderFactory(), 0); + Arrays.asList(AVERAGE_SPEED), new PathDetailsBuilderFactory(), 0, pathDetailGraph); assertTrue(details.size() == 1); List averageSpeedDetails = details.get(AVERAGE_SPEED); assertEquals(4, averageSpeedDetails.size()); @@ -317,7 +317,7 @@ public void testCalcAverageSpeedDetailsWithShortDistances_issue1848() { p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(6, 1); assertTrue(p.isFound()); details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, - Arrays.asList(AVERAGE_SPEED), new PathDetailsBuilderFactory(), 0); + Arrays.asList(AVERAGE_SPEED), new PathDetailsBuilderFactory(), 0, pathDetailGraph); assertTrue(details.size() == 1); averageSpeedDetails = details.get(AVERAGE_SPEED); assertEquals(5, averageSpeedDetails.size()); @@ -331,7 +331,7 @@ public void testCalcStreetNameDetails() { assertTrue(p.isFound()); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, - Arrays.asList(STREET_NAME), new PathDetailsBuilderFactory(), 0); + Arrays.asList(STREET_NAME), new PathDetailsBuilderFactory(), 0, pathDetailGraph); assertTrue(details.size() == 1); List streetNameDetails = details.get(STREET_NAME); @@ -357,7 +357,7 @@ public void testCalcEdgeIdDetails() { assertTrue(p.isFound()); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, - Arrays.asList(EDGE_ID), new PathDetailsBuilderFactory(), 0); + Arrays.asList(EDGE_ID), new PathDetailsBuilderFactory(), 0, pathDetailGraph); assertTrue(details.size() == 1); List edgeIdDetails = details.get(EDGE_ID); @@ -382,7 +382,7 @@ public void testCalcEdgeKeyDetailsForward() { assertTrue(p.isFound()); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, - Arrays.asList(EDGE_KEY), new PathDetailsBuilderFactory(), 0); + Arrays.asList(EDGE_KEY), new PathDetailsBuilderFactory(), 0, pathDetailGraph); List edgeKeyDetails = details.get(EDGE_KEY); assertEquals(4, edgeKeyDetails.size()); @@ -399,7 +399,7 @@ public void testCalcEdgeKeyDetailsBackward() { assertTrue(p.isFound()); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, - Arrays.asList(EDGE_KEY), new PathDetailsBuilderFactory(), 0); + Arrays.asList(EDGE_KEY), new PathDetailsBuilderFactory(), 0, pathDetailGraph); List edgeKeyDetails = details.get(EDGE_KEY); assertEquals(4, edgeKeyDetails.size()); @@ -416,7 +416,7 @@ public void testCalcTimeDetails() { assertTrue(p.isFound()); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, - Arrays.asList(TIME), new PathDetailsBuilderFactory(), 0); + Arrays.asList(TIME), new PathDetailsBuilderFactory(), 0, pathDetailGraph); assertTrue(details.size() == 1); List timeDetails = details.get(TIME); @@ -440,7 +440,7 @@ public void testCalcDistanceDetails() { assertTrue(p.isFound()); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, - Arrays.asList(DISTANCE), new PathDetailsBuilderFactory(), 0); + Arrays.asList(DISTANCE), new PathDetailsBuilderFactory(), 0, pathDetailGraph); assertTrue(details.size() == 1); List distanceDetails = details.get(DISTANCE); @@ -450,6 +450,35 @@ public void testCalcDistanceDetails() { assertEquals(5D, distanceDetails.get(3).getValue()); } + @Test + public void testCalcIntersectionDetails() { + ShortestWeighting weighting = new ShortestWeighting(carAccessEnc, carAvSpeedEnc); + Path p = new Dijkstra(pathDetailGraph, weighting, TraversalMode.NODE_BASED).calcPath(1, 5); + assertTrue(p.isFound()); + + Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, + Arrays.asList(INTERSECTION), new PathDetailsBuilderFactory(), 0, pathDetailGraph); + assertTrue(details.size() == 1); + + List intersectionDetails = details.get(INTERSECTION); + assertEquals(4, intersectionDetails.size()); + + Map intersectionMap = new HashMap<>(); + intersectionMap.put("out", 0); + intersectionMap.put("entries", Arrays.asList(true)); + intersectionMap.put("bearings", Arrays.asList(90)); + + assertEquals(intersectionMap, intersectionDetails.get(0).getValue()); + + intersectionMap.clear(); + intersectionMap.put("out", 0); + intersectionMap.put("in", 1); + intersectionMap.put("entries", Arrays.asList(true, false)); + intersectionMap.put("bearings", Arrays.asList(90, 270)); + + assertEquals(intersectionMap, intersectionDetails.get(1).getValue()); + } + /** * case with one edge being not an exit */ diff --git a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java index 159cb2fe51f..dd9fa7192b3 100644 --- a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java +++ b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java @@ -112,7 +112,7 @@ public void testScenario() { Path p = new Dijkstra(g, weighting, tMode).calcPath(0, 10); InstructionList wayList = InstructionsFromEdges.calcInstructions(p, g, weighting, carManager, usTR); Map> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting, - Arrays.asList(AVERAGE_SPEED), new PathDetailsBuilderFactory(), 0); + Arrays.asList(AVERAGE_SPEED), new PathDetailsBuilderFactory(), 0, g); ResponsePath responsePath = new ResponsePath(); responsePath.setInstructions(wayList); diff --git a/navigation/src/main/java/com/graphhopper/navigation/NavigateResource.java b/navigation/src/main/java/com/graphhopper/navigation/NavigateResource.java index f862a2a7e87..c1a4c2d7818 100644 --- a/navigation/src/main/java/com/graphhopper/navigation/NavigateResource.java +++ b/navigation/src/main/java/com/graphhopper/navigation/NavigateResource.java @@ -39,6 +39,7 @@ import javax.ws.rs.core.UriInfo; import java.util.*; +import static com.graphhopper.util.Parameters.Details.INTERSECTION; import static com.graphhopper.util.Parameters.Routing.*; /** @@ -169,6 +170,8 @@ private GHResponse calcRoute(List headings, List requestPoints, request.setProfile(profileStr). setLocale(localeStr). + // We force the intersection details here as we cannot easily add this to the URL + setPathDetails(Arrays.asList(INTERSECTION)). putHint(CALC_POINTS, true). putHint(INSTRUCTIONS, enableInstructions). putHint(WAY_POINT_MAX_DISTANCE, minPathPrecision). diff --git a/navigation/src/main/java/com/graphhopper/navigation/NavigateResponseConverter.java b/navigation/src/main/java/com/graphhopper/navigation/NavigateResponseConverter.java index e749bbe4690..ada50511e59 100644 --- a/navigation/src/main/java/com/graphhopper/navigation/NavigateResponseConverter.java +++ b/navigation/src/main/java/com/graphhopper/navigation/NavigateResponseConverter.java @@ -24,10 +24,11 @@ import com.graphhopper.ResponsePath; import com.graphhopper.jackson.ResponsePathSerializer; import com.graphhopper.util.*; +import com.graphhopper.util.details.PathDetail; -import java.util.List; -import java.util.Locale; -import java.util.UUID; +import java.util.*; + +import static com.graphhopper.util.Parameters.Details.INTERSECTION; public class NavigateResponseConverter { @@ -82,11 +83,20 @@ private static void putRouteInformation(ObjectNode pathJson, ResponsePath path, long time = 0; double distance = 0; boolean isFirstInstructionOfLeg = true; + int pointIndexFrom = 0; + + Map> pathDetails = path.getPathDetails(); + List intersectionDetails = pathDetails.getOrDefault(INTERSECTION, Collections.emptyList()); for (int i = 0; i < instructions.size(); i++) { ObjectNode instructionJson = steps.addObject(); - putInstruction(instructions, i, locale, translationMap, instructionJson, isFirstInstructionOfLeg, distanceConfig); Instruction instruction = instructions.get(i); + int pointIndexTo = pointIndexFrom; + if (instruction.getSign() != Instruction.REACHED_VIA && instruction.getSign() != Instruction.FINISH) { + pointIndexTo += instructions.get(i).getPoints().size(); + } + putInstruction(path.getPoints(), instructions, i, locale, translationMap, instructionJson, isFirstInstructionOfLeg, distanceConfig, intersectionDetails, pointIndexFrom, pointIndexTo); + pointIndexFrom = pointIndexTo; time += instruction.getTime(); distance += instruction.getDistance(); isFirstInstructionOfLeg = false; @@ -126,26 +136,67 @@ private static void putLegInformation(ObjectNode legJson, ResponsePath path, int legJson.put("distance", Helper.round(distance, 1)); } - private static ObjectNode putInstruction(InstructionList instructions, int index, Locale locale, TranslationMap translationMap, - ObjectNode instructionJson, boolean isFirstInstructionOfLeg, DistanceConfig distanceConfig) { - Instruction instruction = instructions.get(index); + private static ObjectNode putInstruction(PointList points, InstructionList instructions, int instructionIndex, Locale locale, + TranslationMap translationMap, ObjectNode instructionJson, boolean isFirstInstructionOfLeg, + DistanceConfig distanceConfig, List intersectionDetails, int pointIndexFrom, + int pointIndexTo) { + Instruction instruction = instructions.get(instructionIndex); ArrayNode intersections = instructionJson.putArray("intersections"); - ObjectNode intersection = intersections.addObject(); - intersection.putArray("entry"); - intersection.putArray("bearings"); + + for (PathDetail intersectionDetail : intersectionDetails) { + if (intersectionDetail.getFirst() >= pointIndexTo) { + break; + } + if (intersectionDetail.getFirst() >= pointIndexFrom) { + ObjectNode intersection = intersections.addObject(); + Map intersectionValue = (Map) intersectionDetail.getValue(); + // Location + ArrayNode locationArray = intersection.putArray("location"); + locationArray.add(Helper.round6(points.getLon(intersectionDetail.getFirst()))); + locationArray.add(Helper.round6(points.getLat(intersectionDetail.getFirst()))); + // Entry + List entries = (List) intersectionValue.getOrDefault("entries", Collections.emptyList()); + ArrayNode entryArray = intersection.putArray("entry"); + for (Boolean entry : entries) { + entryArray.add(entry); + } + // Bearings + List bearingsList = (List) intersectionValue.getOrDefault("bearings", Collections.emptyList()); + ArrayNode bearingsrray = intersection.putArray("bearings"); + for (Integer bearing : bearingsList) { + bearingsrray.add(bearing); + } + // in + if (intersectionValue.containsKey("in")) { + intersection.put("in", (int) intersectionValue.get("in")); + } + // out + if (intersectionValue.containsKey("out")) { + intersection.put("out", (int) intersectionValue.get("out")); + } + } + } + //Make pointList mutable PointList pointList = instruction.getPoints().clone(false); - if (index + 2 < instructions.size()) { + if (instructionIndex + 2 < instructions.size()) { // Add the first point of the next instruction - PointList nextPoints = instructions.get(index + 1).getPoints(); + PointList nextPoints = instructions.get(instructionIndex + 1).getPoints(); pointList.add(nextPoints.getLat(0), nextPoints.getLon(0), nextPoints.getEle(0)); } else if (pointList.size() == 1) { // Duplicate the last point in the arrive instruction, if the size is 1 pointList.add(pointList.getLat(0), pointList.getLon(0), pointList.getEle(0)); } - putLocation(pointList.getLat(0), pointList.getLon(0), intersection); + if (intersections.size() == 0) { + // this is the fallback if we don't have any intersections. + // this can happen for via points or finish instructions or when no intersection details have been requested + ObjectNode intersection = intersections.addObject(); + intersection.putArray("entry"); + intersection.putArray("bearings"); + putLocation(pointList.getLat(0), pointList.getLon(0), intersection); + } instructionJson.put("driving_side", "right"); @@ -168,9 +219,9 @@ private static ObjectNode putInstruction(InstructionList instructions, int index ArrayNode bannerInstructions = instructionJson.putArray("bannerInstructions"); // Voice and banner instructions are empty for the last element - if (index + 1 < instructions.size()) { - putVoiceInstructions(instructions, distance, index, locale, translationMap, voiceInstructions, distanceConfig); - putBannerInstructions(instructions, distance, index, locale, translationMap, bannerInstructions); + if (instructionIndex + 1 < instructions.size()) { + putVoiceInstructions(instructions, distance, instructionIndex, locale, translationMap, voiceInstructions, distanceConfig); + putBannerInstructions(instructions, distance, instructionIndex, locale, translationMap, bannerInstructions); } return instructionJson; diff --git a/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java b/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java index 08f8f8cf79a..93438d83037 100644 --- a/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java +++ b/navigation/src/test/java/com/graphhopper/navigation/NavigateResponseConverterTest.java @@ -16,10 +16,10 @@ import org.junit.jupiter.api.Test; import java.io.File; +import java.util.Collections; import java.util.Locale; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; public class NavigateResponseConverterTest { @@ -250,6 +250,36 @@ public void roundaboutDegreesTest() { } + @Test + public void intersectionTest() { + GHResponse rsp = hopper.route(new GHRequest(42.554851, 1.536198, 42.510071, 1.548128). + setProfile(profile).setPathDetails(Collections.singletonList("intersection"))); + + ObjectNode json = NavigateResponseConverter.convertFromGHResponse(rsp, trMap, Locale.ENGLISH, distanceConfig); + + JsonNode steps = json.get("routes").get(0).get("legs").get(0).get("steps"); + + JsonNode step = steps.get(0); + + JsonNode intersection = step.get("intersections").get(0); + + assertFalse(intersection.has("in")); + assertEquals(1, intersection.get("out").asInt()); + + JsonNode location = intersection.get("location"); + // The first intersection to be equal to the first snapped waypoint + assertEquals(rsp.getBest().getWaypoints().get(0).lon, location.get(0).asDouble(), .000001); + assertEquals(rsp.getBest().getWaypoints().get(0).lat, location.get(1).asDouble(), .000001); + + step = steps.get(4); + intersection = step.get("intersections").get(3); + assertEquals(1, intersection.get("in").asInt()); + assertEquals(0, intersection.get("out").asInt()); + location = intersection.get("location"); + assertEquals(1.534679, location.get(0).asDouble(), .000001); + assertEquals(42.556444, location.get(1).asDouble(), .000001); + } + @Test public void testMultipleWaypoints() { diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/TripFromLabel.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/TripFromLabel.java index 82ca316c784..605a6ea746e 100644 --- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/TripFromLabel.java +++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/TripFromLabel.java @@ -401,7 +401,7 @@ private List parsePartitionToLegs(List path, Graph g pathh.setFromNode(path.get(0).label.node.streetNode); pathh.setEndNode(path.get(path.size() - 1).label.node.streetNode); pathh.setFound(true); - Map> pathDetails = PathDetailsFromEdges.calcDetails(pathh, encodedValueLookup, weighting, requestedPathDetails, pathDetailsBuilderFactory, 0); + Map> pathDetails = PathDetailsFromEdges.calcDetails(pathh, encodedValueLookup, weighting, requestedPathDetails, pathDetailsBuilderFactory, 0, graph); final Instant departureTime = Instant.ofEpochMilli(path.get(0).label.currentTime); final Instant arrivalTime = Instant.ofEpochMilli(path.get(path.size() - 1).label.currentTime); diff --git a/web-api/src/main/java/com/graphhopper/jackson/PathDetailDeserializer.java b/web-api/src/main/java/com/graphhopper/jackson/PathDetailDeserializer.java index 7db6383c0d7..f40e345ed9d 100644 --- a/web-api/src/main/java/com/graphhopper/jackson/PathDetailDeserializer.java +++ b/web-api/src/main/java/com/graphhopper/jackson/PathDetailDeserializer.java @@ -17,8 +17,6 @@ */ package com.graphhopper.jackson; -import java.io.IOException; - import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; @@ -26,6 +24,9 @@ import com.fasterxml.jackson.databind.JsonNode; import com.graphhopper.util.details.PathDetail; +import java.io.IOException; +import java.util.Map; + public class PathDetailDeserializer extends JsonDeserializer { @Override @@ -47,6 +48,8 @@ else if (val.canConvertToLong()) pd = new PathDetail(val.asLong()); else if (val.isTextual()) pd = new PathDetail(val.asText()); + else if (val.isObject()) + pd = new PathDetail(jp.getCodec().treeToValue(val, Map.class)); else if (val.isNull()) pd = new PathDetail(null); else diff --git a/web-api/src/main/java/com/graphhopper/jackson/PathDetailSerializer.java b/web-api/src/main/java/com/graphhopper/jackson/PathDetailSerializer.java index eb5b614ce98..282905005b9 100644 --- a/web-api/src/main/java/com/graphhopper/jackson/PathDetailSerializer.java +++ b/web-api/src/main/java/com/graphhopper/jackson/PathDetailSerializer.java @@ -24,6 +24,7 @@ import com.graphhopper.util.details.PathDetail; import java.io.IOException; +import java.util.Map; public class PathDetailSerializer extends JsonSerializer { @@ -44,6 +45,8 @@ else if (value.getValue() instanceof Boolean) gen.writeBoolean((Boolean) value.getValue()); else if (value.getValue() instanceof String) gen.writeString((String) value.getValue()); + else if (value.getValue() instanceof Map) + gen.writeObject(value.getValue()); else if (value.getValue() == null) gen.writeNull(); else diff --git a/web-api/src/main/java/com/graphhopper/util/Parameters.java b/web-api/src/main/java/com/graphhopper/util/Parameters.java index a6b02bf20dd..e4607650a4d 100644 --- a/web-api/src/main/java/com/graphhopper/util/Parameters.java +++ b/web-api/src/main/java/com/graphhopper/util/Parameters.java @@ -209,6 +209,7 @@ public static final class Details { public static final String TIME = "time"; public static final String WEIGHT = "weight"; public static final String DISTANCE = "distance"; + public static final String INTERSECTION = "intersection"; } } diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java index d93bde9a1cd..fae5558aa40 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceClientHCTest.java @@ -44,10 +44,7 @@ import org.junit.jupiter.params.provider.EnumSource; import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; import static org.junit.jupiter.api.Assertions.*; @@ -307,14 +304,18 @@ public void testPathDetails(TestParam p) { addPoint(new GHPoint(42.510383, 1.533392)). setProfile("my_car"); req.getPathDetails().add("average_speed"); + req.getPathDetails().add("intersection"); GHResponse res = gh.route(req); assertFalse(res.hasErrors(), "errors:" + res.getErrors().toString()); ResponsePath alt = res.getBest(); - assertEquals(1, alt.getPathDetails().size()); + assertEquals(2, alt.getPathDetails().size()); List details = alt.getPathDetails().get("average_speed"); assertFalse(details.isEmpty()); assertTrue((Double) details.get(0).getValue() > 20); assertTrue((Double) details.get(0).getValue() < 70); + details = alt.getPathDetails().get("intersection"); + assertFalse(details.isEmpty()); + assertTrue(((Map) details.get(0).getValue()).containsKey("bearings")); } @ParameterizedTest From 17f50b827c28902553d1cdc8ee488aaa5042c5ed Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 7 Oct 2022 13:17:01 +0200 Subject: [PATCH 204/389] Add branch name to core benchmark trigger --- .github/workflows/trigger-benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trigger-benchmarks.yml b/.github/workflows/trigger-benchmarks.yml index e15b2fa8de2..0aace67ba95 100644 --- a/.github/workflows/trigger-benchmarks.yml +++ b/.github/workflows/trigger-benchmarks.yml @@ -11,4 +11,4 @@ jobs: curl -X POST -H "Authorization: token ${{ secrets.BENCHMARKS_TOKEN }}" \ -H "Accept: application/vnd.github+json" \ "https://api.github.com/repos/${{ secrets.BENCHMARKS_REPO }}/dispatches" \ - -d '{"event_type":"measurement_core","client_payload":{"core_commit": "'$GITHUB_SHA'" }}' + -d '{"event_type":"measurement_core","client_payload":{"core_commit": "'$GITHUB_SHA'", "core_branch": "${{ github.ref_name }}" }}' From 0aca3cb0f43de141605b978f517e3a6a2406ce5d Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 7 Oct 2022 12:20:35 +0200 Subject: [PATCH 205/389] Rename OSMTurnRelation to OSMTurnRestriction --- ...nRelation.java => OSMTurnRestriction.java} | 16 +++---- .../com/graphhopper/reader/osm/OSMReader.java | 48 +++++++++---------- .../routing/ch/CHPreparationGraph.java | 2 +- .../graphhopper/routing/util/OSMParsers.java | 10 ++-- ...ser.java => OSMTurnRestrictionParser.java} | 26 +++++----- .../routing/util/parsers/TurnCostParser.java | 10 ++-- .../graphhopper/storage/TurnCostStorage.java | 18 +++---- .../java/com/graphhopper/GraphHopperTest.java | 4 +- .../graphhopper/reader/osm/OSMReaderTest.java | 8 ++-- ...nTest.java => OSMTurnRestrictionTest.java} | 32 ++++++------- .../EdgeBasedRoutingAlgorithmTest.java | 2 +- ...java => OSMTurnRestrictionParserTest.java} | 10 ++-- .../storage/TurnCostStorageTest.java | 34 ++++++------- 13 files changed, 108 insertions(+), 112 deletions(-) rename core/src/main/java/com/graphhopper/reader/{OSMTurnRelation.java => OSMTurnRestriction.java} (88%) rename core/src/main/java/com/graphhopper/routing/util/parsers/{OSMTurnRelationParser.java => OSMTurnRestrictionParser.java} (75%) rename core/src/test/java/com/graphhopper/reader/osm/{OSMTurnRelationTest.java => OSMTurnRestrictionTest.java} (56%) rename core/src/test/java/com/graphhopper/routing/util/parsers/{OSMTurnRelationParserTest.java => OSMTurnRestrictionParserTest.java} (88%) diff --git a/core/src/main/java/com/graphhopper/reader/OSMTurnRelation.java b/core/src/main/java/com/graphhopper/reader/OSMTurnRestriction.java similarity index 88% rename from core/src/main/java/com/graphhopper/reader/OSMTurnRelation.java rename to core/src/main/java/com/graphhopper/reader/OSMTurnRestriction.java index 1f34ea6ec21..42ff3837840 100644 --- a/core/src/main/java/com/graphhopper/reader/OSMTurnRelation.java +++ b/core/src/main/java/com/graphhopper/reader/OSMTurnRestriction.java @@ -24,17 +24,17 @@ * * @author Karl Hübner */ -public class OSMTurnRelation { +public class OSMTurnRestriction { private final long fromOsmWayId; private final long viaOsmNodeId; private final long toOsmWayId; - private final Type restriction; + private final RestrictionType restriction; // vehicleTypeRestricted contains the dedicated vehicle type // example: restriction:bus = no_left_turn => vehicleTypeRestricted = "bus"; private String vehicleTypeRestricted; private List vehicleTypesExcept; - public OSMTurnRelation(long fromWayID, long viaNodeID, long toWayID, Type restrictionType) { + public OSMTurnRestriction(long fromWayID, long viaNodeID, long toWayID, RestrictionType restrictionType) { this.fromOsmWayId = fromWayID; this.viaOsmNodeId = viaNodeID; this.toOsmWayId = toWayID; @@ -55,7 +55,7 @@ public long getViaOsmNodeId() { return viaOsmNodeId; } - public Type getRestriction() { + public RestrictionType getRestriction() { return restriction; } @@ -92,10 +92,10 @@ public String toString() { return "*-(" + fromOsmWayId + ")->" + viaOsmNodeId + "-(" + toOsmWayId + ")->*"; } - public enum Type { + public enum RestrictionType { UNSUPPORTED, NOT, ONLY; - private static final Map tags = new HashMap<>(); + private static final Map tags = new HashMap<>(); static { tags.put("no_left_turn", NOT); @@ -108,8 +108,8 @@ public enum Type { tags.put("only_straight_on", ONLY); } - public static Type getRestrictionType(String tag) { - Type result = null; + public static RestrictionType getRestrictionType(String tag) { + RestrictionType result = null; if (tag != null) { result = tags.get(tag); } diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java index 41acbe77851..0005e12b422 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMReader.java @@ -519,14 +519,14 @@ protected void preprocessRelations(ReaderRelation relation) { } if (relation.hasTag("type", "restriction")) { - // we keep the osm way ids that occur in turn relations, because this way we know for which GH edges + // we keep the osm way ids that occur in turn restriction relations, because this way we know for which GH edges // we need to remember the associated osm way id. this is just an optimization that is supposed to save // memory compared to simply storing the osm way ids in a long array where the array index is the GH edge // id. - List turnRelations = createTurnRelations(relation); - for (OSMTurnRelation turnRelation : turnRelations) { - osmWayIdSet.add(turnRelation.getOsmIdFrom()); - osmWayIdSet.add(turnRelation.getOsmIdTo()); + List turnRestrictions = createTurnRestrictions(relation); + for (OSMTurnRestriction turnRestriction : turnRestrictions) { + osmWayIdSet.add(turnRestriction.getOsmIdFrom()); + osmWayIdSet.add(turnRestriction.getOsmIdTo()); } } } @@ -548,11 +548,11 @@ public long getOsmIdOfInternalEdge(int edgeId) { return getEdgeIdToOsmWayIdMap().get(edgeId); } }; - for (OSMTurnRelation turnRelation : createTurnRelations(relation)) { - int viaNode = map.getInternalNodeIdOfOsmNode(turnRelation.getViaOsmNodeId()); + for (OSMTurnRestriction turnRestriction : createTurnRestrictions(relation)) { + int viaNode = map.getInternalNodeIdOfOsmNode(turnRestriction.getViaOsmNodeId()); // street with restriction was not included (access or tag limits etc) if (viaNode >= 0) - osmParsers.handleTurnRelationTags(turnRelation, map, baseGraph); + osmParsers.handleTurnRestrictionTags(turnRestriction, map, baseGraph); } } } @@ -566,10 +566,10 @@ private IntLongMap getEdgeIdToOsmWayIdMap() { } /** - * Creates turn relations out of an unspecified OSM relation + * Creates turn restrictions given an OSM relation */ - static List createTurnRelations(ReaderRelation relation) { - List osmTurnRelations = new ArrayList<>(); + static List createTurnRestrictions(ReaderRelation relation) { + List osmTurnRestrictions = new ArrayList<>(); String vehicleTypeRestricted = ""; List vehicleTypesExcept = new ArrayList<>(); if (relation.hasTag("except")) { @@ -581,26 +581,26 @@ static List createTurnRelations(ReaderRelation relation) { } } if (relation.hasTag("restriction")) { - osmTurnRelations.addAll(createTurnRelations(relation, relation.getTag("restriction"), + osmTurnRestrictions.addAll(createTurnRestrictions(relation, relation.getTag("restriction"), vehicleTypeRestricted, vehicleTypesExcept)); - return osmTurnRelations; + return osmTurnRestrictions; } if (relation.hasTagWithKeyPrefix("restriction:")) { List vehicleTypesRestricted = relation.getKeysWithPrefix("restriction:"); for (String vehicleType : vehicleTypesRestricted) { String restrictionType = relation.getTag(vehicleType); vehicleTypeRestricted = vehicleType.replace("restriction:", "").trim(); - osmTurnRelations.addAll(createTurnRelations(relation, restrictionType, vehicleTypeRestricted, + osmTurnRestrictions.addAll(createTurnRestrictions(relation, restrictionType, vehicleTypeRestricted, vehicleTypesExcept)); } } - return osmTurnRelations; + return osmTurnRestrictions; } - static List createTurnRelations(ReaderRelation relation, String restrictionType, - String vehicleTypeRestricted, List vehicleTypesExcept) { - OSMTurnRelation.Type type = OSMTurnRelation.Type.getRestrictionType(restrictionType); - if (type != OSMTurnRelation.Type.UNSUPPORTED) { + static List createTurnRestrictions(ReaderRelation relation, String restrictionType, + String vehicleTypeRestricted, List vehicleTypesExcept) { + OSMTurnRestriction.RestrictionType type = OSMTurnRestriction.RestrictionType.getRestrictionType(restrictionType); + if (type != OSMTurnRestriction.RestrictionType.UNSUPPORTED) { // we use -1 to indicate 'missing', which is fine because we exclude negative OSM IDs (see #2652) long viaNodeID = -1; long toWayID = -1; @@ -612,13 +612,13 @@ else if (ReaderElement.Type.NODE == member.getType() && "via".equals(member.getR viaNodeID = member.getRef(); } if (toWayID >= 0 && viaNodeID >= 0) { - List res = new ArrayList<>(2); + List res = new ArrayList<>(2); for (ReaderRelation.Member member : relation.getMembers()) { if (ReaderElement.Type.WAY == member.getType() && "from".equals(member.getRole())) { - OSMTurnRelation osmTurnRelation = new OSMTurnRelation(member.getRef(), viaNodeID, toWayID, type); - osmTurnRelation.setVehicleTypeRestricted(vehicleTypeRestricted); - osmTurnRelation.setVehicleTypesExcept(vehicleTypesExcept); - res.add(osmTurnRelation); + OSMTurnRestriction osmTurnRestriction = new OSMTurnRestriction(member.getRef(), viaNodeID, toWayID, type); + osmTurnRestriction.setVehicleTypeRestricted(vehicleTypeRestricted); + osmTurnRestriction.setVehicleTypesExcept(vehicleTypesExcept); + res.add(osmTurnRestriction); } } return res; diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java index ac10b55d5de..4eb49e17dd1 100644 --- a/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java +++ b/core/src/main/java/com/graphhopper/routing/ch/CHPreparationGraph.java @@ -125,7 +125,7 @@ public static TurnCostFunction buildTurnCostFunctionFromTurnCostStorage(Graph gr DoubleArrayList turnCosts = new DoubleArrayList(); // for each node we store the index of the first turn cost entry/triple in the list final int[] turnCostNodes = new int[graph.getNodes() + 1]; - TurnCostStorage.TurnRelationIterator tcIter = turnCostStorage.getAllTurnRelations(); + TurnCostStorage.Iterator tcIter = turnCostStorage.getAllTurnCosts(); int lastNode = -1; while (tcIter.next()) { int viaNode = tcIter.getViaNode(); diff --git a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java index b908a7ce234..3a4eaed771c 100644 --- a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java +++ b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java @@ -18,11 +18,11 @@ package com.graphhopper.routing.util; -import com.graphhopper.reader.OSMTurnRelation; +import com.graphhopper.reader.OSMTurnRestriction; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.util.parsers.OSMTurnRelationParser; +import com.graphhopper.routing.util.parsers.OSMTurnRestrictionParser; import com.graphhopper.routing.util.parsers.RelationTagParser; import com.graphhopper.routing.util.parsers.TagParser; import com.graphhopper.routing.util.parsers.TurnCostParser; @@ -59,7 +59,7 @@ public OSMParsers addWayTagParser(TagParser tagParser) { public OSMParsers addVehicleTagParser(VehicleTagParser vehicleTagParser) { vehicleTagParsers.add(vehicleTagParser); if (vehicleTagParser.supportsTurnCosts()) - turnCostParsers.add(new OSMTurnRelationParser(vehicleTagParser.getAccessEnc(), vehicleTagParser.getTurnCostEnc(), vehicleTagParser.getRestrictions())); + turnCostParsers.add(new OSMTurnRestrictionParser(vehicleTagParser.getAccessEnc(), vehicleTagParser.getTurnCostEnc(), vehicleTagParser.getRestrictions())); return this; } @@ -94,8 +94,8 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationF return edgeFlags; } - public void handleTurnRelationTags(OSMTurnRelation turnRelation, TurnCostParser.ExternalInternalMap map, Graph graph) { - turnCostParsers.forEach(t -> t.handleTurnRelationTags(turnRelation, map, graph)); + public void handleTurnRestrictionTags(OSMTurnRestriction turnRestriction, TurnCostParser.ExternalInternalMap map, Graph graph) { + turnCostParsers.forEach(t -> t.handleTurnRestrictionTags(turnRestriction, map, graph)); } public IntsRef createRelationFlags() { diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParser.java similarity index 75% rename from core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java rename to core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParser.java index fc3a5cfc0b6..5fea1f7aff5 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParser.java @@ -17,7 +17,7 @@ */ package com.graphhopper.routing.util.parsers; -import com.graphhopper.reader.OSMTurnRelation; +import com.graphhopper.reader.OSMTurnRestriction; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.AccessFilter; @@ -31,13 +31,13 @@ /** * This parser takes the turn restrictions from OSM (OSM does not provide turn costs, but only restrictions) and creates the appropriate turn costs (with value infinity) */ -public class OSMTurnRelationParser implements TurnCostParser { +public class OSMTurnRestrictionParser implements TurnCostParser { private final BooleanEncodedValue accessEnc; private final DecimalEncodedValue turnCostEnc; private final List restrictions; private EdgeExplorer cachedOutExplorer, cachedInExplorer; - public OSMTurnRelationParser(BooleanEncodedValue accessEnc, DecimalEncodedValue turnCostEnc, List restrictions) { + public OSMTurnRestrictionParser(BooleanEncodedValue accessEnc, DecimalEncodedValue turnCostEnc, List restrictions) { if (restrictions.isEmpty()) throw new IllegalArgumentException("restrictions cannot be empty"); this.accessEnc = accessEnc; @@ -46,11 +46,11 @@ public OSMTurnRelationParser(BooleanEncodedValue accessEnc, DecimalEncodedValue } @Override - public void handleTurnRelationTags(OSMTurnRelation turnRelation, ExternalInternalMap map, Graph graph) { - if (!turnRelation.isVehicleTypeConcernedByTurnRestriction(restrictions)) + public void handleTurnRestrictionTags(OSMTurnRestriction turnRestriction, ExternalInternalMap map, Graph graph) { + if (!turnRestriction.isVehicleTypeConcernedByTurnRestriction(restrictions)) return; - addRelationToTCStorage(turnRelation, map, graph); + addRelationToTCStorage(turnRestriction, map, graph); } private EdgeExplorer getInExplorer(Graph graph) { @@ -64,9 +64,9 @@ private EdgeExplorer getOutExplorer(Graph graph) { /** * Add the specified relation to the TurnCostStorage */ - void addRelationToTCStorage(OSMTurnRelation osmTurnRelation, ExternalInternalMap map, Graph graph) { + void addRelationToTCStorage(OSMTurnRestriction osmTurnRestriction, ExternalInternalMap map, Graph graph) { TurnCostStorage tcs = graph.getTurnCostStorage(); - int viaNode = map.getInternalNodeIdOfOsmNode(osmTurnRelation.getViaOsmNodeId()); + int viaNode = map.getInternalNodeIdOfOsmNode(osmTurnRestriction.getViaOsmNodeId()); EdgeExplorer edgeOutExplorer = getOutExplorer(graph), edgeInExplorer = getInExplorer(graph); try { @@ -76,7 +76,7 @@ void addRelationToTCStorage(OSMTurnRelation osmTurnRelation, ExternalInternalMap EdgeIterator iter = edgeInExplorer.setBaseNode(viaNode); while (iter.next()) { - if (map.getOsmIdOfInternalEdge(iter.getEdge()) == osmTurnRelation.getOsmIdFrom()) { + if (map.getOsmIdOfInternalEdge(iter.getEdge()) == osmTurnRestriction.getOsmIdFrom()) { edgeIdFrom = iter.getEdge(); break; } @@ -92,15 +92,15 @@ void addRelationToTCStorage(OSMTurnRelation osmTurnRelation, ExternalInternalMap while (iter.next()) { int edgeId = iter.getEdge(); long wayId = map.getOsmIdOfInternalEdge(edgeId); - if (edgeId != edgeIdFrom && osmTurnRelation.getRestriction() == OSMTurnRelation.Type.ONLY && wayId != osmTurnRelation.getOsmIdTo() - || osmTurnRelation.getRestriction() == OSMTurnRelation.Type.NOT && wayId == osmTurnRelation.getOsmIdTo() && wayId >= 0) { + if (edgeId != edgeIdFrom && osmTurnRestriction.getRestriction() == OSMTurnRestriction.RestrictionType.ONLY && wayId != osmTurnRestriction.getOsmIdTo() + || osmTurnRestriction.getRestriction() == OSMTurnRestriction.RestrictionType.NOT && wayId == osmTurnRestriction.getOsmIdTo() && wayId >= 0) { tcs.set(turnCostEnc, edgeIdFrom, viaNode, iter.getEdge(), Double.POSITIVE_INFINITY); - if (osmTurnRelation.getRestriction() == OSMTurnRelation.Type.NOT) + if (osmTurnRestriction.getRestriction() == OSMTurnRestriction.RestrictionType.NOT) break; } } } catch (Exception e) { - throw new IllegalStateException("Could not built turn table entry for relation of node with osmId:" + osmTurnRelation.getViaOsmNodeId(), e); + throw new IllegalStateException("Could not built turn table entry for relation of node with osmId:" + osmTurnRestriction.getViaOsmNodeId(), e); } } diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java index 42102b792e0..ed746b8c2d6 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java @@ -17,21 +17,17 @@ */ package com.graphhopper.routing.util.parsers; -import com.graphhopper.reader.OSMTurnRelation; -import com.graphhopper.routing.ev.EncodedValue; -import com.graphhopper.routing.ev.EncodedValueLookup; +import com.graphhopper.reader.OSMTurnRestriction; import com.graphhopper.storage.Graph; -import java.util.List; - /** * This interface serves the purpose of converting relation flags into turn cost information. Unlike RelationTagParser - * it can be assumed that the graph topology is already intact when handleTurnRelationTags is called. + * it can be assumed that the graph topology is already intact when handleTurnRestrictionTags is called. */ public interface TurnCostParser { String getName(); - void handleTurnRelationTags(OSMTurnRelation turnRelation, ExternalInternalMap map, Graph graph); + void handleTurnRestrictionTags(OSMTurnRestriction turnRestriction, ExternalInternalMap map, Graph graph); /** * This map associates the internal GraphHopper nodes IDs with external IDs (OSM) and similarly for the edge IDs diff --git a/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java b/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java index 8464898290b..a05c086c4b6 100644 --- a/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java +++ b/core/src/main/java/com/graphhopper/storage/TurnCostStorage.java @@ -22,13 +22,13 @@ import com.graphhopper.util.EdgeIterator; /** - * A key/value store, where the unique keys are turn relations, and the values are IntRefs. - * A turn relation is a triple (fromEdge, viaNode, toEdge), + * A key/value store, where the unique keys are turn cost relations, and the values are IntRefs. + * A turn cost relation is a triple (fromEdge, viaNode, toEdge), * and refers to one of the possible ways of crossing an intersection. *

    * Like IntRefs on edges, this can in principle be used to store values of any kind. *

    - * In practice, the IntRefs are used to store generalized travel costs per turn relation per vehicle type. + * In practice, the IntRefs are used to store generalized travel costs per turn cost relation per vehicle type. * In practice, we only store 0 or infinity. (Can turn, or cannot turn.) * * @author Karl Hübner @@ -86,8 +86,8 @@ public boolean loadExisting() { /** * Sets the turn cost at the viaNode when going from "fromEdge" to "toEdge" - * WARNING: It is tacitly assumed that for every encoder, this method is only called once per turn relation. - * Subsequent calls for the same encoder and the same turn relation will have undefined results. + * WARNING: It is tacitly assumed that for every encoder, this method is only called once per turn cost relation. + * Subsequent calls for the same encoder and the same turn cost relation will have undefined results. * (The implementation below ORs the new bits into the existing bits.) */ public void set(DecimalEncodedValue turnCostEnc, int fromEdge, int viaNode, int toEdge, double cost) { @@ -126,7 +126,7 @@ private void merge(IntsRef tcFlags, int fromEdge, int viaNode, int toEdge) { previousEntryIndex = next; // search for the last added cost entry if (i++ > 1000) { - throw new IllegalStateException("Something unexpected happened. A node probably will not have 1000+ relations."); + throw new IllegalStateException("Something unexpected happened. A node probably will not have 1000+ turn cost relations."); } // get index of next turn cost entry next = turnCosts.getInt((long) next * BYTES_PER_ENTRY + TC_NEXT); @@ -220,11 +220,11 @@ public String toString() { * * @return an iterator over all entries. */ - public TurnRelationIterator getAllTurnRelations() { + public Iterator getAllTurnCosts() { return new Itr(); } - public interface TurnRelationIterator { + public interface Iterator { int getFromEdge(); int getViaNode(); @@ -236,7 +236,7 @@ public interface TurnRelationIterator { boolean next(); } - private class Itr implements TurnRelationIterator { + private class Itr implements Iterator { private int viaNode = -1; private int turnCostIndex = -1; private final IntsRef intsRef = TurnCost.createFlags(); diff --git a/core/src/test/java/com/graphhopper/GraphHopperTest.java b/core/src/test/java/com/graphhopper/GraphHopperTest.java index adb026e5589..a0cb41f8be8 100644 --- a/core/src/test/java/com/graphhopper/GraphHopperTest.java +++ b/core/src/test/java/com/graphhopper/GraphHopperTest.java @@ -2021,9 +2021,9 @@ public void testEncoderWithTurnCostSupport_stillAllows_nodeBasedRouting() { @Test public void testOneWaySubnetwork_issue1807() { - // There is a straight-only turn relation at the junction of Franziskastraße and Gudulastraße, which restricts + // There is a straight-only turn restriction at the junction of Franziskastraße and Gudulastraße, which restricts // turning onto Gudulastraße. However, Gudulastraße can also not be accessed from the south/west, because - // its a one-way. This creates a subnetwork that is not accessible at all. We can only detect this if we + // it is a one-way. This creates a subnetwork that is not accessible at all. We can only detect this if we // consider the turn restrictions during the subnetwork search. GraphHopper hopper = new GraphHopper(). setGraphHopperLocation(GH_LOCATION). diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 99aa995172d..604816bb969 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -22,7 +22,7 @@ import com.graphhopper.GraphHopper; import com.graphhopper.GraphHopperTest; import com.graphhopper.config.Profile; -import com.graphhopper.reader.OSMTurnRelation; +import com.graphhopper.reader.OSMTurnRestriction; import com.graphhopper.reader.ReaderElement; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; @@ -590,16 +590,16 @@ public void testMultipleFromForNoEntry() { rel.add(new ReaderRelation.Member(ReaderElement.Type.NODE, 3L, "via")); rel.add(new ReaderRelation.Member(ReaderElement.Type.WAY, 4L, "to")); - List osmRel = OSMReader.createTurnRelations(rel); + List osmRel = OSMReader.createTurnRestrictions(rel); assertEquals(2, osmRel.size()); assertEquals(1, osmRel.get(0).getOsmIdFrom()); assertEquals(4, osmRel.get(0).getOsmIdTo()); - assertEquals(OSMTurnRelation.Type.NOT, osmRel.get(0).getRestriction()); + assertEquals(OSMTurnRestriction.RestrictionType.NOT, osmRel.get(0).getRestriction()); assertEquals(2, osmRel.get(1).getOsmIdFrom()); assertEquals(4, osmRel.get(1).getOsmIdTo()); - assertEquals(OSMTurnRelation.Type.NOT, osmRel.get(1).getRestriction()); + assertEquals(OSMTurnRestriction.RestrictionType.NOT, osmRel.get(1).getRestriction()); } @Test diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMTurnRelationTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMTurnRestrictionTest.java similarity index 56% rename from core/src/test/java/com/graphhopper/reader/osm/OSMTurnRelationTest.java rename to core/src/test/java/com/graphhopper/reader/osm/OSMTurnRestrictionTest.java index 3f9bf3fff53..dd008de043b 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMTurnRelationTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMTurnRestrictionTest.java @@ -17,7 +17,7 @@ */ package com.graphhopper.reader.osm; -import com.graphhopper.reader.OSMTurnRelation; +import com.graphhopper.reader.OSMTurnRestriction; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -30,35 +30,35 @@ /** * @author Peter Karich */ -public class OSMTurnRelationTest { +public class OSMTurnRestrictionTest { @Test - public void testAcceptsTurnRelation() { + public void testAcceptsTurnRestriction() { List vehicleTypes = new ArrayList<>(Arrays.asList("motorcar", "motor_vehicle", "vehicle")); List vehicleTypesExcept = new ArrayList<>(); - OSMTurnRelation osmTurnRelation = new OSMTurnRelation(1, 1, 1, OSMTurnRelation.Type.NOT); - assertTrue(osmTurnRelation.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); + OSMTurnRestriction osmTurnRestriction = new OSMTurnRestriction(1, 1, 1, OSMTurnRestriction.RestrictionType.NOT); + assertTrue(osmTurnRestriction.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); vehicleTypesExcept.add("bus"); - osmTurnRelation.setVehicleTypesExcept(vehicleTypesExcept); - assertTrue(osmTurnRelation.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); + osmTurnRestriction.setVehicleTypesExcept(vehicleTypesExcept); + assertTrue(osmTurnRestriction.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); vehicleTypesExcept.clear(); vehicleTypesExcept.add("vehicle"); - osmTurnRelation.setVehicleTypesExcept(vehicleTypesExcept); - assertFalse(osmTurnRelation.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); + osmTurnRestriction.setVehicleTypesExcept(vehicleTypesExcept); + assertFalse(osmTurnRestriction.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); vehicleTypesExcept.clear(); vehicleTypesExcept.add("motor_vehicle"); vehicleTypesExcept.add("vehicle"); - osmTurnRelation.setVehicleTypesExcept(vehicleTypesExcept); - assertFalse(osmTurnRelation.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); + osmTurnRestriction.setVehicleTypesExcept(vehicleTypesExcept); + assertFalse(osmTurnRestriction.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); vehicleTypesExcept.clear(); - osmTurnRelation.setVehicleTypeRestricted("bus"); - osmTurnRelation.setVehicleTypesExcept(vehicleTypesExcept); - assertFalse(osmTurnRelation.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); + osmTurnRestriction.setVehicleTypeRestricted("bus"); + osmTurnRestriction.setVehicleTypesExcept(vehicleTypesExcept); + assertFalse(osmTurnRestriction.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); - osmTurnRelation.setVehicleTypeRestricted("vehicle"); - assertTrue(osmTurnRelation.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); + osmTurnRestriction.setVehicleTypeRestricted("vehicle"); + assertTrue(osmTurnRestriction.isVehicleTypeConcernedByTurnRestriction(vehicleTypes)); } } diff --git a/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java b/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java index 0675629765c..104586a4d04 100644 --- a/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java +++ b/core/src/test/java/com/graphhopper/routing/EdgeBasedRoutingAlgorithmTest.java @@ -279,7 +279,7 @@ private void assertDistTimeWeight(Path path, int numEdges, double distPerEdge, d } private void blockNode3(BaseGraph g) { - // Totally block this node (all 9 turn relations) + // Totally block this node (all 9 turn restrictions) setTurnRestriction(g, 2, 3, 1); setTurnRestriction(g, 2, 3, 4); setTurnRestriction(g, 4, 3, 1); diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParserTest.java similarity index 88% rename from core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java rename to core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParserTest.java index 03bb29050a6..b46fb646fee 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRelationParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParserTest.java @@ -1,6 +1,6 @@ package com.graphhopper.routing.util.parsers; -import com.graphhopper.reader.OSMTurnRelation; +import com.graphhopper.reader.OSMTurnRestriction; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.TransportationMode; @@ -15,7 +15,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -public class OSMTurnRelationParserTest { +public class OSMTurnRestrictionParserTest { @Test public void testGetRestrictionAsEntries() { @@ -31,7 +31,7 @@ public void testGetRestrictionAsEntries() { internalToOSMEdge.put(3, 3L); internalToOSMEdge.put(4, 4L); - OSMTurnRelationParser parser = new OSMTurnRelationParser(accessEnc, turnCostEnc, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR)); + OSMTurnRestrictionParser parser = new OSMTurnRestrictionParser(accessEnc, turnCostEnc, OSMRoadAccessParser.toOSMRestrictions(TransportationMode.CAR)); BaseGraph graph = new BaseGraph.Builder(em.getIntsForFlags()).withTurnCosts(true).create(); initGraph(graph, accessEnc, speedEnc); TurnCostParser.ExternalInternalMap map = new TurnCostParser.ExternalInternalMap() { @@ -51,7 +51,7 @@ public long getOsmIdOfInternalEdge(int edgeId) { }; // TYPE == ONLY - OSMTurnRelation instance = new OSMTurnRelation(4, 3, 3, OSMTurnRelation.Type.ONLY); + OSMTurnRestriction instance = new OSMTurnRestriction(4, 3, 3, OSMTurnRestriction.RestrictionType.ONLY); parser.addRelationToTCStorage(instance, map, graph); TurnCostStorage tcs = graph.getTurnCostStorage(); @@ -60,7 +60,7 @@ public long getOsmIdOfInternalEdge(int edgeId) { assertTrue(Double.isInfinite(tcs.get(turnCostEnc, 4, 3, 2))); // TYPE == NOT - instance = new OSMTurnRelation(4, 3, 3, OSMTurnRelation.Type.NOT); + instance = new OSMTurnRestriction(4, 3, 3, OSMTurnRestriction.RestrictionType.NOT); parser.addRelationToTCStorage(instance, map, graph); assertTrue(Double.isInfinite(tcs.get(turnCostEnc, 4, 3, 3))); } diff --git a/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java b/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java index 6da4ff09932..12433258c43 100644 --- a/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java +++ b/core/src/test/java/com/graphhopper/storage/TurnCostStorageTest.java @@ -109,21 +109,21 @@ public void testMultipleTurnCosts() { assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(carEnc, edge02, 2, edge23), 0); assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bikeEnc, edge02, 2, edge23), 0); - Set> allTurnRelations = new HashSet<>(); - TurnCostStorage.TurnRelationIterator iterator = turnCostStorage.getAllTurnRelations(); + Set> turnCosts = new HashSet<>(); + TurnCostStorage.Iterator iterator = turnCostStorage.getAllTurnCosts(); while (iterator.next()) { - allTurnRelations.add(Arrays.asList(iterator.getFromEdge(), iterator.getViaNode(), iterator.getToEdge(), + turnCosts.add(Arrays.asList(iterator.getFromEdge(), iterator.getViaNode(), iterator.getToEdge(), (int) iterator.getCost(carEnc), (int) iterator.getCost(bikeEnc))); } - Set> expectedTurnRelations = new HashSet<>(); - expectedTurnRelations.add(Arrays.asList(edge31, 1, edge10, 2, Integer.MAX_VALUE)); - expectedTurnRelations.add(Arrays.asList(edge42, 2, edge23, Integer.MAX_VALUE, Integer.MAX_VALUE)); - expectedTurnRelations.add(Arrays.asList(edge02, 2, edge24, 0, Integer.MAX_VALUE)); - expectedTurnRelations.add(Arrays.asList(edge02, 2, edge23, Integer.MAX_VALUE, Integer.MAX_VALUE)); - expectedTurnRelations.add(Arrays.asList(edge23, 3, edge31, Integer.MAX_VALUE, 2)); + Set> expectedTurnCosts = new HashSet<>(); + expectedTurnCosts.add(Arrays.asList(edge31, 1, edge10, 2, Integer.MAX_VALUE)); + expectedTurnCosts.add(Arrays.asList(edge42, 2, edge23, Integer.MAX_VALUE, Integer.MAX_VALUE)); + expectedTurnCosts.add(Arrays.asList(edge02, 2, edge24, 0, Integer.MAX_VALUE)); + expectedTurnCosts.add(Arrays.asList(edge02, 2, edge23, Integer.MAX_VALUE, Integer.MAX_VALUE)); + expectedTurnCosts.add(Arrays.asList(edge23, 3, edge31, Integer.MAX_VALUE, 2)); - assertEquals(expectedTurnRelations, allTurnRelations); + assertEquals(expectedTurnCosts, turnCosts); } @Test @@ -142,17 +142,17 @@ public void testMergeFlagsBeforeAdding() { assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(carEnc, edge02, 2, edge23), 0); assertEquals(Double.POSITIVE_INFINITY, turnCostStorage.get(bikeEnc, edge02, 2, edge23), 0); - Set> allTurnRelations = new HashSet<>(); - TurnCostStorage.TurnRelationIterator iterator = turnCostStorage.getAllTurnRelations(); + Set> turnCosts = new HashSet<>(); + TurnCostStorage.Iterator iterator = turnCostStorage.getAllTurnCosts(); while (iterator.next()) { - allTurnRelations.add(Arrays.asList(iterator.getFromEdge(), iterator.getViaNode(), iterator.getToEdge(), + turnCosts.add(Arrays.asList(iterator.getFromEdge(), iterator.getViaNode(), iterator.getToEdge(), (int) iterator.getCost(carEnc), (int) iterator.getCost(bikeEnc))); } - Set> expectedTurnRelations = new HashSet<>(); - expectedTurnRelations.add(Arrays.asList(edge02, 2, edge23, Integer.MAX_VALUE, Integer.MAX_VALUE)); + Set> expectedTurnCosts = new HashSet<>(); + expectedTurnCosts.add(Arrays.asList(edge02, 2, edge23, Integer.MAX_VALUE, Integer.MAX_VALUE)); - assertEquals(expectedTurnRelations, allTurnRelations); + assertEquals(expectedTurnCosts, turnCosts); } @Test @@ -161,7 +161,7 @@ public void testIterateEmptyStore() { initGraph(g, accessEnc, speedEnc); TurnCostStorage turnCostStorage = g.getTurnCostStorage(); - TurnCostStorage.TurnRelationIterator iterator = turnCostStorage.getAllTurnRelations(); + TurnCostStorage.Iterator iterator = turnCostStorage.getAllTurnCosts(); assertFalse(iterator.next()); } From 4e9357517ab5b8e50cdb7db95c4b606ce3b49f36 Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 7 Oct 2022 14:04:16 +0200 Subject: [PATCH 206/389] Move OSMTurnRestriction, PillarInfo and ConditionalTagInspector to another package --- .../main/java/com/graphhopper/reader/osm/OSMNodeData.java | 1 - .../graphhopper/reader/{ => osm}/OSMTurnRestriction.java | 2 +- .../java/com/graphhopper/reader/{ => osm}/PillarInfo.java | 2 +- .../reader/osm/conditional/ConditionalOSMTagInspector.java | 1 - .../{ => osm/conditional}/ConditionalTagInspector.java | 4 +++- .../main/java/com/graphhopper/routing/util/OSMParsers.java | 2 +- .../java/com/graphhopper/routing/util/VehicleTagParser.java | 2 +- .../routing/util/parsers/OSMTurnRestrictionParser.java | 2 +- .../graphhopper/routing/util/parsers/TurnCostParser.java | 2 +- .../test/java/com/graphhopper/reader/osm/OSMReaderTest.java | 1 - .../com/graphhopper/reader/osm/OSMTurnRestrictionTest.java | 1 - .../{OSMElementTest.java => osm/ReaderElementTest.java} | 6 ++++-- .../osm/conditional/ConditionalOSMTagInspectorTest.java | 1 - .../routing/util/parsers/OSMTurnRestrictionParserTest.java | 2 +- 14 files changed, 14 insertions(+), 15 deletions(-) rename core/src/main/java/com/graphhopper/reader/{ => osm}/OSMTurnRestriction.java (99%) rename core/src/main/java/com/graphhopper/reader/{ => osm}/PillarInfo.java (98%) rename core/src/main/java/com/graphhopper/reader/{ => osm/conditional}/ConditionalTagInspector.java (91%) rename core/src/test/java/com/graphhopper/reader/{OSMElementTest.java => osm/ReaderElementTest.java} (92%) diff --git a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java index 154c5bbfbdf..b787d78edd5 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMNodeData.java @@ -20,7 +20,6 @@ import com.graphhopper.coll.GHLongIntBTree; import com.graphhopper.coll.LongIntMap; -import com.graphhopper.reader.PillarInfo; import com.graphhopper.reader.ReaderNode; import com.graphhopper.storage.Directory; import com.graphhopper.util.PointAccess; diff --git a/core/src/main/java/com/graphhopper/reader/OSMTurnRestriction.java b/core/src/main/java/com/graphhopper/reader/osm/OSMTurnRestriction.java similarity index 99% rename from core/src/main/java/com/graphhopper/reader/OSMTurnRestriction.java rename to core/src/main/java/com/graphhopper/reader/osm/OSMTurnRestriction.java index 42ff3837840..12c1ad4717e 100644 --- a/core/src/main/java/com/graphhopper/reader/OSMTurnRestriction.java +++ b/core/src/main/java/com/graphhopper/reader/osm/OSMTurnRestriction.java @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.graphhopper.reader; +package com.graphhopper.reader.osm; import java.util.*; diff --git a/core/src/main/java/com/graphhopper/reader/PillarInfo.java b/core/src/main/java/com/graphhopper/reader/osm/PillarInfo.java similarity index 98% rename from core/src/main/java/com/graphhopper/reader/PillarInfo.java rename to core/src/main/java/com/graphhopper/reader/osm/PillarInfo.java index ada0681b381..4439d90638f 100644 --- a/core/src/main/java/com/graphhopper/reader/PillarInfo.java +++ b/core/src/main/java/com/graphhopper/reader/osm/PillarInfo.java @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.graphhopper.reader; +package com.graphhopper.reader.osm; import com.graphhopper.storage.DataAccess; import com.graphhopper.storage.Directory; diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspector.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspector.java index 83300999246..eec6ac9ed42 100644 --- a/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspector.java +++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspector.java @@ -17,7 +17,6 @@ */ package com.graphhopper.reader.osm.conditional; -import com.graphhopper.reader.ConditionalTagInspector; import com.graphhopper.reader.ReaderWay; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/core/src/main/java/com/graphhopper/reader/ConditionalTagInspector.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalTagInspector.java similarity index 91% rename from core/src/main/java/com/graphhopper/reader/ConditionalTagInspector.java rename to core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalTagInspector.java index fee51086749..7b5e54eaeb8 100644 --- a/core/src/main/java/com/graphhopper/reader/ConditionalTagInspector.java +++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalTagInspector.java @@ -15,7 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.graphhopper.reader; +package com.graphhopper.reader.osm.conditional; + +import com.graphhopper.reader.ReaderWay; /** * @author Peter Karich diff --git a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java index 3a4eaed771c..e70c1041c16 100644 --- a/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java +++ b/core/src/main/java/com/graphhopper/routing/util/OSMParsers.java @@ -18,9 +18,9 @@ package com.graphhopper.routing.util; -import com.graphhopper.reader.OSMTurnRestriction; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; +import com.graphhopper.reader.osm.OSMTurnRestriction; import com.graphhopper.routing.ev.EncodedValue; import com.graphhopper.routing.util.parsers.OSMTurnRestrictionParser; import com.graphhopper.routing.util.parsers.RelationTagParser; diff --git a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java index c300e29a771..365660a11cf 100644 --- a/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/VehicleTagParser.java @@ -17,10 +17,10 @@ */ package com.graphhopper.routing.util; -import com.graphhopper.reader.ConditionalTagInspector; import com.graphhopper.reader.ReaderNode; import com.graphhopper.reader.ReaderWay; import com.graphhopper.reader.osm.conditional.ConditionalOSMTagInspector; +import com.graphhopper.reader.osm.conditional.ConditionalTagInspector; import com.graphhopper.reader.osm.conditional.DateRangeParser; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParser.java index 5fea1f7aff5..8c9245f952b 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParser.java @@ -17,7 +17,7 @@ */ package com.graphhopper.routing.util.parsers; -import com.graphhopper.reader.OSMTurnRestriction; +import com.graphhopper.reader.osm.OSMTurnRestriction; import com.graphhopper.routing.ev.BooleanEncodedValue; import com.graphhopper.routing.ev.DecimalEncodedValue; import com.graphhopper.routing.util.AccessFilter; diff --git a/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java b/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java index ed746b8c2d6..455026ecbfe 100644 --- a/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java +++ b/core/src/main/java/com/graphhopper/routing/util/parsers/TurnCostParser.java @@ -17,7 +17,7 @@ */ package com.graphhopper.routing.util.parsers; -import com.graphhopper.reader.OSMTurnRestriction; +import com.graphhopper.reader.osm.OSMTurnRestriction; import com.graphhopper.storage.Graph; /** diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java index 604816bb969..4154fa13e1b 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMReaderTest.java @@ -22,7 +22,6 @@ import com.graphhopper.GraphHopper; import com.graphhopper.GraphHopperTest; import com.graphhopper.config.Profile; -import com.graphhopper.reader.OSMTurnRestriction; import com.graphhopper.reader.ReaderElement; import com.graphhopper.reader.ReaderRelation; import com.graphhopper.reader.ReaderWay; diff --git a/core/src/test/java/com/graphhopper/reader/osm/OSMTurnRestrictionTest.java b/core/src/test/java/com/graphhopper/reader/osm/OSMTurnRestrictionTest.java index dd008de043b..77ea1916542 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/OSMTurnRestrictionTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/OSMTurnRestrictionTest.java @@ -17,7 +17,6 @@ */ package com.graphhopper.reader.osm; -import com.graphhopper.reader.OSMTurnRestriction; import org.junit.jupiter.api.Test; import java.util.ArrayList; diff --git a/core/src/test/java/com/graphhopper/reader/OSMElementTest.java b/core/src/test/java/com/graphhopper/reader/osm/ReaderElementTest.java similarity index 92% rename from core/src/test/java/com/graphhopper/reader/OSMElementTest.java rename to core/src/test/java/com/graphhopper/reader/osm/ReaderElementTest.java index 754af4851b4..4589b7fc8d3 100644 --- a/core/src/test/java/com/graphhopper/reader/OSMElementTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/ReaderElementTest.java @@ -15,8 +15,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.graphhopper.reader; +package com.graphhopper.reader.osm; +import com.graphhopper.reader.ReaderElement; +import com.graphhopper.reader.ReaderWay; import org.junit.jupiter.api.Test; import java.util.HashMap; @@ -27,7 +29,7 @@ /** * @author Peter Karich */ -public class OSMElementTest { +public class ReaderElementTest { @Test public void testHasTag() { ReaderElement instance = new ReaderWay(1); diff --git a/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspectorTest.java b/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspectorTest.java index 364d2383ea0..5efca154e75 100644 --- a/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspectorTest.java +++ b/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspectorTest.java @@ -17,7 +17,6 @@ */ package com.graphhopper.reader.osm.conditional; -import com.graphhopper.reader.ConditionalTagInspector; import com.graphhopper.reader.ReaderWay; import org.junit.jupiter.api.Test; diff --git a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParserTest.java b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParserTest.java index b46fb646fee..d4585fc04d3 100644 --- a/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParserTest.java +++ b/core/src/test/java/com/graphhopper/routing/util/parsers/OSMTurnRestrictionParserTest.java @@ -1,6 +1,6 @@ package com.graphhopper.routing.util.parsers; -import com.graphhopper.reader.OSMTurnRestriction; +import com.graphhopper.reader.osm.OSMTurnRestriction; import com.graphhopper.routing.ev.*; import com.graphhopper.routing.util.EncodingManager; import com.graphhopper.routing.util.TransportationMode; From 6df9908159bbedf3deba0ced7a39a3fc7c854b38 Mon Sep 17 00:00:00 2001 From: easbar Date: Fri, 7 Oct 2022 14:06:55 +0200 Subject: [PATCH 207/389] Remove GraphHopperOSM --- .../reader/osm/GraphHopperOSM.java | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 core/src/main/java/com/graphhopper/reader/osm/GraphHopperOSM.java diff --git a/core/src/main/java/com/graphhopper/reader/osm/GraphHopperOSM.java b/core/src/main/java/com/graphhopper/reader/osm/GraphHopperOSM.java deleted file mode 100644 index 56bfe5c93e8..00000000000 --- a/core/src/main/java/com/graphhopper/reader/osm/GraphHopperOSM.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ -package com.graphhopper.reader.osm; - -import com.graphhopper.GraphHopper; -import com.graphhopper.util.JsonFeatureCollection; - -/** - * This class only exists for backward compatibility. - * @deprecated Use {@link GraphHopper} instead. - */ -@Deprecated -public class GraphHopperOSM extends GraphHopper { -} From 1e2c349463e64509db59e78fb48114028b052372 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 7 Oct 2022 17:04:02 +0200 Subject: [PATCH 208/389] fixed bike2.yml, #2668 --- custom_models/bike2.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/custom_models/bike2.yml b/custom_models/bike2.yml index d46a4105685..29b1ebaf845 100644 --- a/custom_models/bike2.yml +++ b/custom_models/bike2.yml @@ -1,7 +1,12 @@ distance_influence: 10 speed: - - if: "average_slope >= 10", limit_to: "4" - - if: "average_slope >= 5", "multiply_by": "0.45" - - if: "average_slope >= 3.5", multiply_by: "0.7" - - if: "average_slope >= 2", multiply_by: "0.9" - - if: "average_slope < -5", multiply_by: "1.25" + - if: "average_slope >= 10" + limit_to: "4" + - if: "average_slope >= 5" + multiply_by: "0.45" + - if: "average_slope >= 3.5" + multiply_by: "0.7" + - if: "average_slope >= 2" + multiply_by: "0.9" + - if: "average_slope < -5" + multiply_by: "1.25" From 19f2757132627cd3a98303724a1035baa392761e Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 11 Oct 2022 10:26:16 +0200 Subject: [PATCH 209/389] Remove YAML support for server-side custom models (#2672) * initial version * link issue * fix in measurement too * add truck.json from #223 --- CHANGELOG.md | 7 +- benchmark/benchmark.sh | 4 +- benchmark/little_custom.json | 15 ++ benchmark/little_custom.yml | 9 -- benchmark/very_custom.json | 43 ++++++ benchmark/very_custom.yml | 24 ---- config-example.yml | 6 +- .../DefaultVehicleEncodedValuesFactory.java | 4 +- custom_models/bike2.json | 10 ++ custom_models/bike2.yml | 12 -- custom_models/car4wd.json | 20 +++ custom_models/car4wd.yml | 10 -- custom_models/curvature.json | 8 ++ custom_models/curvature.yml | 3 - custom_models/truck.json | 22 +++ tools/pom.xml | 4 - .../com/graphhopper/tools/Measurement.java | 5 +- .../java/com/graphhopper/util/Helper.java | 12 ++ .../graphhopper/http/GraphHopperManaged.java | 15 +- .../RouteResourceCustomModelTest.java | 22 +-- .../application/resources/cargo_bike.json | 49 +++++++ .../application/resources/cargo_bike.yml | 29 ---- .../application/resources/truck.json | 133 ++++++++++++++++++ .../application/resources/truck.yml | 70 --------- 24 files changed, 338 insertions(+), 198 deletions(-) create mode 100644 benchmark/little_custom.json delete mode 100644 benchmark/little_custom.yml create mode 100644 benchmark/very_custom.json delete mode 100644 benchmark/very_custom.yml create mode 100644 custom_models/bike2.json delete mode 100644 custom_models/bike2.yml create mode 100644 custom_models/car4wd.json delete mode 100644 custom_models/car4wd.yml create mode 100644 custom_models/curvature.json delete mode 100644 custom_models/curvature.yml create mode 100644 custom_models/truck.json create mode 100644 web/src/test/resources/com/graphhopper/application/resources/cargo_bike.json delete mode 100644 web/src/test/resources/com/graphhopper/application/resources/cargo_bike.yml create mode 100644 web/src/test/resources/com/graphhopper/application/resources/truck.json delete mode 100644 web/src/test/resources/com/graphhopper/application/resources/truck.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index b17f5faadb1..3c9032ee386 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ ### 7.0 [not yet released] -- Bike2WeightTagParser was removed. Use the bike vehicle with a custom model, see custom_models/bike2.yml -- Car4WDTagParser was removed. Use the roads vehicle with a custom model, see custom_models/car4wd.yml -- CurvatureWeighting was removed. Use a custom model with 'curvature' instead, see custom_models/curvature.yml (#2665) +- removed YAML support for custom models on the server-side. Only allow JSON with // comments. +- Bike2WeightTagParser was removed. Use the bike vehicle with a custom model, see custom_models/bike2.json +- Car4WDTagParser was removed. Use the roads vehicle with a custom model, see custom_models/car4wd.json +- CurvatureWeighting was removed. Use a custom model with 'curvature' instead, see custom_models/curvature.json (#2665) - internal keys for EdgeKVStorage changed to contain the street_ prefix like the path details too. Similarly, the extra_info in the instructions of the API response, see #2661 ### 6.0 [13 Sep 2022] diff --git a/benchmark/benchmark.sh b/benchmark/benchmark.sh index 7f72d46d997..c1caf9c1ee3 100755 --- a/benchmark/benchmark.sh +++ b/benchmark/benchmark.sh @@ -104,7 +104,7 @@ measurement.summaryfile=${SUMMARY_DIR}summary_big_little_custom.dat \ measurement.repeats=1 \ measurement.run_slow_routing=false \ measurement.weighting=custom \ -measurement.custom_model_file=benchmark/little_custom.yml \ +measurement.custom_model_file=benchmark/little_custom.json \ graph.encoded_values=max_width,max_height,toll,hazmat \ measurement.ch.node=true \ measurement.ch.edge=false \ @@ -135,7 +135,7 @@ measurement.summaryfile=${SUMMARY_DIR}summary_big_very_custom.dat \ measurement.repeats=1 \ measurement.run_slow_routing=false \ measurement.weighting=custom \ -measurement.custom_model_file=benchmark/very_custom.yml \ +measurement.custom_model_file=benchmark/very_custom.json \ graph.encoded_values=max_width,max_height,toll,hazmat \ measurement.ch.node=true \ measurement.ch.edge=false \ diff --git a/benchmark/little_custom.json b/benchmark/little_custom.json new file mode 100644 index 00000000000..1b548fecdd9 --- /dev/null +++ b/benchmark/little_custom.json @@ -0,0 +1,15 @@ +// this is a little customized model used to benchmark routing with a customized weighting that is similar to the +// standard car profile +{ + "priority": [ + { + "if": "road_access == PRIVATE", + "multiply_by": "0.1" + }, + { + "else_if": "road_access == DESTINATION", + "multiply_by": "0.1" + } + ], + "distance_influence": 0 +} diff --git a/benchmark/little_custom.yml b/benchmark/little_custom.yml deleted file mode 100644 index e6a5230e20c..00000000000 --- a/benchmark/little_custom.yml +++ /dev/null @@ -1,9 +0,0 @@ -# this is a little customized model used to benchmark routing with a customized weighting that is similar to the -# standard car profile -priority: - - if: road_access == PRIVATE - multiply_by: 0.1 - - else_if: road_access == DESTINATION - multiply_by: 0.1 - -distance_influence: 0 diff --git a/benchmark/very_custom.json b/benchmark/very_custom.json new file mode 100644 index 00000000000..933cb2a2e05 --- /dev/null +++ b/benchmark/very_custom.json @@ -0,0 +1,43 @@ +// this is a heavily customized model used to benchmark routing with a custom weighting +{ + "speed": [ + { + "if": "road_class == MOTORWAY", + "multiply_by": "0.85" + }, + { + "else_if": "road_class == PRIMARY", + "multiply_by": "0.9" + }, + { + "if": "true", + "limit_to": "110" + } + ], + "priority": [ + { + "if": "max_height < 3.8", + "multiply_by": "0" + }, + { + "if": "max_width < 2.5", + "multiply_by": "0" + }, + { + "if": "road_class == PRIMARY", + "multiply_by": "0.5" + }, + { + "else_if": "road_class != MOTORWAY", + "multiply_by": "0.9" + }, + { + "if": "toll != NO", + "multiply_by": "0.5" + }, + { + "if": "hazmat == NO", + "multiply_by": "0" + } + ] +} \ No newline at end of file diff --git a/benchmark/very_custom.yml b/benchmark/very_custom.yml deleted file mode 100644 index 0234ad30c13..00000000000 --- a/benchmark/very_custom.yml +++ /dev/null @@ -1,24 +0,0 @@ -# this is a heavily customized model used to benchmark routing with a custom weighting -speed: - - if: road_class == MOTORWAY - multiply_by: 0.85 - - else_if: road_class == PRIMARY - multiply_by: 0.9 - - if: true - limit_to: 110 - -priority: - - if: max_height < 3.8 - multiply_by: 0 - - if: max_width < 2.5 - multiply_by: 0 - - - if: road_class == PRIMARY - multiply_by: 0.5 - - else_if: road_class != MOTORWAY - multiply_by: 0.9 - - - if: toll != NO - multiply_by: 0.5 - - if: hazmat == NO - multiply_by: 0 diff --git a/config-example.yml b/config-example.yml index 5d1b5526a14..415338a43ca 100644 --- a/config-example.yml +++ b/config-example.yml @@ -23,7 +23,7 @@ graphhopper: # - u_turn_costs: 60 (time-penalty for doing a u-turn in seconds (only possible when `turn_costs: true`)). # Note that since the u-turn costs are given in seconds the weighting you use should also calculate the weight # in seconds, so for example it does not work with shortest weighting. - # - custom_model_file: when you specified "weighting: custom" you need to set a yaml or json file inside your custom_model_folder + # - custom_model_file: when you specified "weighting: custom" you need to set a json file inside your custom_model_folder # or working directory that defines the custom_model. If you want an empty model you can also set "custom_model_file: empty". # You can also use th e`custom_model` field instead and specify your custom model in the profile directly. # @@ -42,8 +42,8 @@ graphhopper: # - name: bike # vehicle: bike # weighting: custom - # # the custom model in bike2.yml is defined to avoid hills - # custom_model_file: bike2.yml + # # the custom model in bike2.json is defined to avoid hills + # custom_model_file: bike2.json custom_model_folder: custom_models # Speed mode: diff --git a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java index ddc9d15432c..7c0cb5e22e1 100644 --- a/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java +++ b/core/src/main/java/com/graphhopper/routing/util/DefaultVehicleEncodedValuesFactory.java @@ -34,13 +34,13 @@ public VehicleEncodedValues createVehicleEncodedValues(String name, PMap configu return VehicleEncodedValues.car(configuration); if (name.equals("car4wd")) - throw new IllegalArgumentException("Instead of car4wd use the roads vehicle and a custom_model, see web/src/test/resources/com/graphhopper/application/resources/car4wd.yml"); + throw new IllegalArgumentException("Instead of car4wd use the roads vehicle and a custom_model, see custom_models/car4wd.json"); if (name.equals(BIKE)) return VehicleEncodedValues.bike(configuration); if (name.equals("bike2")) - throw new IllegalArgumentException("Instead of bike2 use the bike vehicle and a custom model, see custom_models/bike2.yml and #1234"); + throw new IllegalArgumentException("Instead of bike2 use the bike vehicle and a custom model, see custom_models/bike2.json and #1234"); if (name.equals(RACINGBIKE)) return VehicleEncodedValues.racingbike(configuration); diff --git a/custom_models/bike2.json b/custom_models/bike2.json new file mode 100644 index 00000000000..a584226e99e --- /dev/null +++ b/custom_models/bike2.json @@ -0,0 +1,10 @@ +{ + "distance_influence": 10, + "speed": [ + { "if": "average_slope >= 10", "limit_to": "4" }, + { "if": "average_slope >= 5", "multiply_by": "0.45" }, + { "if": "average_slope >= 3.5", "multiply_by": "0.7" }, + { "if": "average_slope >= 2", "multiply_by": "0.9" }, + { "if": "average_slope < -5", "multiply_by": "1.25" } + ] +} \ No newline at end of file diff --git a/custom_models/bike2.yml b/custom_models/bike2.yml deleted file mode 100644 index 29b1ebaf845..00000000000 --- a/custom_models/bike2.yml +++ /dev/null @@ -1,12 +0,0 @@ -distance_influence: 10 -speed: - - if: "average_slope >= 10" - limit_to: "4" - - if: "average_slope >= 5" - multiply_by: "0.45" - - if: "average_slope >= 3.5" - multiply_by: "0.7" - - if: "average_slope >= 2" - multiply_by: "0.9" - - if: "average_slope < -5" - multiply_by: "1.25" diff --git a/custom_models/car4wd.json b/custom_models/car4wd.json new file mode 100644 index 00000000000..c5588c756ec --- /dev/null +++ b/custom_models/car4wd.json @@ -0,0 +1,20 @@ +// use this custom model with vehicle: roads +{ + "distance_influence": 1, + "speed": [ + { + "if": "track_type == GRADE4 || track_type == GRADE5", + "limit_to": 5 + }, + { + "else": "", + "limit_to": "car_average_speed" + } + ], + "priority": [ + { + "if": "track_type != GRADE4 && track_type != GRADE5 && car_access == false", + "multiply_by": "0" + } + ] +} \ No newline at end of file diff --git a/custom_models/car4wd.yml b/custom_models/car4wd.yml deleted file mode 100644 index 930eb4364f7..00000000000 --- a/custom_models/car4wd.yml +++ /dev/null @@ -1,10 +0,0 @@ -# use this custom model with vehicle: roads -distance_influence: 1 -speed: - - if: "track_type == GRADE4 || track_type == GRADE5" - limit_to: 5 - - else: "" - limit_to: "car_average_speed" -priority: - - if: "track_type != GRADE4 && track_type != GRADE5 && car_access == false" - multiply_by: "0" \ No newline at end of file diff --git a/custom_models/curvature.json b/custom_models/curvature.json new file mode 100644 index 00000000000..93f1b3afff4 --- /dev/null +++ b/custom_models/curvature.json @@ -0,0 +1,8 @@ +{ + "priority": [ + { + "if": "curvature > 0.9", + "multiply_by": "0.3" + } + ] +} \ No newline at end of file diff --git a/custom_models/curvature.yml b/custom_models/curvature.yml deleted file mode 100644 index 565a24bbe70..00000000000 --- a/custom_models/curvature.yml +++ /dev/null @@ -1,3 +0,0 @@ -priority: - - if: "curvature > 0.9" - multiply_by: "0.3" \ No newline at end of file diff --git a/custom_models/truck.json b/custom_models/truck.json new file mode 100644 index 00000000000..3f74086d088 --- /dev/null +++ b/custom_models/truck.json @@ -0,0 +1,22 @@ +{ + "comment0": "to use this custom model you need to set the following option in the config.yml", + "comment1": "graph.flag_encoders: roads|transportation_mode=HGV,car", + "comment2": "graph.encoded_values: toll,hgv,surface,max_width,max_height", + "distance_influence": 1, + "speed": [ + { + "if": "true", + "limit_to": "car_average_speed * 0.9" + }, + { + "if": "true", + "limit_to": "95" + } + ], + "priority": [ + { + "if": "car_access == false || hgv == NO || max_width < 3 || max_height < 4", + "multiply_by": "0" + } + ] +} \ No newline at end of file diff --git a/tools/pom.xml b/tools/pom.xml index a1d103cfba9..2aa29aece58 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -44,10 +44,6 @@ com.graphhopper.external jackson-datatype-jts - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - org.slf4j slf4j-api diff --git a/tools/src/main/java/com/graphhopper/tools/Measurement.java b/tools/src/main/java/com/graphhopper/tools/Measurement.java index 920d70fad6e..18f3ab50331 100644 --- a/tools/src/main/java/com/graphhopper/tools/Measurement.java +++ b/tools/src/main/java/com/graphhopper/tools/Measurement.java @@ -19,7 +19,6 @@ import com.carrotsearch.hppc.IntArrayList; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.graphhopper.*; import com.graphhopper.coll.GHBitSet; import com.graphhopper.coll.GHBitSetImpl; @@ -735,9 +734,9 @@ private void storeJson(String jsonLocation, boolean useMeasurementTimeAsRefTime) } private CustomModel loadCustomModel(String customModelLocation) { - ObjectMapper yamlOM = Jackson.initObjectMapper(new ObjectMapper(new YAMLFactory())); + ObjectMapper om = Jackson.initObjectMapper(new ObjectMapper()); try { - return yamlOM.readValue(new File(customModelLocation), CustomModel.class); + return om.readValue(Helper.readJSONFileWithoutComments(customModelLocation), CustomModel.class); } catch (Exception e) { throw new RuntimeException("Cannot load custom_model from " + customModelLocation, e); } diff --git a/web-api/src/main/java/com/graphhopper/util/Helper.java b/web-api/src/main/java/com/graphhopper/util/Helper.java index e168e8a8607..f13ecdf8c25 100644 --- a/web-api/src/main/java/com/graphhopper/util/Helper.java +++ b/web-api/src/main/java/com/graphhopper/util/Helper.java @@ -90,6 +90,18 @@ public static void saveProperties(Map map, Writer tmpWriter) thr } } + public static String readJSONFileWithoutComments(String file) throws IOException { + return Helper.readFile(file).stream(). + filter(line -> !line.trim().startsWith("//")). + reduce((s1, s2) -> s1 + "\n" + s2).orElse(""); + } + + public static String readJSONFileWithoutComments(InputStreamReader reader) throws IOException { + return Helper.readFile(reader).stream(). + filter(line -> !line.trim().startsWith("//")). + reduce((s1, s2) -> s1 + "\n" + s2).orElse(""); + } + public static List readFile(String file) throws IOException { return readFile(new InputStreamReader(new FileInputStream(file), UTF_CS)); } diff --git a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java index fc72db0c6be..96ae027f090 100644 --- a/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java +++ b/web-bundle/src/main/java/com/graphhopper/http/GraphHopperManaged.java @@ -19,7 +19,6 @@ package com.graphhopper.http; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.graphhopper.GraphHopper; import com.graphhopper.GraphHopperConfig; import com.graphhopper.config.Profile; @@ -28,6 +27,7 @@ import com.graphhopper.routing.weighting.custom.CustomProfile; import com.graphhopper.routing.weighting.custom.CustomWeighting; import com.graphhopper.util.CustomModel; +import com.graphhopper.util.Helper; import io.dropwizard.lifecycle.Managed; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,7 +57,6 @@ public GraphHopperManaged(GraphHopperConfig configuration) { } public static List resolveCustomModelFiles(String customModelFolder, List profiles) { - ObjectMapper yamlOM = Jackson.initObjectMapper(new ObjectMapper(new YAMLFactory())); ObjectMapper jsonOM = Jackson.newObjectMapper(); List newProfiles = new ArrayList<>(); for (Profile profile : profiles) { @@ -73,8 +72,8 @@ public static List resolveCustomModelFiles(String customModelFolder, Li newProfiles.add(new CustomProfile(profile).setCustomModel(customModel)); continue; } catch (Exception ex) { - throw new RuntimeException("Cannot load custom_model from " + cm + " for profile " + profile.getName() - + ". If you are trying to load from a file, use 'custom_model_file' instead.", ex); + throw new RuntimeException("Cannot load custom_model from " + cm + " for profile " + profile.getName() + + ". If you are trying to load from a file, use 'custom_model_file' instead.", ex); } } String customModelFileName = profile.getHints().getString("custom_model_file", ""); @@ -86,10 +85,12 @@ public static List resolveCustomModelFiles(String customModelFolder, Li else { if (customModelFileName.contains(File.separator)) throw new IllegalArgumentException("Use custom_model_folder for the custom_model_file parent"); - // Somehow dropwizard makes it very hard to find out the folder of config.yml -> use an extra parameter for the folder - File file = Paths.get(customModelFolder).resolve(customModelFileName).toFile(); + if (!customModelFileName.endsWith(".json")) + throw new IllegalArgumentException("Yaml is no longer supported, see #2672. Use JSON with optional comments //"); try { - CustomModel customModel = (customModelFileName.endsWith(".json") ? jsonOM : yamlOM).readValue(file, CustomModel.class); + // Somehow dropwizard makes it very hard to find out the folder of config.yml -> use an extra parameter for the folder + String string = Helper.readJSONFileWithoutComments(Paths.get(customModelFolder).resolve(customModelFileName).toFile().getAbsolutePath()); + CustomModel customModel = jsonOM.readValue(string, CustomModel.class); newProfiles.add(new CustomProfile(profile).setCustomModel(customModel)); } catch (Exception ex) { throw new RuntimeException("Cannot load custom_model from location " + customModelFileName + " for profile " + profile.getName(), ex); diff --git a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java index 01a5ee8cec2..965b410e1a5 100644 --- a/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java +++ b/web/src/test/java/com/graphhopper/application/resources/RouteResourceCustomModelTest.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.graphhopper.application.GraphHopperApplication; import com.graphhopper.application.GraphHopperServerConfiguration; import com.graphhopper.application.util.GraphHopperServerTestConfiguration; @@ -42,6 +41,7 @@ import javax.ws.rs.core.Response; import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; import java.util.Arrays; import static com.graphhopper.application.util.TestUtils.clientTarget; @@ -72,9 +72,9 @@ private static GraphHopperServerConfiguration createConfig() { new CustomProfile("bike").setCustomModel(new CustomModel().setDistanceInfluence(0)).setVehicle("bike"), new Profile("bike_fastest").setWeighting("fastest").setVehicle("bike"), new CustomProfile("truck").setVehicle("car"). - putHint("custom_model_file", "truck.yml"), + putHint("custom_model_file", "truck.json"), new CustomProfile("cargo_bike").setVehicle("bike"). - putHint("custom_model_file", "cargo_bike.yml"), + putHint("custom_model_file", "cargo_bike.json"), new CustomProfile("json_bike").setVehicle("bike"). putHint("custom_model_file", "json_bike.json"), new Profile("foot_profile").setVehicle("foot").setWeighting("fastest"), @@ -222,8 +222,8 @@ public void testCargoBike() throws IOException { JsonNode path = getPath(body); assertEquals(path.get("distance").asDouble(), 661, 5); - String jsonFromYamlFile = yamlToJson(Helper.isToString(getClass().getResourceAsStream("cargo_bike.yml"))); - body = "{\"points\": [[11.58199, 50.0141], [11.5865, 50.0095]], \"profile\": \"bike\", \"custom_model\":" + jsonFromYamlFile + ", \"ch.disable\": true}"; + String json = Helper.readJSONFileWithoutComments(new InputStreamReader(getClass().getResourceAsStream("cargo_bike.json"))); + body = "{\"points\": [[11.58199, 50.0141], [11.5865, 50.0095]], \"profile\": \"bike\", \"custom_model\":" + json + ", \"ch.disable\": true}"; path = getPath(body); assertEquals(path.get("distance").asDouble(), 1007, 5); @@ -382,16 +382,4 @@ Response query(String body, int code) { assertEquals(code, response.getStatus(), jsonNode.has("message") ? jsonNode.get("message").toString() : "no error message"); return response; } - - private static String yamlToJson(String yaml) { - try { - ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); - Object obj = yamlReader.readValue(yaml, Object.class); - - ObjectMapper jsonWriter = new ObjectMapper(); - return jsonWriter.writeValueAsString(obj); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } } \ No newline at end of file diff --git a/web/src/test/resources/com/graphhopper/application/resources/cargo_bike.json b/web/src/test/resources/com/graphhopper/application/resources/cargo_bike.json new file mode 100644 index 00000000000..11dfb341d94 --- /dev/null +++ b/web/src/test/resources/com/graphhopper/application/resources/cargo_bike.json @@ -0,0 +1,49 @@ +// For a custom request you need to specify a profile (with weighting=custom) but on import we don't need this +// profile: bike +// let's assume cargo bikes are e-bikes and we should lower speed to prefer shorter and not faster routes automatically +{ + "speed": [ + { + "if": "road_class == PRIMARY", + "limit_to": 28 + }, + { + "else": null, + "limit_to": 25 + } + ], + "priority": [ + // exclude steps + { + "if": "road_class == STEPS", + "multiply_by": 0 + }, + { + "if": "surface == SAND", + "multiply_by": 0.5 + }, + // prefer better tracks + { + "if": "track_type != MISSING && track_type != GRADE1", + "multiply_by": 0.9 + }, + // prefer official bike routes + { + "if": "bike_network == OTHER", + "multiply_by": 0.5 + }, + // avoid all situations where we have to get off the bike + { + "if": "get_off_bike", + "multiply_by": 0.5 + }, + { + "if": "max_height < 2.3", + "multiply_by": 0 + }, + { + "if": "max_width < 1.2", + "multiply_by": 0 + } + ] +} \ No newline at end of file diff --git a/web/src/test/resources/com/graphhopper/application/resources/cargo_bike.yml b/web/src/test/resources/com/graphhopper/application/resources/cargo_bike.yml deleted file mode 100644 index 36e3d7ab50c..00000000000 --- a/web/src/test/resources/com/graphhopper/application/resources/cargo_bike.yml +++ /dev/null @@ -1,29 +0,0 @@ -# For a custom request you need to specify a profile (with weighting=custom) but on import we don't need this -# profile: bike - -# let's assume cargo bikes are e-bikes and we should lower speed to prefer shorter and not faster routes automatically -speed: - - if: road_class == PRIMARY - limit_to: 28 - - else: - limit_to: 25 - -priority: - # exclude steps - - if: road_class == STEPS - multiply_by: 0 - - if: surface == SAND - multiply_by: 0.5 - # prefer better tracks - - if: track_type != MISSING && track_type != GRADE1 - multiply_by: 0.9 - # prefer official bike routes - - if: bike_network == OTHER - multiply_by: 0.5 - # avoid all situations where we have to get off the bike - - if: get_off_bike - multiply_by: 0.5 - - if: max_height < 2.3 - multiply_by: 0 - # oneliner - - { if: "max_width < 1.2", multiply_by: 0 } diff --git a/web/src/test/resources/com/graphhopper/application/resources/truck.json b/web/src/test/resources/com/graphhopper/application/resources/truck.json new file mode 100644 index 00000000000..e73bff27cdc --- /dev/null +++ b/web/src/test/resources/com/graphhopper/application/resources/truck.json @@ -0,0 +1,133 @@ +// For a custom request you need to specify a profile (with weighting=custom) but on import we don't need this +// profile: car + +// Now we want to set a preference without changing the taken time. The default priority is 1 and does not change something. +// The minimum value is 0 (block access). A value lower than 1 will avoid it. Values higher than 1 are only allowed for server-side models. +// To prefer a certain case you lower the priority of all other entries. See the road_class entry where motorways are preferred. +// If two conditions are met the values will be multiplied except when first_match is used. + +{ + // This term changes the influence of the distance. I.e. longer roads get a higher cost. + // The distance_influence is independent of the edge properties and does not influence the ETA. The default is 70 (seconds/1km). + // Let's assume a route that takes 1000sec and is 10km long, then a value of 30 means that I would like to drive maximum 11km + // to reduce the travel time to 970sec or 12km to reduce it to 940sec. + "distance_influence": 90, + "priority": [ + { + "if": "road_class == RESIDENTIAL", + "multiply_by": 0.4 + }, + { + "else_if": "road_class != MOTORWAY", + "multiply_by": 0.9 + }, + // and if you do not want that routes go over tracks just exclude them: + // { "else_if": "road_class==TRACK", "multiply_by": "0" } + // let's assume we transport gas: so NEVER go on restricted roads with hazmat==NO + { + "if": "hazmat == NO", + "multiply_by": 0 + }, + // avoid destination-only roads + // TODO include private and delivery only access for base car profile so that we can avoid it here, but not exclude it + { + "if": "road_access == DESTINATION", + "multiply_by": 0.1 + }, + // avoid turns if possible and links are one simple indication for that + { + "if": "road_class_link", + "multiply_by": 0.5 + }, + // avoid toll roads + { + "if": "toll != NO", + "multiply_by": 0.5 + }, + // avoid a certain area + { + "if": "in_custom1", + "multiply_by": 0.5 + }, + { + "if": "max_weight < 4.5", + "multiply_by": 0 + }, + { + "if": "max_height < 3.8", + "multiply_by": 0 + }, + { + "if": "max_width < 2.5", + "multiply_by": 0 + } + ], + // The formula is defined in CustomWeighting, where the "multiply_by" operation can be used to decrease speed. + // The minimum value is 0 and the maximum is 1. If two conditions are satisfied the values are + // multiplied e.g. if road_class==MOTORWAY and road_environment==TUNNEL, then the resulting speed is + // average_speed*0.85*0.9 + "speed": [ + { + "if": "road_environment == TUNNEL", + "multiply_by": 0.85 + }, + // trucks should be a bit slower on certain road classes compared to the 'base' car + { + "if": "road_class == MOTORWAY", + "multiply_by": 0.85 + }, + { + "if": "road_class == PRIMARY", + "multiply_by": 0.9 + }, + // You can lower the average speed for certain conditions via the "limit_to" operation: + { + "if": "road_class == MOTORWAY", + "limit_to": 95 + }, + { + "if": "road_class == RESIDENTIAL", + "limit_to": 30 + }, + { + "if": "road_environment == BRIDGE", + "limit_to": 85 + }, + { + "else": null, + "limit_to": 100 + } + ], + "areas": { + "custom1": { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 13.722, + 51.053 + ], + [ + 13.722, + 51.055 + ], + [ + 13.731, + 51.055 + ], + [ + 13.731, + 51.053 + ], + [ + 13.722, + 51.053 + ] + ] + ] + } + } + } +} \ No newline at end of file diff --git a/web/src/test/resources/com/graphhopper/application/resources/truck.yml b/web/src/test/resources/com/graphhopper/application/resources/truck.yml deleted file mode 100644 index 2fade4ff4a4..00000000000 --- a/web/src/test/resources/com/graphhopper/application/resources/truck.yml +++ /dev/null @@ -1,70 +0,0 @@ -# For a custom request you need to specify a profile (with weighting=custom) but on import we don't need this -# profile: car - -# This term changes the influence of the distance. I.e. longer roads get a higher cost. -# The distance_influence is independent of the edge properties and does not influence the ETA. The default is 70 (seconds/1km). -# Let's assume a route that takes 1000sec and is 10km long, then a value of 30 means that I would like to drive maximum 11km -# to reduce the travel time to 970sec or 12km to reduce it to 940sec. -distance_influence: 90 - -# Now we want to set a preference without changing the taken time. The default priority is 1 and does not change something. -# The minimum value is 0 (block access). A value lower than 1 will avoid it. Values higher than 1 are not allowed. -# To prefer a certain case you lower the priority of all other entries. See the road_class entry where motorways are preferred. -# If two conditions are met the values will be multiplied except when first_match is used. -priority: - - if: road_class == RESIDENTIAL - multiply_by: 0.4 - - else_if: road_class != MOTORWAY - multiply_by: 0.9 - # and if you do not want that routes go over tracks just exclude them: - # else_if: road_class==TRACK - # multiply_by: 0 - # let's assume we transport gas: so NEVER go on restricted roads with hazmat==NO - - if: hazmat == NO - multiply_by: 0 - # avoid destination-only roads - # TODO include private and delivery only access for base car profile so that we can avoid it here, but not exclude it - - if: road_access == DESTINATION - multiply_by: 0.1 - # avoid turns if possible and links are one simple indication for that - - if: road_class_link - multiply_by: 0.5 - # avoid toll roads - - if: toll != NO - multiply_by: 0.5 - # avoid a certain area - - if: in_custom1 - multiply_by: 0.5 - - if: max_weight < 4.5 - multiply_by: 0 - - if: max_height < 3.8 - multiply_by: 0 - - if: max_width < 2.5 - multiply_by: 0 - -# The formula is defined in CustomWeighting, where the "multiply_by" operation can be used to decrease speed. -# The minimum value is 0 and the maximum is 1. If two conditions are satisfied the values are -# multiplied e.g. if road_class==MOTORWAY and road_environment==TUNNEL, then the resulting speed is -# average_speed*0.85*0.9 -speed: - - if: road_environment == TUNNEL - multiply_by: 0.85 - # trucks should be a bit slower on certain road classes compared to the 'base' car - - if: road_class == MOTORWAY - multiply_by: 0.85 - - if: road_class == PRIMARY - multiply_by: 0.9 - # You can lower the average speed for certain conditions via the "limit_to" operation: - - if: road_class == MOTORWAY - limit_to: 95 - - if: road_class == RESIDENTIAL - limit_to: 30 - - if: road_environment == BRIDGE - limit_to: 85 - - else: - limit_to: 100 - -areas: - custom1: - type: "Feature" - geometry: { type: "Polygon", coordinates: [ [ [ 13.722, 51.053 ], [ 13.722, 51.055 ], [ 13.731, 51.055 ], [ 13.731, 51.053 ], [ 13.722, 51.053 ] ] ] } \ No newline at end of file From 5580bbc6f284ffc1374ac093c1fae33d5c8ff20f Mon Sep 17 00:00:00 2001 From: Andi Date: Fri, 14 Oct 2022 08:36:37 +0200 Subject: [PATCH 210/389] Replace old with new maps client (#2674) --- README.md | 2 +- core/files/licenses/D3-LICENSE.txt | 26 - core/files/licenses/MAPBOX-LICENSE.txt | 28 - core/files/licenses/autocomplete-license.txt | 21 - core/files/licenses/copying-osmosis.txt | 16 - docs/core/deploy.md | 13 +- docs/core/quickstart-from-source.md | 52 +- docs/index.md | 9 +- pom.xml | 4 + web-bundle/.jshintignore | 2 - web-bundle/package.json | 47 - web-bundle/pom.xml | 56 +- .../resources/com/graphhopper/maps/config.js | 22 + .../maps/css/L.Control.Heightgraph.css | 148 --- .../css/codemirror/addon/hint/show-hint.css | 37 - .../maps/css/codemirror/addon/lint/lint.css | 73 -- .../maps/css/codemirror/lib/codemirror.css | 352 ------ .../graphhopper/maps/css/flatpickr.min.css | 13 - .../maps/css/images/area-chart.svg | 1 - .../graphhopper/maps/css/images/elevation.png | Bin 687 -> 0 bytes .../graphhopper/maps/css/images/layers-2x.png | Bin 1259 -> 0 bytes .../graphhopper/maps/css/images/layers.png | Bin 696 -> 0 bytes .../maps/css/images/marker-icon-2x.png | Bin 2464 -> 0 bytes .../maps/css/images/marker-icon.png | Bin 1466 -> 0 bytes .../maps/css/images/marker-shadow.png | Bin 618 -> 0 bytes .../graphhopper/maps/css/images/remove.svg | 1 - .../maps/css/leaflet.contextmenu.css | 54 - .../com/graphhopper/maps/css/leaflet.css | 640 ----------- .../graphhopper/maps/css/leaflet.loading.css | 26 - .../maps/css/leaflet_numbered_markers.css | 12 - .../com/graphhopper/maps/css/style.css | 528 --------- .../maps/css/ui-lightness/LICENSE.txt | 43 - .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin 418 -> 0 bytes .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin 312 -> 0 bytes .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin 262 -> 0 bytes .../images/ui-bg_glass_100_fdf5ce_1x400.png | Bin 348 -> 0 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 207 -> 0 bytes .../ui-bg_gloss-wave_35_f6a828_500x100.png | Bin 5815 -> 0 bytes .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin 278 -> 0 bytes .../ui-bg_highlight-soft_75_ffe45c_1x100.png | Bin 328 -> 0 bytes .../images/ui-icons_222222_256x240.png | Bin 6922 -> 0 bytes .../images/ui-icons_228ef1_256x240.png | Bin 4549 -> 0 bytes .../images/ui-icons_ef8c08_256x240.png | Bin 4549 -> 0 bytes .../images/ui-icons_ffd27a_256x240.png | Bin 4549 -> 0 bytes .../images/ui-icons_ffffff_256x240.png | Bin 6299 -> 0 bytes .../maps/css/ui-lightness/jquery-ui.min.css | 7 - .../css/ui-lightness/jquery-ui.theme.min.css | 5 - .../com/graphhopper/maps/favicon.ico | Bin 15086 -> 0 bytes .../com/graphhopper/maps/img/alt_route.png | Bin 562 -> 0 bytes .../com/graphhopper/maps/img/bike.png | Bin 2051 -> 0 bytes .../com/graphhopper/maps/img/bike2.png | Bin 2414 -> 0 bytes .../com/graphhopper/maps/img/bus.png | Bin 1034 -> 0 bytes .../com/graphhopper/maps/img/bus.svg | 171 --- .../com/graphhopper/maps/img/car.png | Bin 1018 -> 0 bytes .../com/graphhopper/maps/img/car4wd.png | Bin 1122 -> 0 bytes .../com/graphhopper/maps/img/continue.png | Bin 807 -> 0 bytes .../com/graphhopper/maps/img/delete.png | Bin 257 -> 0 bytes .../graphhopper/maps/img/direction-icons.svg | 499 -------- .../com/graphhopper/maps/img/foot.png | Bin 1122 -> 0 bytes .../com/graphhopper/maps/img/foot.svg | 150 --- .../com/graphhopper/maps/img/full-reverse.png | Bin 582 -> 0 bytes .../com/graphhopper/maps/img/full-reverse.svg | 106 -- .../com/graphhopper/maps/img/full.png | Bin 546 -> 0 bytes .../com/graphhopper/maps/img/full.svg | 98 -- .../com/graphhopper/maps/img/gpx.png | Bin 405 -> 0 bytes .../com/graphhopper/maps/img/header.png | Bin 14196 -> 0 bytes .../com/graphhopper/maps/img/hike.png | Bin 1783 -> 0 bytes .../com/graphhopper/maps/img/hike.svg | 175 --- .../com/graphhopper/maps/img/icon.png | Bin 21575 -> 0 bytes .../graphhopper/maps/img/indicator-bar.gif | Bin 723 -> 0 bytes .../com/graphhopper/maps/img/indicator.gif | Bin 847 -> 0 bytes .../com/graphhopper/maps/img/keep_left.png | Bin 1948 -> 0 bytes .../com/graphhopper/maps/img/keep_right.png | Bin 1910 -> 0 bytes .../com/graphhopper/maps/img/left.png | Bin 1302 -> 0 bytes .../com/graphhopper/maps/img/link.png | Bin 343 -> 0 bytes .../com/graphhopper/maps/img/loading.gif | Bin 1840 -> 0 bytes .../com/graphhopper/maps/img/marker-from.png | Bin 672 -> 0 bytes .../graphhopper/maps/img/marker-icon-blue.png | Bin 1745 -> 0 bytes .../maps/img/marker-icon-green.png | Bin 1660 -> 0 bytes .../graphhopper/maps/img/marker-icon-red.png | Bin 1768 -> 0 bytes .../maps/img/marker-small-blue.png | Bin 598 -> 0 bytes .../maps/img/marker-small-green.png | Bin 596 -> 0 bytes .../graphhopper/maps/img/marker-small-red.png | Bin 630 -> 0 bytes .../com/graphhopper/maps/img/marker-to.png | Bin 665 -> 0 bytes .../com/graphhopper/maps/img/marker_hole.png | Bin 4586 -> 0 bytes .../com/graphhopper/maps/img/motorcycle.png | Bin 1676 -> 0 bytes .../com/graphhopper/maps/img/motorcycle.svg | 149 --- .../com/graphhopper/maps/img/mtb-bicycle.svg | 153 --- .../com/graphhopper/maps/img/mtb.png | Bin 1623 -> 0 bytes .../com/graphhopper/maps/img/point_add.png | Bin 438 -> 0 bytes .../com/graphhopper/maps/img/point_delete.png | Bin 402 -> 0 bytes .../resources/com/graphhopper/maps/img/pt.png | Bin 789 -> 0 bytes .../resources/com/graphhopper/maps/img/pt.svg | 68 -- .../com/graphhopper/maps/img/pt_end_trip.png | Bin 1649 -> 0 bytes .../graphhopper/maps/img/pt_start_trip.png | Bin 1667 -> 0 bytes .../graphhopper/maps/img/pt_transfer_to.png | Bin 1751 -> 0 bytes .../com/graphhopper/maps/img/racingbike.png | Bin 890 -> 0 bytes .../com/graphhopper/maps/img/racingbike.svg | 168 --- .../com/graphhopper/maps/img/right.png | Bin 1237 -> 0 bytes .../com/graphhopper/maps/img/roundabout.png | Bin 1494 -> 0 bytes .../com/graphhopper/maps/img/scooter.png | Bin 1280 -> 0 bytes .../com/graphhopper/maps/img/scooter.svg | 150 --- .../com/graphhopper/maps/img/sharp_left.png | Bin 1373 -> 0 bytes .../com/graphhopper/maps/img/sharp_right.png | Bin 1472 -> 0 bytes .../com/graphhopper/maps/img/slight_left.png | Bin 1117 -> 0 bytes .../com/graphhopper/maps/img/slight_right.png | Bin 1098 -> 0 bytes .../com/graphhopper/maps/img/small_truck.png | Bin 962 -> 0 bytes .../com/graphhopper/maps/img/small_truck.svg | 163 --- .../com/graphhopper/maps/img/truck.png | Bin 908 -> 0 bytes .../com/graphhopper/maps/img/truck.svg | 170 --- .../com/graphhopper/maps/img/u_turn.png | Bin 1461 -> 0 bytes .../com/graphhopper/maps/img/u_turn_left.png | Bin 1461 -> 0 bytes .../com/graphhopper/maps/img/u_turn_right.png | Bin 1480 -> 0 bytes .../com/graphhopper/maps/img/unknown.png | Bin 721 -> 0 bytes .../com/graphhopper/maps/img/wheelchair.png | Bin 1281 -> 0 bytes .../com/graphhopper/maps/img/wheelchair.svg | 122 -- .../resources/com/graphhopper/maps/index.html | 152 --- .../com/graphhopper/maps/isochrone/index.css | 52 - .../com/graphhopper/maps/isochrone/index.html | 66 -- .../com/graphhopper/maps/isochrone/index.js | 268 ----- .../com/graphhopper/maps/js/autocomplete.js | 174 --- .../com/graphhopper/maps/js/config/options.js | 21 - .../graphhopper/maps/js/config/tileLayers.js | 212 ---- .../com/graphhopper/maps/js/gpxexport.js | 88 -- .../maps/js/graphhopper/GHInput.js | 67 -- .../maps/js/graphhopper/GHRequest.js | 351 ------ .../maps/js/graphhopper/GHRoute.js | 223 ---- .../graphhopper/maps/js/graphhopper/tools.js | 53 - .../com/graphhopper/maps/js/instructions.js | 136 --- .../js/lib/jquery-ui-custom-1.12.0.min.js | 9 - .../maps/js/lib/jquery.autocomplete.js | 831 -------------- .../graphhopper/maps/js/lib/jquery.history.js | 1 - .../maps/js/lib/leaflet_numbered_markers.js | 30 - .../com/graphhopper/maps/js/main-template.js | 1002 ----------------- .../resources/com/graphhopper/maps/js/map.js | 616 ---------- .../com/graphhopper/maps/js/messages.js | 59 - .../com/graphhopper/maps/js/nominatim.js | 152 --- .../graphhopper/maps/js/routeManipulation.js | 31 - .../com/graphhopper/maps/js/tools/format.js | 70 -- .../com/graphhopper/maps/js/tools/math.js | 25 - .../com/graphhopper/maps/js/tools/url.js | 78 -- .../com/graphhopper/maps/js/translate.js | 181 --- .../map-matching/css/images/layers-2x.png | Bin 2898 -> 0 bytes .../maps/map-matching/css/images/layers.png | Bin 1502 -> 0 bytes .../maps/map-matching/css/images/loading.gif | Bin 1840 -> 0 bytes .../css/images/marker-icon-2x.png | Bin 4033 -> 0 bytes .../map-matching/css/images/marker-icon.png | Bin 1747 -> 0 bytes .../map-matching/css/images/marker-shadow.png | Bin 797 -> 0 bytes .../maps/map-matching/css/style.css | 16 - .../maps/map-matching/img/header.png | Bin 14196 -> 0 bytes .../graphhopper/maps/map-matching/index.html | 44 - .../maps/map-matching/js/GHUtil.js | 129 --- .../graphhopper/maps/map-matching/js/demo.js | 173 --- .../maps/map-matching/js/togeojson.js | 392 ------- .../com/graphhopper/maps/opensearch.xml | 12 - .../com/graphhopper/maps/pt/data/Leg.js | 66 -- .../com/graphhopper/maps/pt/data/Path.js | 117 -- .../com/graphhopper/maps/pt/data/PtLeg.js | 72 -- .../com/graphhopper/maps/pt/data/Query.js | 82 -- .../com/graphhopper/maps/pt/data/WalkLeg.js | 38 - .../com/graphhopper/maps/pt/data/Waypoint.js | 205 ---- .../com/graphhopper/maps/pt/favicon.png | Bin 21575 -> 0 bytes .../com/graphhopper/maps/pt/index.html | 81 -- .../com/graphhopper/maps/pt/view/App.css | 31 - .../com/graphhopper/maps/pt/view/App.js | 143 --- .../maps/pt/view/components/Inputs.css | 22 - .../maps/pt/view/components/Inputs.js | 65 -- .../maps/pt/view/components/SecondaryText.css | 4 - .../maps/pt/view/components/SecondaryText.js | 7 - .../graphhopper/maps/pt/view/img/arrow.svg | 7 - .../com/graphhopper/maps/pt/view/img/bus.png | Bin 1034 -> 0 bytes .../com/graphhopper/maps/pt/view/img/foot.png | Bin 1122 -> 0 bytes .../com/graphhopper/maps/pt/view/img/logo.png | Bin 7956 -> 0 bytes .../com/graphhopper/maps/pt/view/map/Map.css | 4 - .../com/graphhopper/maps/pt/view/map/Map.js | 257 ----- .../graphhopper/maps/pt/view/map/circle.png | Bin 764 -> 0 bytes .../graphhopper/maps/pt/view/sidebar/Leg.css | 27 - .../graphhopper/maps/pt/view/sidebar/Leg.js | 104 -- .../maps/pt/view/sidebar/SearchInput.css | 44 - .../maps/pt/view/sidebar/SearchInput.js | 206 ---- .../maps/pt/view/sidebar/Sidebar.css | 81 -- .../maps/pt/view/sidebar/Sidebar.js | 76 -- .../maps/pt/view/sidebar/TripDisplay.css | 111 -- .../maps/pt/view/sidebar/TripDisplay.js | 123 -- .../maps/pt/view/sidebar/TripElement.css | 117 -- .../maps/pt/view/sidebar/TripElement.js | 201 ---- .../maps/spec/config/TileLayersSpec.js | 30 - .../maps/spec/graphhopper/GHInputSpec.js | 32 - .../maps/spec/graphhopper/GHRequestSpec.js | 72 -- .../maps/spec/graphhopper/ToolsSpec.js | 20 - .../maps/spec/helpers/requireFile.js | 3 - .../com/graphhopper/maps/spec/jasmine.json | 9 - .../maps/spec/routeManipulationSpec.js | 110 -- .../graphhopper/maps/spec/tools/formatSpec.js | 24 - .../graphhopper/maps/spec/tools/urlSpec.js | 62 - .../graphhopper/maps/spec/translateSpec.js | 73 -- 196 files changed, 85 insertions(+), 12935 deletions(-) delete mode 100644 core/files/licenses/D3-LICENSE.txt delete mode 100644 core/files/licenses/MAPBOX-LICENSE.txt delete mode 100644 core/files/licenses/autocomplete-license.txt delete mode 100644 core/files/licenses/copying-osmosis.txt delete mode 100644 web-bundle/.jshintignore delete mode 100644 web-bundle/package.json create mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/config.js delete mode 100755 web-bundle/src/main/resources/com/graphhopper/maps/css/L.Control.Heightgraph.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/addon/hint/show-hint.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/addon/lint/lint.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/lib/codemirror.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/flatpickr.min.css delete mode 100755 web-bundle/src/main/resources/com/graphhopper/maps/css/images/area-chart.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/images/elevation.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/images/layers-2x.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/images/layers.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/images/marker-icon-2x.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/images/marker-icon.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/images/marker-shadow.png delete mode 100755 web-bundle/src/main/resources/com/graphhopper/maps/css/images/remove.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.contextmenu.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.loading.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet_numbered_markers.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/style.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/LICENSE.txt delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-icons_222222_256x240.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-icons_228ef1_256x240.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-icons_ef8c08_256x240.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-icons_ffd27a_256x240.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-icons_ffffff_256x240.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/jquery-ui.min.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/jquery-ui.theme.min.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/favicon.ico delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/alt_route.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/bike.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/bike2.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/bus.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/bus.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/car.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/car4wd.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/continue.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/delete.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/direction-icons.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/foot.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/foot.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/full-reverse.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/full-reverse.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/full.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/full.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/gpx.png delete mode 100755 web-bundle/src/main/resources/com/graphhopper/maps/img/header.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/hike.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/hike.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/icon.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/indicator-bar.gif delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/indicator.gif delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/keep_left.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/keep_right.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/left.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/link.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/loading.gif delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/marker-from.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/marker-icon-blue.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/marker-icon-green.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/marker-icon-red.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/marker-small-blue.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/marker-small-green.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/marker-small-red.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/marker-to.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/marker_hole.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/motorcycle.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/motorcycle.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/mtb-bicycle.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/mtb.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/point_add.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/point_delete.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/pt.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/pt.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/pt_end_trip.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/pt_start_trip.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/pt_transfer_to.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/racingbike.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/racingbike.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/right.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/roundabout.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/scooter.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/scooter.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/sharp_left.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/sharp_right.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/slight_left.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/slight_right.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/small_truck.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/small_truck.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/truck.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/truck.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/u_turn.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/u_turn_left.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/u_turn_right.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/unknown.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/wheelchair.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/img/wheelchair.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/index.html delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.html delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/autocomplete.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/config/options.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/gpxexport.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHInput.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRequest.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRoute.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/tools.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/instructions.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery-ui-custom-1.12.0.min.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery.autocomplete.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery.history.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/lib/leaflet_numbered_markers.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/map.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/messages.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/nominatim.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/routeManipulation.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/tools/format.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/tools/math.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/tools/url.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/js/translate.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/css/images/layers-2x.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/css/images/layers.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/css/images/loading.gif delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/css/images/marker-icon-2x.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/css/images/marker-icon.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/css/images/marker-shadow.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/css/style.css delete mode 100755 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/img/header.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/index.html delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/js/GHUtil.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/js/demo.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/map-matching/js/togeojson.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/opensearch.xml delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/data/Leg.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/data/Path.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/data/PtLeg.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/data/Query.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/data/WalkLeg.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/data/Waypoint.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/favicon.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/index.html delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/App.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/App.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/components/Inputs.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/components/Inputs.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/components/SecondaryText.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/components/SecondaryText.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/img/arrow.svg delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/img/bus.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/img/foot.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/img/logo.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/map/Map.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/map/Map.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/map/circle.png delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/sidebar/Leg.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/sidebar/Leg.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/sidebar/SearchInput.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/sidebar/SearchInput.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/sidebar/Sidebar.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/sidebar/Sidebar.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/sidebar/TripDisplay.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/sidebar/TripDisplay.js delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/sidebar/TripElement.css delete mode 100644 web-bundle/src/main/resources/com/graphhopper/maps/pt/view/sidebar/TripElement.js delete mode 100644 web-bundle/src/test/resources/com/graphhopper/maps/spec/config/TileLayersSpec.js delete mode 100644 web-bundle/src/test/resources/com/graphhopper/maps/spec/graphhopper/GHInputSpec.js delete mode 100644 web-bundle/src/test/resources/com/graphhopper/maps/spec/graphhopper/GHRequestSpec.js delete mode 100644 web-bundle/src/test/resources/com/graphhopper/maps/spec/graphhopper/ToolsSpec.js delete mode 100644 web-bundle/src/test/resources/com/graphhopper/maps/spec/helpers/requireFile.js delete mode 100644 web-bundle/src/test/resources/com/graphhopper/maps/spec/jasmine.json delete mode 100644 web-bundle/src/test/resources/com/graphhopper/maps/spec/routeManipulationSpec.js delete mode 100644 web-bundle/src/test/resources/com/graphhopper/maps/spec/tools/formatSpec.js delete mode 100644 web-bundle/src/test/resources/com/graphhopper/maps/spec/tools/urlSpec.js delete mode 100644 web-bundle/src/test/resources/com/graphhopper/maps/spec/translateSpec.js diff --git a/README.md b/README.md index 0e5e70ed604..2ceb8313537 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ The Docker images created by the community from the `master` branch can be found To see the road routing feature of GraphHopper in action please go to [GraphHopper Maps](https://graphhopper.com/maps). -[![GraphHopper Maps](https://karussell.files.wordpress.com/2014/12/graphhopper-maps-0-4-preview.png)](https://graphhopper.com/maps) +[![GraphHopper Maps](https://www.graphhopper.com/wp-content/uploads/2022/10/maps2-1024x661.png)](https://graphhopper.com/maps) GraphHopper Maps uses the commercial offering the [GraphHopper Directions API](https://www.graphhopper.com) under the hood, which provides the Routing API (based on this routing engine), a Route Optimization API based on [jsprit](http://jsprit.github.io/), a fast Matrix API and an address search based on [photon](https://github.com/komoot/photon). The photon project is also supported by the GraphHopper GmbH. Additionally to the GraphHopper Directions API, map tiles from various providers are used where the default is [Omniscale](http://omniscale.com/). All this is available for free, via encrypted connections and from German servers for a nice and private route planning experience! diff --git a/core/files/licenses/D3-LICENSE.txt b/core/files/licenses/D3-LICENSE.txt deleted file mode 100644 index fb7d95d70ba..00000000000 --- a/core/files/licenses/D3-LICENSE.txt +++ /dev/null @@ -1,26 +0,0 @@ -Copyright (c) 2014, Michael Bostock -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* The name Michael Bostock may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/core/files/licenses/MAPBOX-LICENSE.txt b/core/files/licenses/MAPBOX-LICENSE.txt deleted file mode 100644 index 793dca9fb74..00000000000 --- a/core/files/licenses/MAPBOX-LICENSE.txt +++ /dev/null @@ -1,28 +0,0 @@ -BSD License - -Copyright© 2012, MapBox, LLC. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -* Neither the name of the Development Seed, Inc. nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/core/files/licenses/autocomplete-license.txt b/core/files/licenses/autocomplete-license.txt deleted file mode 100644 index 11b3ff11a79..00000000000 --- a/core/files/licenses/autocomplete-license.txt +++ /dev/null @@ -1,21 +0,0 @@ -Copyright 2012 DevBridge and other contributors -http://www.devbridge.com/projects/autocomplete/jquery/ - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/core/files/licenses/copying-osmosis.txt b/core/files/licenses/copying-osmosis.txt deleted file mode 100644 index 4e6d150af98..00000000000 --- a/core/files/licenses/copying-osmosis.txt +++ /dev/null @@ -1,16 +0,0 @@ -Osmosis consists of all files in this archive with the exception of the -third party libraries in the lib sub-directory, and the osmosis-osm-binary -library which is a re-packaged version of a third-party library. - -Osmosis is placed into the public domain and where this is not legally -possible everybody is granted a perpetual, irrevocable license to use -this work for any purpose whatsoever. - -DISCLAIMERS -By making Osmosis publicly available, it is hoped that users will find the -software useful. However: -* Osmosis comes without any warranty, to the extent permitted by applicable -law. -* Unless required by applicable law, no liability will be accepted by -the authors and distributors of this software for any damages caused -as a result of its use. diff --git a/docs/core/deploy.md b/docs/core/deploy.md index 470ef765381..ceb414e618f 100644 --- a/docs/core/deploy.md +++ b/docs/core/deploy.md @@ -31,15 +31,14 @@ Otherwise it might require lots of RAM per request! See [#734](https://github.co ### API Tokens -By default, the GraphHopper UI uses [Omniscale](http://omniscale.com/) and/or [Thunderforest](http://thunderforest.com/) as layer service. -Either you get a plan there, then set the API key in the options.js file, or you -have to remove Omniscale from the [JavaScript file](https://github.com/graphhopper/graphhopper/blob/master/web/src/main/resources/com/graphhopper/maps/js/map.js). +The GraphHopper Maps UI uses the [GraphHopper Directions API](https://docs.graphhopper.com/#tag/Geocoding-API) for geocoding. +To be able to use the autocomplete feature of the point inputs you get your API Token at +[graphhopper.com](https://www.graphhopper.com/) and set this in the config.js file, see +web-bundle/src/main/resources/com/graphhopper/maps/config.js -GraphHopper uses the [GraphHopper Directions API](https://docs.graphhopper.com/#tag/Geocoding-API) for geocoding. -To be able to use the autocomplete feature of the point inputs you have to: +The Maps UI also uses [Omniscale](http://omniscale.com/) and [Thunderforest](http://thunderforest.com/) as layer service. +You can get a plan there too and set the API keys in the config.js file. - * Get your API Token at: https://www.graphhopper.com/ and set this in the options.js - * Don't forget the Attribution when using the free package ## Worldwide Setup diff --git a/docs/core/quickstart-from-source.md b/docs/core/quickstart-from-source.md index 3d108ee5372..8bf5c3e1329 100644 --- a/docs/core/quickstart-from-source.md +++ b/docs/core/quickstart-from-source.md @@ -17,7 +17,7 @@ mvn clean install -DskipTests # start GraphHopper and before download the road data wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf java -Ddw.graphhopper.datareader.file=berlin-latest.osm.pbf -jar web/target/graphhopper-web-*.jar server config-example.yml -# This does mainly 3 things: +# This does the following things: # - it creates routable files for graphhopper in the folder graph-data (see the config.yml) # - it creates data for a special routing algorithm to improve query speed. (this and the previous step is skipped, if the graph-data folder is already present) # - it starts the web service to service the UI and endpoints like /route @@ -86,54 +86,8 @@ as those versions are not in maven central: ### Web UI (JavaScript) -Running `mvn package` from the root folder will install a local copy of node/npm and build the javascript bundle for GH -maps. You just need to start the server and GH maps and if you use the default port GH maps will be visible at -`http://localhost:8989/`. - -To develop the web UI running the whole maven build usually takes too long so here are the separate steps that you need -to perform when you make changes to the JavaScript code: - -1. install the [node package manager](https://github.com/nvm-sh/nvm#install--update-script). For windows - use [nvm-windows](https://github.com/coreybutler/nvm-windows). -2. Build the Web UI: `cd web-bundle && npm install && npm run bundle` which results in the `main.js` file -3. Restart the GH server so it picks up the latest version of the UI bundle - -You can achieve an even faster development cycle by running `npm run watch` which will update `main.js` whenever you -make changes to one of the .js files. To hot-reload your changes in the browser the best option is to serve GH maps from -a separate server like live-server. You can do this by running `npm run serve` from a separate terminal and pointing the -routing.host property in src/main/resources/com/graphhopper/maps/js/config/options.js to your GH server: - -```js -... -routing: { - host: 'http://localhost:8989', api_key -: - '' -} -... -``` - -Re-building `main.js` on every change might cause your IDE (like IntelliJ) to re-index the file all the time. Therefore -it is a good idea to remove `main.js` from your editor's index. For example in IntelliJ right-click the file and choose -`Mark as plain text`. - -The following npm commands are available in the `web-bundle` directory: - -```bash -# bundle creates the main file -npm run bundle - -# create main.js for debugging -npm run bundleDebug - -# create main.js for production and specify as CLI parameter `export NODE_ENV=development` which `options_*.js` file should be selected -npm run bundleProduction - -# Forcing consistent code style with jshint: -npm run lint - -# see the package.json where more scripts are defined -``` +The development of the GraphHopper Maps UI happens in a [different repository](https://github.com/graphhopper/graphhopper-maps). +The mvn life-cycle will just download one of its releases. ### Swing and Desktop Usage diff --git a/docs/index.md b/docs/index.md index f0798389292..a339dfb0450 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,17 +2,18 @@ ## First Steps -Try out our live demo called [GraphHopper Maps](https://graphhopper.com/maps) +Try out our live demo called [GraphHopper Maps](https://graphhopper.com/maps/) - [![GraphHopper Maps](https://karussell.files.wordpress.com/2014/12/graphhopper-maps-0-4-preview.png)](https://graphhopper.com/maps) + [![GraphHopper Maps](https://www.graphhopper.com/wp-content/uploads/2022/10/maps2-1024x661.png)](https://graphhopper.com/maps) + +[The Readme](../README.md#features) lists all features. -[The Readme](../README.md#features) lists all features or [this list of slides](https://graphhopper.com/public/slides/). See [users of GraphHopper](https://www.graphhopper.com/showcases/) and let us know your application! ## Community For all questions regarding the GraphHopper routing engine please use [our forum](https://discuss.graphhopper.com). -For bugs see our contribute section below. +For bugs see our [contributing guide](https://github.com/graphhopper/graphhopper/blob/master/CONTRIBUTING.md). --- diff --git a/pom.xml b/pom.xml index b99c235a107..e57e730508d 100644 --- a/pom.xml +++ b/pom.xml @@ -216,6 +216,10 @@ + + maven-antrun-plugin + 1.8 + diff --git a/web-bundle/.jshintignore b/web-bundle/.jshintignore deleted file mode 100644 index 257834843d2..00000000000 --- a/web-bundle/.jshintignore +++ /dev/null @@ -1,2 +0,0 @@ -src/main/resources/com/graphhopper/maps/js/lib/*.js -src/main/resources/com/graphhopper/maps/js/main.js diff --git a/web-bundle/package.json b/web-bundle/package.json deleted file mode 100644 index 89dc56bd928..00000000000 --- a/web-bundle/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "graphhopper-js-ui", - "version": "1.0.0", - "description": "A Route Planner Frontend for GraphHopper", - "author": "GraphHopper Community", - "license": "Apache-2.0", - "main": "main.js", - "scripts": { - "watch": "watchify src/main/resources/com/graphhopper/maps/js/main-template.js -o src/main/resources/com/graphhopper/maps/js/main.js --debug --verbose", - "bundle": "browserify src/main/resources/com/graphhopper/maps/js/main-template.js -o src/main/resources/com/graphhopper/maps/js/main.js", - "bundleDebug": "browserify src/main/resources/com/graphhopper/maps/js/main-template.js --debug -o src/main/resources/com/graphhopper/maps/js/main.js", - "bundleProduction": "browserify -g uglifyify src/main/resources/com/graphhopper/maps/js/main-template.js -o src/main/resources/com/graphhopper/maps/js/main.js", - "test": "JASMINE_CONFIG_PATH=src/test/resources/com/graphhopper/maps/spec/jasmine.json jasmine", - "lint": "jshint src/main/resources/com/graphhopper/maps/js/", - "serve": "live-server --port=8991 --mount=/:src/main/resources/com/graphhopper/maps/ --wait=1000" - }, - "browserify": { - "transform": [ - "browserify-swap" - ] - }, - "browserify-swap": { - "production": { - "config/options.js$": "./src/main/resources/com/graphhopper/maps/js/config/options_prod.js" - } - }, - "dependencies": { - "custom-model-editor": "github:graphhopper/custom-model-editor#a8c97e4ef8e76c963be375984a3c08ff3c1e8288", - "flatpickr": "4.4.6", - "jquery": "3.5.0", - "leaflet": "1.5.1", - "leaflet-contextmenu": "1.4.0", - "leaflet-loading": "0.1.24", - "leaflet.heightgraph": "1.4.0", - "leaflet.vectorgrid": "1.3.0", - "moment": "2.29.2" - }, - "devDependencies": { - "browserify": "16.2.0", - "browserify-swap": "0.2.2", - "jasmine": "3.1.0", - "jshint": "^2.10.2", - "live-server": "^1.2.1", - "uglifyify": "5.0.2", - "watchify": "^3.11.1" - } -} diff --git a/web-bundle/pom.xml b/web-bundle/pom.xml index 31cab763042..661dc7c4fe0 100644 --- a/web-bundle/pom.xml +++ b/web-bundle/pom.xml @@ -6,6 +6,9 @@ graphhopper-web-bundle jar 7.0-SNAPSHOT + + 0.0.0-53606529ed5243bf01aa985f474c0e3d078be04a + GraphHopper Dropwizard Bundle Use the GraphHopper routing engine as a web-service @@ -136,37 +139,66 @@ install-node-and-npm - v16.13.0 - 8.1.0 + v16.17.0 + 8.15.0 - npm install + download graphhopper maps + generate-resources npm - install + + + pack --pack-destination=${basedir}/target + @graphhopper/graphhopper-maps-bundle@${graphhopper-maps.version} + + + + + maven-antrun-plugin + - npm run bundleProduction + + create target directory + initialize + + + + + - npm + run - generate-resources + + + unzip maps bundle + process-resources - run bundleProduction - - development - + + + + + + + + + + + run + - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/config.js b/web-bundle/src/main/resources/com/graphhopper/maps/config.js new file mode 100644 index 00000000000..6006f906561 --- /dev/null +++ b/web-bundle/src/main/resources/com/graphhopper/maps/config.js @@ -0,0 +1,22 @@ +const config = { + api: location.origin + '/', + defaultTiles: 'OpenStreetMap', + keys: { + graphhopper: "", + maptiler: "missing_api_key", + omniscale: "missing_api_key", + thunderforest: "missing_api_key", + kurviger: "missing_api_key" + }, + routingGraphLayerAllowed: true, + extraProfiles: {}, + request: { + details: [ + 'road_class', + 'road_environment', + 'max_speed', + 'average_speed', + ], + snapPreventions: ['ferry'], + }, +} \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/L.Control.Heightgraph.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/L.Control.Heightgraph.css deleted file mode 100755 index 3267718ec94..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/L.Control.Heightgraph.css +++ /dev/null @@ -1,148 +0,0 @@ -.heightgraph-container { - background-color: rgba(250,250,250,.8); - border-radius: 10px; - display: none; - cursor: default; - user-select: none; -} - -.heightgraph-toggle { - cursor: pointer; - box-shadow: 0 1px 7px rgba(0, 0, 0, .4); - border-radius: 5px; - width: 28px; - height: 28px; - background: #f8f8f9; - display: block; -} - -.heightgraph-toggle-icon { - background: url(images/area-chart.svg) no-repeat center center; - background-size: 14px 14px; - width: 26px; - height: 26px; - position: absolute; -} - -.heightgraph-close-icon { - background: url(images/remove.svg) no-repeat center center; - background-size: 14px 14px; - width: 26px; - height: 26px; - position: absolute; - right: 0; - display: none; - cursor: pointer; -} - -.border-top { - fill: none; -} - -.legend-hover { - cursor: pointer; -} - -.legend-text { - fill: #000; - font-size: 10px; - cursor: pointer; -} - -.tick, .tick text { - fill: #000; - pointer-events: none; -} - -.axis .tick line { - visibility: hidden; - pointer-events: none; -} - -.axis path { - stroke: black; - fill: none; - stroke-width: 2px; - shape-rendering: crispEdges; - pointer-events: none; -} - -.focusbox { - display: none; - font-size: 10px; - fill: #000; - pointer-events: none; -} - -.focusbox rect { - fill: rgba(255, 255, 255, 0.8); - stroke-width: 1px; - stroke: #888; - pointer-events: none; -} - -.focusbox text { - font-size: 12px; -} - -.focusLine line { - stroke-width: 1px; - stroke: rgb(20, 20, 20); - display: none; - cursor: default; - shape-rendering: crispEdges; -} - -.height-focus.label rect { - fill: rgba(255, 255, 255, 0.5); - stroke-width: 1px; - stroke: #888; - pointer-events: none; - shape-rendering: crispEdges; -} - -.height-focus.line { - stroke: rgb(20, 20, 20); - stroke-width: 1px; - shape-rendering: crispEdges; -} - -.height-focus.circle { - stroke: #FFF; - stroke-width: 1px; -} - -.mouse-height-box-text{ - font-size: 12px; -} - -.grid .tick { - pointer-events: none; -} - -.grid .tick line { - stroke: #EEE; - stroke-width: 1px; - shape-rendering: crispEdges; -} - -.grid path { - stroke-width: 0; - pointer-events: none; -} - -.tspan { - font-weight: bold; -} - -.select-symbol { - cursor: pointer; -} - -.select-info { - cursor: default; -} - -.lineSelection { - cursor: move; -} \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/addon/hint/show-hint.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/addon/hint/show-hint.css deleted file mode 100644 index 83bba5393ee..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/addon/hint/show-hint.css +++ /dev/null @@ -1,37 +0,0 @@ -/* Copied from code mirror 5.59.2, do not edit this file */ -.CodeMirror-hints { - position: absolute; - z-index: 10; - overflow: hidden; - list-style: none; - - margin: 0; - padding: 2px; - - -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); - -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); - box-shadow: 2px 3px 5px rgba(0,0,0,.2); - border-radius: 3px; - border: 1px solid silver; - - background: white; - font-size: 90%; - font-family: monospace; - - max-height: 20em; - overflow-y: auto; -} - -.CodeMirror-hint { - margin: 0; - padding: 0 4px; - border-radius: 2px; - white-space: pre; - color: black; - cursor: pointer; -} - -li.CodeMirror-hint-active { - background: #08f; - color: white; -} diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/addon/lint/lint.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/addon/lint/lint.css deleted file mode 100644 index 6a59c0e6fd6..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/addon/lint/lint.css +++ /dev/null @@ -1,73 +0,0 @@ -/* Copied from code mirror 5.59.2, do not edit this file */ - -/* The lint marker gutter */ -.CodeMirror-lint-markers { - width: 16px; -} - -.CodeMirror-lint-tooltip { - background-color: #ffd; - border: 1px solid black; - border-radius: 4px 4px 4px 4px; - color: black; - font-family: monospace; - font-size: 10pt; - overflow: hidden; - padding: 2px 5px; - position: fixed; - white-space: pre; - white-space: pre-wrap; - z-index: 100; - max-width: 600px; - opacity: 0; - transition: opacity .4s; - -moz-transition: opacity .4s; - -webkit-transition: opacity .4s; - -o-transition: opacity .4s; - -ms-transition: opacity .4s; -} - -.CodeMirror-lint-mark { - background-position: left bottom; - background-repeat: repeat-x; -} - -.CodeMirror-lint-mark-warning { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII="); -} - -.CodeMirror-lint-mark-error { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg=="); -} - -.CodeMirror-lint-marker { - background-position: center center; - background-repeat: no-repeat; - cursor: pointer; - display: inline-block; - height: 16px; - width: 16px; - vertical-align: middle; - position: relative; -} - -.CodeMirror-lint-message { - padding-left: 18px; - background-position: top left; - background-repeat: no-repeat; -} - -.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII="); -} - -.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII="); -} - -.CodeMirror-lint-marker-multiple { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC"); - background-repeat: no-repeat; - background-position: right bottom; - width: 100%; height: 100%; -} diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/lib/codemirror.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/lib/codemirror.css deleted file mode 100644 index 0ce9be8de80..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/codemirror/lib/codemirror.css +++ /dev/null @@ -1,352 +0,0 @@ -/* Copied from code mirror 5.59.2, do not edit this file */ - -/* BASICS */ - -.CodeMirror { - /* Set height, width, borders, and global font properties here */ - font-family: monospace; - height: 300px; - color: black; - direction: ltr; -} - -/* PADDING */ - -.CodeMirror-lines { - padding: 4px 0; /* Vertical padding around content */ -} -.CodeMirror pre.CodeMirror-line, -.CodeMirror pre.CodeMirror-line-like { - padding: 0 4px; /* Horizontal padding of content */ -} - -.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { - background-color: transparent; /* The little square between H and V scrollbars */ -} - -/* GUTTER */ - -.CodeMirror-gutters { - border-right: 1px solid #ddd; - background-color: #f7f7f7; - white-space: nowrap; -} -.CodeMirror-linenumbers {} -.CodeMirror-linenumber { - padding: 0 3px 0 5px; - min-width: 20px; - text-align: right; - color: #999; - white-space: nowrap; -} - -.CodeMirror-guttermarker { color: black; } -.CodeMirror-guttermarker-subtle { color: #999; } - -/* CURSOR */ - -.CodeMirror-cursor { - border-left: 1px solid black; - border-right: none; - width: 0; -} -/* Shown when moving in bi-directional text */ -.CodeMirror div.CodeMirror-secondarycursor { - border-left: 1px solid silver; -} -.cm-fat-cursor .CodeMirror-cursor { - width: auto; - border: 0 !important; - background: #7e7; -} -.cm-fat-cursor div.CodeMirror-cursors { - z-index: 1; -} -.cm-fat-cursor-mark { - background-color: rgba(20, 255, 20, 0.5); - -webkit-animation: blink 1.06s steps(1) infinite; - -moz-animation: blink 1.06s steps(1) infinite; - animation: blink 1.06s steps(1) infinite; -} -.cm-animate-fat-cursor { - width: auto; - border: 0; - -webkit-animation: blink 1.06s steps(1) infinite; - -moz-animation: blink 1.06s steps(1) infinite; - animation: blink 1.06s steps(1) infinite; - background-color: #7e7; -} -@-moz-keyframes blink { - 0% {} - 50% { background-color: transparent; } - 100% {} -} -@-webkit-keyframes blink { - 0% {} - 50% { background-color: transparent; } - 100% {} -} -@keyframes blink { - 0% {} - 50% { background-color: transparent; } - 100% {} -} - -/* Can style cursor different in overwrite (non-insert) mode */ -.CodeMirror-overwrite .CodeMirror-cursor {} - -.cm-tab { display: inline-block; text-decoration: inherit; } - -.CodeMirror-rulers { - position: absolute; - left: 0; right: 0; top: -50px; bottom: 0; - overflow: hidden; -} -.CodeMirror-ruler { - border-left: 1px solid #ccc; - top: 0; bottom: 0; - position: absolute; -} - -/* DEFAULT THEME */ - -.cm-s-default .cm-header {color: blue;} -.cm-s-default .cm-quote {color: #090;} -.cm-negative {color: #d44;} -.cm-positive {color: #292;} -.cm-header, .cm-strong {font-weight: bold;} -.cm-em {font-style: italic;} -.cm-link {text-decoration: underline;} -.cm-strikethrough {text-decoration: line-through;} - -.cm-s-default .cm-keyword {color: #708;} -.cm-s-default .cm-atom {color: #219;} -.cm-s-default .cm-number {color: #164;} -.cm-s-default .cm-def {color: #00f;} -.cm-s-default .cm-variable, -.cm-s-default .cm-punctuation, -.cm-s-default .cm-property, -.cm-s-default .cm-operator {} -.cm-s-default .cm-variable-2 {color: #05a;} -.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;} -.cm-s-default .cm-comment {color: #a50;} -.cm-s-default .cm-string {color: #a11;} -.cm-s-default .cm-string-2 {color: #f50;} -.cm-s-default .cm-meta {color: #555;} -.cm-s-default .cm-qualifier {color: #555;} -.cm-s-default .cm-builtin {color: #30a;} -.cm-s-default .cm-bracket {color: #997;} -.cm-s-default .cm-tag {color: #170;} -.cm-s-default .cm-attribute {color: #00c;} -.cm-s-default .cm-hr {color: #999;} -.cm-s-default .cm-link {color: #00c;} - -.cm-s-default .cm-error {color: #f00;} -.cm-invalidchar {color: #f00;} - -.CodeMirror-composing { border-bottom: 2px solid; } - -/* Default styles for common addons */ - -div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;} -div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;} -.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } -.CodeMirror-activeline-background {background: #e8f2ff;} - -/* STOP */ - -/* The rest of this file contains styles related to the mechanics of - the editor. You probably shouldn't touch them. */ - -.CodeMirror { - position: relative; - overflow: hidden; - background: white; -} - -.CodeMirror-scroll { - overflow: scroll !important; /* Things will break if this is overridden */ - /* 50px is the magic margin used to hide the element's real scrollbars */ - /* See overflow: hidden in .CodeMirror */ - margin-bottom: -50px; margin-right: -50px; - padding-bottom: 50px; - height: 100%; - outline: none; /* Prevent dragging from highlighting the element */ - position: relative; -} -.CodeMirror-sizer { - position: relative; - border-right: 50px solid transparent; -} - -/* The fake, visible scrollbars. Used to force redraw during scrolling - before actual scrolling happens, thus preventing shaking and - flickering artifacts. */ -.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { - position: absolute; - z-index: 6; - display: none; - outline: none; -} -.CodeMirror-vscrollbar { - right: 0; top: 0; - overflow-x: hidden; - overflow-y: scroll; -} -.CodeMirror-hscrollbar { - bottom: 0; left: 0; - overflow-y: hidden; - overflow-x: scroll; -} -.CodeMirror-scrollbar-filler { - right: 0; bottom: 0; -} -.CodeMirror-gutter-filler { - left: 0; bottom: 0; -} - -.CodeMirror-gutters { - position: absolute; left: 0; top: 0; - min-height: 100%; - z-index: 3; -} -.CodeMirror-gutter { - white-space: normal; - height: 100%; - display: inline-block; - vertical-align: top; - margin-bottom: -50px; -} -.CodeMirror-gutter-wrapper { - position: absolute; - z-index: 4; - background: none !important; - border: none !important; -} -.CodeMirror-gutter-background { - position: absolute; - top: 0; bottom: 0; - z-index: 4; -} -.CodeMirror-gutter-elt { - position: absolute; - cursor: default; - z-index: 4; -} -.CodeMirror-gutter-wrapper ::selection { background-color: transparent } -.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent } - -.CodeMirror-lines { - cursor: text; - min-height: 1px; /* prevents collapsing before first draw */ -} -.CodeMirror pre.CodeMirror-line, -.CodeMirror pre.CodeMirror-line-like { - /* Reset some styles that the rest of the page might have set */ - -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; - border-width: 0; - background: transparent; - font-family: inherit; - font-size: inherit; - margin: 0; - white-space: pre; - word-wrap: normal; - line-height: inherit; - color: inherit; - z-index: 2; - position: relative; - overflow: visible; - -webkit-tap-highlight-color: transparent; - -webkit-font-variant-ligatures: contextual; - font-variant-ligatures: contextual; -} -.CodeMirror-wrap pre.CodeMirror-line, -.CodeMirror-wrap pre.CodeMirror-line-like { - word-wrap: break-word; - white-space: pre-wrap; - word-break: normal; -} - -.CodeMirror-linebackground { - position: absolute; - left: 0; right: 0; top: 0; bottom: 0; - z-index: 0; -} - -.CodeMirror-linewidget { - position: relative; - z-index: 2; - padding: 0.1px; /* Force widget margins to stay inside of the container */ -} - -.CodeMirror-widget {} - -.CodeMirror-rtl pre { direction: rtl; } - -.CodeMirror-code { - outline: none; -} - -/* Force content-box sizing for the elements where we expect it */ -.CodeMirror-scroll, -.CodeMirror-sizer, -.CodeMirror-gutter, -.CodeMirror-gutters, -.CodeMirror-linenumber { - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -.CodeMirror-measure { - position: absolute; - width: 100%; - height: 0; - overflow: hidden; - visibility: hidden; -} - -.CodeMirror-cursor { - position: absolute; - pointer-events: none; -} -.CodeMirror-measure pre { position: static; } - -div.CodeMirror-cursors { - visibility: hidden; - position: relative; - z-index: 3; -} -div.CodeMirror-dragcursors { - visibility: visible; -} - -.CodeMirror-focused div.CodeMirror-cursors { - visibility: visible; -} - -.CodeMirror-selected { background: #d9d9d9; } -.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } -.CodeMirror-crosshair { cursor: crosshair; } -.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; } -.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } - -.cm-searching { - background-color: #ffa; - background-color: rgba(255, 255, 0, .4); -} - -/* Used to force a border model for a node */ -.cm-force-border { padding-right: .1px; } - -@media print { - /* Hide the cursor when printing */ - .CodeMirror div.CodeMirror-cursors { - visibility: hidden; - } -} - -/* See issue #2901 */ -.cm-tab-wrap-hack:after { content: ''; } - -/* Help users use markselection to safely style text background */ -span.CodeMirror-selectedtext { background: none; } diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/flatpickr.min.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/flatpickr.min.css deleted file mode 100644 index 292438b5a32..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/flatpickr.min.css +++ /dev/null @@ -1,13 +0,0 @@ -.flatpickr-calendar{background:transparent;opacity:0;display:none;text-align:center;visibility:hidden;padding:0;-webkit-animation:none;animation:none;direction:ltr;border:0;font-size:14px;line-height:24px;border-radius:5px;position:absolute;width:307.875px;-webkit-box-sizing:border-box;box-sizing:border-box;-ms-touch-action:manipulation;touch-action:manipulation;background:#fff;-webkit-box-shadow:1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08);box-shadow:1px 0 0 #e6e6e6,-1px 0 0 #e6e6e6,0 1px 0 #e6e6e6,0 -1px 0 #e6e6e6,0 3px 13px rgba(0,0,0,0.08);}.flatpickr-calendar.open,.flatpickr-calendar.inline{opacity:1;max-height:640px;visibility:visible}.flatpickr-calendar.open{display:inline-block;z-index:99999}.flatpickr-calendar.animate.open{-webkit-animation:fpFadeInDown 300ms cubic-bezier(.23,1,.32,1);animation:fpFadeInDown 300ms cubic-bezier(.23,1,.32,1)}.flatpickr-calendar.inline{display:block;position:relative;top:2px}.flatpickr-calendar.static{position:absolute;top:calc(100% + 2px);}.flatpickr-calendar.static.open{z-index:999;display:block}.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+1) .flatpickr-day.inRange:nth-child(7n+7){-webkit-box-shadow:none !important;box-shadow:none !important}.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1){-webkit-box-shadow:-2px 0 0 #e6e6e6,5px 0 0 #e6e6e6;box-shadow:-2px 0 0 #e6e6e6,5px 0 0 #e6e6e6}.flatpickr-calendar .hasWeeks .dayContainer,.flatpickr-calendar .hasTime .dayContainer{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.flatpickr-calendar .hasWeeks .dayContainer{border-left:0}.flatpickr-calendar.showTimeInput.hasTime .flatpickr-time{height:40px;border-top:1px solid #e6e6e6}.flatpickr-calendar.noCalendar.hasTime .flatpickr-time{height:auto}.flatpickr-calendar:before,.flatpickr-calendar:after{position:absolute;display:block;pointer-events:none;border:solid transparent;content:'';height:0;width:0;left:22px}.flatpickr-calendar.rightMost:before,.flatpickr-calendar.rightMost:after{left:auto;right:22px}.flatpickr-calendar:before{border-width:5px;margin:0 -5px}.flatpickr-calendar:after{border-width:4px;margin:0 -4px}.flatpickr-calendar.arrowTop:before,.flatpickr-calendar.arrowTop:after{bottom:100%}.flatpickr-calendar.arrowTop:before{border-bottom-color:#e6e6e6}.flatpickr-calendar.arrowTop:after{border-bottom-color:#fff}.flatpickr-calendar.arrowBottom:before,.flatpickr-calendar.arrowBottom:after{top:100%}.flatpickr-calendar.arrowBottom:before{border-top-color:#e6e6e6}.flatpickr-calendar.arrowBottom:after{border-top-color:#fff}.flatpickr-calendar:focus{outline:0}.flatpickr-wrapper{position:relative;display:inline-block}.flatpickr-months{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.flatpickr-months .flatpickr-month{background:transparent;color:rgba(0,0,0,0.9);fill:rgba(0,0,0,0.9);height:28px;line-height:1;text-align:center;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:hidden;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}.flatpickr-months .flatpickr-prev-month,.flatpickr-months .flatpickr-next-month{text-decoration:none;cursor:pointer;position:absolute;top:0;line-height:16px;height:28px;padding:10px;z-index:3;}.flatpickr-months .flatpickr-prev-month.disabled,.flatpickr-months .flatpickr-next-month.disabled{display:none}.flatpickr-months .flatpickr-prev-month i,.flatpickr-months .flatpickr-next-month i{position:relative}.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month,.flatpickr-months .flatpickr-next-month.flatpickr-prev-month{/* - /*rtl:begin:ignore*/left:0;/* - /*rtl:end:ignore*/}/* - /*rtl:begin:ignore*/ -/* - /*rtl:end:ignore*/ -.flatpickr-months .flatpickr-prev-month.flatpickr-next-month,.flatpickr-months .flatpickr-next-month.flatpickr-next-month{/* - /*rtl:begin:ignore*/right:0;/* - /*rtl:end:ignore*/}/* - /*rtl:begin:ignore*/ -/* - /*rtl:end:ignore*/ -.flatpickr-months .flatpickr-prev-month:hover,.flatpickr-months .flatpickr-next-month:hover{color:#959ea9;}.flatpickr-months .flatpickr-prev-month:hover svg,.flatpickr-months .flatpickr-next-month:hover svg{fill:#f64747}.flatpickr-months .flatpickr-prev-month svg,.flatpickr-months .flatpickr-next-month svg{width:14px;height:14px;}.flatpickr-months .flatpickr-prev-month svg path,.flatpickr-months .flatpickr-next-month svg path{-webkit-transition:fill .1s;transition:fill .1s;fill:inherit}.numInputWrapper{position:relative;height:auto;}.numInputWrapper input,.numInputWrapper span{display:inline-block}.numInputWrapper input{width:100%;}.numInputWrapper input::-ms-clear{display:none}.numInputWrapper span{position:absolute;right:0;width:14px;padding:0 4px 0 2px;height:50%;line-height:50%;opacity:0;cursor:pointer;border:1px solid rgba(57,57,57,0.15);-webkit-box-sizing:border-box;box-sizing:border-box;}.numInputWrapper span:hover{background:rgba(0,0,0,0.1)}.numInputWrapper span:active{background:rgba(0,0,0,0.2)}.numInputWrapper span:after{display:block;content:"";position:absolute}.numInputWrapper span.arrowUp{top:0;border-bottom:0;}.numInputWrapper span.arrowUp:after{border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:4px solid rgba(57,57,57,0.6);top:26%}.numInputWrapper span.arrowDown{top:50%;}.numInputWrapper span.arrowDown:after{border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid rgba(57,57,57,0.6);top:40%}.numInputWrapper span svg{width:inherit;height:auto;}.numInputWrapper span svg path{fill:rgba(0,0,0,0.5)}.numInputWrapper:hover{background:rgba(0,0,0,0.05);}.numInputWrapper:hover span{opacity:1}.flatpickr-current-month{font-size:135%;line-height:inherit;font-weight:300;color:inherit;position:absolute;width:75%;left:12.5%;padding:6.16px 0 0 0;line-height:1;height:28px;display:inline-block;text-align:center;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);}.flatpickr-current-month span.cur-month{font-family:inherit;font-weight:700;color:inherit;display:inline-block;margin-left:.5ch;padding:0;}.flatpickr-current-month span.cur-month:hover{background:rgba(0,0,0,0.05)}.flatpickr-current-month .numInputWrapper{width:6ch;width:7ch\0;display:inline-block;}.flatpickr-current-month .numInputWrapper span.arrowUp:after{border-bottom-color:rgba(0,0,0,0.9)}.flatpickr-current-month .numInputWrapper span.arrowDown:after{border-top-color:rgba(0,0,0,0.9)}.flatpickr-current-month input.cur-year{background:transparent;-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;cursor:text;padding:0 0 0 .5ch;margin:0;display:inline-block;font-size:inherit;font-family:inherit;font-weight:300;line-height:inherit;height:auto;border:0;border-radius:0;vertical-align:initial;}.flatpickr-current-month input.cur-year:focus{outline:0}.flatpickr-current-month input.cur-year[disabled],.flatpickr-current-month input.cur-year[disabled]:hover{font-size:100%;color:rgba(0,0,0,0.5);background:transparent;pointer-events:none}.flatpickr-weekdays{background:transparent;text-align:center;overflow:hidden;width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:28px;}.flatpickr-weekdays .flatpickr-weekdaycontainer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}span.flatpickr-weekday{cursor:default;font-size:90%;background:transparent;color:rgba(0,0,0,0.54);line-height:1;margin:0;text-align:center;display:block;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;font-weight:bolder}.dayContainer,.flatpickr-weeks{padding:1px 0 0 0}.flatpickr-days{position:relative;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;width:307.875px;}.flatpickr-days:focus{outline:0}.dayContainer{padding:0;outline:0;text-align:left;width:307.875px;min-width:307.875px;max-width:307.875px;-webkit-box-sizing:border-box;box-sizing:border-box;display:inline-block;display:-ms-flexbox;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-wrap:wrap;-ms-flex-pack:justify;-webkit-justify-content:space-around;justify-content:space-around;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1;}.dayContainer + .dayContainer{-webkit-box-shadow:-1px 0 0 #e6e6e6;box-shadow:-1px 0 0 #e6e6e6}.flatpickr-day{background:none;border:1px solid transparent;border-radius:150px;-webkit-box-sizing:border-box;box-sizing:border-box;color:#393939;cursor:pointer;font-weight:400;width:14.2857143%;-webkit-flex-basis:14.2857143%;-ms-flex-preferred-size:14.2857143%;flex-basis:14.2857143%;max-width:39px;height:39px;line-height:39px;margin:0;display:inline-block;position:relative;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;}.flatpickr-day.inRange,.flatpickr-day.prevMonthDay.inRange,.flatpickr-day.nextMonthDay.inRange,.flatpickr-day.today.inRange,.flatpickr-day.prevMonthDay.today.inRange,.flatpickr-day.nextMonthDay.today.inRange,.flatpickr-day:hover,.flatpickr-day.prevMonthDay:hover,.flatpickr-day.nextMonthDay:hover,.flatpickr-day:focus,.flatpickr-day.prevMonthDay:focus,.flatpickr-day.nextMonthDay:focus{cursor:pointer;outline:0;background:#e6e6e6;border-color:#e6e6e6}.flatpickr-day.today{border-color:#959ea9;}.flatpickr-day.today:hover,.flatpickr-day.today:focus{border-color:#959ea9;background:#959ea9;color:#fff}.flatpickr-day.selected,.flatpickr-day.startRange,.flatpickr-day.endRange,.flatpickr-day.selected.inRange,.flatpickr-day.startRange.inRange,.flatpickr-day.endRange.inRange,.flatpickr-day.selected:focus,.flatpickr-day.startRange:focus,.flatpickr-day.endRange:focus,.flatpickr-day.selected:hover,.flatpickr-day.startRange:hover,.flatpickr-day.endRange:hover,.flatpickr-day.selected.prevMonthDay,.flatpickr-day.startRange.prevMonthDay,.flatpickr-day.endRange.prevMonthDay,.flatpickr-day.selected.nextMonthDay,.flatpickr-day.startRange.nextMonthDay,.flatpickr-day.endRange.nextMonthDay{background:#569ff7;-webkit-box-shadow:none;box-shadow:none;color:#fff;border-color:#569ff7}.flatpickr-day.selected.startRange,.flatpickr-day.startRange.startRange,.flatpickr-day.endRange.startRange{border-radius:50px 0 0 50px}.flatpickr-day.selected.endRange,.flatpickr-day.startRange.endRange,.flatpickr-day.endRange.endRange{border-radius:0 50px 50px 0}.flatpickr-day.selected.startRange + .endRange:not(:nth-child(7n+1)),.flatpickr-day.startRange.startRange + .endRange:not(:nth-child(7n+1)),.flatpickr-day.endRange.startRange + .endRange:not(:nth-child(7n+1)){-webkit-box-shadow:-10px 0 0 #569ff7;box-shadow:-10px 0 0 #569ff7}.flatpickr-day.selected.startRange.endRange,.flatpickr-day.startRange.startRange.endRange,.flatpickr-day.endRange.startRange.endRange{border-radius:50px}.flatpickr-day.inRange{border-radius:0;-webkit-box-shadow:-5px 0 0 #e6e6e6,5px 0 0 #e6e6e6;box-shadow:-5px 0 0 #e6e6e6,5px 0 0 #e6e6e6}.flatpickr-day.disabled,.flatpickr-day.disabled:hover,.flatpickr-day.prevMonthDay,.flatpickr-day.nextMonthDay,.flatpickr-day.notAllowed,.flatpickr-day.notAllowed.prevMonthDay,.flatpickr-day.notAllowed.nextMonthDay{color:rgba(57,57,57,0.3);background:transparent;border-color:transparent;cursor:default}.flatpickr-day.disabled,.flatpickr-day.disabled:hover{cursor:not-allowed;color:rgba(57,57,57,0.1)}.flatpickr-day.week.selected{border-radius:0;-webkit-box-shadow:-5px 0 0 #569ff7,5px 0 0 #569ff7;box-shadow:-5px 0 0 #569ff7,5px 0 0 #569ff7}.flatpickr-day.hidden{visibility:hidden}.rangeMode .flatpickr-day{margin-top:1px}.flatpickr-weekwrapper{display:inline-block;float:left;}.flatpickr-weekwrapper .flatpickr-weeks{padding:0 12px;-webkit-box-shadow:1px 0 0 #e6e6e6;box-shadow:1px 0 0 #e6e6e6}.flatpickr-weekwrapper .flatpickr-weekday{float:none;width:100%;line-height:28px}.flatpickr-weekwrapper span.flatpickr-day,.flatpickr-weekwrapper span.flatpickr-day:hover{display:block;width:100%;max-width:none;color:rgba(57,57,57,0.3);background:transparent;cursor:default;border:none}.flatpickr-innerContainer{display:block;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;}.flatpickr-rContainer{display:inline-block;padding:0;-webkit-box-sizing:border-box;box-sizing:border-box}.flatpickr-time{text-align:center;outline:0;display:block;height:0;line-height:40px;max-height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.flatpickr-time:after{content:"";display:table;clear:both}.flatpickr-time .numInputWrapper{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;width:40%;height:40px;float:left;}.flatpickr-time .numInputWrapper span.arrowUp:after{border-bottom-color:#393939}.flatpickr-time .numInputWrapper span.arrowDown:after{border-top-color:#393939}.flatpickr-time.hasSeconds .numInputWrapper{width:26%}.flatpickr-time.time24hr .numInputWrapper{width:49%}.flatpickr-time input{background:transparent;-webkit-box-shadow:none;box-shadow:none;border:0;border-radius:0;text-align:center;margin:0;padding:0;height:inherit;line-height:inherit;cursor:pointer;color:#393939;font-size:14px;position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;}.flatpickr-time input.flatpickr-hour{font-weight:bold}.flatpickr-time input.flatpickr-minute,.flatpickr-time input.flatpickr-second{font-weight:400}.flatpickr-time input:focus{outline:0;border:0}.flatpickr-time .flatpickr-time-separator,.flatpickr-time .flatpickr-am-pm{height:inherit;display:inline-block;float:left;line-height:inherit;color:#393939;font-weight:bold;width:2%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center}.flatpickr-time .flatpickr-am-pm{outline:0;width:18%;cursor:pointer;text-align:center;font-weight:400;}.flatpickr-time .flatpickr-am-pm:hover,.flatpickr-time .flatpickr-am-pm:focus{background:#f0f0f0}.flatpickr-input[readonly]{cursor:pointer}@-webkit-keyframes fpFadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes fpFadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}} \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/images/area-chart.svg b/web-bundle/src/main/resources/com/graphhopper/maps/css/images/area-chart.svg deleted file mode 100755 index cf8b4a36b01..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/images/area-chart.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/images/elevation.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/images/elevation.png deleted file mode 100644 index 68fb537e42d5d95807e000643cc44ba9c326f6b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 687 zcmV;g0#N;lP)Kl}$)gQ5462_s)AWV=6W_ zANeurFs3GBP)11<(JnBApom)6uBMR()xvzxwuqut?OXU2RM094T(p#EQ8qD|W|>+x zHHkB$zT0YI@B=O91wsGSz2|VwkN@F*z<>QSG7O{GFpP_K^_RKD{QP_g&}lo!ZmkOx z8=#`Ihf}tKOcRO4V8=l~IcxK`>epO!-ZA}kCP;!i-U zj^f-ST#h-%Jt?HsT;KNm{p4H!$LZm{u>tnoP&|wEb46LS3z!4uEJ<2e+_`yz2fyXW zopIh$*5bBsb;}EvR+J6-8zvBP7R7~FAGd)nA=&A4y4siaje_XrH7>* z>2&IhudHfx>z2?IfJ4_8{hsQ?)XZ210s@}8;l|q5M6Tw;%t$6NHq=_FI0p2r=_uOA zk#stB-=!7JhHH1f%FosLo2LMRzQ&jN5P(WgXws>>W`v;2G?({X7SI-m2g>W-G}Z1I za!PG6Kj(HAXLi&d91K-OMwZqIfvWL0jUtF7Tj*F5bp0gp#+uf6S*iE?(j36%5^rjy zI6#FrG@)s(Z_48G($iVcCrAi~3i=vGrC`_jeh%9P0;u+f$2EuZ2a4`|R|N+N;ZT*{ z`gcOm7VG6uF22fzmE#+M1p`eJO(STtXp9&4h>F@ur9*^g%l=8S;pr3*_ VwRy^$)w=)y002ovPDHLkV1jyOJkJ0C diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/images/layers-2x.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/images/layers-2x.png deleted file mode 100644 index 200c333dca9652ac4cba004d609e5af4eee168c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1259 zcmVFhCYNy;#0irRPomHqW|G1C*;4?@4#E?jH>?v@U%cy?3dQAc-DchXVErpOh~ z-jbon+tNbnl6hoEb;)TVk+%hTDDi_G%i3*RZ&15!$Fjr^f;Ke&A@|?=`2&+{zr+3a z{D*=t(`AXyS%X7N z%a#RZw6vD^t_rnM`L4E>m=U&R!A-&}nZIi$BOPvkhrCuUe@BN~-lRD)f44;J%TwgE zcze8u!PQ_NR7?o(NylLXVTfDO zxs5=@|GsYEsNo4M#nT%N!UE(?dnS)t2+{ELYAFp*3=iF=|EQnTp`#vlSXuGVraYo? z+RCzXo6h3qA8{KG?S4nE(lM+;Eb4nT3XV;7gcAxUi5m)`k5tv}cPy()8ZR3TLW3I- zAS^}cq-IJvL7a4RgR!yk@~RT%$lA7{L5ES*hyx)M4(yxI$Ub(4f)K|^v1>zvwQY!_ zIrWw8q9GS^!Dp~}+?mbnB6jDF8mVlbQ!jFKDY;w=7;XO{9bq7>LXGK24WA`;rL)_Z z)&j}pbV(;6gY;VMhbxgvn`X;6x}VUEE-7 z%)7j-%t8S=ZL3yc)HbXDAqJZvBTPoiW_A-+a8m3_Z?v{DN7Tnr#O_VUMT0UBt$;p` zDh6JbGHN8JJ*JN%y2%msb97@_S>9!%Egwk;?PEkU9ntz&3uR}%Fj5d$JHQbQb3}a{ zSzFT^#n=VInPpcAS}CNxj?_ zVscANk5Cfz(51EI1pz};AWWb|kgbYNb4wCEGUn3+eMUMV?1-{=I4TlmLJMot@rd07 zZuo2hk1ccu{YmGkcYdWAVdk{Z4Nm?^cTD&}jGm+Q1SYIXMwmG*oO*83&#>l%nbR`G zhh=lZ%xIb7kU3#;TBbfECrnC9P=-XpL|TG2BoZdj61*XiFbW8?1Z_wp%#;>${SUIy V$8qr;L*)Pf002ovPDHLkV1hYLS~36t diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/images/layers.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/images/layers.png deleted file mode 100644 index 1a72e5784b2b456eac5d7670738db80697af3377..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 696 zcmV;p0!RIcP)*@&l2<6p=!C&s@#ZL+%BQvF&b?w6S%wp=I>1QHj7AP5C)IWy#b znXXB;g;j=$a-tW89K%FbDceHVq&unY*Wx3L#=EGWH=rjqnp|4c_Ulec!ql3#G-5ZF zVlbBA@XP=)C8U&+Lrc)S4O5%1$&{(;7R^K(CSnvSr$v;+B$8q&7Bf|h$#PARo1^%M zf1H^nG-EiXVXr07OH(*8R)xa|FD;lXUlg_-%)~ZGsL2cX0NXaAzN2q%jqLRR6ruVk8`Jb7n#{`T;o@`F= z#3YcynIR^s83UNF3D!f5m#Mg)NJ24&Qfrqb&_z=yF;=B)#9Iq7u-@^O!(mW{D;qvr zPc)gVb%aowtS8m@ElL4A9G>w#ffQ~q{i&_i)*6f^)Sz|C?C>zb4Uo?H<-&Hz@a?J; z$ml@zGygWofb9$ZBj6aLjpLhsT2AzjOu=-*u_gSCUYnU^5s62$4H-fe}gSR(=wKRaTHh!@*b)YV6mo|a4Fn6Rgc&Rpk zvn_X|3VY?v=>nJ{slE^V1GaGWk}m@aIWGIpghbfPh8m@aIWEo_%AZI>==moIFVE^L=C zZJ91?mo03UEp3-BY?wBGur6$uD{Yr9Y?m%SHF8Fk1pc(Nva%QJ+{FLkalfypz3&M|||Fn`7|g3c~4(nXHKFmRnwn$J#_$xE8i z|Ns9!kC;(oC1qQk>LMp3_a2(odYyMT@>voX=UI)k>1cJdn;gjmJ-|6v4nb1Oryh)eQMwHP(i@!36%vGJyFK(JTj?Vb{{C=jx&)@1l zlFmnw%0`&bqruifkkHKC=vbiAM3&E`#Mv>2%tw;VK8?_|&E89cs{a1}$J*!f_xd-C z&F%B|oxRgPlh0F!txkxrQjNA`m9~?&&|jw4W0<`_iNHsX$VQXVK!B}Xkh4>av|f_8 zLY2?t?ejE=%(TnfV5iqOjm?d;&qI~ZGl|SzU77a)002XDQchC<95+*MjE@82?VLm= z3xf6%Vd@99z|q|-ua5l3kJxvZwan-8K1cPiwQAtlcNX~ZqLeoMB+a;7)WA|O#HOB% zg6SX;754xD1{Fy}K~#8Ntklac&zTpadXZ& zC*_=T&g7hfbI$R?v%9?sknIb97gJOJ=`-8YyS3ndqN+Jm+x33!p&Hc@@L$w))s2@N ztv~i}Emc?DykgwFWwma($8+~b>l?tqj$dh13R^nMZnva9 zn0Vflzv2Dvp`oVQw{Guby~i`JGbyBGTEC{y>yzCkg>K&CIeQ$u;lyQ+M{O~gEJ^)Z zrF3p)^>|uT;57}WY&IRwyOQ=dq%Az}_t=_hKowP!Z79q0;@Zu(SWEJJcHY+5T6I({ zw)wj*SNi4wrd+POUfZe4gF77vW?j zoFS}|r2n&$U9Y!S4VEOyN}OpZZi|?cr1VcE_tHsDQgp-ga(SwkBrkCm{|*-yb=}ZW zvcYvLvfA90TPn|!-TuYJV<6`}+RJeRgP3EA=qQcF9k0*#*{f&I_pjam%I6Dd#YE|G zqB!R}tW-K!wV1w+4JcFA_s6~=@9F&j8`u$-ifLN3vK;`lvaA-`jRn_}(8|)!3?-}I zvFi{H;@A$gEZYh?%|Qr_y#*UkOPjwiRCsJQ>mb6h5yGIk6C5_XA=8T?IBfm_?+P0; zhhUs)-(0R*H<&Kku(1>#cGtOpk&Z&kQcw&SJv-4VY<+;=8hYnoX zfNJMCa9)^5Z0;2dCUk;x-%#yS!I~Jr3pNuI!g_tHz!$hKwt1GL~sFvx)3u4TA zv>CLGdQtoZ7Du7ctJRfTqY;FPxs1G{ZJ?73D5J@OO{6BHcPbk{_mjg&p2QFeke%QI zlAJ-kvjuwy1<5D-6>su68A+i998aSZNnQX)+Q}6(GK-C%8G-!1bOJBONU{gT%IOOE z;Yk24YC@^lFW77>r6x7eS1Omc;8=GUp#&zLQ&L{ zv8$hGC`wp~$9pR>f%-_Ps3>YhzP(+vC(E*zr1CVO8ChN^MI-VGMX7+|(r!SGZ9gd5 zzO9sQd>sm|f1|X&oh=8lOzd6+ITvo zCXInR?>RZ#>Hb*PO=7dI!dZ(wY4O}ZGv zdfQFio7+0~PN*RFCZGM6@9-o~y*@?;k00NvOsw54t1^tt{*ATMs^2j}4Wp=4t3RH* z_+8b`F-{E=0sOgM<;VHTo!Ij3u zmmI`2?K7g(GOcGA)@h?$SW&pwHdtj1n57PLI8&6RHhx4R%Q7b z^JEqR)@06V!pbS*@D_ZyRMo_LlT}r{#sXOx4kM-V<_V{!5SSuM^SIVCA37|nY7LWQ zZA#B1h4l`6asz=Lvax_#GMRX|NF>=$=p{Qn0i@ExX1jGhy@B8a*_uR+ODEbVi8ObL zezG?azy>E~S~dl43&8<$(2H}P&*tuBdESUP83KQ?8B z?K(!uS>H1wlWQz;qOfB`T#TZ=EoSp~vZ5XtCvwm1h*Ex6mzTsn_y@_=xREIslV-%- zpdWkEzMjeNOGWrSM32gpBt27*O29NdhGzuDgYxcf`Jjjqw@B;Vmdb@fxdhCRi`Kg> zmUTr$=&@#i!%F4Q6mb&4QKfR^95KJ!<6~fqx-f^66AV!|ywG{6D^Vay-3b99>XOe# e-I|>x8~*?ZhF3snGbtJX0000cOl4 diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/images/marker-icon.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/images/marker-icon.png deleted file mode 100644 index 950edf24677ded147df13b26f91baa2b0fa70513..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1466 zcmV;r1x5OaP)P001cn1^@s6z>|W`000GnNklGNuHDcIX17Zdjl&3`L?0sTjIws<{((Dh&g-s0<@jYQyl?D*X^?%13;ml^gy> ziMrY_^1WI=(g@LMizu=zCoA>C`6|QEq1eV92k*7m>G65*&@&6)aC&e}G zI)pf-Za|N`DT&Cn1J|o`19mumxW~hiKiKyc-P`S@q)rdTo84@QI@;0yXrG%9uhI>A zG5QHb6s4=<6xy{1 z@NMxEkryp{LS44%z$3lP^cX!9+2-;CTt3wM4(k*#C{aiIiLuB>jJj;KPhPzIC00bL zU3a#;aJld94lCW=`4&aAy8M7PY=HQ>O%$YEP4c4UY#CRxfgbE~(|uiI=YS8q;O9y6 zmIkXzR`}p7ti|PrM3a}WMnR=3NVnWdAAR>b9X@)DKL6=YsvmH%?I24wdq?Gh54_;# z$?_LvgjEdspdQlft#4CQ z`2Zyvy?*)N1Ftw|{_hakhG9WjS?Az@I@+IZ8JbWewR!XUK4&6346+d#~gsE0SY(LX8&JfY>Aj)RxGy96nwhs2rv zzW6pTnMpFkDSkT*a*6Dx|u@ds6ISVn0@^RmIsKZ5Y;bazbc;tTSq(kg(=481ODrPyNB6n z-$+U}(w$m6U6H$w17Bw+wDaFIe~GvNMYvnw31MpY0eQKT9l>SU``8k7w4)z!GZKMI z#_cEKq7k~i%nlK@6c-K?+R;B#5$?T#YpKD`t_4bAs^#E+@5QW$@OX3*`;(#{U^d-vY)&xEE>n5lYl&T?Amke9$Lam@{1K@O ze*LXqlKQHiv=gx+V^Cbb2?z@ISBQ*3amF;9UJ3SBg(N|710TLamQmYZ&Qjn2LuO<* zCZlB4n%@pc&7NNnY1}x+NWpHlq`OJEo|`aYN9<`RBUB+79g;>dgb6YlfN#kGL?lO_ z!6~M^7sOnbsUkKk<@Ysie&`G>ruxH&Mgy&8;i=A zB9OO!xR{AyODw>DS-q5YM{0ExFEAzt zm>RdS+ssW(-8|?xr0(?$vBVB*%(xDLtq3Hf0I5yFm<_g=W2`QWAax{1rWVH=I!VrP zs(rTFX@W#t$hXNvbgX`gK&^w_YD;CQ!B@e0QbLIWaKAXQe2-kkloo;{iF#6}z!4=W zi$giRj1{ zt;2w`VSCF#WE&*ev7jpsC=6175@(~nTE2;7M-L((0bH@yG}-TB$R~WXd?tA$s3|%y zA`9$sA(>F%J3ioz<-LJl*^o1|w84l>HBR`>3l9c8$5Xr@xCiIQ7{x$fMCzOk_-M=% z+{a_Q#;42`#KfUte@$NT77uaTz?b-fBe)1s5XE$yA79fm?KqM^VgLXD07*qoM6N<$ Ef<_J(9smFU diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/images/remove.svg b/web-bundle/src/main/resources/com/graphhopper/maps/css/images/remove.svg deleted file mode 100755 index f063b3df429..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/images/remove.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.contextmenu.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.contextmenu.css deleted file mode 100644 index 0b5e2defca7..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.contextmenu.css +++ /dev/null @@ -1,54 +0,0 @@ -.leaflet-contextmenu { - display: none; - box-shadow: 0 1px 7px rgba(0,0,0,0.4); - -webkit-border-radius: 4px; - border-radius: 4px; - padding: 4px 0; - background-color: #fff; - cursor: default; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; -} - -.leaflet-contextmenu a.leaflet-contextmenu-item { - display: block; - color: #222; - font-size: 12px; - line-height: 20px; - text-decoration: none; - padding: 0 12px; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - cursor: default; - outline: none; -} - -.leaflet-contextmenu a.leaflet-contextmenu-item-disabled { - opacity: 0.5; -} - -.leaflet-contextmenu a.leaflet-contextmenu-item.over { - background-color: #f4f4f4; - border-top: 1px solid #f0f0f0; - border-bottom: 1px solid #f0f0f0; -} - -.leaflet-contextmenu a.leaflet-contextmenu-item-disabled.over { - background-color: inherit; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; -} - -.leaflet-contextmenu-icon { - margin: 2px 8px 0 0; - width: 16px; - height: 16px; - float: left; - border: 0; -} - -.leaflet-contextmenu-separator { - border-bottom: 1px solid #ccc; - margin: 5px 0; -} diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.css deleted file mode 100644 index 609a6624536..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.css +++ /dev/null @@ -1,640 +0,0 @@ -/* required styles */ - -.leaflet-pane, -.leaflet-tile, -.leaflet-marker-icon, -.leaflet-marker-shadow, -.leaflet-tile-container, -.leaflet-pane > svg, -.leaflet-pane > canvas, -.leaflet-zoom-box, -.leaflet-image-layer, -.leaflet-layer { - position: absolute; - left: 0; - top: 0; - } -.leaflet-container { - overflow: hidden; - } -.leaflet-tile, -.leaflet-marker-icon, -.leaflet-marker-shadow { - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - -webkit-user-drag: none; - } -/* Prevents IE11 from highlighting tiles in blue */ -.leaflet-tile::selection { - background: transparent; -} -/* Safari renders non-retina tile on retina better with this, but Chrome is worse */ -.leaflet-safari .leaflet-tile { - image-rendering: -webkit-optimize-contrast; - } -/* hack that prevents hw layers "stretching" when loading new tiles */ -.leaflet-safari .leaflet-tile-container { - width: 1600px; - height: 1600px; - -webkit-transform-origin: 0 0; - } -.leaflet-marker-icon, -.leaflet-marker-shadow { - display: block; - } -/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ -/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ -.leaflet-container .leaflet-overlay-pane svg, -.leaflet-container .leaflet-marker-pane img, -.leaflet-container .leaflet-shadow-pane img, -.leaflet-container .leaflet-tile-pane img, -.leaflet-container img.leaflet-image-layer, -.leaflet-container .leaflet-tile { - max-width: none !important; - max-height: none !important; - } - -.leaflet-container.leaflet-touch-zoom { - -ms-touch-action: pan-x pan-y; - touch-action: pan-x pan-y; - } -.leaflet-container.leaflet-touch-drag { - -ms-touch-action: pinch-zoom; - /* Fallback for FF which doesn't support pinch-zoom */ - touch-action: none; - touch-action: pinch-zoom; -} -.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { - -ms-touch-action: none; - touch-action: none; -} -.leaflet-container { - -webkit-tap-highlight-color: transparent; -} -.leaflet-container a { - -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); -} -.leaflet-tile { - filter: inherit; - visibility: hidden; - } -.leaflet-tile-loaded { - visibility: inherit; - } -.leaflet-zoom-box { - width: 0; - height: 0; - -moz-box-sizing: border-box; - box-sizing: border-box; - z-index: 800; - } -/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ -.leaflet-overlay-pane svg { - -moz-user-select: none; - } - -.leaflet-pane { z-index: 400; } - -.leaflet-tile-pane { z-index: 200; } -.leaflet-overlay-pane { z-index: 400; } -.leaflet-shadow-pane { z-index: 500; } -.leaflet-marker-pane { z-index: 600; } -.leaflet-tooltip-pane { z-index: 650; } -.leaflet-popup-pane { z-index: 700; } - -.leaflet-map-pane canvas { z-index: 100; } -.leaflet-map-pane svg { z-index: 200; } - -.leaflet-vml-shape { - width: 1px; - height: 1px; - } -.lvml { - behavior: url(#default#VML); - display: inline-block; - position: absolute; - } - - -/* control positioning */ - -.leaflet-control { - position: relative; - z-index: 800; - pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ - pointer-events: auto; - } -.leaflet-top, -.leaflet-bottom { - position: absolute; - z-index: 1000; - pointer-events: none; - } -.leaflet-top { - top: 0; - } -.leaflet-right { - right: 0; - } -.leaflet-bottom { - bottom: 0; - } -.leaflet-left { - left: 0; - } -.leaflet-control { - float: left; - clear: both; - } -.leaflet-right .leaflet-control { - float: right; - } -.leaflet-top .leaflet-control { - margin-top: 10px; - } -.leaflet-bottom .leaflet-control { - margin-bottom: 10px; - } -.leaflet-left .leaflet-control { - margin-left: 10px; - } -.leaflet-right .leaflet-control { - margin-right: 10px; - } - - -/* zoom and fade animations */ - -.leaflet-fade-anim .leaflet-tile { - will-change: opacity; - } -.leaflet-fade-anim .leaflet-popup { - opacity: 0; - -webkit-transition: opacity 0.2s linear; - -moz-transition: opacity 0.2s linear; - transition: opacity 0.2s linear; - } -.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { - opacity: 1; - } -.leaflet-zoom-animated { - -webkit-transform-origin: 0 0; - -ms-transform-origin: 0 0; - transform-origin: 0 0; - } -.leaflet-zoom-anim .leaflet-zoom-animated { - will-change: transform; - } -.leaflet-zoom-anim .leaflet-zoom-animated { - -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); - -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); - transition: transform 0.25s cubic-bezier(0,0,0.25,1); - } -.leaflet-zoom-anim .leaflet-tile, -.leaflet-pan-anim .leaflet-tile { - -webkit-transition: none; - -moz-transition: none; - transition: none; - } - -.leaflet-zoom-anim .leaflet-zoom-hide { - visibility: hidden; - } - - -/* cursors */ - -.leaflet-interactive { - cursor: pointer; - } -.leaflet-grab { - cursor: -webkit-grab; - cursor: -moz-grab; - cursor: grab; - } -.leaflet-crosshair, -.leaflet-crosshair .leaflet-interactive { - cursor: crosshair; - } -.leaflet-popup-pane, -.leaflet-control { - cursor: auto; - } -.leaflet-dragging .leaflet-grab, -.leaflet-dragging .leaflet-grab .leaflet-interactive, -.leaflet-dragging .leaflet-marker-draggable { - cursor: move; - cursor: -webkit-grabbing; - cursor: -moz-grabbing; - cursor: grabbing; - } - -/* marker & overlays interactivity */ -.leaflet-marker-icon, -.leaflet-marker-shadow, -.leaflet-image-layer, -.leaflet-pane > svg path, -.leaflet-tile-container { - pointer-events: none; - } - -.leaflet-marker-icon.leaflet-interactive, -.leaflet-image-layer.leaflet-interactive, -.leaflet-pane > svg path.leaflet-interactive, -svg.leaflet-image-layer.leaflet-interactive path { - pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ - pointer-events: auto; - } - -/* visual tweaks */ - -.leaflet-container { - background: #ddd; - outline: 0; - } -.leaflet-container a { - color: #0078A8; - } -.leaflet-container a.leaflet-active { - outline: 2px solid orange; - } -.leaflet-zoom-box { - border: 2px dotted #38f; - background: rgba(255,255,255,0.5); - } - - -/* general typography */ -.leaflet-container { - font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; - } - - -/* general toolbar styles */ - -.leaflet-bar { - box-shadow: 0 1px 5px rgba(0,0,0,0.65); - border-radius: 4px; - } -.leaflet-bar a, -.leaflet-bar a:hover { - background-color: #fff; - border-bottom: 1px solid #ccc; - width: 26px; - height: 26px; - line-height: 26px; - display: block; - text-align: center; - text-decoration: none; - color: black; - } -.leaflet-bar a, -.leaflet-control-layers-toggle { - background-position: 50% 50%; - background-repeat: no-repeat; - display: block; - } -.leaflet-bar a:hover { - background-color: #f4f4f4; - } -.leaflet-bar a:first-child { - border-top-left-radius: 4px; - border-top-right-radius: 4px; - } -.leaflet-bar a:last-child { - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - border-bottom: none; - } -.leaflet-bar a.leaflet-disabled { - cursor: default; - background-color: #f4f4f4; - color: #bbb; - } - -.leaflet-touch .leaflet-bar a { - width: 30px; - height: 30px; - line-height: 30px; - } -.leaflet-touch .leaflet-bar a:first-child { - border-top-left-radius: 2px; - border-top-right-radius: 2px; - } -.leaflet-touch .leaflet-bar a:last-child { - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; - } - -/* zoom control */ - -.leaflet-control-zoom-in, -.leaflet-control-zoom-out { - font: bold 18px 'Lucida Console', Monaco, monospace; - text-indent: 1px; - } - -.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { - font-size: 22px; - } - - -/* layers control */ - -.leaflet-control-layers { - box-shadow: 0 1px 5px rgba(0,0,0,0.4); - background: #fff; - border-radius: 5px; - } -.leaflet-control-layers-toggle { - background-image: url(images/layers.png); - width: 36px; - height: 36px; - } -.leaflet-retina .leaflet-control-layers-toggle { - background-image: url(images/layers-2x.png); - background-size: 26px 26px; - } -.leaflet-touch .leaflet-control-layers-toggle { - width: 44px; - height: 44px; - } -.leaflet-control-layers .leaflet-control-layers-list, -.leaflet-control-layers-expanded .leaflet-control-layers-toggle { - display: none; - } -.leaflet-control-layers-expanded .leaflet-control-layers-list { - display: block; - position: relative; - } -.leaflet-control-layers-expanded { - padding: 6px 10px 6px 6px; - color: #333; - background: #fff; - } -.leaflet-control-layers-scrollbar { - overflow-y: scroll; - overflow-x: hidden; - padding-right: 5px; - } -.leaflet-control-layers-selector { - margin-top: 2px; - position: relative; - top: 1px; - } -.leaflet-control-layers label { - display: block; - } -.leaflet-control-layers-separator { - height: 0; - border-top: 1px solid #ddd; - margin: 5px -10px 5px -6px; - } - -/* Default icon URLs */ -.leaflet-default-icon-path { - background-image: url(images/marker-icon.png); - } - - -/* attribution and scale controls */ - -.leaflet-container .leaflet-control-attribution { - background: #fff; - background: rgba(255, 255, 255, 0.7); - margin: 0; - } -.leaflet-control-attribution, -.leaflet-control-scale-line { - padding: 0 5px; - color: #333; - } -.leaflet-control-attribution a { - text-decoration: none; - } -.leaflet-control-attribution a:hover { - text-decoration: underline; - } -.leaflet-container .leaflet-control-attribution, -.leaflet-container .leaflet-control-scale { - font-size: 11px; - } -.leaflet-left .leaflet-control-scale { - margin-left: 5px; - } -.leaflet-bottom .leaflet-control-scale { - margin-bottom: 5px; - } -.leaflet-control-scale-line { - border: 2px solid #777; - border-top: none; - line-height: 1.1; - padding: 2px 5px 1px; - font-size: 11px; - white-space: nowrap; - overflow: hidden; - -moz-box-sizing: border-box; - box-sizing: border-box; - - background: #fff; - background: rgba(255, 255, 255, 0.5); - } -.leaflet-control-scale-line:not(:first-child) { - border-top: 2px solid #777; - border-bottom: none; - margin-top: -2px; - } -.leaflet-control-scale-line:not(:first-child):not(:last-child) { - border-bottom: 2px solid #777; - } - -.leaflet-touch .leaflet-control-attribution, -.leaflet-touch .leaflet-control-layers, -.leaflet-touch .leaflet-bar { - box-shadow: none; - } -.leaflet-touch .leaflet-control-layers, -.leaflet-touch .leaflet-bar { - border: 2px solid rgba(0,0,0,0.2); - background-clip: padding-box; - } - - -/* popup */ - -.leaflet-popup { - position: absolute; - text-align: center; - margin-bottom: 20px; - } -.leaflet-popup-content-wrapper { - padding: 1px; - text-align: left; - border-radius: 12px; - } -.leaflet-popup-content { - margin: 13px 19px; - line-height: 1.4; - } -.leaflet-popup-content p { - margin: 18px 0; - } -.leaflet-popup-tip-container { - width: 40px; - height: 20px; - position: absolute; - left: 50%; - margin-left: -20px; - overflow: hidden; - pointer-events: none; - } -.leaflet-popup-tip { - width: 17px; - height: 17px; - padding: 1px; - - margin: -10px auto 0; - - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); - } -.leaflet-popup-content-wrapper, -.leaflet-popup-tip { - background: white; - color: #333; - box-shadow: 0 3px 14px rgba(0,0,0,0.4); - } -.leaflet-container a.leaflet-popup-close-button { - position: absolute; - top: 0; - right: 0; - padding: 4px 4px 0 0; - border: none; - text-align: center; - width: 18px; - height: 14px; - font: 16px/14px Tahoma, Verdana, sans-serif; - color: #c3c3c3; - text-decoration: none; - font-weight: bold; - background: transparent; - } -.leaflet-container a.leaflet-popup-close-button:hover { - color: #999; - } -.leaflet-popup-scrolled { - overflow: auto; - border-bottom: 1px solid #ddd; - border-top: 1px solid #ddd; - } - -.leaflet-oldie .leaflet-popup-content-wrapper { - zoom: 1; - } -.leaflet-oldie .leaflet-popup-tip { - width: 24px; - margin: 0 auto; - - -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; - filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); - } -.leaflet-oldie .leaflet-popup-tip-container { - margin-top: -1px; - } - -.leaflet-oldie .leaflet-control-zoom, -.leaflet-oldie .leaflet-control-layers, -.leaflet-oldie .leaflet-popup-content-wrapper, -.leaflet-oldie .leaflet-popup-tip { - border: 1px solid #999; - } - - -/* div icon */ - -.leaflet-div-icon { - background: #fff; - border: 1px solid #666; - } - - -/* Tooltip */ -/* Base styles for the element that has a tooltip */ -.leaflet-tooltip { - position: absolute; - padding: 6px; - background-color: #fff; - border: 1px solid #fff; - border-radius: 3px; - color: #222; - white-space: nowrap; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - pointer-events: none; - box-shadow: 0 1px 3px rgba(0,0,0,0.4); - } -.leaflet-tooltip.leaflet-clickable { - cursor: pointer; - pointer-events: auto; - } -.leaflet-tooltip-top:before, -.leaflet-tooltip-bottom:before, -.leaflet-tooltip-left:before, -.leaflet-tooltip-right:before { - position: absolute; - pointer-events: none; - border: 6px solid transparent; - background: transparent; - content: ""; - } - -/* Directions */ - -.leaflet-tooltip-bottom { - margin-top: 6px; -} -.leaflet-tooltip-top { - margin-top: -6px; -} -.leaflet-tooltip-bottom:before, -.leaflet-tooltip-top:before { - left: 50%; - margin-left: -6px; - } -.leaflet-tooltip-top:before { - bottom: 0; - margin-bottom: -12px; - border-top-color: #fff; - } -.leaflet-tooltip-bottom:before { - top: 0; - margin-top: -12px; - margin-left: -6px; - border-bottom-color: #fff; - } -.leaflet-tooltip-left { - margin-left: -6px; -} -.leaflet-tooltip-right { - margin-left: 6px; -} -.leaflet-tooltip-left:before, -.leaflet-tooltip-right:before { - top: 50%; - margin-top: -6px; - } -.leaflet-tooltip-left:before { - right: 0; - margin-right: -12px; - border-left-color: #fff; - } -.leaflet-tooltip-right:before { - left: 0; - margin-left: -12px; - border-right-color: #fff; - } diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.loading.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.loading.css deleted file mode 100644 index f4157bc6f31..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet.loading.css +++ /dev/null @@ -1,26 +0,0 @@ -.leaflet-control-loading:empty { - /* Spinner via ajaxload.info, base64-encoded */ - background-image: url(data:image/gif;base64,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); - background-repeat: no-repeat; -} - -.leaflet-control-loading, -.leaflet-control-zoom a.leaflet-control-loading, -.leaflet-control-zoomslider a.leaflet-control-loading, -.leaflet-control-layer-container { - display: none; -} - -.leaflet-control-loading.is-loading, -.leaflet-control-zoom a.leaflet-control-loading.is-loading, -.leaflet-control-zoomslider a.leaflet-control-loading.is-loading, -.leaflet-control-layer-container.is-loading { - display: block; -} - -/* Necessary for display consistency in Leaflet >= 0.6 */ -.leaflet-bar-part-bottom { - border-bottom: medium none; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; -} diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet_numbered_markers.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet_numbered_markers.css deleted file mode 100644 index 2edafa072d2..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/leaflet_numbered_markers.css +++ /dev/null @@ -1,12 +0,0 @@ -.leaflet-div-icon { - background: transparent; - border: none; -} - -.leaflet-marker-icon .number{ - position: relative; - top: -41px; - font-size: 12px; - width: 25px; - text-align: center; -} \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/style.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/style.css deleted file mode 100644 index 91c21711f17..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/style.css +++ /dev/null @@ -1,528 +0,0 @@ -body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - line-height: 1.4; - color: #111; - background-color: white; - margin: 0; - min-width: 300px; -} -#map { - /* set size via JS */ - cursor: default; -} - -#input { - float: left; - margin-left: 10px; - /*padding-right: 15px; */ -} - -#info { - margin-top: 10px; - display: none; - padding: 5px; -} - -#info a { - padding-right: 5px; -} - -#info ul { - margin-left:5px; - padding-left:5px; - list-style-type: none; -} - -.route_results { - max-height: 40%; -} - -#input { - min-height: 300px; - max-width: 270px; -} - -.instructions_info { - overflow: auto; - width: 100%; -} - -.route_description { - padding: 7px 5px; -} - -#input, #instructions, #footer { - width: 280px; -} - -.pointInput { - width: 215px; - float: left; -} - -.pointResolveFound a { - background-color: white; - padding-left: 4px; - padding-right: 3px; -} -.pointResolveFound { - overflow: hidden; - max-height: 24px; - font-size: 10px; - color: blue; - float: right; - cursor: pointer; - margin-top: -20px; - margin-right: 2px; -} - -.pointResolveError { - float: left; - font-size: 12px; - padding-bottom: 4px; - width: 100%; - text-align: right; -} - -.time_input { - display: none; - float: right; - padding-right: 20px; -} - -.time_input input { - float: left; - margin-left: 10px; - width: 220px; -} - -.boxSizingBorder { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.warn { - color: orange; -} -.error, .pointResolveError { - color: red; -} -#moreattribution a { - text-decoration: none; - color: black -} -#moreattribution { - padding-top: 20px; - color: #666666 -} - -#locationpoints { - padding-bottom: 10px; - float: left; -} - -#locationpoints>div:nth-child(n+2) { - counter-increment: pointcounter; -} - -#locationpoints>div:nth-child(n+2):nth-last-child(n+3)::before { - content: counter(pointcounter); - position: absolute; - padding-top: 0.45em; - right: calc(100% - 1.2em); - text-align: right; - font-size: 60%; -} - -.pointDiv { - margin: 6px 0; -} -.pointDiv > img { - margin-top: 4px; - padding-left: 3px; - padding-right: 3px; - float: left; -} -.left { - float: left; -} -.right { - float: right; -} -#routeDetails { - padding: 15px; - font-size: 12px; - padding-bottom: 4px; -} -#versionDetails { - font-size: 10px; - padding-top: 4px; - padding-left: 15px; - padding-right: 15px; -} -.hidden { - display: none; -} -.no_link { - text-decoration: none; - color: black; -} -.no_link img { - margin-bottom: -10px; -} -.small_text { - font-size: small; -} -#options { - padding-bottom: 10px; - padding-left: 20px; - padding-right: 20px; -} -.vehicle-info-link { - padding-top: 3px; - float: right; - text-decoration: none; -} -.bold { - font-weight: bold; -} -#header_img { - padding-top: 15px; - padding-left: 20px; - padding-bottom: 15px; -} -#header_img img { - width: 230px; -} - -#gpx_dialog { - display: none; -} - -#gpxExportButton { - margin-top: -3px; -} -#gpxExportButton img { - padding-left: 6px; -} -#searchButton { - float: right; - margin-bottom: 5px; - margin-right: 5px; -} - -#searchButton:hover { - cursor: pointer; -} -.clear { - clear: both; -} -#hosting { - clear: both; - display: none; - /* float: left;*/ - padding-top: 4px; - padding-bottom: 10px; - /* color: #666666; */ - font-size: smaller; - opacity: 0.8; -} - -#footer { - position: fixed; - bottom: 5px; - left: 30px; -} - -#hosting a, .footer-link { - text-decoration: none; - color: #00cc33; -} -.footer-link { - padding-right: 12px; - font-size: 12px; -} - -#export-link { - padding-left: 3px; - padding-top: 3px; - float: left; -} - -tr.instruction { - cursor: pointer; - border-bottom: #dadada dashed thin; -} - -.instructions { - table-layout:fixed; - border-collapse: collapse; - padding-top: 10px; - width: 98%; - font-size: smaller; -} - -.instructions td { - padding: 7px 5px; -} - -td.instr_title { - width: 130px; -} -td.instr_distance { - min-width: 50px; - float: right; - color: gray; - text-align: right; -} - -.instructions tr .instr_pic { - width: 20px; -} -td img.pic { - max-height: 24px; - max-width: 16px; -} - -.vehicle-btn { - padding: 0; - width: 32px; - height: 32px; - border-width: 1px; - -moz-border-radius: 0px; - -webkit-border-radius: 0px; - background-image: linear-gradient(to bottom, white, #e7e7e7); -} - -.vehicle-btn img { - width: 24px; - height: 24px; - vertical-align: middle; -} - -.selectprofile { - background-color: #bbb; - -moz-border-radius: 0px; - -webkit-border-radius: 0px; - background-image: linear-gradient(to bottom, #9f9f9f, #e7e7e7); -} - -#more-vehicle-btn { - cursor: pointer; -} - -.autocomplete { - border: 1px solid #999; - background: #FFF; - overflow: auto; -} -.autocomplete strong { - font-weight: normal; - color: #04B431; -} -.autocomplete-suggestion { - padding: 5px 5px; - white-space: nowrap; - overflow: hidden; - font-size: small; - background-image: linear-gradient(to bottom, white, #e7e7e7); -} -.autocomplete-selected { - padding: 5px 5px; - background: #e7e7e7; - background-image: linear-gradient(to bottom, #9f9f9f, #e7e7e7); -} -.light { font-weight: lighter; color: #9f9f9f; font-size: smaller } -.wikilink { float: right; } -.wikilink img { max-width: 16px; } - -/* .nameseg { border-top: #dadada dashed thin; } */ -.cityseg { float: left; font-size: 10px; } -.moreseg { float: right; font-size: 9px; } - -.pointFlag { - width: 16px; - height: 16px; -} -.pointFlag:hover { cursor: ns-resize; } -.pointAdd { - padding-left: 3px; -} -.pointDelete { - float: left; - padding-left: 2px; -} -.pointDelete:hover, .pointAdd:hover { cursor: pointer; } -.pointDelete:disabled { - background: red; -} - -.expandDetails { - color: gray; - font-size:11px; - float: right; - font-weight: bold; - width: 20px; - height: 20px; - height: 20px; - margin: 0 10px; - padding: 0; - background-image: linear-gradient(to bottom, white, #e7e7e7); -} -#moreButton { - background-image: linear-gradient(to bottom, white, #e7e7e7); -} - -.ui-dialog { - /* Must be > 700, the z-index of .leaflet-popup-pane */ - z-index: 1000; -} - -.ui-dialog > .ui-widget-header { - padding: 1em; - border: 1px solid black; -} - -.ui-dialog .ui-dialog-content { - padding: 1em; -} - -.ui-dialog .ui-widget-content { - background: white; -} - -.ui-widget-content { - background-image: none; -} - -.ui-dialog .ui-dialog-titlebar { - padding: 10px; - background: #00cc33; -} - -.alt_route_img { - padding-left: 2px; - margin-bottom: -3px; -} - -#route_result_tabs { - list-style: none; - padding: 0; - margin: 0; -} - -#route_result_tabs li { - background-color: #FFF; - cursor: pointer; - float: left; - padding: 5px 10px; -} - -#route_result_tabs li.current { - font-weight: bold; - background-image: linear-gradient(to bottom, #e7e7e7, white); - border-top-left-radius: 5px; - border-top-right-radius: 5px; -} - -.route_result_tab { - border: lightgray groove thin; - display: none; -} - -.route_result_tab.current { - display: block; -} - -#donate_form { - padding: 0; -} - -#donate_form_button { - background: none; - border: none; - padding-left: 0; - margin-top: 5px; - cursor: pointer; - float: left; -} - -.gray { - color: gray; -} - -.plain_text_button { - font-size: small; - padding: 0; - border: none; - background: none; - cursor: pointer; -} - -.fullscreen-reverse-btn, .fullscreen-btn { - cursor: pointer; - width: 30px; - height: 30px; - border-radius: 4px; - background-color: white; - background-position: 50% 50%; - background-repeat: no-repeat; - box-shadow: none; - border: 2px solid rgba(0, 0, 0, 0.2); -} - -.fullscreen-btn { - background-image: url("../img/full.png"); -} - -.fullscreen-reverse-btn { - background-image: url("../img/full-reverse.png"); -} - -.CodeMirror-lint-tooltip { - /* tool tip should not be hidden by map*/ - z-index: 2000; -} - -.CodeMirror-hints { - /* hints should not be hidden by map*/ - z-index: 1000; -} - -/* override default json mode colors in custom model editor */ -.cm-s-default .cm-string { - color: #067D17; -} -.cm-s-default .cm-property { - color: #871094; -} -.cm-s-default .cm-number { - color: #1750EB; -} -.cm-s-default .cm-atom { - color: #0033B3; -} - -#custom-model-util-buttons button { - background: none; - border: none; - padding: 0; - cursor: pointer; - text-decoration: underline; - color: #00cc33; -} - -#custom-model-docs { - color: #00cc33; -} - -#custom-model-search-button { - float: right; - margin-right: 5px; - cursor: pointer -} - -#custom-model-search-button:disabled { - cursor: default; -} - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/LICENSE.txt b/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/LICENSE.txt deleted file mode 100644 index 4819e54213f..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/LICENSE.txt +++ /dev/null @@ -1,43 +0,0 @@ -Copyright jQuery Foundation and other contributors, https://jquery.org/ - -This software consists of voluntary contributions made by many -individuals. For exact contribution history, see the revision history -available at https://github.com/jquery/jquery-ui - -The following license applies to all parts of this software except as -documented below: - -==== - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -==== - -Copyright and related rights for sample code are waived via CC0. Sample -code is defined as all source code contained within the demos directory. - -CC0: http://creativecommons.org/publicdomain/zero/1.0/ - -==== - -All files located in the node_modules and external directories are -externally maintained libraries used by this software which have their -own licenses; we recommend you read them, as their terms may differ from -the terms above. diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png deleted file mode 100644 index a9229606fa0091e175bf8b25e92991f1ee5b35f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 418 zcmeAS@N?(olHy`uVBq!ia0vp^8Xzpd1SErbK34)Mwj^(Nm;YeE8S(uNP=vFJ#Am<$En9-cLebC{re^wgoll|t(`&s7)9J{YxO^N-aI z$5L3jD^ISzl+wQbw$Cm(|Mhq4jH=@2wI8o7+Gd%b|IIx5*Zn&?>lgCSXrXO^WskXw=UX3LH%8!s;k z#x%*aEGp*Jjm(QM&8zq~)!)n5QqVsS=vUPe*NBpo#FA922>S z4={E+nQaGTRC&5MhIkx*d-b$ng949h;3{8svn*F5o}?c;Kir+G=xvlfb9Ucnx!LzV zKYw1UzcGecb6t~6xWlB=3a51)dX2qx%p0t(H?ll;Xvl-Ua7M6%M)vm*~w}RD4lnZuhbmcl2i$G2U9fNc+T-xj%reP%UwdC`m~y zNwrEYN(E93Mh1pvx(4RDMrI*~##W|gR;K3K1_o9J1|k>43Q#oU=BH$)RpQo=+Pm%y PPy>UftDnm{r-UW|o6>2* diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png deleted file mode 100644 index 29e3d7c105aa423ef5d26e31f166ad979ef4a3d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^j6gI&0LWmFTHNUZq?nSt-Ch3w7g=q17Rci)@Q5r1 z(jH*!b~4)z#PD=+46!(!{KIr+qDZgOs>S*DCH8q6)|^lLQ8(vdyV&7=Rv!DK5_Nv5 zKU5EWSl#{5ocZwkn6~@klK(Ue|8%DOm~7JJCTPgP@M)6!J>`Xd0YEcVOI#yLQW8s2 zt&)pUffR$0fuWhMfw``cS%{&rm8lsJX&V?=85nF@E_(z;LvDUbW?Cg~4Tpa%tpI9Z N@O1TaS?83{1OTAcQHB5j diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png deleted file mode 100644 index f363a133a53d0add3171767ed6f4932e7c6e1e0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 348 zcmeAS@N?(olHy`uVBq!ia0vp^j6gI&fCnc6a#?2AmP!?*K(O3p^r= zfwTu0yPeFo12SfLx;Tb-9DjS>o|}bBPw4YFRSXO})J!^(4ctv-3U*RGnKs-FC}~_ul&Gb7#drdngNlvfq|8Q!KUT1M^H56=BH$)RpQog_}9`3paup{S3j3^ HP6MEJtYe9Is2zh8d8x(zs>(nB!5aFurwutU!fp#PHqD@uqmI=MKv@&q5k6MqRAfp zW>mrthO^_NafHu!$(&GJ)G^2ZZTuNg$O=X?SmLFQXTcq0jGp;CMPcZwpDX+kY6Uu zca&CK|68hQST^tHx{?ZO_BP3aSPZ1Ih< z0bT(3B7*of_+ktL`WflfdelE|bA`ffbO zt7`@eG&nAFPT_4Jt?3}b>jpk_|3?}Oo|6}waWgyZwwN1`4!N@8T3y3;k8$-4J+@v6 zH`H4}VDq~r@;&^K)kf19oMYw5^TNpnut~EhH%s}cO;e0ZpEG-~%0D*#Y<0UEtn#Z8ITspTG%P(!_I&^l@mRj`Q^ryF#27AW;Y}u3KY99i|sGA-eC;Fpk zN)&0)&@^a+OowK0U$WlEhJBh|!_Gr;O86ApTe$;+s-6rth*QVo3YarGr(aRciQOie zAIULwOjvbt3I{5&dY+HC-CWX+dcRzjSy&MyW0A>rA?JnJy1cB>41VsUJ3E}4-$W6x zl~sfr);SP4Hpw2tp0%)`a$M8qri1F2fZ^>%)|30oMye^4cr3p`XS6HV-&n6LC(HJH zDQx21ByDYLW!vS+1F+8=iv(xNHFapy`z}li{MxwfO6y;T7HW3E4n-k=ZH;-rf5F)6uidW5yc1{qc_&gea0?b;{{|7zz}U^ zr6ah}H-m8?px6{>DqYd{x;{?}L8fjj3n?foYMxVL`fFO`f!!UrBbx+b3BA(C`37`u`2FE~tFOEU^wDYG)KYhI_zc&f?HL&(I(+^i{E zbc2BU?uNRh{Lxz;$9Tb9FBO+_z6l;vNf2*P30s9@yXXu6xPF`PY!|?#p!RC|8*s_J zc`lbBXs0TOBT*AqW(SqT_qwva2InNyV1Ez9qy~=lTb=`h#QduK0sUNTj$CRHh4pi^ zAmGO5->ii1d!IXTW24z8YoSOYVa}8Ay=N$V;)7UgxO5Jv7uT>OYWG2u5ElG2=Vdr` zGd)c?5Clzgc(&E-3LiugChEXwN3>&>)9t*Ja}c3{gU~vl^ua4|xhAE&)OtgXi%vs1 zBWpV{DCK5X?eW;AdzKi!Dp+t4PL$V#A>AzF;~ zW{^(V@VWVs%W6$R48c{$fx=*mI9RR%COV{*r{&T2yjUVH?mS($f^-=U9jUrbP+8e<=i3QKs-0jj zVLMzHJJ(itDaBLxCIQ~CQ;_OehkaBUj~7=4z6*B4*du~}Aml~MawDmUT0t|OkdK{% zH!>TS!@h+N7GAPoXGv1X;Ul6!6?2J5ZP^?(BQRKc0HN!IBoDs0|E~8==#B8v7WzB; z5W`uQs>B0XEIuEx!m zRQMwTrfH32pd&Msm(akm=}2SH@SNJu!pGw zfmCWSO0i*jfcX5+^r2v4ksJ=2wyq*1 zT4Y#ZyuL z$49`NBT{Jgu8Kb3KojutC*8=WdNwB`8Zhe8dmuM!hqi4bDfHtlXM(W;>~;qIc*fQd z!-8!pot&?3uyd5eXr@xAzs3Rz-^U6+ghXZ=t2Y`>JXk*7)CI*vWan8PFJ>Y2pDh)0 zifPxnP>oFib1i-MZCZ#O#&NOXA(C&lLgK4X5fcXc0B>>E<5trd#h-bjGZHzGSk6)= zZPgd!P@lfN6PAqQ=5F_Fr#NRPGQXG84LvW|AtvZ}$cjy#)yV*A4|dZlBTUB!CoIe` z-4odpQ4`>aqN#M8+UYlmP~lI)kj-cz#$;>FZ}Z+e&xv%dHo(R8puCj)8Le$Vbl}+2C!SrU{G!5rvCRq8tp(!~aKhr~bd)sHT z>E8griPuaocaSRRNO%%<2ZbbHP>7FD1S=}rV%hNPI&@e(38RP1_Kh!`zKmH|T?<>2 zKtMaKJFamxQpk=BJCqsSmxRK~NVOLB?Ef{5%DXQD?5oe_7 zD1RDFpVaMcS+k+YCIoOeM7@g%r$C!DaubR}!5;tdApNUo=A*@}*E`mjku}_(Z^aUo zWW9ArOCee`-r{3dgj7cTp!5+v)wi@EjLb@Mfbi1D@BsOcMYCqADDVSVpk($v~a z*`g*l6T>ijeC6%ksPR4H9N<*kZX@0~s4v%5YxyGX&h88Vdc2DH`+~RT38&cxM>xvT zz$O-I4~r$$Hu%Gb8Pmq8Di7jysQGa^gnwy@r<-CdG*dh?TTX?W&GM}^*P1=5HP8QgE&wtDO!b>fwgx&U+93a2xaT1GmTdIV;)*jqCc z1GmoiCngvXZG?E$&V&#$L=(XqK`++~@Rb_V@zH6`pXbuN;>%m~_k#U!_`g{gzxLVC zzKuO^$xojY6Lu`#qWr#PB}0?hT-eSmEVtVT zI(!=*QpoPl&Ba_#K_WL;XOSf;wpIxK{6>Wed!Bc*)f~sFobue~ZthSm8rP+5IAmI^ zyVIxkf_r|#{vRSr`9~Fg@)?c#`1LRKy23^VbUHr(K()L(H52mbNs7b8cTxwn@g#`H=9Lf)x8T7D7~4W#Py#TWLNyy0lLZEfIi=`Aj>5E>{P?!kmV%rK9pI5(}bALAm zTY*>44O_~U8HW(o=hsiBb##RwTr?at-VEkCq?b-6r2R=1$h?yz^247$E-_; zuo9|Kz?krpU8a?=;k$dCQ8$F|%<`$qj_X4)A8^CSSd`)~HgDu&O8zJ(g{_tGClgo6 z;q$e-x`J8!e&6PFW^ic9bYH}@fX(EywAtlLDBXE>#>%2@Ze4U&1A4a6Ag|OXr39%8 zP8@l9FSZA@F=W%tf%<-{#~_{Afa#S4>uSBn%eL-NOvyG5DkXmw70#0Up{l4^6}uFT z*?Ue?4d`$qWYlAmJT3+o1CsMBQ_`N&V$AS1#;XhKZ@zqmb2$k7+Wogpd< z=Q5obeZze@m6?CA>g5|-=lXWG=9cZ*CCO4e_DE;1+j1KDs*fYl?E5pJp{NudHZvJ~T$^#ENqoNLnM+bmkaS4Vp|by_TLu z4vP;4<*ESVs=L!59p+uJ=M^l1akr2G)Qz9B@?)cVRIBq^X0_jBowYbm2uDOUFK3he z)v*MDfCY^M<*m?ci^ZLM@^`5tO&%)`vGe%w@q7ua`BZ@Cdf10~(JKG#rfq^rE0ab> zk9P@-jii$dpi$lg$f_zo)N7&eqy>ER<~MpPslA$$3ZdLbV3u2Q+TgC=azzs4^{Vh>#D7vwb}2` z*eaRZ7X7*-T9Dm{FcrIMi2q&TOt=7S|8-WyC6A}C_!#|7zVPTPbB9;{YLj-1hOPMv zv%j4i!$3_4eaNBIqzgc-_Ju`A&S)Sii+qGRl5^#Yv4s$*plu%4n04i=X#rxJsWr+e z959(}rW$DH)ci&|qUhp0kO}TCd{OC0(Y}Hs)qQss5ogDm!<}H$%N2XTCqMN(b|-dc zxMN1nj#dA1IEiIJQ^TH~*l_r!8c`zR;!3 zghnpgP7r#z#2amluF%EEVN+EyY>c2>b0sY z%VY#}nuNDDJjsN?*N2VTP^ygA`H5{qi~m7^00VIvfs`Q@Uqf{SEi=P)@a5TSxX;Su z#ofKp@kpN=m*!$*=|BUOvA zlGO7tkhQC8HVoZ!vp7(y3dD9Fv?B*jNCM`TxBpV@47$>V4V%l%LR)buOYwoWxW!=? zp0zXng^4w_C+K%ls@79x)u$e0D>U4ick_;W6!EHTtNpdan8_e3Mwn8*`GH&-w|KuF zulNl~`Wla$HPXe-xff1hZ$so!n5bO0FWUoh6yH_q1a@Ifi!|11a% b_rDc@_|FUA>Ge diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png deleted file mode 100644 index 646cc3e32350bf9adde2bd2405821be04a0d0e0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^j6j?s03;ZUuHXC*q?nSt-Ch3w7g=q17Rci)@Q5r1 z(jH*!b~4)z$cXTCaSV~TeDu&>UIzz;hKv1@CM62OC7#SFv=^B{p8kvO{8e5r~0g<+Wft7*5rsc9n eP&DM`r(~v8;?{8Z*U}201_n=8KbLh*2~7a9sa9J6 diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png deleted file mode 100644 index 5f4e1fa73f496965f0d9b00bed5db82a1c1e24cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 328 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�_j6WK+Gj+xJRxVvl#lh7y-4uY);t)n47k4ot z9YsU`HVk7fg4;r{;)FHk7ZHyZJ+W|$aKwj=g&_$VCVFn5%XzSA`|z}+4ItZ|`hB}R z>h-6Be`d>nmv8;kQHJg!HMr^cCGG=T5;3HhZ_JRq0_4a3TsY7Pz{V+}z>;!R^U4*c zJ>wRI59B-)92Vi?b&EWvH(`<(G5A?W)z>EuDMG@VENAb7aHa`I#tKw{0uUc3(#J8& z*_S%A_ZxCIY385{%qN-b1K)TWmCjUA4nWKx_ZnKLSvEf0($&_0@DS~ zN8JOXJXXcaFm^OCYrz(R7N5DQkXKGnnt}yzfw^8s%=A?7hxza;ylJ;XQ&XtC`pM%b z6$5Ff0{(ALcSlTKvIbr@mR`0Z)*iM`2EfO|E5OMk$jQsE!^mat*drqV diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-icons_228ef1_256x240.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-icons_228ef1_256x240.png deleted file mode 100644 index ab0da63d7c5741ada4911b46e4eb9b3baf073a39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4549 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 Mq_Iww7W(o301+6dWB>pF diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-icons_ffffff_256x240.png b/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/images/ui-icons_ffffff_256x240.png deleted file mode 100644 index fe41d2d0fdd40f87538d2312fa537a799994e55b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6299 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 diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/jquery-ui.min.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/jquery-ui.min.css deleted file mode 100644 index 80a19f6d259..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/jquery-ui.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*! jQuery UI - v1.12.0 - 2016-07-26 -* http://jqueryui.com -* Includes: draggable.css, core.css, resizable.css, sortable.css, button.css, controlgroup.css, checkboxradio.css, dialog.css, theme.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/?scope=&folderName=ui-lightness&cornerRadiusShadow=5px&offsetLeftShadow=-5px&offsetTopShadow=-5px&thicknessShadow=5px&opacityShadow=20&bgImgOpacityShadow=10&bgTextureShadow=flat&bgColorShadow=000000&opacityOverlay=50&bgImgOpacityOverlay=20&bgTextureOverlay=diagonals_thick&bgColorOverlay=666666&iconColorError=ffd27a&fcError=ffffff&borderColorError=cd0a0a&bgImgOpacityError=18&bgTextureError=diagonals_thick&bgColorError=b81900&iconColorHighlight=228ef1&fcHighlight=363636&borderColorHighlight=fed22f&bgImgOpacityHighlight=75&bgTextureHighlight=highlight_soft&bgColorHighlight=ffe45c&iconColorActive=ef8c08&fcActive=eb8f00&borderColorActive=fbd850&bgImgOpacityActive=65&bgTextureActive=glass&bgColorActive=ffffff&iconColorHover=ef8c08&fcHover=c77405&borderColorHover=fbcb09&bgImgOpacityHover=100&bgTextureHover=glass&bgColorHover=fdf5ce&iconColorDefault=ef8c08&fcDefault=1c94c4&borderColorDefault=cccccc&bgImgOpacityDefault=100&bgTextureDefault=glass&bgColorDefault=f6f6f6&iconColorContent=222222&fcContent=333333&borderColorContent=dddddd&bgImgOpacityContent=100&bgTextureContent=highlight_soft&bgColorContent=eeeeee&iconColorHeader=ffffff&fcHeader=ffffff&borderColorHeader=e78f08&bgImgOpacityHeader=35&bgTextureHeader=gloss_wave&bgColorHeader=f6a828&cornerRadius=4px&fsDefault=1.1em&fwDefault=bold&ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif -* Copyright jQuery Foundation and other contributors; Licensed MIT */ - -.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-button{padding:.4em 1em;display:inline-block;position:relative;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2em;box-sizing:border-box;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-button-icon-only{text-indent:0}.ui-button-icon-only .ui-icon{position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.ui-button.ui-icon-notext .ui-icon{padding:0;width:2.1em;height:2.1em;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-icon-notext .ui-icon{width:auto;height:auto;text-indent:0;white-space:normal;padding:.4em 1em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-controlgroup{vertical-align:middle;display:inline-block}.ui-controlgroup > .ui-controlgroup-item{float:left;margin-left:0;margin-right:0}.ui-controlgroup > .ui-controlgroup-item:focus,.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus{z-index:9999}.ui-controlgroup-vertical > .ui-controlgroup-item{display:block;float:none;width:100%;margin-top:0;margin-bottom:0;text-align:left}.ui-controlgroup-vertical .ui-controlgroup-item{box-sizing:border-box}.ui-controlgroup .ui-controlgroup-label{padding:.4em 1em}.ui-controlgroup .ui-controlgroup-label span{font-size:80%}.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item{border-left:none}.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item{border-top:none}.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content{border-right:none}.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content{border-bottom:none}.ui-controlgroup-vertical .ui-spinner-input{width:75%;width:calc( 100% - 2.4em )}.ui-controlgroup-vertical .ui-spinner .ui-spinner-up{border-top-style:solid}.ui-checkboxradio-label .ui-icon-background{box-shadow:inset 1px 1px 1px #ccc;border-radius:.12em;border:none}.ui-checkboxradio-radio-label .ui-icon-background{width:16px;height:16px;border-radius:1em;overflow:visible;border:none}.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon{background-image:none;width:8px;height:8px;border-width:4px;border-style:solid}.ui-checkboxradio-disabled{pointer-events:none}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-n{height:2px;top:0}.ui-dialog .ui-resizable-e{width:2px;right:0}.ui-dialog .ui-resizable-s{height:2px;bottom:0}.ui-dialog .ui-resizable-w{width:2px;left:0}.ui-dialog .ui-resizable-se,.ui-dialog .ui-resizable-sw,.ui-dialog .ui-resizable-ne,.ui-dialog .ui-resizable-nw{width:7px;height:7px}.ui-dialog .ui-resizable-se{right:0;bottom:0}.ui-dialog .ui-resizable-sw{left:0;bottom:0}.ui-dialog .ui-resizable-ne{right:0;top:0}.ui-dialog .ui-resizable-nw{left:0;top:0}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-widget{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #ccc}.ui-widget-content{border:1px solid #ddd;background:#eee url("images/ui-bg_highlight-soft_100_eeeeee_1x100.png") 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url("images/ui-bg_gloss-wave_35_f6a828_500x100.png") 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #ccc;background:#f6f6f6 url("images/ui-bg_glass_100_f6f6f6_1x400.png") 50% 50% repeat-x;font-weight:bold;color:#1c94c4}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#1c94c4;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #fbcb09;background:#fdf5ce url("images/ui-bg_glass_100_fdf5ce_1x400.png") 50% 50% repeat-x;font-weight:bold;color:#c77405}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#c77405;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #fbd850;background:#fff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;font-weight:bold;color:#eb8f00}.ui-icon-background,.ui-state-active .ui-icon-background{border:#fbd850;background-color:#eb8f00}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#eb8f00;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fed22f;background:#ffe45c url("images/ui-bg_highlight-soft_75_ffe45c_1x100.png") 50% top repeat-x;color:#363636}.ui-state-checked{border:1px solid #fed22f;background:#ffe45c}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url("images/ui-bg_diagonals-thick_18_b81900_40x40.png") 50% 50% repeat;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_ef8c08_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon,.ui-state-default .ui-icon{background-image:url("images/ui-icons_ef8c08_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ef8c08_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_228ef1_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_ffd27a_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#666 url("images/ui-bg_diagonals-thick_20_666666_40x40.png") 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{-webkit-box-shadow:-5px -5px 5px #000;box-shadow:-5px -5px 5px #000} \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/jquery-ui.theme.min.css b/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/jquery-ui.theme.min.css deleted file mode 100644 index 09ace29b29e..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/css/ui-lightness/jquery-ui.theme.min.css +++ /dev/null @@ -1,5 +0,0 @@ -/*! jQuery UI - v1.12.0 - 2016-07-26 -* http://jqueryui.com -* Copyright jQuery Foundation and other contributors; Licensed MIT */ - -.ui-widget{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #ccc}.ui-widget-content{border:1px solid #ddd;background:#eee url("images/ui-bg_highlight-soft_100_eeeeee_1x100.png") 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url("images/ui-bg_gloss-wave_35_f6a828_500x100.png") 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #ccc;background:#f6f6f6 url("images/ui-bg_glass_100_f6f6f6_1x400.png") 50% 50% repeat-x;font-weight:bold;color:#1c94c4}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#1c94c4;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #fbcb09;background:#fdf5ce url("images/ui-bg_glass_100_fdf5ce_1x400.png") 50% 50% repeat-x;font-weight:bold;color:#c77405}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#c77405;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #fbd850;background:#fff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;font-weight:bold;color:#eb8f00}.ui-icon-background,.ui-state-active .ui-icon-background{border:#fbd850;background-color:#eb8f00}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#eb8f00;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fed22f;background:#ffe45c url("images/ui-bg_highlight-soft_75_ffe45c_1x100.png") 50% top repeat-x;color:#363636}.ui-state-checked{border:1px solid #fed22f;background:#ffe45c}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url("images/ui-bg_diagonals-thick_18_b81900_40x40.png") 50% 50% repeat;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_ef8c08_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon,.ui-state-default .ui-icon{background-image:url("images/ui-icons_ef8c08_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ef8c08_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_228ef1_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_ffd27a_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#666 url("images/ui-bg_diagonals-thick_20_666666_40x40.png") 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{-webkit-box-shadow:-5px -5px 5px #000;box-shadow:-5px -5px 5px #000} \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/favicon.ico b/web-bundle/src/main/resources/com/graphhopper/maps/favicon.ico deleted file mode 100644 index a9c5dc7ee1e0b8f7f123c009bf328fd08dbe104b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 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 - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/car.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/car.png deleted file mode 100644 index 1a0b843b1570dbd088867108269e122d8a950662..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1018 zcmVI?8)+EFKbC08baiyuYPV6^@z&m~-4-ddg*FVK zy9jA6g566&+TQD-e?ZZLR}Ti=%UlzX-IG?(RcMzD>mgOKhf)|U4h^l@fT50bdhl%- zqnXT%#;G)47-sgF~-+A62yi;dc7RMPUf+lcK)C2^Lnt-5D6A&~)KK;&!=QMEg zkhpvV-T~|4afLb`2iYaytXC(GcnkdJW}w#!oCnS>E-to=jg8%1TU-03SS%ijm~c4! zHWG>aJ1{Vi>gwtOcn`d(ii{E~G-TU*<6P1BwNTfj5mQzcSv z(F!!AQmM{rkq0mgqbHS0bpj0{rz5-w=m40Sn!4qan`_u|bW|Gab`6{aS__3jNZ0in zc7r5I`sC!~Baa++p|`hpbaQj_D_LFFZxjlJKN=ewTSe}V<$T>%AOh4SlgZ1bY07qk zq9_Y~NIS(aO;b)Llb3-yk-IG1R-hdqlgZpJHK?jOFPi_bvyXehY2d1=s`E=rOMP~O z$n`?xeqAnrn+nK4Q#PBGbGcl%-5^Pl9*f0vzyxw0$s>HsSS+SXlBDl4Qx z8O_bj%kg-893Y)e-{08SxEMqn-vZ+C_;_Dm-z)JtJ~1&d5=5NucM7G`>HEOAtsO`l zr<3?sfM_)Or(bf1iRtO--$e5-d;hVYLNx(F!)Xm%1NNN4<<^94j(UQ}c>e=`+dG^p zup%736?_0*mUcRAqwm?R_7)J9WqBo^&tI?)lx2BEG>gEDOG1Yd&&wLn0TPKs(v|>O zmRAyqMAAOyDC2qgwHN|=D1X7u1J8l&qm1YE?{o<0WapCo<&Iip=S#h=l&l)@{QO@3 orf}@fftrAzQ4JNGJV#QngJ z8SXv5bH3;N{$6l!aBy&NaBy&NFySF!7Ptod0z7_i<=EpXAPxv{3wYw*%CU!&#D4`R zi7blF^T&WXz*mHiuYp55!GY(1nD+k`@IH{#v0VX{%pAHkL1Ll3Wm7!Bn-*hD0$wAB zZ&-9Fz)j$O8{$iWKWxPN)X3@gHXPa=1*_H1wq+xyOE#VU38)stmjX9VBLSC%phlbp zUbkT13sjv_>|@v+0V|_$lImL?fkWUk;6FVm*9UB|FoJ=NL zMWjrNQ38BdD1rQwcnP=-yr3m@3U6%edWc8XFtw>FN2oy1M!`MNu|^ zGR^Thqw3`FJMawfFmP2>RqyENC>0eI%*@QNwY5c6RTb^+?YG0>@Vknld`#x7xdt2o z0X@e{n&S{4&CSg+Jv}X6ulKGB`u%>Ho15Dbk?ed9>r}c>dr9jvUs6&c(P&g!T3QO) zc6N5k(b3Tdn*9Y#rqDOq?}w_YN-P!=RaJF``2Bv_+}ymP^>G2)MTpLc zdwUK03=Iv5h%{(%E*m9~HTt}xqeJ@o`b?`iGBT3R8HIK-=YdgsRkN)EBo>Q_+wC@t zQC3zadwY9d=4k{n3pJNT?e}^h5MXL*$|zX?78Vv1;At}Vnr}@z+~F@(RpZ;++YhEv z#yjQy{yr-!E7{#@G54L`Iq;Ro<2g*H)21p!1n%DYiXo+{>L*%%Qxruhc=gvy;P2Yn z+K(C<8gyRYp}xKz;Mby5sIQ+l(7dkRhEfMIuY5)KL07*qoM6N<$g2!V7zW@LL diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/continue.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/continue.png deleted file mode 100644 index e74e2042d66834f849bb8a7d7356480fe16e9f14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 807 zcmV+?1K9kDP)`RY%pz; z$to^_ASj9s7ExONbS=8Lh`6}9bm?~qwjdNI5iGbUC|JQ&5FCVP>GyLmZ@8wp+||pS z%lAMaclUDdlP8xYAc-Wev9Ylmqobp}N$%kx0p)VJUqtTba=FV%?vqFYz!ZQy$*IZ7 z$?cg-l*{FQl2;msyX*D(#mptpsGtWVZTxJq26_mZ6=UvE50xcC35xF%uIJhl! ziI57)fq{X6^QlW9q=G{7cA-${NlhZ6f^smQ&!0<80udDgOwZ2F#=dv#!I%}4Ln|vQ zXSyzd_!R&E*4h~nkvOwLGIFR<;mcMe8l3ihe?Dp`Ziy{b2oS4AWQhb7001N_)oRsr znu$~5Un~4w;CXkVW;&KgTA{f_q-2bF5q3SQM4}1`$&NKbOLVJ3K;&e#T7B8>TBj0S zsnA^1;n`?gqT3ak%S1+uF|RfWhRk=hf)e&@Y$}mfg#g38@4pV7XjdYY3W|u_-E=Nk zB7+J50Bh}uTCMh0k6TNmTA{hL<(JYdkyQo7T6?@!tGxp@mdK=n;(6YTz88{_6-49* z$qxX20T_v~1WbENxFiQP@II~Bors1I0?l`C{99g5{i>h loP^>e6epoL3B^e$e*h7vb-_C)h%W#D002ovPDHLkV1k?(SoHt^ diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/delete.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/delete.png deleted file mode 100644 index 4b7ad6f739e2d2b8b647ce7b8437d709f205d1dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}c0*}aI1_r*vAk26?e?r% z`o-5wpo$Vt7sn6_|Fstaxf%?3SOW8(OttaLTid%s;E~9|x5u4jvOMl8C298XA;F`D za}NL8^W6CU=I@)$dtB>ur1VPu6)!M*wdEuCv1R#Yd-D!O=-l7H7x{_b)I~b;@yo4- gRt7NmPy9CPvWj`Xls?sc2iniz>FVdQ&MBb@09uV$Q2+n{ diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/direction-icons.svg b/web-bundle/src/main/resources/com/graphhopper/maps/img/direction-icons.svg deleted file mode 100644 index d97df165cae..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/img/direction-icons.svg +++ /dev/null @@ -1,499 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/foot.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/foot.png deleted file mode 100644 index 45ff1e27938483109158b99c890b4e1219b45276..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1122 zcmV-o1fBbdP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L04^f{04^f|c%?sf00007bV*G`2i*%B z7aRtJ!3jeE00ZJlL_t(&-tCxQXj@er$G^XGnk9UkoQHg0a?bDk?!D)8f9Ll*=LTr0rIuQ1rpT)san5}JdH{p~>;bS2 z;4%?il^%d|-VNXg0Kd!d?*Psdk+mBDZ5~X%1He%LY;ke%u531YY;A2V+}YWAd2DR# zi^0J`05AbukTL?C^G5)L=H}*lr>CdiG)*&Lk12{$8y_Ekb!24ZHvo%7wC*(k+u`Kf z0PF*RY&QF%bMgRSnr2{TX6CqfQQ_T)0Ndg9?RFHa)vD^|P_0(`MDq?A0ZhB$_xmeu z4h}n$5#Tz28vqcEMvHC^s;U-5b4@w`BH{qP1;8gKCubv($gEv1iO5n_b#`K6;!6M= zH_NGfRY)ZBy#NjYP*zq}0?W(GclY=A|IyRaQxh&1iRe3N0R%*FYHDh%TrN-4YPJ0U z5DJCPrBbOAqobpF5iNNE;_>*M04@U9+c5N#&*$sU<#O`nK!XmuOdbGK!!TaMF3B?h z(==Cav%Fr>G;N>M0D(Z@XE^qS1_g=ed8q+%x!fiI!)2%{eqYLDGE7|0t|N=XY4i^cqKscJ-20Pwx&o`Q#!&r<-u-@o@ZN&K#8KB#HhsFVQR-Q5S=?CtIC z_n4-62Ea8Dk=J9fSetYJ!C>&9>jM}&P%4$K1NcaoRL0oDUOm^dH&LlnqHgwjz1|A| zhGCpm6y*{TU0GOII4d2%#>PgUn|*V0a}WSZrBW5ZThdmcdcA)5KN9%uabC>Dz!OBDgm`O^)i5ADXl zz`*+eZhh<%(Mia5lwgcGm(O1SKCwHQOvYl29mhW>()%<`J1Px8B9RD-zZUIie5ULA zHK$KLpT9&zXB<&DCQ}4b4fpuK&B?N?f&+3y8UV|(o^d8`u~>9HBGhWNuK?6V1da?1 z4fQr1V0d_VKM_6Vmb{HBm&@y%^Kb0_*4EY&O$RUx<4FK^UB96yN_LxMcUGf;rUNu= zUZ2m;&sVnb{}jNV0^sYW0}#=Q9SkCRXFGpg*MIf-d=W)aqJ=`?J+A=%_ok9gr - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/full-reverse.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/full-reverse.png deleted file mode 100644 index fbc3ee41fdebb03b128fc9af8541732c875ba294..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 582 zcmV-M0=fN(P)6HC?r00E{+L_t(Ijn$Pq zs=`1Rg-=4jYDz&Z6h$zg5<~-oglHkyx&ikgh`k%IvvL7q>kEWn8jBzVNhLPvT!Xnq zh;hv0UIP~QRGBmX|K;StKb+$@4!$4(0M_d@48sU5==FMNwOWjKJRYHGT4+6`6y0vu z1)tAntX8Yg!eX%)09%$7Sx*S@!JZ0*0ve45Q&=jM0?n051%ttW@lK}`Y}!1uNnWKW3KT_QyzzLa}DJZ3hp6B?uRTb@aoAC~Z1Gd{O - - - - - image/svg+xml - - rail-15.svg - - - - - - - - rail-15.svg - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/full.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/full.png deleted file mode 100644 index b243dd72b71e47bd1c2025f61062f9b4e8c917d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 546 zcmV+-0^R+IP)6HC?r00DwYL_t(Ijn$Ps zs=`1JfWL&OomYq=1Pc*^vIYdP5dD}0H@ z2oHiO-q-Cg`|V_s*+{l++k}7uFdB{6Znqy3s?{p_eBKkA&1OueQ+FMWMv28@02qcr zrBZo_ce@?^e*dF5l}h=<=kwVkekC4{KgABJs-o+nXt0jSk#q|<2 - - - - - image/svg+xml - - rail-15.svg - - - - - - - - rail-15.svg - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/gpx.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/gpx.png deleted file mode 100644 index 1ecb22ccada844215ab21fd215d93a5eb687ad8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 405 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 diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/hike.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/hike.png deleted file mode 100644 index 2a31cb8da9cd790dc3f100a363809be7df3cd7b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1783 zcmV<{98FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H126Rb8K~#90?OR<;6jv1f&g>$ClqyoNLQMsOrKzSqXj%=yKzC;- z3bwUu($u6$n}+z-G@4XRBhu8ww0$UP(#D#Q_+Utynn+X3vg__csj+ROKNf;MRHIE= z1fj|Tm6dB@xC>wqKuR|vUJD=q*aToB07~K?18^0<9glg~ zf;`*_`T;x#AlGbUjFHdhGoO?L=mv1pDy5^-W5=qKT|5AckB_fuZf<@@@2&!{#v?wq@JfJHMx(pCyUHnW zXlQ85<;#~J)4Ts00YsybNF<(|Ex4hsBWBSzW?r3e z&}bAE7XIQCn3?kLCbT6z|m6*T3J;&|u7v`vCs&h>tD2+zAqZtpJJ)LvL?y zPG@IlaY;!@e^pi0UzYgq0StLX#tvQzV4wg%*_A6-Hng;~?C$UH-=ru?R$*b`)ryLW zOQBHcI)L8*-1eGCGPo*$BuS-2%<07Ue{EFq7~;V|#H!DYU1YX&$z@BmQfaExt| zB+VwI>sYV=b#-+sF;Vt%g3~Q9Y&1CMi#`h$EI?aZ+bCnKjEG)x2z%h*YXb0x-VOwV z!M7L6X+Ch}7Kp`S*NEtEhmdhQ2N4ZunpTe~k(#TktDRO2SK->y!x&rVXgR$Qb*orl#gmx41dMH35joRscZ|Ryqt-0idI!;|l<1bz7;TC})VsX=!x@iy{E$ zJm1de^Z6#rV5+J%0O-}bdjo;M5x4l+!8HLiO>+{!w$vqxVzJSV$Kwgc*sGXYH9iOi zgSRC~+T|8cE8Ls`b_GqR`yY(4LUTVBi*@VI6yumEtv#V>TCF=QXTr_>_jv&ST5O6S z2;VvlQdPCsYKumrtpG}i=oA1DQMPL=EpSbMNF;JbRn>e|Ro5ARV`F1^nx_5aG)_^J z?XoNvBstzKOuZ@cOaND3jm6{f1T2NkKp?PjmSpbJG%W<+vn0L|{r}RR0d^pwt#gQZ z&Bm490!Wfniix_QBRJNE!bN(ea zm7(=Q>a?#yh^SGP0`LkZ+Bsk}v zSWLlCD6~Qlgh>H3O-l~}Dl02jV`i23MkEr6*o}!sqt~IoP1cb!I5@bgy}kVb^ruNh zQ9Q{5t_zTnk+BCrhS_FKe#t;Y(*zO(VUOM%)&1!)12j#uZhmGYKbvvW1mK(-0(iO^ za#eu3y1JD_RBbUQO@2ub1)!PwCBb0uX?VODa#et_v9T8cWSMPF$H+H*ah2&n5Yp5e|n(%FD~Q2!gOJD=TYrEEcn_ZH4_Iu_$2sU?kv{x?I*0;HNis - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/icon.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/icon.png deleted file mode 100644 index 2101141930752cddde80fe53cef57e4b27bd6558..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21575 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 qR&*pBVEQRw*vTQWVY)*bLIMx~ diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/keep_left.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/keep_left.png deleted file mode 100644 index b098f1f279ca86f86ae55aea93b48e4ec0e0eeaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1948 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 diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/left.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/left.png deleted file mode 100644 index 286b17aedd393a4f02a2f66f1507d991c3c4ac38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1302 zcmV+x1?l>UP)+XIq?Ci|{{`c|k_x}IAd9xG|v=VIF&XRmwDfPaN{*pR6*$SCVCYeg5 zo&_*X@>5j65PD(*TYEFlyP6oYlc+Gqx=N zBx&3BD1d1IPlRY9B65Da_|yX9E`!6v!)AYf{|OP90`NeDrr#;09*dPs2*jpQ0hn_fXAr<7fa3@+ze)_%%cTNA1Y5?E)Ra;` zDy3cyf?$B;hXDSn!_C8Sa6tqG05D?B>htsSe|nzxK{A;f0PqTcs}Y(Xv@GjT3^epB zpc1a@7L`(8Dy0TRBt!B-7-ES;;zSJHM+rc@3aExcp>WCbyraJF-v{6`5&5Te>GZt- zo&oSpg~_=FyNFT-8T-aaJ+N(is65?%4nRsojur}q3w8SXndE_x=2u%H0PDzPGP_OF zJPp9=?d{FX&d&ZD)raFaKOy|{%WEyQxLI6Wysng*NhXs|6^q4s_ZlK4!IpSKq!O;{ z7E%Ahnbs6aWAK diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/link.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/link.png deleted file mode 100644 index 25eacb7c2524142262d68bf729c5e2b61adfd6d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 343 zcmV-d0jU0oP)$`dXYaZs9=SbAto%g@>T~?_bH&lTUn@`uo|1bXE{eSR(AO)ESb=V4`uk}mK|39Px&03WLbv~pzk+s7D@lK^ zn+aB+sp)&Y_x-B3>;6ywU--WQNUr<8>TU0P-|L#1U&;A)67w(+> pDf@fM7q9#F25QXo3rUI;002ro52U44e~JJA002ovPDHLkV1l;_q@Mr) diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/loading.gif b/web-bundle/src/main/resources/com/graphhopper/maps/img/loading.gif deleted file mode 100644 index ed65b705afeaac6b9a13edf8d2efe503ccd7e5b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1840 zcma*mdr(tX9tZI2z31lM+(&YVKtrTX2#F>kG2s=WSobD?L10;+3gxvVVpv0=1}ef9 zMDjpL_)TTNG>oAJcYA#K?@c9b1_?yVGqugB^B9Tel0l?Nn#lx(PG8vwvh~ z_WXIy@67qk_ji7lT|13iZ4iOTHwg0d=~DzjR#sO0e*e- zsX!nQ6B9EwHiqMPMn;Ci;Rv1n|104M;8UUUgdZhY&34;C`#x!_8M-_q^i zl<4ve+cfrCwmS&_%1M8IE!y<(g~vlhEyChxg5{s?4)@=$pwGMT{6f z@X@vux#SSW0ZQJXNd-chVu8CR5hZyDyAO1w177MW8U1oPP1_TYf8+nlawu$ZaQ3YO z*(UNm6YQJyFRacBqI8pSR_A`XxIfFL;G}rpt%uIs3nY04PPfhNL|ws_=Y7%8v#u?% z8)pFsZn^%s_h@-^-9Qv5Kxm(}QeM^Kilk^9`8`OU5j zQ*&g@S}vcYg)rU(GIv$>fm$@UfxcTjsN*~{y;=bjxzf5Iz;9k~!Zbl&Nz!-kYDL7^ z2Une!$lI@57mJi94W#G(xigZLJ-Y9ue3DjcfL8@DWsc$YIX9La51rSX8N25L$h}<(>&lP5#XYRfqwcDHX z=q{X#eIw@UrWh!BF#fk0`>V{Cdk*BM)Ra~H0wLRS*ek0g2;5fa&@n_c!KhUI zT7pCh>gf>+66=!-ieYj-oGojO90}nQxz&H^g0_bB{kUNx_4=SB%8i%QLm3Bh>}gUJjf@k zgixhYG6Y7ve559C2=wl#sS*&I1(wDPvQHjavo_Fc8dR-0CRHw|1Iq8s>6M~n@w!>* z?<;0M-eudLz_XmXXm1n0GW#e`-)p~am=AKL9eXBmu$uPHwd}^(ZiQTM=Qm$D#SF!- zB5(_Wwek7vVT4Np9e`m_A@N)iMI@il@^ftIXoD)UWi1)i*z&}yn@wZ+7mmNV^yhxf zZ?F9z04IDoRmuj>*o94*>C*lsm@dlpEyQ){A8fpw>b6bkwW4D&Lszx&g2iXg&x=RE zz)g=cH!T|CrF^Jh9TkHKK8Ow6 zS--rf*P#OzLzmW%#X62jlc|%5q?8#bLR!8}Jj+(D%MkNE?Uv3g_r@CEzS3Zps?Vn-F zI<@fKVe6uX&-9%9c3iA^v;#vSFOy=8C578HG}aBbC+`-*Y931cx)uzd+RQe+D5tov GCi7qYbq=Qh diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/marker-from.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/marker-from.png deleted file mode 100644 index e4bc611f87b454e5969078aa167f48798adfd208..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 672 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 diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/marker-small-green.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/marker-small-green.png deleted file mode 100644 index d4b959ebe1a94e6f002220d1c268eb7794112534..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~OrP)H;LN@>a0li5?K~y+Tos!)vLva|#ce4vF zlneiYm(AX{bN0S@op5WHYIl|^Tr!Eg3{fI4k++D*qP0?rxNsptE?CK(BFscF>G3?j z*_rL^LVoo@j&-wnIb0z_Re=C0ZwFO55@i1Y-NNoq}R+@ z!j?T3*bl0itOr$K-mL`1C>KIMk8&ay4TFBw{zjl-!zq$w-vz2^(-r1&Q{aMjr4)@Y zA1VXgiX9B=4lr()GbQ#&rkx7FQRdU(T7Ih()U#&LE?QYr{c!_yUG}r1^TD{MS+J1* zN%X_suE9Opr|Y=gjUkb#ld zGdz4eg8Rq=37^_2pKNYd*5O;Gd4PUBCyfk#`iQ{w>kV+5C9IWvIsxScIKNeqO^|Fr z2gSn%HedB&9e7WhfeScU8+rJ-Ks8}JBSwH}$p>}4>KQZ0{8|>Idy;aDkME(VprAwL z7Qxt_gN^4jS5c3K<`P68KIjWS=Q!rFL@+H3=RQJFD0000JP)H;LN@>a0pCePK~y+ToszptBT*E_Z7kM8 z*kb>aB$Gs$fFX&Ki7{#teBcWdjoo6MPF%LI6BbMT2Lxf=UGbe{#+k(E1jOAm+SzCk zFc^sPdCpY^bu1PSeDk>9_nUL>a9aR;SWlN1^~dXNC8@i9|M#3MuWb8#S$g+8+oIlu zDdf`P@#^XHG_1KfSeXp0*;$-UO<_M2+9dxA=NvE@ZX=njGgulNbjX^SL0(b*QSS3A z_@~Fynu|uO<*_jo2L@0|r*SedAygh87i+AO$w}-60;_M~*zw2+j#L$9A^~$~2za=SLN~NGjBBJZX@-iM84WVYOCMGcZ`h;IhCc$|d z=09ro_d^SXVA6Ouxtsv+@9xmNy~W>b7Pe2_Id8)>M#_lCk(Xugy}G#g1lQ|mTwS3! zJS@7h&)ed>4R5&JZ92o9ohSqXFk&%O=I3#?v;>nt-Ya`rFo?rQ#A3#Vx%OoFo31E0 z@cVJl(E*K~S$P^&tdWeK9&Acd+5xY-TW2MxECPn{*ELdZ1op0xyVpxzDdhz3h^YVPo^S(T97!Wp}{CC5s zOO0&MCbYN{*S_u5sKy(UFm7-Lr)M|odnZ1F`|tp z;QLC~;7ZS9V!0QqC_yL9nVW1CJTMZN4M(R$+ zOTZBsFr_4h`&3JNv0I_O8fwI~`z}0v3|$@I8UFpf@&;uE8s7DoF&~bRfJhmzX*a6< zs}(O~Kx~cpZxH}pS*S{qZRPWYW?G`zW8AQcn3#1@S*BcNV6f!zir{5lPjYZSt>eR~E27PJ0+es0y~s0ch&nN;M*NkCc% zXiQ#beHkC&om4IpK8qPut?)aNVjs<%39&#|d3=N1!OZi|I!ONj#Vr@M%?lVEC`+Fg zAQwL{?FfzVoB-$9WC=Ju7r^r86-w*!nR~wgLM67#gs;7-00000NkvXXu0mjfgI^=` diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/marker_hole.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/marker_hole.png deleted file mode 100644 index 17481f2ebbca306868b212b83234fd2ba930bcbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4586 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 UKjhgk!vFvP07*qoM6N<$f&(X?O#lD@ diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/motorcycle.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/motorcycle.png deleted file mode 100644 index 552a98a58717806c98ea1786a88b64064c532ca2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1676 zcmV;726Op|P)FpZBiajYEt>rk@t2iO3HjVA|+H?4^GtRPEuh-3wbtS*jYUbX1&OPsY=iW1CR%XWQ8Lrg?t`sW* zT8$L}t;ULgR%1m#tFa=W)mRbGYP{|Rw6&Um=Xuvl`l560V4+a>+fx0t9KHv#+3ZQ6 zThgt*@1I(V@3PoJW_A?lHnSnm^ENHTchN1B%jIqc*2RG)opUcwO--FG7K^j5jqc@e z&iyIg37aJS6nJ;DzKd?5Y&QE3;M$t*2sj5Em-K`4=gLeckSBsrgFKQku(6@SvziKkA-3Qsb=PC z>JWRLw^P#3fj2K=`e>q30`rUnL9l&MVk{vGd7igH z(no;1fLj`vo&p{!l}bNZwQAMdqbRyvQh(wjX*7zW4U*dH_(s4FqbNFX^ytyQG{dXu zEY#K2b-~OEsZ=WKoVy8l061O8bPMo!I-MRjv*#r3=aS&FX0~x5@@BR>2!fBcwY81q z^Z8UWyc#|MNy=n0_elB>unkxp51j#?bIyIm%(~3%t3Y4FK+?a>ta}kY{{%|Fjlh(o z5i>hJJ3IT0;o;%2B?-voa@PTe%kK7ME<;_(>3G)R!jO>5Cqv$skG6|_5(8j zQ4~Fx$z*P9C?J!`Y%{Y@#Ld5^)9Ks7FgzWv##-PGGy5*^keN-yb}2LaHo*Gz>t}#} z0asI5{kkx-ubbIt;^vs7-&PGjn9t|0Di({gVHiFj>23f?9nQJ$G!)>ROCCRFw(rQ1 zBa?l7eO+dj0?wG(DDdBksjJT8JG0sBA0{RyPEkph)PfScC z;_!X{`@nDF=6id3dgim(WdbDiB=<8jGsgf@snlLc?*OiqbPbg!Av3G>zXiB%5%K_s zfF1KBoEr*);P=22RW|#3dwbVZwSN^~)7{4<)^>DsT%9UZXkQ9Vr zc+Sj{x_@;NXK-+ERMH*52ymeK14q&g$^G2i+{xtrvU1uv_k5CCopS@g!(kX6_dM?& zN&8~6Nl8;?HZAF0X4VPJ#&tcCT;-xeSMo# zsnknAJMfBgZfmlY>crU>za#5Gx!O5*-1EGT<@5QDs^HgT zv)QMr$e(l0-PB&N&P--|qlgQoBQVQ@bHDYj%K#(eggvoS0#(P*l$_ - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/mtb-bicycle.svg b/web-bundle/src/main/resources/com/graphhopper/maps/img/mtb-bicycle.svg deleted file mode 100644 index 155e16298ac..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/img/mtb-bicycle.svg +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/mtb.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/mtb.png deleted file mode 100644 index 2a5bc0ab4d17ba5950fc2e64f4d801eead6fea72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1623 zcmV-d2B`UoP)004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw00004XF*Lt006O$eEU(800001 zb5ch_0Itp)=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m_e01m_fl`9S#000H9 zNkl+ACt7Z=-je1sNuxm+Cs0|OteXHR!B8324c zT@x*jwtIPb`NQh!>XI$P0JQTa0B(2QR$^e>^d3bEQ|s9g!sO)Sbqny%(H&E-GpuV%PftIHwq7qSEj<&BM*rfsa>lmN_TVSKi_fgt z2jaC;=50guv)a-Dv{0w-RaaNHgY`cv$xp#}6-C`u3nr!L3#h;#Ox|lY$G9}WrDH!5 z2(Uqu#B9MSJ?#m8e;(=oIzB%BqY+&S3kypaD>JN1Bsw-W_P4Pgh&?eU$QzE ziT}yoKk#^nmdT!faLyO2x)0!FhgkTr;ba!%m75jPYSJz#@9Gn%dn!!X_yP5J73~Z= zosYzWbXVjVt=+S#3k~4+s!GzMRCp9S-Oiyd%;|2%TKRoiP4AZZ+M)m1sms-FdN=$e z9H#|G)VjP?F#y0e1wM*Ys{nSaudi?A(B9tO2&zAhRQAcZHs1jGwzgH7XLxa~4fVM6+ z1Awa44s@(fh&rb=Ev&4=)N*apzsogXJi};<)86>c%SOW0*TrOjjd!WXD@fn*;w|Q+ zIodAOm)Xr%+BE#+g{rEma;tg#z8lc5sn?)x1%&HdqGOxKK}vbL1I0nprgaDPlEPyD zqpJAxpy3e$zzO;u@i8$QBrhTRh)QHD^G#Zp$XM%fFrg_`lf?Vo#%ppkzczNxB0PQt z=w=n=awGuAS3AOS8p-iSJ*22v=4;WhU72dw?Vy2g)nf^pR>laoe$CN-GQRm3{A> z$(Ga1m&{pA>%uI~JA5m;o{^F94QC0KG3Nh*|MbznhZ!{v4-bE*RRkiW^UADRVC)lD zj2d4GuCrRfWoM^G#CefTJ7ay|1z@Gh#-h0r!_F;eMrlXPS?7&IA<>IYE)f1PT6Em zk&tBM&pFsDQHZ(sE1#&asP*OG%gh^P-bL2fhG_|vL>sTFMt!n3tw*097Xz|Uc6Rnl zfZW6DcEyPJ#_hB_Vl0=aBw)V=?B%(+xlu!UN%=A-jsw@9sSmPF#g+h#NEijE1b_+N zhf#MZ*1a}i45*ORt;}E=Moud`4Wo@PcY(<4>})uZ0N2cbq-g-Zq3V!#kYwvdsy<;1 zD92ez)8cS2(Y)UOu@Xr)l@esl76pC^TYlWGjJ{QyiEWA002ovPDHLkV1hAZ5itM& diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/point_add.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/point_add.png deleted file mode 100644 index a7424380d6e27cb52c73f664419df7459e18d01e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 438 zcmV;n0ZIOeP)h-x=rT(I-2(MMSQ`q zlX!qDoOB8d6W{OQWAYr}t^(fSLl&5*VuMzf@#MXc++a6j)9K$}AAwE$#1H&x`ToaP zD?@(w)p~@B+#gGPGoFESEZ|RaeaI_+#c}qz?aV^rpIh_|TOD=3XVPvbzLogZ9x77LUW7tmUGUWx%YpkkyUGL@f6ST7!9uQ7Z(vRl!t1q9lXRUp5S%n z?BfhSa1s%NCX)+RFo7=-ag;%?(8UeD;&=?RnfM6jSgp1GM2k1*;YE6`T1;aepD~GT zyu$`|FojR)nQie9%h|?9yvJLt=cV1$mhqtVe>E7OpYwDu9MSJOrIcxmmr~BLhOKPt z5FgMlrCcWJUt{=}=(@>#6T6w%PeR@F^jiGE0j}{3dl50rMeSiGwFC4<7gw-|IV|N1 w-|!pXaU2nYX5?!$7{@}QgbSSFHX`oe9!lw37HUhBl>h($07*qoM6N<$f{WXvCIA2c diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/pt.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/pt.png deleted file mode 100644 index 8bb8743d6010ce7e73c3a66f002bb4b5335a0862..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 789 zcmV+w1M2*VP)g000>g0g#8KXaE2J8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10+LBYK~z|U?Uv7L6G0Tmzi*}~7PZm}wb3Y&AWbc)VQ05k5$wT> z3L;3ri{c;P(US)eJooHT@!(mcs22~4UXo065K#-}R6-DH(L$lEJI_P65SINhZ9}Dy z&t*36ec!wJcSh^H|%cZleAIBtx|1Gu##BLGS<@$1Hz^HB*R8i|TC^SPu(X-2m20sINYhJx`( zF#Zn44FJm>x$#*=*X=2&V9{J16SG3lHLWmgvYZ00?W6UM3^&k;l!{&+HT_eogn4h12 z3jnoR?LB}`VGR*|Y&04l0H9v4zb2wa*NqTSp;Rgj0l>t>#32C12(!h>$;pENFg-mz z%*^?)CXTc{(z*P@{r&wl$8p{e(PeCI!Z0T?nM}=boOkQ%>sJAE-eaO(rL~dg0A@RW z7l`OyO3gSCjfY~)%+HdF5^rb#pp+^KAtL`-Z863yYOTNRW{y20^}@1+=Xv>THv4LH zbo6t(-Htol006G*-pppRbGck@uGMNSCuz5^J - - - - - image/svg+xml - - - - - - - rail-15.svg - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/pt_end_trip.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/pt_end_trip.png deleted file mode 100644 index f67dfdd9ef01e128e57f54c792a01cb51b4d429a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1649 zcmV-%29EiOP)IG&-PtZkkf~#Yu@>8YuNR!o+O=KJ+A;TD zHRt=j_kGTL-k<0FN&spB3}NO-d4UD^&uIif0NBm}G2L$Sdc6x=avW060xVhjm>)pGlY7?OrZ~ z_yNElLqkK=Jv}{<3Cvg84iAsVvyzA|19%|~U;rouu!ot?c|4wrnx<_`r%zFo>UgA7 zR8(xrdrW&goA{iJCgu|h}v`ZwAbr>nVH|3qB8wAfWj2XS?Blrdne^- zRaKWT^MNVsErqEbMx)VPlTAb-qW1w5Phj{fBHAvcTnbNjjr_eSIO*G{14VT*ry%0lSGzL~NSonG{RKA`PPb0ID-6eAh6HGuar| zb-iEL^~acb4}cLHp5Es3`HHiOX-(4>0C+WnzF%(Myt&`*=PoNNJ3&NUHatD&_U+qS zvjWY`uVqR;B6{P(g$p5@)5-nA!^2-Q^Cp{d-991cmX?-kX5O1YNpERs=}8;ZwMbRf zea!qLfW}D_5_d~WOLay*ttiSX0A^)S^3KVVCu3Q7woXd9BNmH2Lqt_M)Nw^ol$`($ zrUb2NT6ruM+e<`gOI%S=(TU`T9UUE_tE+3B5TcoxA10!8%Y+ ze8u5#_#lAitgb1gl=IJ?J^NQKE>l%?34jd%8i{BFfCnx86G`GIR+*9Isj8|H(P1LG zuIu`We6uCD+kLO1DC?NH(R!J+0E*IV-x3G}KARA9e25i7H0!#4daADzd_G@sC=^;v zL~E>&Y5`DTh3BWbu5Zf<^mK|c*y^RaOjVbu&do zujdL_RaLtK?;YduHzlH0n+mj&k`g5s&>0wI+WjRZB@hV|a*<7&vukQsPiMOjO%zVhdnTrGqc>Fn(M9pnGQ&N~;3^Zqw6w`7-|iV)jD+4~&mD00000NkvXXu0mjf=x_Wx diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/pt_start_trip.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/pt_start_trip.png deleted file mode 100644 index 6c91d000e7a327225128cdc32ceb283ebf8d1464..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1667 zcmV-}27LL6P)bpu%Y0S>*mv3*up$Ef5IIY-nhhIj*2R9#5ZT zSATy(_a@d*GRrECOnG1r}2<}`Y!s#;7$djPx$U}BmnJphgq(SBXm&t}u*^Z6DC zA$|k!cUMwDepc zaQM^F`ZUF2u|qBb1HeWpWlM8&^VSq#5K-f(Egc91-eTqt$0$q>0LV|XIjcjVP}_(s zt*YugX5KS~xg|f{plO=hM!FG+h&}^QILyL7647QU<$M5(iD(-U9R_e`#AP4R_NJyL z;n+R=e*bm=Uu4l81MosP9R4cZLrv4BN-5t2uq#VE&nV2i#xRUXI`>d)OWsZK<01gZ z0ZhrPlQ$cN@pYy}J32c0qtWP3Ua$8s5k2N~BNGuvqtO#-9ufZW#%0K`W#q#Q!p4T%*m%UO`8GWohdh)${ z_crDP&CKs++k8ay{`vFg`yF;Cv%0&xPc!pchko5SEOdQ+eFZb`%%Y^NxVZSJgVMD? zRn=Y0{5yb^BM2nE`uh5cto5{_C~pIpkVVPIM~@!0aC7xUGLUNp8i;vQ~Mjs;We^ zpNMYjy1vluYRTvGJ)$Vea%Ns>f0<Jgvjc5ElR}%`jym5pAff ztc*pY(PjXJqO7cJ2rx54N;&AVEDJ&i)YR0t3hnWDJ_j%-hp8XguKvY*(X9Tt^ zYsfWe(j?b_RaISV`*2RDVMO#E0OWZ*oJ{!4v_wF5Gnr5cfY7ltheqdn0P3T`7 z&Tqeb`EsAQb?cUsMiV_fJ+2Wm^LGGlJMig)03h1h+7bizKhs?R5Rb=k?bvUbe z37}9(jCOW*qP)BuilPjHHBA$}y}f8{ZFLq&qM3F?N%W{!nR%bb<9R+5 z3JvNJ(@J@HId0sz@xV(syVa`@LiC+HdGZE^{%<}$OH+E#3%a0V>VK`F-2KwW_$2@U N002ovPDHLkV1foN21Eb= diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/pt_transfer_to.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/pt_transfer_to.png deleted file mode 100644 index c629fc4315250ea957b90c92594874504ad9e34c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1751 zcmV;|1}OQ7P)Ebgd9?h>AfVl0%!*?i2sjT>QDs!eF7l}K*AU(rwAml z48u4#kw}~y#%98yBaz7ALZNVL7@G-)9vmFZipZKUHWLm#W5$d+02iC4xiF|r-N^(@ zBob3|x!f{EQQAag63Jgh_hmYr&Ij?4%jG5kfa|(z0DK@j2*zz&kHT9)-mHDB>~{8B|xz5;M?aBy(;z`#JRM)+vx^w4#E0m-icJm>=q z0L=jI5RqNFuJ1KXbD5t%RaIw~E@w=iKK+aGtZJVZP zqwGZF(z5G7FJxe7!!Rxe@BzswL2b%JlDClDr)kVS6A1R zk&%(l0L%-G>#gmIqTIcB@#3NW{{Ei<%q;7>FO^DdsA3x^r^et(_4Q7sIP2PRdrr(Z|{B|o9cI3)3muF^7MGn`Dhd{ z0Oa%e)zyruL6hW00F5;Qe@OBs*L5!ha5>4qyM5Vw(?i$w+X1{$ z#dj9KovBpnO|MSVG+SKPeHg$x_|NCQ5|I_QZKplDqAH4a@@RRhVHiySb^w^_?^ABF zZTl_1pqWf&#BrRDW3kv)l5-I9MJ6eZ}t| z$8PZI8wD*QkE6=VNAjsXd-jY34GsW?VVpNKH1v^(1ln7av3SneCqQ?0cFq=&%4N3P z$^Pc%=ANKI6NyBFrfKU$0@MDdcxPwls5CucKdq|jS^$%(IC-I`r>9UWl3^J0 zT-Uv&P$=9>^6c=elgKR@X!?w!C?(S}7_wL<`6h&Df zBA1X{BqD7jArk74?WZ-B(8s5|_V#ucKofw)@LqJb_xAQ~u53)F)8aVJPwnmPUl$66 z-$)LT%mX+FCwVd|X=W@Idq0!O{9O9pIBIb*4C89obvKc`u-ua5YRj^=1dY_u(NR}l zUw@g1EJZP&SCnFnMK7jOsfS9}QO^}InM^ijv)N|>+>hd_>AJ2vv#+o3k1+-XP~6J^ zSPEbX$)y11m;BdK`BBUpx-5uB@>P<5T9$R$$pCvP9*>`;s_G&US%Tt^xe`Ew&+t{L zRO;QD&?WF@MNw8*mbGKNp(~Y4CL2daMi!F10>zZ-1TY-{NWN`Z){TLnCsL)E=^~V# zLO!2=Ae~O10gV0Sm?(uWA)F36VIEB+5)Ju${$`Szh|B^oO!89zTP(}^?Nr0)x_%{q z>rgCF91)QL0PongJzPHScupIJagB&<1<>l@?=Z}L^2U_yxG*$q$(uO3K`4y>^KI6DP#h` zUG9zCMu^Z7v4_cD#=?D0j&@jo0maNw|V@ZiC>QBn7( zp_fAj@|B3Z2jI`3<4JA;0A=64eZP==GN9e|()Ms%WZU*|sm4-MBC;RA^FZmimC0m2 zip63CupIuI@^?wD&SWyR{u2o$$8kOn5c_*oRaaV;^(!imTk&}ODn(J&0WbiZ2_P#X zdjM>(ZMz2{{|*i#UDubBd{RU@@ZX;3ClPr)5{azexpU`VrMBqtk4pKKq)xSx$z-Fh t>lc(NU0!$IANn*_v<^VaL{o%R%RhDVGo+D37GMAX002ovPDHLkV1hQ%Jox|s diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/racingbike.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/racingbike.png deleted file mode 100644 index fa40d2ba69ac2f6caf43171734079c341cccda30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 890 zcmV-=1BLvFP)<=RT^Y3(_FSNkBirxy#W@vtf5O}cOU37; z#Jb|W&kU2$*z_zXU?Hdy#24KGwU~s;OXhfVd8X#E?i(7Pb#elVQ!hcjMr@L5Q2?`&=N}Er7}Ph?%OJ`W!5p_RfK_KZsEYT_|!Js)=_8z zp@I_UGadJ$q43(L;?5OdiZqEX!TR zlQe`uR#oAbh1R<=C%?21DiXq{2z#onMTU-)V4zegN(wG~fOS3L8*{9i3ZHsv8%8;w z3(zDsoRG5Ql#TlgZtJ;AO$Chq$*5RpMQF^0P;$$ZT$<=qcLEC$^J7DVDyYp^#`d5L z&)@?QGJQsm8(4g8h

    )b>E0WqPomX!po$_?#C60X)KJQB97wtyd->UI(deCRCxkC z+9Vdaf>*2osG@OT_g+PQF(E0D$=ZpVAh$?p{t0WgR^ZBVT);LBN-}pY0ze&Zt15s? z%km+t+YAwlZ!{3G+;sn7k%Oisr(tyhG2?AiQ(mmZhmck{6%M`Okp*+huoCOMQs7;c z^!F8}}l diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/racingbike.svg b/web-bundle/src/main/resources/com/graphhopper/maps/img/racingbike.svg deleted file mode 100644 index 354b426510f..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/img/racingbike.svg +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/right.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/right.png deleted file mode 100644 index 40203ca74967a258a16eb7615ddb6e8bda1b65bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1237 zcmV;`1S8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H11X4*vK~!jg?VI0gBUKc~zu(Ek9}n84PqO&nf*>wFs0)JagR~@f zQhn%)^kM%2(N}-qixw6{tQBJy?ZRSJ5O=M<#Dz#^QsOQv`cQEFg`(J%Rm5E=!WOAX zJ9B)4Vwije^$LQ?^79A`{K zJ}3DNfVoDa@nNl2+cq+I7mNh}0F+W60eCz-y&@v7Tb6aYQmOoH%!xLP2B1(V+#LkL zPXM^<@?Rw10SHk7a7079^KDm~H{^ z1b`nM$N9KWC_H4upFU*3VF175|7FmL^8n^N&-+yN$x-700J@ezC%z*&zrMcy!RqSj zRxf=qUIHOsYTkdJh`c*GI=ZHmdU|?#`nFy<(w6{`{5EFOI|0mZZf;(29OvbUiHSRs z`f{TMpv55(c|M!X{;HHZJvB9TPi$Xy&jE!(;lUsXo&<0Vz+C_W06xh;M0@}~fPkbQ zp1172hyL7Tk&=kaRjbu6bQVifENJRJ#wmFTmhm@1*EPp$_0IfTHWVmu&R!b=WjlNuKh3f3aGvUTs}G2pMn*O%*s( zE|=@=#t;&h-}0?C7J(anIw0mx)B$0ID$Bghd&xZB=Rowo1g;oGa#tOj9%*;(Bp964W zYinz=*Kf9MdvZTyEGb50uv98-#A#;&3x;KI(6GWKYgGC&Q|~91 zrVOSp0ML`c^p${42E>)YK}L5DNM8oP@M>_-7|I}q8PJzK!GU2YgF_h{%HVJkJlG|G zgFXpjD1%yig6Ycu5s91uNp^(?6-(#ycq#(`Jrzh_3BbU2fk8$q06`F>G6RM$LK^p{ zG5`m9N5}?nT|_eBvY7ZUD7%j>H2++Yx(xUi=WX5l?%Dle00000NkvXXu0mjfv}h_% diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/roundabout.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/roundabout.png deleted file mode 100644 index 1a02efd5b9172ef653af08b2dec4ac571548fa58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1494 zcmV;{1u6Q8P)iK^r@pG#2@sJXz%<}tJ4R=8c?kH>j&@c3C!@b!L`#5()B-O6vw>@)I6ar2 zfepZms(Ltv!^{Z~k*k2`fQ7)7F+`QY@4zd-N>%+Wiz9aeMC3ByDPS3JeHIZJI0h^Q z)~f2i9tW-jh{!nL9blX%Xb$WH9#_?UX$_OK1|m`i>}K#Z9)gzLrY#kz5+EWAfmUF6 z+CUXxIM6C0i_#dCbqk2dP~dgoNuRcgvksWAs(+XIV#x&9bA2-~BaXI;u?={r)VQIX zTVOR8UgIHXUR~--=j{O^(g?f}QPe;%PgR?XT`Zaa5t$0K0hi|_tWul?rmO0w{ax%g z0U|OQ_zD;qQOGG^E3h3nNSOE>0jhu-?YJ434%|oFQRPp-9jbb$?}Z^n3|=E%<6D5W zz;;#rv&eUj17F+cS4E^6xS#OUX^5aMq&lA0RfQUQ-Y|Id# z6KGJ?jtoAEA|ewBw^U6AH}$Hzx$sAK0&I4-7r4#o_&dU{ZIpR>G3>oV8!*=C;#**X zs-A(~1ED$i8-D_rnRnv>EXGWW>EU+5OBZZJOj*C)dNoZ)L5*!7Td#|!iNMv zM6SR;++CrnA3JT`SWNE^_6%!tcMq5j40AX-4lH+yh{1Bxkd|SDHg_k$JJ?vJswbVc znX%Z*oaPMxiHKAI^$rII3D4z$rkS86E%hQ&l>ig*Jy$oX>S>2vR7`_s>{0_vNPt_N zu{SyG^1!QQOoH#fe}Xvkg;=!X8yD1g6R;=t5>*yV%N~cRI{~?m_#AjNxf9Uou*n;b zrkVs8RiR*cVO6d(+HZ<(wP9?JA-;=ka^+Nav%XZ@b!XOA~N91W~O15!?Y9l zCQ;Qce6y*WfJTR1Y#Iq#(y~cay9xuL7H9CKA~ImrA{Kk8)4T=Fz7lIAEMBJNI$*I= zKnxa}hP0d_v^gX|RsSMXRCs6-kq4Z%ZY*Y#(|nt?x!1bDdroHwuwF#QIPFtovDV|L zax>m7d`SA7-0yTaf>5EA`v}ouwBmd2Ls%NyQ23)e0aj_bB!jlGK!+`0=7Ra|z`rgC zu%xgq2z|Pcs(wHyg7i`Y?6jrqsF=^4WSfY6)^lYT`mYaYBHIhkYTzvqnGY;d)h{ym zLPYKYRsmD8_%WXEd!ks4P%H61CK`1u}M`+m&llaJc^`# z1-1~n@sD;CUS!sCwovLG!VZ(GBgQUTBz4i3$rXK$n!$p+R8^1##TpMK1`<|bxhA@# z%CY8rRiaSdNa`72M;tvBWd}j~c`2CyTXw1=l%QWItOM%GS-wlPWyUs4ti(SC&zmzq zld7&N*C6$tA={R+p24?k!UPA-c3{E2@?u$SzT=Q1G80iZ(2iFSGGXofq8_j wYXikG(=guCc(}B2^3vAXOPi-J_U-fk0jZYk)D5+;JOBUy07*qoM6N<$g3{ce9smFU diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/scooter.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/scooter.png deleted file mode 100644 index 82ff2469abacc06e9a7532684f03fd52f1080527..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1280 zcmV+b1^@bqP)?t6M_(W5fw-fVQ{tK8^zmMkuHn6l+z-L3@jq7tn;{=v%1~e znWq;wm*d{LH|EJj%?E~^{mt{|`^@ioW(E=x5)u*;5)u*;68^8qYztVkX3Z*9{n@gt zO+YmWg4ZgQ%8zmVtxKpa7KUML6Ol!#x&S~#dVtsk7?(_04D$K>-9Y=K_>ikFB*v`l zK%r1b2SIR1Rcj(LpsLG7q#6Xlx^z1I$%Vw4l^y8q?X3Y%bar;$1$+vis%a6~H8wW3 zptbk8{2PY&7Q--(MV3xvv)P+VrP7~q{9CqAu~?kzdEQar4-pv-f?z~MMu1_U3ZSaP zBBG&-3Csho0n)%LuInCdm1AgV=&O#7j^BZ{aOnom^ELuIFS>xy(b4OGMWIkcrfyiX zwFoBA-O6BKU|>9-&wr+>_e7Q-AZ7tAXFyfGI6+$Y?~iGBq+#hMVzzh70DRbPS{6_$m1@ADxWO7kZRzdpja9s180QSEh`duQ7E`f&r!xqG z;MF*R8aP&|RNjqitg7>)DOL43&-2bWj`NXi+ugKir^RO-z{(aT0gxAw zaHnt%z)PU3W3CDb#seyRTaZ9d{y;TH4u?H@JmDxKphwj&$GaazeR}DRMirZE>+zJw5jTwl}cp; zfa5r?1COif^OZ_vM>O}89k49xzBuAl&(5fbpsFS?M?@|It^jTXmPd}2KrTF1L_!U# z>KqX{S}vFS2wO@-9=2_JDL@beyTi39^VqC~TE6g04 z0stJx*#^A8#MbT%g5V&~W*9~{u%3xWo9(*p2j`0sms~El&@{~>z?Hy3Rox{br$yv; zRec)h0N!$4cYUMpc?;OOb*s_e-@ijuH#4=>MnvS1a=Eiep?u;G%5 z$gWH#^JMsKb`H}{qT@JAnD{ - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/sharp_left.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/sharp_left.png deleted file mode 100644 index 6b8d2f449a922c039e47c730502d1065b45662dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1373 zcmV-j1)}K>w}0dR%j`Ug(}K6No$}F)fd6P7oqslC+Wi!T1ZJU z_xR8TmYUto+?izEWItF)X3jbH-ZST%@7y~ZiU{Tt#+a?mX7fP3UO$(Y%{6P*c*SCI z9Ka(a*NVt_lD}DNkJf6n$?3A3PX}nNUk312wOU=7hrK9@ib;}eCHW$N>$}O2JOW^A zrBXQs%%cOsFnojLha`WhR4NZ-u~jaYS0_ob1HjV&miC}>s?}=UQLop}6tWEL3a$0K zB;N)A5jp8X2~{eU zz69`Gmq{#{O*e|7JFT@ll~S7l^yI7*xVP^P2!f#C`~E(XPjtIa^0G^>O-xLv6DLlr zx7O|?8T4^_%lhhoi+p@gL>`+(YzX%9|;A+qFY5?xa%jN)(PXq)( zaGmFQ#{k@xhrIzpsjL=^F{?b!JC237cp$3-j4?Nh$Z-I-<}{%!h|?;Nq_YFcjH2isrPO}pzcJ|rf0EqOY&Q4T>-F=~Z-|I>Xr0s1U>Jt?lbpf;+f`h6vQr}R zNv&2pI+GB|)De)X6VzHiMDlw8SEe1v1tQW=N`0l2`gCe)>aQN;Q%3-M?Z36w8o*%y zm!}#b8;(^fm2JHWle7+F%v}VHF^>ZH4uf4hNREeL_)ZFWmlT+t28}U~i^w4W|2ec6 z1W4}ET7S@stcawJ0FpCDfY$mc5jhCJOKUi1ylITt%efOgbp*`lfG`ZV0N4j$EUnRg zKt#5OVR&HOx^>HEkx3l^T~i;lkp)y)DCIZHCeg$+y$AQq9BWGo`FQYsda*jgKp zjg7@glEl96$BjlKuGj1Bt}Ah*!2$qitv>?rTADQgID5(D&yidK;1>}&-C0Oy5!Twc z)oR56&djukEFdXq4|qj{g^S@70{F4>1g1ZQ&NXXoTqqRccDo%Hi^VgOlaoo_i^u|3 z8Z1<+)!hJg_hC*01xcGW0%q+478+cN;GCV{LP9PyxWM5=gG1v0mm-K^ihz-KfXj9m z!;}Ipo!}x3F4Eu-)d0BB;P5!Wkp+e)1xB6*G3uS5OA%b8LD#p#|3^5|;P9k?wRW_N z;K=U<79(KPBfzBy4iyXJ{&skwVdPU_u?UWO1dRNF$YKgOrog=XQllTR)^`3+(Bi_` f!1TYFuGxP9eoYLfxWt2(00000NkvXXu0mjfs33S= diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/sharp_right.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/sharp_right.png deleted file mode 100644 index 0c40d140bfc078a904c31e965d7aef33d4ebf1e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1472 zcmV;x1wZ1P_YD|rGi7} z-bq5(fR%`%Aow6c^+AyO;8*Q~DQHEDU!X6dSYkzph?!YUvJVY@R4MdDtPe^NE0H!z z8`Dj8jt|*w)9r4ub7!V?H~WKOcV_N6_wMDK^S^UviJ7qw$8oj@A^HGxG4n4(bW{lO zNCk=b-Dl&qna0jgV5_3Sg&(?G*r?WaeW^ zsZSio*`nd&&(arW-lLRyNyA4Z1b}VDPhC;~?h`^xxUM@PrQET5_wHK#nPunCDWwJ@ zj3qRJh&IRNjG4C((ZNH94jq$HKH<7<`w}Lt6|U`4O1&D_n3h5SNGITT0};K!%*T~d zgG#9zskA>@T*elgYNF`@eB72+O*VCG8^0hQQ@+SBi$Q>RXSWZSk8_aKB2BJn~K2Sjv#OH0dvuCA_f>5RnX zjDXNE^Nw^neQ;o4pd~J!0?`&hmxIjI)YNCTZC8`fP$VsbNzrSX=J3|7Tic>Kx>Pcl z1hT!o{fin_n~NftIdlXt^IHJ+0Qf6P=TRXdI|za=`}_N^)b*iN1BmE^@B7c6K7D!} zfX4y+tUG|H5YgS!)6?Jg_4Qdg_CjZ=Nkj|)6B85v`o8~8Hk;i@L>T}%ok2u}h&uE6 zd`@Q)v}BN(gR*n>JnwVg_wOO1E&v|`m<#JSBDdx9`L7+vSrx`eHwC!bJn@N78xvI+qU7l?u$e;2H>i&eiLL}DwWDPj&n=-jo4(+ahy%2 zX@0}ZF93*r<01yuq*AF|@jb{n3~0z;5Cj)RfMFQd6$*uY0MbNcF|$QP77lv0lG`$vo zkS-Jo7fc`)L?6yaTYACw(oWJU0HaDNWgsCLOp4+g=_vqzgtg6NGAqxVIb#VS(n1J} zncI!x{(LA$OUdB>mEqyxX#mrhf5i_VW*MwUv>t})H3BN3wGOBxgY}A53RIH8dL_}P z!FnLEr@?w5k*C3WqA7!D%HT4WL1;`sL&+fY_5+r83N&S~k&0kb2AeY2l)+fv4%ZvH zGPt}WprIB*I)9RCs1(ron_N={8z}Px#8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H11KLSMK~z|U?U+w!9CZ}OKkv6Yq0*RWKoGrnsDd7()Zif(9i92j zVh#b7y{P1>V(CE-6%VCU1@WNNi#@5dMckvt;7qbvD9uu6OhJo?=pjh)66)3v)@HNw zJY+Y7WdF==c9T&1g<+WAd%yks-n=(&=QsGi|H1h9`2DKNULQt89#~sj`#A^#pFNfV z^1#EY8U{gdc5H0yo;`!7QmHvW0a4ZCgM)*M*4oj%fQzbPt-S^u-7>xooT*eQ9~KIQ z^?t!k?VR5>o(4`kjx+Ch-eY}*$8kK{#QwA~=2{R0Z}tN&s!9+9hgJ0^FwnwxPDD)zKhxQH~%`wof7D~{v* zWUYOEH*ir^09@Bir_<@1B64pB^A$K-sZ>rD3Wa|=g>Ob)C=}L3WU<5f0-SIhXEBq> z9P1hmAR<>g{ehYukK_1?@B8m%v)NQvaNw&h;jmGR@0UuY%b85(NRkPgIj<`Sg1=Pt z!Cfo@U=?^filTF^oVG^}Ft0>oyH!2fRhA?M5#+j&t4j{g)EKN!DzV zstT-#$Q!=zKfB$yBj*6t+TVajyMUE}PgM0%DwXM@L7UuHmUvssO~@&_(3f$jHd)M81u34q&Za0G{e* z0YI#(&&gwt| zaC^(pjg^&^7pv9ktH7;<3z!Uo;N_0t#bU7x%-63)c7PMdEJ&_om%jK%+bo#Ys_9%+-s`_aXIB>`q zb1|FEZte}*<(%p1>3>?;9mjbWNV<_YS}K*!)GwNLxK8AG-jl|dtF+$n)D??}8;0Sf zp1=Wo-+xC$K2GSqRH;;s^b9T{;(1xZgpEF$rL@d(@t2Je^?00000NkvXXu0mjf=@lQB diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/slight_right.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/slight_right.png deleted file mode 100644 index 41409d79955e39f5955857a331269dac37879b4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1098 zcmV-Q1hxB#P)M~F1u1yb3Q{WTLE`Q08;h2F=iI{OjZ3M!&>=#zEG>x zHdEVnW6Z0ndIiWO482~f)iz;!5R7G&O65Uo?PcI)$0^O;kA1;|AgFkrcLjLFb&j=m ze{f^W1FCw-^Sn1loceF4(^(lC9){twBC-UW7#3sgx}iiyw-}d0=W( zFo1}x_P3qjK@dD$C=`}d^_g*?J@Y*8^KFY6mggcOK@hwxA{T-De!!~wccanR7MOb~ z55w@$APBCC$gqOpY`v1&Zv)F~xm-RiBEO~u?%K6Pco>E+0b!e+S+Wk&)r5x=VE;yl0Dx zi&Ndga%@yE3=TGMJkQtH*DnC4#sLF1m&^S)a8XI;dH4Rc%=m}UN)$yW2R#`2!tMd` z^*+GRcZBY=q;3Bcc)}5K1Nd%0|E~N_gqO?Z1yz0B5xi-wePw25<|W|IzW%LtyS+RT zJP3k^fiE4w0Pi-N&9!Q^+5+D1b&AMO-E?(_cW)=hU8t)1eH2BPd+kP}@eS}ZfVFnd zEguLs#+(ISZ~+6iJkL9`V=)SxhrRQAAlw);tE!hA!HCG2dcA&YXMYq$5%BHY+}zEf z^Lu$-DwVQ@LgBiIxLz2(h@xoEJDl(P$Kp8tZ`cd&DlZm`ACCZD%jfg&3>%OHhOTmB z%yX(5<5q5OTWe1>o6VKvp~KDdeLthBUpayik&n^<19-Vy&IcZI9KSq0J$*3^Fx*k= z^qHfo8zOSLTCH|cgRAPm6KAK1$hmsG{#ROHxTD;~*FQv2bTv(|Gh9{wNE_@77ZE!t zxFiiy)rr9mRk=&R9ZltlKDX9R08j<_N0{m52h`0J^^h2 QK>z>%07*qoM6N<$g7gvyw*UYD diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/small_truck.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/small_truck.png deleted file mode 100644 index 1f6bd47caeb0d887d2fce3abe330c760c6a67062..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 962 zcmV;z13mnSP)i$*2QawF2Wux&~?mRT8Ieg;3=qscu>ir_M)($JNteeTxHb# zH|y#s%m)VMy~q2__xs+wdGEJN%#8Dla9hA}@eH_)XTWVd18(CPa2wBn+js`t##f0T zhG8^IDMJ8m5z!3*REfAYmZg+W78VwM9d0PwfUfJe0X)cFH;F2(`2aVC5LW@TA8sHg z`9Obv|D8-GGYX&wKr<>o(gm?B>vB9E|6{K!c?Jx_=war0Cw(f7s;Wl@tfWOuM8wRm zu`B*7fG80y5YZ<9s{l4Ds?-4`ji#>aA!cp|uquS;o|~K7wzYl0?mBRVqBEdrnva=Z zWsBo>@n?ae22@pj2%r_fkNW!hcPB5&83he!npVTiF9CpvUPL01%<0G~oq`6ctE(Rq z(G>vSOw)XSN}3#zcOU5M>+>s$vI5`|fHVM^Cx*c8esJQSS4B}8qtWPZdtKg#3L&0h zSG)zF>V&nGP0m-Sx3{-}h{D;TYa3T7z>a(PxO@`FXM4<2;}=?>7wrXR#^B%}y1KfMNF*>jJ6o2>LIeT< z3=a=ueSIBMQ&ZU4*@5jdzmZC%{vGaf#DL%LU)kK;{0JbpS4Tu>X=%aO*cbqyt*s49 zOH0_;*g&QJUmzlc!(lWvH30yU$s}fGX7-xbiD)R1NLWP;L?V$LP16R15DluTl4V)7 zilQt5xBy!M!_1P1{%&n;U8}09O792s`BclY?DKDBue_+LI!#1+ZEfv-zq-0Q0DzRT zKNgFboM)s;%E)wGe*@rYC=^0xXD4E@7);Xy5lxt;IbJkC5e&n)&&<(|jt-2Bj9_hT z4U?0ToJysZP1C%dPrMTY0V0YrbE~cTyOc7RE75k!#KeSHTwMIj%=h+%5p6T`qxt#y zf+t`{IdL!;>=r@{0GKvS^Go@Xb7L6BU1lC7qMzw>`fWTOPZsOr$iP|T-2brU8E_lV kfZKQm+{QEDHs{{Je;-8;>nYa5OaK4?07*qoM6N<$g59~VC;$Ke diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/small_truck.svg b/web-bundle/src/main/resources/com/graphhopper/maps/img/small_truck.svg deleted file mode 100644 index e001e957ec0..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/img/small_truck.svg +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/truck.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/truck.png deleted file mode 100644 index 052de16454e3810dd135dca0f82bd9b5fef2cb82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 908 zcmV;719SX|P)97b=Ngx?6N*(qfp))E-hfdvsAPc+|bnK!lEb}_FvuN&?&Q1>1 z{0_4_^WOXR|9>;z`{uEtl;Uqji(5dgBnILpF%UP2fw)Nw#7$x#ZW04=qem6Uah!9& z1aLa4m{lkOFJ0Gt2q00sPFt3B(lCsVz^R&p9T26|UC;9-bO6V39AFM;2@&g6I-P#b z5sC*8k?X)jkOMaeCm!Ich_pr{>rm+BgNSIQN9hxg{l%auD&&o(X`1i*e?a5!(E*fF zQu_SjdERuj&W__uQo%qlJ`Vo+Wi&8Q(+nnepawLEWCmlq1A7uuL^R8?j#cYy7)HhG zA`(eK41*4!X<8uQqG1@@A>tfq5!+2vIS_9W*O~+W!YbrM6z9-HQU`#pT7`t=|EL3X zb#+yj&{|2S(_z~clnjVS)mO=$o*r_!9P{(@WHOnMGWXNk+REhQB>8-vv9Ymz?aj^2 zWV2cF`8?y}u=1H;3^=z27}&`c&nM@I*`uG8Dw zi)osB+6M;*F-;R)*Rd>%uC8*L`M^SBW8)nt6*ABBURjoPoL!aKFpSs0`K_(3a?qWf z9em$ML_QY^g|qAH>&3$gw{81@h}_%W-disVg+lOk8o0IV9Dty|@B5clR#x5w*UN%S zV#J7ye$@s z_jO$#aa}jn-ri1UXD6$xt88p+0KD5R9)7W@9~c-glu{c?sWU${eJd7=?Q3gmUqc$e zahwh{z~#St+$3B9C3yeZMbO@-Jn~BnILp iF%UP2fw)Nw#Lah;QT@+R$V2r20000 - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/u_turn.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/u_turn.png deleted file mode 100644 index 453d682af0e3315004751d5f0782f37b4ae89c22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1461 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 D;Osp^ diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/img/wheelchair.png b/web-bundle/src/main/resources/com/graphhopper/maps/img/wheelchair.png deleted file mode 100644 index c8f17d664c0b381050cdf9075d34e0afb0af61cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1281 zcmV+c1^)VpP)e^1uACYh5&sB%|R zp{T`85xtq{7~ZHw9D;*g3}Ld34VfS+Dg_yt=#4ksNp@hvUHH+-T!pRGRrg_G>$XbP z&LrpYq9-HG(oJ$+@Fu^T^X7S<^ZwsIZ{Dv2nlx$BfNMosv%W<5O@HP@$vDcqoboq%d*bJ zVzF|N@`H%{WlFDt>76*Sef#!TMn*=q6bgkEB2tRQV&`MA*ugVr&b)i<*s&RtdSKXq z<2Y-4-#-p4s#AT+_kAay&l}y$jIIj4?>|BP&I7Cz5wE|$zs;nk>1A!@ttv&Nvsf&C zhQX0HzAo28L_P<`f{*Jnnaq2p+BRxHRj2F4ecwL^3;=~7^tNr=gC;bM8dzwV6p>Y~ z>z+{6mn$(rkp6w4PU1To|u?$s$Tgikw|oBv)O;bYC}i^wr%&Q z>QUy7)Ef^SI`lKJx;8J9$vj>?LaI8H%jI4Qqg^4?Bv#dTg5rMHb-x1YeKlsvb_IESJlbjxF!*?!IwZ7m=&LQQ#zSr21Dm5$OtwlT}UK z5s5^yeSLk)8|g>G20YI@%iIC2H6D*YQ(Y$_(<1VFou3q+3!Yivo2q!crKP2zzJywZ zMC4-tRo!7(*4?+tbsQ%Rya4zj@<}3*cveKV0_RnA@9^;OpAGe)k(VlTcXvnQ@%VA( zjt@Tq1Fq}-QJZJmwxgMhH9R73`VHO&1- rFsZ8FiO7M - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/index.html b/web-bundle/src/main/resources/com/graphhopper/maps/index.html deleted file mode 100644 index a7ee8b1158c..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/index.html +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - - - - - - Driving Directions - GraphHopper Maps - - - - - - - - - - - - - - - -

    -
    - - -
    - - - -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    custom
    - -
    gpx
    -
    - -
    Powered by GraphHopper API
    -
    -
    -
    -
    -
    -
    - - - - -
    -
    -
    - -
    - -
    - -
    -
    -
    -
    -
    - - - - - - - diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.css b/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.css deleted file mode 100644 index bc419c87bbf..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.css +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ - -#map { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; -} - -#layer-menu { - position: absolute; - background: #fff; - padding: 10px; -} - -#mvt-menu { - position: absolute; - left: 200px; - background: #fff; - padding: 10px; -} - -#iso-menu { - position: absolute; - left: 400px; - background: #fff; - padding: 10px; -} - -#hint { - position: absolute; - bottom: 30px; - background: #fff; - padding: 10px; -} \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.html b/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.html deleted file mode 100644 index 500063b4635..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - -
    - -
    -

    Click map to calculate isochrone

    -
    - - - - \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.js b/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.js deleted file mode 100644 index d68ae56ebf2..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/isochrone/index.js +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Licensed to GraphHopper GmbH under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. - * - * GraphHopper GmbH licenses this file to you 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. - */ - -var menu = new Vue({ - el: '#menu', - data: { - layer: 'raster', - showGraph: false, - isochroneRadius: 600, - showSpt: false, - isochronePoint: undefined, - isochroneProfile: undefined, - isochroneProfiles: [] - }, - methods: { - changeLayer: function (event) { - this.showGraph = false; - setGHMvtVisible(map, false); - removeIsoLayers(); - setLayer(map, event.target.id); - }, - toggleGHMvt: function (event) { - setGHMvtVisible(map, event.target.checked); - }, - updateIsochrone: function (event) { - if (!this.isochronePoint) - return; - var coordinates = this.isochronePoint.split(',') - .map(item => item.trim()) - .map(parseFloat); - if (coordinates.length != 2) { - console.error('invalid point: ' + this.isochronePoint); - } else { - _updateIsochrone({ lng: coordinates[1], lat: coordinates[0] }); - } - } - } -}); -var mapTilerKey = 'ADD_YOUR_KEY_HERE'; -var rasterStyle = { - 'version': 8, - 'sources': { - 'raster-tiles-source': { - 'type': 'raster', - 'tiles': [ - 'https://a.tile.openstreetmap.de/{z}/{x}/{y}.png', - 'https://b.tile.openstreetmap.de/{z}/{x}/{y}.png', - 'https://c.tile.openstreetmap.de/{z}/{x}/{y}.png' - ] - } - }, - 'layers': [ - { - 'id': 'raster-tiles', - 'type': 'raster', - 'source': 'raster-tiles-source' - } - ] -}; -var vectorStyle = 'https://api.maptiler.com/maps/basic/style.json?key=' + mapTilerKey; - -fetch('/info') - .then(response => response.json()) - .then(json => { - _updateProfiles(json.profiles); - _drawMap(json.bbox); - }) - .catch(e => console.error('Could not receive bbox from GH server', e)); - -function _updateProfiles(profiles) { - menu.isochroneProfiles = profiles.map(p => p.name) - menu.isochroneProfile = menu.isochroneProfiles[0] -} -// the mapbox map object used in various places here -var map; - -function _drawMap(bbox) { - map = new mapboxgl.Map({ - container: 'map', - style: rasterStyle, - }); - map.fitBounds([ - [bbox[0], bbox[1]], - [bbox[2], bbox[3]] - ], { - animate: false, - padding: 50 - }); - map.on('style.load', function addGHMvt() { - // add GraphHopper vector tiles of road network. this is also called when we change the style - map.addSource('gh-mvt', { - type: 'vector', - tiles: ['http://' + window.location.host + '/mvt/{z}/{x}/{y}.mvt'] - }); - var boundsPolygon = [[bbox[0], bbox[1]], [bbox[2], bbox[1]], [bbox[2], bbox[3]], [bbox[0], bbox[3]], [bbox[0], bbox[1]]]; - map.addLayer({ - 'id': 'gh-bounds', - 'type': 'line', - 'source': { - 'type': 'geojson', - 'data': { - 'type': 'Feature', - 'geometry': { - 'type': 'Polygon', - 'coordinates': [boundsPolygon] - } - } - }, - 'layout': {}, - 'paint': { - 'line-color': 'grey', - 'line-width': 1.5 - } - }, getFirstSymbolLayer(map)); - map.addLayer({ - 'id': 'gh', - 'type': 'line', - 'source': 'gh-mvt', - 'source-layer': 'roads', - 'paint': { - 'line-color': [ - 'match', - ['get', 'road_class'], - 'motorway', 'red', - 'primary', 'orange', - 'trunk', 'orange', - 'secondary', 'yellow', - /*other*/ 'grey' - ] - }, - 'layout': { - 'visibility': 'none' - } - // we make sure the map labels stay on top - }, getFirstSymbolLayer(map)); - }); - map.on('click', function (e) { - _updateIsochrone(e.lngLat); - }); -} - -function _updateIsochrone(lngLat) { - menu.isochronePoint = lngLat.lat.toFixed(6) + "," + lngLat.lng.toFixed(6); - if (menu.showSpt) - fetchAndDrawSPT(lngLat); - else - fetchAndDrawIsoline(lngLat); -} - -function fetchAndDrawSPT(point) { - // fetch GraphHopper isochrone and draw on map - var counter = 0; - var coordinates = []; - var radius = menu.isochroneRadius; - var profile = menu.isochroneProfile; - Papa.parse("http://" + window.location.host + "/spt?profile=" + profile + "&point=" + point.lat + "," + point.lng + "&columns=prev_longitude,prev_latitude,longitude,latitude,distance,time&time_limit=" + radius, { - download: true, - worker: true, - step: function (results) { - var d = results.data; - // skip the first line (column names) and the second (root node) - if (counter > 1) - coordinates.push([[parseFloat(d[0]), parseFloat(d[1])], [parseFloat(d[2]), parseFloat(d[3])]]); - counter++; - }, - complete: function () { - var geojson = { - 'type': 'FeatureCollection', - 'features': [ - { - 'type': 'Feature', - 'geometry': { - 'type': 'MultiLineString', - 'coordinates': coordinates - } - } - ] - }; - drawIsoLayer(geojson, coordinates); - }, - error: function (e) { - console.error('error when trying to show SPT', e); - } - }); -} - -function fetchAndDrawIsoline(point) { - var radius = menu.isochroneRadius; - var profile = menu.isochroneProfile; - fetch("/isochrone?profile=" + profile + "&point=" + point.lat + "," + point.lng + "&time_limit=" + radius + (profile === "pt" ? "&pt.earliest_departure_time=" + new Date().toISOString() : "")) - .then(response => response.json()) - .then(data => { - console.log('isoline took: ' + data.info.took + 'ms'); - // since we do not use the buckets parameter there is always just one polygon - drawIsoLayer(data.polygons[0], undefined) - }) - .catch(e => { - console.error('error when trying to show isoline', e) - }); -} - -function drawIsoLayer(geojson, coordinates) { - removeIsoLayers(); - var source = map.getSource('isochrone'); - if (!source) { - map.addSource('isochrone', { - 'type': 'geojson', - 'data': geojson - }); - } else { - source.setData(geojson); - } - map.addLayer({ - 'id': 'isochrone-layer', - 'type': 'line', - 'source': 'isochrone', - 'paint': { - 'line-color': '#0000e1' - } - }, getFirstSymbolLayer(map)); -} - -function removeIsoLayers() { - if (map.getLayer('isochrone-layer')) { - map.removeLayer('isochrone-layer'); - } -} - -function setLayer(map, layerId) { - if (layerId == 'vector') { - map.setStyle(vectorStyle); - } else if (layerId == 'raster') { - map.setStyle(rasterStyle); - } -} - -function setGHMvtVisible(map, visible) { - if (visible) { - map.setLayoutProperty('gh', 'visibility', 'visible'); - } else { - map.setLayoutProperty('gh', 'visibility', 'none'); - } -} - -function getFirstSymbolLayer(map) { - var layers = map.getStyle().layers; - // Find the index of the first symbol layer in the map style - for (var i = 0; i < layers.length; i++) { - if (layers[i].type === 'symbol') { - return layers[i].id; - } - } -} \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/autocomplete.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/autocomplete.js deleted file mode 100644 index 0ecbb3d5061..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/autocomplete.js +++ /dev/null @@ -1,174 +0,0 @@ -var formatTools = require('./tools/format.js'); -var GHInput = require('./graphhopper/GHInput.js'); -var GHRoute = require('./graphhopper/GHRoute.js'); -var mapLayer = require('./map.js'); - -var dataToHtml = function (data, query) { - var element = ""; - if (data.name) { - var name = data.name; - if (data.housenumber) - name = formatTools.insComma(name, data.housenumber); - - element += "
    " + formatTools.formatValue(name, query) + "
    "; - } - - var addStr = ""; - if (data.postcode) - addStr = data.postcode; - if (data.city) - addStr = formatTools.insComma(addStr, data.city); - if (data.country) - addStr = formatTools.insComma(addStr, data.country); - - if (addStr) - element += "
    " + formatTools.formatValue(addStr, query) + "
    "; - - if (data.osm_key === "highway") { - // ignore - } - if (data.osm_key === "place") { - element += "" + data.osm_value + ""; - } else - element += "" + data.osm_key + ""; - return element; -}; - -var dataToText = function (data) { - var text = ""; - if (data.name) { - text = data.name; - } else if (data.street) { - text = data.street; - if (data.housenumber) - text = formatTools.insComma(text, data.housenumber); - } - - if (data.postcode) - text = formatTools.insComma(text, data.postcode); - - // make sure name won't be duplicated - if (data.city && text.indexOf(data.city) < 0) - text = formatTools.insComma(text, data.city); - - if (data.country && text.indexOf(data.country) < 0) - text = formatTools.insComma(text, data.country); - return text; -}; - -var AutoComplete = function (host, key) { - this.host = host; - this.key = key; - this.dataType = "json"; - this.api_params = {"locale": "en"}; -}; - -AutoComplete.prototype.createPath = function (url) { - for (var key in this.api_params) { - var val = this.api_params[key]; - if (GHRoute.isArray(val)) { - for (var keyIndex in val) { - url += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(val[keyIndex]); - } - } else { - url += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(val); - } - } - return url; -}; - -AutoComplete.prototype.createGeocodeURL = function (ghRequest, prevIndex) { - var path = this.createPath(this.host + "/geocode?limit=6&type=" + this.dataType + "&key=" + this.key); - if (prevIndex >= 0 && prevIndex < ghRequest.route.size()) { - var point = ghRequest.route.getIndex(prevIndex); - if (point.isResolved()) { - path += "&point=" + point.lat + "," + point.lng; - } - } - return path; -}; - -AutoComplete.prototype.getAutoCompleteDiv = function (index) { - return $('#locationpoints > div.pointDiv').eq(index).find(".pointInput"); -}; - -AutoComplete.prototype.hide = function () { - $(':input[id$="_Input"]').autocomplete().hide(); -}; - -AutoComplete.prototype.showListForIndex = function (ghRequest, routeIfAllResolved, index) { - var myAutoDiv = this.getAutoCompleteDiv(index); - var url = this.createGeocodeURL(ghRequest, index - 1); - - var options = { - containerClass: "autocomplete", - timeout: 1000, - /* avoid too many requests when typing quickly */ - deferRequestBy: 200, - minChars: 2, - maxHeight: 510, - noCache: true, - /* this default could be problematic: preventBadQueries: true, */ - triggerSelectOnValidInput: false, - autoSelectFirst: false, - paramName: "q", - dataType: ghRequest.dataType, - onSearchStart: function (params) { - // query server only if not a parsable point (i.e. format lat,lon) - var val = new GHInput(params.q).lat; - return val === undefined; - }, - serviceUrl: function () { - return url; - }, - transformResult: function (response, originalQuery) { - response.suggestions = []; - if (response.hits) - for (var i = 0; i < response.hits.length; i++) { - var hit = response.hits[i]; - response.suggestions.push({value: dataToText(hit), data: hit}); - } - return response; - }, - onSearchError: function (element, q, jqXHR, textStatus, errorThrown) { - // too many errors if interrupted console.log(element + ", " + JSON.stringify(q) + ", textStatus " + textStatus + ", " + errorThrown); - }, - formatResult: function (suggestion, currInput) { - // avoid highlighting for now as this breaks the html sometimes - return dataToHtml(suggestion.data, currInput); - }, - onSelect: function (suggestion) { - options.onPreSelect(suggestion); - }, - onPreSelect: function (suggestion) { - var req = ghRequest.route.getIndex(index); - - myAutoDiv.autocomplete().disable(); - - var point = suggestion.data.point; - req.setCoord(point.lat, point.lng); - - req.input = suggestion.value; - if (!routeIfAllResolved(true)) - mapLayer.focus(req, 15, index); - - myAutoDiv.autocomplete().enable(); - } - }; - - myAutoDiv.autocomplete(options); -}; - -AutoComplete.prototype.createStub = function () { - complete = new AutoComplete(); - complete.showListForIndex = function () {}; - complete.hide = function () {}; - return complete; -}; - -AutoComplete.prototype.setLocale = function (locale) { - if (locale) - this.api_params.locale = locale; -}; - -module.exports = AutoComplete; diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/config/options.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/config/options.js deleted file mode 100644 index b44962d9045..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/config/options.js +++ /dev/null @@ -1,21 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////////////////////// -// We know that you love 'free', we love it too :)! And so the entire GraphHopper routing engine is not -// only free but even Open Source! The GraphHopper Directions API is also free for development. -// Grab an API key and have fun with installing anything: https://graphhopper.com/#directions-api -// Misuse of API keys that you don't own is prohibited and you'll be blocked. -//////////////////////////////////////////////////////////////////////////////////////////////////////// - -// Easily replace this options.js with an additional file that you provide as options_prod.js activate via: -// BROWSERIFYSWAP_ENV='production' npm run watch -// see also package.json and https://github.com/thlorenz/browserify-swap -exports.options = { - with_tiles: true, - environment: "development", - // use this if you serve the web UI from a different server like live-server and the GH server runs on the standard port - // routing: {host: 'http://localhost:8989', api_key: ''}, - routing: {host: '', api_key: ''}, - geocoding: {host: '', api_key: ''}, - thunderforest: {api_key: ''}, - omniscale: {api_key: ''}, - mapilion: {api_key: ''} -}; \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js deleted file mode 100644 index ba2e2dd898c..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/config/tileLayers.js +++ /dev/null @@ -1,212 +0,0 @@ -var ghenv = require("./options.js").options; -var tfAddition = ''; -if (ghenv.thunderforest.api_key) - tfAddition = '?apikey=' + ghenv.thunderforest.api_key; - -var mapilionAddition = ''; -if (ghenv.mapilion.api_key) - mapilionAddition = '?key=' + ghenv.mapilion.api_key; - -var osAPIKey = 'mapsgraph-bf48cc0b'; -if (ghenv.omniscale.api_key) - osAPIKey = ghenv.omniscale.api_key; - -var osmAttr = '© OpenStreetMap contributors'; - -// Automatically enable high-DPI tiles if provider and browser support it. -var retinaTiles = L.Browser.retina; - -var lyrk = L.tileLayer('https://tiles.lyrk.org/' + (retinaTiles ? 'lr' : 'ls') + '/{z}/{x}/{y}?apikey=6e8cfef737a140e2a58c8122aaa26077', { - attribution: osmAttr + ', Lyrk' -}); - -var omniscale = L.tileLayer('https://maps.omniscale.net/v2/' +osAPIKey + '/style.default/{z}/{x}/{y}.png' + (retinaTiles ? '?hq=true' : ''), { - layers: 'osm', - attribution: osmAttr + ', © Omniscale' -}); - -// Not an option as too fast over limit. -// var mapbox= L.tileLayer('https://{s}.tiles.mapbox.com/v4/peterk.map-vkt0kusv/{z}/{x}/{y}' + (retinaTiles ? '@2x' : '') + '.png?access_token=pk.eyJ1IjoicGV0ZXJrIiwiYSI6IkdFc2FJd2MifQ.YUd7dS_gOpT3xrQnB8_K-w', { -// attribution: osmAttr + ', © MapBox' -// }); - -var sorbianLang = L.tileLayer('http://a.tile.openstreetmap.de/tiles/osmhrb/{z}/{x}/{y}.png', { - attribution: osmAttr + ', © Alberding GmbH, CC-BY-SA' -}); - -var thunderTransport = L.tileLayer('https://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png' + tfAddition, { - attribution: osmAttr + ', Thunderforest Transport' -}); - -var thunderCycle = L.tileLayer('https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png' + tfAddition, { - attribution: osmAttr + ', Thunderforest Cycle' -}); - -var thunderOutdoors = L.tileLayer('https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png' + tfAddition, { - attribution: osmAttr + ', Thunderforest Outdoors' -}); - -var thunderNeighbourhood = L.tileLayer('https://{s}.tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png' + tfAddition, { - attribution: osmAttr + ', Thunderforest Neighbourhood' -}); - -var kurvigerLiberty = L.tileLayer('https://{s}-tiles.mapilion.com/raster/styles/kurviger-liberty/{z}/{x}/{y}{r}.png'+mapilionAddition, { - subdomains: ['a', 'b', 'c', 'd', 'e'], - attribution: osmAttr + ',© Kurviger © Mapilion © OpenMapTiles' -}); - -var wrk = L.tileLayer('http://{s}.wanderreitkarte.de/topo/{z}/{x}/{y}.png', { - attribution: osmAttr + ', WanderReitKarte', - subdomains: ['topo4', 'topo', 'topo2', 'topo3'] -}); - -var osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - attribution: osmAttr -}); - -var osmde = L.tileLayer('http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', { - attribution: osmAttr -}); - -var mapLink = 'Esri'; -var wholink = 'i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'; -var esriAerial = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { - attribution: '© ' + mapLink + ', ' + wholink, - maxZoom: 18 -}); - -var availableTileLayers = { - "Omniscale": omniscale, - "OpenStreetMap": osm, - "Esri Aerial": esriAerial, - "TF Transport": thunderTransport, - "TF Cycle": thunderCycle, - "TF Outdoors": thunderOutdoors, - "TF Neighbourhood": thunderNeighbourhood, - "Kurviger Liberty": kurvigerLiberty, - "Lyrk": lyrk, - "WanderReitKarte": wrk, - "Sorbian Language": sorbianLang, - "OpenStreetMap.de": osmde -}; - -var overlays; -module.exports.enableVectorTiles = function () { - var omniscaleGray = L.tileLayer('https://maps.omniscale.net/v2/' +osAPIKey + '/style.grayscale/layers.world,buildings,landusages,labels/{z}/{x}/{y}.png?' + (retinaTiles ? '&hq=true' : ''), { - layers: 'osm', - attribution: osmAttr + ', © Omniscale' - }); - availableTileLayers["Omniscale Dev"] = omniscaleGray; - - require('leaflet.vectorgrid'); - var vtLayer = L.vectorGrid.protobuf("/mvt/{z}/{x}/{y}.mvt", { - rendererFactory: L.canvas.tile, - maxZoom: 20, - minZoom: 10, - interactive: true, - vectorTileLayerStyles: { - 'roads': function(properties, zoom) { - // weight == line width - var color, opacity = 1, weight = 1, rc = properties.road_class; - // if(properties.speed < 30) console.log(properties) - if (rc === "motorway") { - color = '#dd504b'; // red - weight = 3; - } else if (rc === "primary" || rc === "trunk") { - color = '#e2a012'; // orange - weight = 2; - } else if (rc === "secondary") { - weight = 2; - color = '#f7c913'; // yellow - } else { - color = "#aaa5a7"; // grey - } - if (zoom > 16) - weight += 3; - else if (zoom > 15) - weight += 2; - else if (zoom > 13) - weight += 1; - - return { - weight: weight, - color: color, - opacity: opacity - } - }, - }, - }) - var urbanDensityLayer = L.vectorGrid.protobuf("/mvt/{z}/{x}/{y}.mvt?render_all=true", { - rendererFactory: L.canvas.tile, - maxZoom: 20, - minZoom: 10, - interactive: true, - vectorTileLayerStyles: { - 'roads': function (properties, zoom) { - var ud = properties.urban_density; - let c = getUrbanDensityColor(ud); - return { - weight: 1 + c.weight, - color: c.color, - opacity: 1 - } - }, - }, - }); - var vtLayers = [vtLayer, urbanDensityLayer]; - for (var i = 0; i < vtLayers.length; ++i) { - vtLayers[i] - .on('click', function (e) { - }) - .on('mouseover', function (e) { - console.log(e.layer.properties); - // remove route info - $("#info").children("div").remove(); - // remove last vector tile info - $("#info").children("ul").remove(); - - var list = ""; - $.each(e.layer.properties, function (key, value) { - list += "
  • " + key + ": " + value + "
  • "; - }); - $("#info").append("
      " + list + "
    "); - $("#info").show(); - }).on('mouseout', function (e) { - // $("#info").html(""); - } - ); - } - overlays = { - "Local MVT": vtLayer, - "Show Urban Density": urbanDensityLayer - }; -} - -function getUrbanDensityColor(urbanDensity) { - var color = '#0aaff1'; - if (urbanDensity === "residential") color = '#fd084a'; - else if (urbanDensity === "city") color = '#edf259'; - return { - weight: 1, - color: color - } -} - -module.exports.activeLayerName = "Omniscale"; -module.exports.defaultLayer = omniscale; - -module.exports.getAvailableTileLayers = function () { - return availableTileLayers; -}; - -module.exports.getOverlays = function () { - return overlays; -}; - -module.exports.selectLayer = function (layerName) { - var defaultLayer = availableTileLayers[layerName]; - if (!defaultLayer) - defaultLayer = module.exports.defaultLayer; - - return defaultLayer; -}; diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/gpxexport.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/gpxexport.js deleted file mode 100644 index 40ddcc00826..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/gpxexport.js +++ /dev/null @@ -1,88 +0,0 @@ - -var ensureOneCheckboxSelected = function () { - //Make sure that at least one of the data types remains checked for the GPX export: - $("#gpx_route").change(function () { - if (!$(this).is(':checked')) - { - if (!$("#gpx_track").is(':checked')) - $("#gpx_waypoints").prop("disabled", true); - else { - if (!$("#gpx_waypoints").is(':checked')) - $("#gpx_track").prop("disabled", true); - } - } else - { - $("#gpx_track").prop("disabled", false); - $("#gpx_waypoints").prop("disabled", false); - } - }); - $("#gpx_track").change(function () { - if (!$(this).is(':checked')) - { - if (!$("#gpx_route").is(':checked')) - $("#gpx_waypoints").prop("disabled", true); - else { - if (!$("#gpx_waypoints").is(':checked')) - $("#gpx_route").prop("disabled", true); - } - } else - { - $("#gpx_route").prop("disabled", false); - $("#gpx_waypoints").prop("disabled", false); - } - }); - $("#gpx_waypoints").change(function () { - if (!$(this).is(':checked')) - { - if (!$("#gpx_route").is(':checked')) - $("#gpx_track").prop("disabled", true); - else { - if (!$("#gpx_track").is(':checked')) - $("#gpx_route").prop("disabled", true); - } - } else - { - $("#gpx_route").prop("disabled", false); - $("#gpx_track").prop("disabled", false); - } - }); -}; - -module.exports.addGpxExport = function (ghRequest) { - var dialog; - - function exportGPX(withRoute, withTrack, withWayPoint) { - if (ghRequest.route.isResolved()) - window.open(ghRequest.createGPXURL(withRoute, withTrack, withWayPoint)); - return false; - } - - function exportFlaggedGPX() { - exportGPX($("#gpx_route").is(':checked'), $("#gpx_track").is(':checked'), $("#gpx_waypoints").is(':checked')); - dialog.dialog("close"); - return false; - } - - $(function () { - dialog = $("#gpx_dialog").dialog({ - width: 420, - height: 260, - autoOpen: false, - resizable: false, - draggable: false, - buttons: { - "Export GPX": exportFlaggedGPX, - Cancel: function () { - $(this).dialog("close"); - } - } - }); - ensureOneCheckboxSelected(); - }); - - $('#gpxExportButton a').click(function (e) { - // no page reload - e.preventDefault(); - $("#gpx_dialog").dialog('open'); - }); -}; diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHInput.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHInput.js deleted file mode 100644 index 0ed1a2e71a9..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHInput.js +++ /dev/null @@ -1,67 +0,0 @@ -function round(val, precision) { - if (precision === undefined) - precision = 1e6; - return Math.round(val * precision) / precision; -} - -var GHInput = function (input) { - this.set(input); -}; - -GHInput.isObject = function (value) { - var stringValue = Object.prototype.toString.call(value); - return (stringValue.toLowerCase() === "[object object]"); -}; - -GHInput.isString = function (value) { - var stringValue = Object.prototype.toString.call(value); - return (stringValue.toLowerCase() === "[object string]"); -}; - -GHInput.prototype.isResolved = function () { - return !isNaN(this.lat) && !isNaN(this.lng); -}; - -GHInput.prototype.setCoord = function (lat, lng) { - this.lat = round(lat); - this.lng = round(lng); - this.input = this.toString(); -}; - -GHInput.prototype.setUnresolved = function () { - this.lat = undefined; - this.lng = undefined; -}; - -GHInput.prototype.set = function (strOrObject) { - // either text or coordinates or object - this.input = strOrObject; - // reset to unresolved - - - if (GHInput.isObject(strOrObject)) { - this.setCoord(strOrObject.lat, strOrObject.lng); - } else if (GHInput.isString(strOrObject)) { - var index = strOrObject.indexOf(","); - if (index >= 0) { - this.lat = round(parseFloat(strOrObject.substr(0, index))); - this.lng = round(parseFloat(strOrObject.substr(index + 1))); - - if (this.isResolved()) { - this.input = this.toString(); - } else { - this.setUnresolved(); - } - } else { - this.setUnresolved(); - } - } -}; - -GHInput.prototype.toString = function () { - if (this.lat !== undefined && this.lng !== undefined) - return this.lat + "," + this.lng; - return undefined; -}; - -module.exports = GHInput; diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRequest.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRequest.js deleted file mode 100644 index 7e29731a32c..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRequest.js +++ /dev/null @@ -1,351 +0,0 @@ -var GHRoute = require('./GHRoute.js'); -var GHInput = require('./GHInput.js'); -var graphhopperTools = require('./tools.js'); - -// compatibility script taken from http://stackoverflow.com/a/11054570/194609 -if (!Function.prototype.bind) { - Function.prototype.bind = function (oThis) { - if (typeof this !== 'function') { - // closest thing possible to the ECMAScript 5 - // internal IsCallable function - throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); - } - - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, - fNOP = function () { - }, - fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, - aArgs.concat(Array.prototype.slice.call(arguments))); - }; - - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - - return fBound; - }; -} - -var GHRequest = function (host, api_key) { - this.host = host; - this.route = new GHRoute(new GHInput(), new GHInput()); - this.from = this.route.first(); - this.to = this.route.last(); - this.profiles = [] - - this.do_zoom = true; - this.useMiles = false; - this.dataType = "json"; - this.api_params = {"locale": "en", "key": api_key, "pt": {}}; - - // register events - this.route.addListener('route.add', function (evt) { - this.to = this.route.last(); - }.bind(this)); - this.route.addListener('route.remove', function (evt) { - this.from = this.route.first(); - this.to = this.route.last(); - }.bind(this)); - this.route.addListener('route.move', function (evt) { - this.from = this.route.first(); - this.to = this.route.last(); - }.bind(this)); - - this.route.addListener('route.reverse', function (evt) { - this.from = this.route.first(); - this.to = this.route.last(); - }.bind(this)); -}; - -GHRequest.prototype.init = function (params) { - for (var key in params) { - if (key === "point" || key === "mathRandom" || key === "do_zoom" || key === "layer" || key === "use_miles" || key === "selected_detail") - continue; - - var val = params[key]; - if (val === "false") - val = false; - else if (val === "true") - val = true; - - this.api_params[key] = val; - } - - if ('do_zoom' in params) - this.do_zoom = params.do_zoom; - - if ('use_miles' in params) - this.useMiles = params.use_miles; - - if ('selected_detail' in params) - this.selectedDetail = params.selected_detail; - - if (!this.api_params.profile) - this.api_params.profile = this.profiles[0].profile_name - - if (params.q) { - var qStr = params.q; - if (!params.point) - params.point = []; - var indexFrom = qStr.indexOf("from:"); - var indexTo = qStr.indexOf("to:"); - if (indexFrom >= 0 && indexTo >= 0) { - // google-alike query schema - if (indexFrom < indexTo) { - params.point.push(qStr.substring(indexFrom + 5, indexTo).trim()); - params.point.push(qStr.substring(indexTo + 3).trim()); - } else { - params.point.push(qStr.substring(indexTo + 3, indexFrom).trim()); - params.point.push(qStr.substring(indexFrom + 5).trim()); - } - } else { - var points = qStr.split("p:"); - for (var i = 0; i < points.length; i++) { - var str = points[i].trim(); - if (str.length === 0) - continue; - - params.point.push(str); - } - } - } -}; - -GHRequest.prototype.setEarliestDepartureTime = function (localdatetime) { - this.api_params.pt.earliest_departure_time = localdatetime; -}; - -GHRequest.prototype.getEarliestDepartureTime = function () { - if (this.api_params.pt.earliest_departure_time) - return this.api_params.pt.earliest_departure_time; - return undefined; -}; - -GHRequest.prototype.setProfile = function (profileName) { - this.api_params.profile = profileName; -}; - -GHRequest.prototype.getProfile = function () { - return this.api_params.profile; -}; - -GHRequest.prototype.setElevation = function (elevation) { - this.api_params.elevation = elevation; -}; - -GHRequest.prototype.hasElevation = function () { - if (Array.isArray(this.api_params.elevation)) { - return this.api_params.elevation.every(function (e) { - return e === true || e === "true"; - }) - } else - return this.api_params.elevation === true; -}; - -GHRequest.prototype.getVehicle = function () { - var profileName = this.api_params.profile; - var profile = this.profiles.find(function(p) { return p.profile_name === profileName; }); - if (!profile) - return ""; - else - return profile.vehicle; -}; - -GHRequest.prototype.isPublicTransit = function () { - // legacy support: we might have set vehicle=pt instead of pt - return this.getProfile() === "pt" || this.getVehicle() === "pt";; -}; - -GHRequest.prototype.removeProfileParameterIfLegacyRequest = function() { - // we still allow using legacy parameters to support older urls pasted from somewhere, but when they are used - // we may not add the profile parameter to the url - if ( - this.api_params["vehicle"] || - this.api_params["weighting"] || - this.api_params["turn_costs"] || - this.api_params["edge_based"] - ) { - delete this.api_params.profile; - } -} - -GHRequest.prototype.removeLegacyParameters = function() { - delete this.api_params["vehicle"]; - delete this.api_params["weighting"]; - delete this.api_params["turn_costs"]; - delete this.api_params["edge_based"]; -} - -GHRequest.prototype.createGeocodeURL = function (host, prevIndex) { - var tmpHost = this.host; - if (host) - tmpHost = host; - - var path = this.createPath(tmpHost + "/geocode?limit=6&type=" + this.dataType); - if (prevIndex >= 0 && prevIndex < this.route.size()) { - var point = this.route.getIndex(prevIndex); - if (point.isResolved()) { - path += "&point=" + point.lat + "," + point.lng; - } - } - return path; -}; - -GHRequest.prototype.createURL = function () { - return this.createPath(this.host + "/route?" + this.createPointParams(false) + "&type=" + this.dataType); -}; - -GHRequest.prototype.createGPXURL = function (withRoute, withTrack, withWayPoints) { - return this.createPath(this.host + "/route?" + this.createPointParams(false) + "&type=gpx&gpx.route=" + withRoute + "&gpx.track=" + withTrack + "&gpx.waypoints=" + withWayPoints); -}; - -GHRequest.prototype.createHistoryURL = function () { - var skip = {"key": true, "custom_model": true}; - return this.createPath("?" + this.createPointParams(true), skip) + "&use_miles=" + !!this.useMiles + (this.selectedDetail ? "&selected_detail=" + this.selectedDetail : ""); -}; - -GHRequest.prototype.createPointParams = function (useRawInput) { - var str = "", point, i, l; - - for (i = 0, l = this.route.size(); i < l; i++) { - point = this.route.getIndex(i); - if (i > 0) - str += "&"; - if (typeof point.input == 'undefined') - str += "point="; - else if (useRawInput) - str += "point=" + encodeURIComponent(point.input); - else - str += "point=" + encodeURIComponent(point.toString()); - } - return (str); -}; - -GHRequest.prototype.createPath = function (url, skipParameters) { - for (var key in this.api_params) { - if(skipParameters && skipParameters[key]) - continue; - - var val = this.api_params[key]; - url += this.flatParameter(key, val); - } - return url; -}; - -GHRequest.prototype.flatParameter = function (key, val) { - if(val == undefined) - return ""; - - if (GHRoute.isObject(val)) { - var url = ""; - var arr = Object.keys(val); - for (var keyIndex in arr) { - var objKey = arr[keyIndex]; - url += this.flatParameter(key + "." + objKey, val[objKey]); - } - return url; - - } else if (GHRoute.isArray(val)) { - var arr = val; - var url = ""; - for (var keyIndex in arr) { - url += this.flatParameter(key, arr[keyIndex]); - } - return url; - } - - return "&" + encodeURIComponent(key) + "=" + encodeURIComponent(val); -}; - -GHRequest.prototype.doRequest = function (url, callback) { - var that = this; - $.ajax({ - timeout: 60000, - url: url, - beforeSend: function(request) { - request.setRequestHeader("GH-Client", "web-ui 3.0") - }, - success: function (json) { - if (json.paths) { - for (var i = 0; i < json.paths.length; i++) { - var path = json.paths[i]; - // convert encoded polyline to geo json - if (path.points_encoded) { - var tmpArray = graphhopperTools.decodePath(path.points, that.hasElevation()); - path.points = { - "type": "LineString", - "coordinates": tmpArray - }; - - var tmpSnappedArray = graphhopperTools.decodePath(path.snapped_waypoints, that.hasElevation()); - path.snapped_waypoints = { - "type": "MultiPoint", - "coordinates": tmpSnappedArray - }; - } - } - } - callback(json); - }, - error: function (err) { - var msg = "API did not respond! "; - var json; - - if (err && err.responseText && err.responseText.indexOf('{') >= 0) { - json = JSON.parse(err.responseText); - } else if (err && err.statusText && err.statusText !== "OK") { - msg += err.statusText; - var details = "Error for " + url; - json = { - message: msg, - hints: [{"message": msg, "details": details}] - }; - } - console.log(msg + " " + JSON.stringify(err)); - - callback(json); - }, - type: "GET", - dataType: this.dataType, - crossDomain: true - }); -}; - -GHRequest.prototype.getInfo = function () { - var url = this.host + "/info?type=" + this.dataType + "&key=" + this.getKey(); - // console.log(url); - return $.ajax({ - url: url, - timeout: 3000, - type: "GET", - dataType: this.dataType, - crossDomain: true - }); -}; - -GHRequest.prototype.setLocale = function (locale) { - if (locale) - this.api_params.locale = locale; -}; - -GHRequest.prototype.getKey = function() { - return this.api_params.key; -}; - -GHRequest.prototype.fetchTranslationMap = function (urlLocaleParam) { - if (!urlLocaleParam) - // let servlet figure out the locale from the Accept-Language header - urlLocaleParam = ""; - var url = this.host + "/i18n/" + urlLocaleParam + "?type=" + this.dataType + "&key=" + this.getKey(); - // console.log(url); - return $.ajax({ - url: url, - timeout: 3000, - type: "GET", - dataType: this.dataType, - crossDomain: true - }); -}; - -module.exports = GHRequest; diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRoute.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRoute.js deleted file mode 100644 index 1bff018c56e..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/GHRoute.js +++ /dev/null @@ -1,223 +0,0 @@ -var GHInput = require('./GHInput.js'); - -var GHroute = function () { - var route = Object.create(Array.prototype); - route = (Array.apply(route, arguments) || route); - GHroute.injectClassMethods(route); - route._listeners = {}; - return (route); -}; - -GHroute.injectClassMethods = function (route) { - for (var method in GHroute.prototype) { - if (GHroute.prototype.hasOwnProperty(method)) { - route[method] = GHroute.prototype[method]; - } - } - return (route); -}; - -GHroute.fromArray = function (array) { - var route = GHroute.apply(null, array); - return (route); -}; - -GHroute.isArray = function (value) { - var stringValue = Object.prototype.toString.call(value); - return (stringValue.toLowerCase() === "[object array]"); -}; - -GHroute.isObject = function (value) { - var stringValue = Object.prototype.toString.call(value); - return (stringValue.toLowerCase() === "[object object]"); -}; - -GHroute.prototype = { - first: function () { - return this.getIndex(0); - }, - last: function () { - return this.getIndex((this.length - 1)); - }, - getIndex: function (index) { - index = (isNaN(index)) ? 0 : index; - if (this[index] instanceof GHInput) { - return this[index]; - } else - return false; - }, - getIndexByCoord: function (value) { - var point, - index = false, - coord = new GHInput(value), - i, - l; - - for (i = 0, l = this.length; i < l; i++) { - point = this[i]; - if (point.toString() === coord.toString()) { - index = i; - break; - } - } - return index; - }, - getIndexFromCoord: function (value) { - return this.getIndex(this.getIndexByCoord(value)); - }, - size: function () { - return this.length; - }, - add: function (value, to) { - if (GHroute.isArray(value)) { - for (var i = 0; i < value.length; i++) { - Array.prototype.push.call(this, (value[i] instanceof GHInput) ? value[i] : new GHInput(value[i])); - if (to !== undefined) { - this.move(-1, to, true); - to++; - } else - to = this.length - 1; - this.fire('route.add', { - point: this[to], - to: to - }); - } - return (this); - } else { - Array.prototype.push.call(this, (value instanceof GHInput) ? value : new GHInput(value)); - if (to !== undefined) - this.move(-1, to, true); - else - to = this.length - 1; - this.fire('route.add', { - point: this[to], - to: to - }); - } - return (this[to]); - }, - removeSingle: function (value) { - var index = false; - if (!(isNaN(value) || value >= this.length) && this[value] !== undefined) { - index = value; - } else { - if (value instanceof GHInput) { - value = value.toString(); - } - index = this.getIndexByCoord(value); - } - if (index !== false) { - this.remove(index); - } - return (this); - }, - remove: function (from, to) { - var tmpTo = to || 1; - Array.prototype.splice.call(this, from, tmpTo); - if (this.length === 1) - Array.prototype.push.call(this, new GHInput()); - this.fire('route.remove', { - from: from, - to: tmpTo - }); - return (this); - }, - addAll: function () { - for (var i = 0; i < arguments.length; i++) { - this.add(arguments[i]); - } - return (this); - }, - set: function (value, to, create) { - if (value instanceof GHInput) - this[to] = value; - else if (this[to] instanceof GHInput) { - this[to].set(value); - } else if (create) - return this.add(value, to); - else - return false; - this.fire('route.set', { - point: this[to], - to: to - }); - return (this[to]); - }, - move: function (old_index, new_index, supress_event) { - while (old_index < 0) { - old_index += this.length; - } - while (new_index < 0) { - new_index += this.length; - } - if (new_index >= this.length) { - var k = new_index - this.length; - while ((k--) + 1) { - Array.prototype.push.call(this, undefined); - } - } - Array.prototype.splice.call(this, new_index, 0, Array.prototype.splice.call(this, old_index, 1)[0]); - if (!supress_event) - this.fire('route.move', { - old_index: old_index, - new_index: new_index - }); - return (this); - }, - reverse: function () { - Array.prototype.reverse.call(this); - this.fire('route.reverse', {}); - return (this); - }, - isResolved: function () { - for (var i = 0, l = this.length; i < l; i++) { - var point = this[i]; - if (!point.isResolved()) { - return false; - } - } - return true; - }, - addListener: function (type, listener) { - if (typeof this._listeners[type] === "undefined") { - this._listeners[type] = []; - } - this._listeners[type].push(listener); - return this; - }, - fire: function (event, options) { - if (typeof event === "string") { - event = {type: event}; - } - if (typeof options === "object") { - for (var attrname in options) { - event[attrname] = options[attrname]; - } - } - if (!event.route) { - event.route = this; - } - if (!event.type) { //falsy - throw new Error("Event object missing 'type' property."); - } - if (this._listeners[event.type] instanceof Array) { - var listeners = this._listeners[event.type]; - for (var i = 0, len = listeners.length; i < len; i++) { - listeners[i].call(this, event); - } - } - }, - removeListener: function (type, listener) { - if (this._listeners[type] instanceof Array) { - var listeners = this._listeners[type]; - for (var i = 0, len = listeners.length; i < len; i++) { - if (listeners[i] === listener) { - listeners.splice(i, 1); - break; - } - } - } - } -}; - -module.exports = GHroute; diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/tools.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/tools.js deleted file mode 100644 index b37b16faeeb..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/graphhopper/tools.js +++ /dev/null @@ -1,53 +0,0 @@ -var decodePath = function (encoded, is3D) { - // var start = new Date().getTime(); - var len = encoded.length; - var index = 0; - var array = []; - var lat = 0; - var lng = 0; - var ele = 0; - - while (index < len) { - var b; - var shift = 0; - var result = 0; - do { - b = encoded.charCodeAt(index++) - 63; - result |= (b & 0x1f) << shift; - shift += 5; - } while (b >= 0x20); - var deltaLat = ((result & 1) ? ~(result >> 1) : (result >> 1)); - lat += deltaLat; - - shift = 0; - result = 0; - do { - b = encoded.charCodeAt(index++) - 63; - result |= (b & 0x1f) << shift; - shift += 5; - } while (b >= 0x20); - var deltaLon = ((result & 1) ? ~(result >> 1) : (result >> 1)); - lng += deltaLon; - - if (is3D) { - // elevation - shift = 0; - result = 0; - do - { - b = encoded.charCodeAt(index++) - 63; - result |= (b & 0x1f) << shift; - shift += 5; - } while (b >= 0x20); - var deltaEle = ((result & 1) ? ~(result >> 1) : (result >> 1)); - ele += deltaEle; - array.push([lng * 1e-5, lat * 1e-5, ele / 100]); - } else - array.push([lng * 1e-5, lat * 1e-5]); - } - // var end = new Date().getTime(); - // console.log("decoded " + len + " coordinates in " + ((end - start) / 1000) + "s"); - return array; -}; - -module.exports.decodePath = decodePath; diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/instructions.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/instructions.js deleted file mode 100644 index 839e16d632d..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/instructions.js +++ /dev/null @@ -1,136 +0,0 @@ -var translate = require('./translate.js'); -var messages = require('./messages.js'); - -var routeSegmentPopup = null; - -function addInstruction(mapLayer, main, instr, instrIndex, lngLat, useMiles, debug) { - var sign = instr.sign; - if (instrIndex === 0) - sign = "marker-icon-green"; - else - sign = messages.getSignName(sign); - var title = instr.text; - - var pathname = window.location.pathname; - var dirname = pathname.substring(0, pathname.lastIndexOf('/')); - - var instructionDiv = $(""); - if (sign !== "continue") { - var indiPic = ""; - instructionDiv.append("" + indiPic + ""); - } else { - instructionDiv.append(""); - } - - var tdVar = $(""); - tdVar.text(title); - - instructionDiv.append(tdVar); - var distance = instr.distance; - if (distance > 0) { - instructionDiv.append("" + translate.createDistanceString(distance, useMiles) + "
    " + translate.createTimeString(instr.time) + "
    "); - } - - if (lngLat) { - instructionDiv.click(function () { - if (routeSegmentPopup) - mapLayer.removeLayerFromMap(routeSegmentPopup); - - routeSegmentPopup = L.popup().setLatLng([lngLat[1], lngLat[0]]).setContent(title).openOn(mapLayer.getMap()); - - }); - - if (debug) { - // Debug Turn Instructions more easily - L.marker([lngLat[1], lngLat[0]], { - icon: L.icon({ - iconUrl: './img/marker-small-red.png', - // Made the instructions icon a bit bigger, as they are placed before the path details - iconSize: [16, 16] - }), - draggable: true, - autoPan: true - }).addTo(mapLayer.getRoutingLayer()).bindPopup(title); - } - } - main.append(instructionDiv); -} - -module.exports.create = function (mapLayer, path, urlForHistory, request) { - var instructionsElement = $(""); - var debug = request.api_params.debug; - - var partialInstr = path.instructions.length > 100; - var len = Math.min(path.instructions.length, 100); - for (var m = 0; m < len; m++) { - var instr = path.instructions[m]; - var lngLat = path.points.coordinates[instr.interval[0]]; - addInstruction(mapLayer, instructionsElement, instr, m, lngLat, request.useMiles, debug); - } - var infoDiv = $("
    "); - infoDiv.append(instructionsElement); - - if (partialInstr) { - var moreDiv = $(""); - moreDiv.click(function () { - moreDiv.remove(); - for (var m = len; m < path.instructions.length; m++) { - var instr = path.instructions[m]; - var lngLat = path.points.coordinates[instr.interval[0]]; - addInstruction(mapLayer, instructionsElement, instr, m, lngLat, request.useMiles); - } - }); - instructionsElement.append(moreDiv); - } - - var hiddenDiv = $("
    "); - hiddenDiv.hide(); - - var toggly = $(""); - toggly.click(function () { - hiddenDiv.toggle(); - }); - infoDiv.append(toggly); - var infoStr = "points: " + path.points.coordinates.length; - - hiddenDiv.append("" + infoStr + ""); - - var osmRouteLink = $("
    view on OSM"); - - var osmVehicle = request.getVehicle(); - if (osmVehicle === "bicycle") { - osmVehicle = "bike"; - } else if (osmVehicle.indexOf("truck") >= 0) { - osmVehicle = "car"; - } - - osmRouteLink.attr("href", "http://www.openstreetmap.org/directions?engine=graphhopper_" + osmVehicle + "&route=" + encodeURIComponent(request.from.lat + "," + request.from.lng + ";" + request.to.lat + "," + request.to.lng)); - hiddenDiv.append(osmRouteLink); - - var osrmLink = $("OSRM"); - osrmLink.attr("href", "http://map.project-osrm.org/?z=13&loc=" + request.from + "&loc=" + request.to); - hiddenDiv.append("
    Compare with: "); - hiddenDiv.append(osrmLink); - var googleLink = $("Google "); - var addToGoogle = ""; - var addToBing = ""; - if (request.getVehicle().toUpperCase() === "FOOT") { - addToGoogle = "&dirflg=w"; - addToBing = "&mode=W"; - } else if ((request.getVehicle().toUpperCase().indexOf("BIKE") >= 0) || - (request.getVehicle().toUpperCase() === "MTB")) { - addToGoogle = "&dirflg=b"; - } - - googleLink.attr("href", "https://maps.google.com/?saddr=" + request.from + "&daddr=" + request.to + addToGoogle); - hiddenDiv.append(googleLink); - var bingLink = $("Bing "); - bingLink.attr("href", "https://www.bing.com/maps/default.aspx?rtp=adr." + request.from + "~adr." + request.to + addToBing); - hiddenDiv.append(bingLink); - if (metaVersionInfo) - hiddenDiv.append(metaVersionInfo); - - infoDiv.append(hiddenDiv); - return infoDiv; -}; diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery-ui-custom-1.12.0.min.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery-ui-custom-1.12.0.min.js deleted file mode 100644 index 5db2c6d4e9b..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery-ui-custom-1.12.0.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/*! jQuery UI - v1.12.0 - 2016-07-26 -* http://jqueryui.com -* Custom: select dialog, sortable and jquery 1.7 support -* Copyright jQuery Foundation and other contributors; Licensed MIT */ - -(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){function e(t){for(var e=t.css("visibility");"inherit"===e;)t=t.parent(),e=t.css("visibility");return"hidden"!==e}t.ui=t.ui||{},t.ui.version="1.12.0";var i=0,s=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},l=e.split(".")[0];e=e.split(".")[1];var h=l+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][h.toLowerCase()]=function(e){return!!t.data(e,h)},t[l]=t[l]||{},n=t[l][e],o=t[l][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:l,widgetName:e,widgetFullName:h}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,n,o=s.call(arguments,1),a=0,r=o.length;r>a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),l=this;return a?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var l=s.match(/^([\w:-]*)\s*(.*)$/),h=l[1]+o.eventNamespace,c=l[2];c?n.on(h,c,r):i.on(h,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o,a=Math.max,r=Math.abs,l=Math.round,h=/left|center|right/,c=/top|center|bottom/,u=/[\+\-]\d+(\.[\d]+)?%?/,d=/^\w+/,p=/%$/,f=t.fn.position;o=function(){var e=t("
    ").css("position","absolute").appendTo("body").offset({top:1.5,left:1.5}),i=1.5===e.offset().top;return e.remove(),o=function(){return i},i},t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
    "),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>o?"top":s>0?"bottom":"middle"};u>g&&g>r(e+i)&&(l.horizontal="center"),d>m&&m>r(s+o)&&(l.vertical="middle"),l.important=a(r(e),r(i))>a(r(s),r(o))?"horizontal":"vertical",n.using.call(this,t,l)}),c.offset(t.extend(I,{using:h}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,o=s.width,r=t.left-e.collisionPosition.marginLeft,l=n-r,h=r+e.collisionWidth-o-n;e.collisionWidth>o?l>0&&0>=h?(i=t.left+l+e.collisionWidth-o-n,t.left+=l-i):t.left=h>0&&0>=l?n:l>h?n+o-e.collisionWidth:n:l>0?t.left+=l:h>0?t.left-=h:t.left=a(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,o=e.within.height,r=t.top-e.collisionPosition.marginTop,l=n-r,h=r+e.collisionHeight-o-n;e.collisionHeight>o?l>0&&0>=h?(i=t.top+l+e.collisionHeight-o-n,t.top+=l-i):t.top=h>0&&0>=l?n:l>h?n+o-e.collisionHeight:n:l>0?t.top+=l:h>0?t.top-=h:t.top=a(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,a=n.width,l=n.isWindow?n.scrollLeft:n.offset.left,h=t.left-e.collisionPosition.marginLeft,c=h-l,u=h+e.collisionWidth-a-l,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-a-o,(0>i||r(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-l,(s>0||u>r(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,a=n.height,l=n.isWindow?n.scrollTop:n.offset.top,h=t.top-e.collisionPosition.marginTop,c=h-l,u=h+e.collisionHeight-a-l,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-a-o,(0>s||r(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-l,(i>0||u>r(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,l,h=i.nodeName.toLowerCase();return"area"===h?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(h)?(r=!i.disabled,r&&(l=t(i).closest("fieldset")[0],l&&(r=!l.disabled))):r="a"===h?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.0",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")},t.widget("ui.draggable",t.ui.mouse,{version:"1.12.0",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(e){var i=this.options;return this._blurActiveElement(e),this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var e=t(this);return t("
    ").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var i=t.ui.safeActiveElement(this.document[0]),s=t(e.target);this._getHandle(e)&&s.closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp(new t.Event("mouseup",e)),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1},_mouseUp:function(e){return this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper),n=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options,o=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,t(o).width()-this.helperProportions.width-this.margins.left,(t(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0)},_convertPositionTo:function(t,e){e||(e=this.position);var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,n,o,a=this.options,r=this._isRootNode(this.scrollParent[0]),l=t.pageX,h=t.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.lefti[2]&&(l=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(h=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,h=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,l=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o),"y"===a.axis&&(l=this.originalPageX),"x"===a.axis&&(h=this.originalPageY)),{top:h-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)} -},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var n=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,n))})},stop:function(e,i,s){var n=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,n))})},drag:function(e,i,s){t.each(s.sortables,function(){var n=!1,o=this;o.positionAbs=s.positionAbs,o.helperProportions=s.helperProportions,o.offset.click=s.offset.click,o._intersectsWith(o.containerCache)&&(n=!0,t.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==o&&this._intersectsWith(this.containerCache)&&t.contains(o.element[0],this.element[0])&&(n=!1),n})),n?(o.isOver||(o.isOver=1,s._parent=i.helper.parent(),o.currentItem=i.helper.appendTo(o.element).data("ui-sortable-item",!0),o.options._helper=o.options.helper,o.options.helper=function(){return i.helper[0]},e.target=o.currentItem[0],o._mouseCapture(e,!0),o._mouseStart(e,!0,!0),o.offset.click.top=s.offset.click.top,o.offset.click.left=s.offset.click.left,o.offset.parent.left-=s.offset.parent.left-o.offset.parent.left,o.offset.parent.top-=s.offset.parent.top-o.offset.parent.top,s._trigger("toSortable",e),s.dropped=o.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,o.fromOutside=s),o.currentItem&&(o._mouseDrag(e),i.position=o.position)):o.isOver&&(o.isOver=0,o.cancelHelperRemoval=!0,o.options._revert=o.options.revert,o.options.revert=!1,o._trigger("out",e,o._uiHash(o)),o._mouseStop(e,!0),o.options.revert=o.options._revert,o.options.helper=o.options._helper,o.placeholder&&o.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var n=t("body"),o=s.options;n.css("cursor")&&(o._cursor=n.css("cursor")),n.css("cursor",o.cursor)},stop:function(e,i,s){var n=s.options;n._cursor&&t("body").css("cursor",n._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("opacity")&&(o._opacity=n.css("opacity")),n.css("opacity",o.opacity)},stop:function(e,i,s){var n=s.options;n._opacity&&t(i.helper).css("opacity",n._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var n=s.options,o=!1,a=s.scrollParentNotHidden[0],r=s.document[0];a!==r&&"HTML"!==a.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+a.offsetHeight-e.pageY=0;d--)l=s.snapElements[d].left-s.margins.left,h=l+s.snapElements[d].width,c=s.snapElements[d].top-s.margins.top,u=c+s.snapElements[d].height,l-g>_||m>h+g||c-g>b||v>u+g||!t.contains(s.snapElements[d].item.ownerDocument,s.snapElements[d].item)?(s.snapElements[d].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=!1):("inner"!==f.snapMode&&(n=g>=Math.abs(c-b),o=g>=Math.abs(u-v),a=g>=Math.abs(l-_),r=g>=Math.abs(h-m),n&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left)),p=n||o||a||r,"outer"!==f.snapMode&&(n=g>=Math.abs(c-v),o=g>=Math.abs(u-b),a=g>=Math.abs(l-m),r=g>=Math.abs(h-_),n&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left)),!s.snapElements[d].snapping&&(n||o||a||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=n||o||a||r||p)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var n,o=s.options,a=t.makeArray(t(o.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});a.length&&(n=parseInt(t(a[0]).css("zIndex"),10)||0,t(a).each(function(e){t(this).css("zIndex",n+e)}),this.css("zIndex",n+a.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("zIndex")&&(o._zIndex=n.css("zIndex")),n.css("zIndex",o.zIndex)},stop:function(e,i,s){var n=s.options;n._zIndex&&t(i.helper).css("zIndex",n._zIndex)}}),t.ui.draggable,t.widget("ui.resizable",t.ui.mouse,{version:"1.12.0",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
    ").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
    "),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,l=this._change[o];return this._updatePrevProperties(),l?(i=l.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,l,h=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,l=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,h.animate||this.element.css(t.extend(a,{top:l,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!h.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,l=this.originalPosition.top+this.originalSize.height,h=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&h&&(t.left=r-e.minWidth),s&&h&&(t.left=r-e.maxWidth),a&&c&&(t.top=l-e.minHeight),n&&c&&(t.top=l-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
    "),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,l={width:i.size.width-r,height:i.size.height-a},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(l,c&&h?{top:c,left:h}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,l=t(this).resizable("instance"),h=l.options,c=l.element,u=h.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(l.containerElement=t(d),/document/.test(u)||u===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=l._num(e.css("padding"+s))}),l.containerOffset=e.offset(),l.containerPosition=e.position(),l.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=l.containerOffset,n=l.containerSize.height,o=l.containerSize.width,a=l._hasScroll(d,"left")?d.scrollWidth:o,r=l._hasScroll(d)?d.scrollHeight:n,l.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,l=a.containerOffset,h=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=l),h.left<(a._helper?l.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-l.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?l.left:0),h.top<(a._helper?l.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-l.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?l.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-l.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-l.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),l=a.outerWidth()-e.sizeDiff.width,h=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:l,height:h}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:l,height:h})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,l="number"==typeof s.grid?[s.grid,s.grid]:s.grid,h=l[0]||1,c=l[1]||1,u=Math.round((n.width-o.width)/h)*h,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,g=s.maxWidth&&p>s.maxWidth,m=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=l,_&&(p+=h),v&&(f+=c),g&&(p-=h),m&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-h)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-h>0?(i.size.width=p,i.position.left=a.left-u):(p=h-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable,t.widget("ui.sortable",t.ui.mouse,{version:"1.12.0",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&e+i>t},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){var e=this;this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){e._addClass(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item,"ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):void 0}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1 -},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,l=r+t.height,h=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+h>r&&l>s+h,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&l>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),o=s&&n;return o?(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1)):!1},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],l=[],h=this._connectWith();if(h&&e)for(s=h.length-1;s>=0;s--)for(o=t(h[s],this.document[0]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&l.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(l.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=l.length-1;s>=0;s--)l[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,l,h,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i],this.document[0]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,h=r.length;h>s;s++)l=t(r[s]),l.data(this.widgetName+"-item",a),c.push({item:l,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]);return e._addClass(n,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("
    ",e.document[0]).appendTo(n)):"tr"===s?e._createTrPlaceholder(e.currentItem,n):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t("",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,n,o,a,r,l,h,c,u,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&t.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,o=null,c=d.floating||this._isFloating(this.currentItem),a=c?"left":"top",r=c?"width":"height",u=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(l=this.items[s].item.offset()[a],h=!1,e[u]-l>this.items[s][r]/2&&(h=!0),n>Math.abs(e[u]-l)&&(n=Math.abs(e[u]-l),o=this.items[s],this.direction=h?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;o?this._rearrange(e,o,null,!0):this._rearrange(e,null,this.containers[p].element,!0),this._trigger("change",e,this._uiHash()),this.containers[p]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,l=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.leftthis.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():l?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():l?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}});var o=/ui-corner-([a-z]){2,6}/g;t.widget("ui.controlgroup",{version:"1.12.0",defaultElement:"
    ",options:{direction:"horizontal",disabled:null,onlyVisible:!0,items:{button:"input[type=button], input[type=submit], input[type=reset], button, a",controlgroupLabel:".ui-controlgroup-label",checkboxradio:"input[type='checkbox'], input[type='radio']",selectmenu:"select",spinner:".ui-spinner-input"}},_create:function(){this._enhance()},_enhance:function(){this.element.attr("role","toolbar"),this.refresh()},_destroy:function(){this._callChildMethod("destroy"),this.childWidgets.removeData("ui-controlgroup-data"),this.element.removeAttr("role"),this.options.items.controlgroupLabel&&this.element.find(this.options.items.controlgroupLabel).find(".ui-controlgroup-label-contents").contents().unwrap()},_initWidgets:function(){var e=this,i=[];t.each(this.options.items,function(s,n){var o,a={};return n?"controlgroupLabel"===s?(o=e.element.find(n),o.each(function(){var e=t(this);e.children(".ui-controlgroup-label-contents").length||e.contents().wrapAll("")}),e._addClass(o,null,"ui-widget ui-widget-content ui-state-default"),i=i.concat(o.get()),void 0):(t.fn[s]&&(e["_"+s+"Options"]&&(a=e["_"+s+"Options"]("middle")),e.element.find(n).each(function(){var n=t(this),o=n[s]("instance"),r=t.widget.extend({},a);if("button"!==s||!n.parent(".ui-spinner").length){o||(o=n[s]()[s]("instance")),o&&(r.classes=e._resolveClassesValues(r.classes,o)),n[s](r);var l=n[s]("widget");t.data(l[0],"ui-controlgroup-data",o?o:n[s]("instance")),i.push(l[0])}})),void 0):void 0}),this.childWidgets=t(t.unique(i)),this._addClass(this.childWidgets,"ui-controlgroup-item")},_callChildMethod:function(e){this.childWidgets.each(function(){var i=t(this),s=i.data("ui-controlgroup-data");s&&s[e]&&s[e]()})},_updateCornerClass:function(t,e){var i="ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all",s=this._buildSimpleOptions(e,"label").classes.label;this._removeClass(t,null,i),this._addClass(t,null,s)},_buildSimpleOptions:function(t,e){var i="vertical"===this.options.direction,s={classes:{}};return s.classes[e]={middle:"",first:"ui-corner-"+(i?"top":"left"),last:"ui-corner-"+(i?"bottom":"right"),only:"ui-corner-all"}[t],s},_spinnerOptions:function(t){var e=this._buildSimpleOptions(t,"ui-spinner");return e.classes["ui-spinner-up"]="",e.classes["ui-spinner-down"]="",e},_buttonOptions:function(t){return this._buildSimpleOptions(t,"ui-button")},_checkboxradioOptions:function(t){return this._buildSimpleOptions(t,"ui-checkboxradio-label")},_selectmenuOptions:function(t){var e="vertical"===this.options.direction;return{width:e?"auto":!1,classes:{middle:{"ui-selectmenu-button-open":"","ui-selectmenu-button-closed":""},first:{"ui-selectmenu-button-open":"ui-corner-"+(e?"top":"tl"),"ui-selectmenu-button-closed":"ui-corner-"+(e?"top":"left")},last:{"ui-selectmenu-button-open":e?"":"ui-corner-tr","ui-selectmenu-button-closed":"ui-corner-"+(e?"bottom":"right")},only:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"}}[t]}},_resolveClassesValues:function(e,i){var s={};return t.each(e,function(t){var n=i.options.classes[t]||"";n=n.replace(o,"").trim(),s[t]=(n+" "+e[t]).replace(/\s+/g," ")}),s},_setOption:function(t,e){return"direction"===t&&this._removeClass("ui-controlgroup-"+this.options.direction),this._super(t,e),"disabled"===t?(this._callChildMethod(e?"disable":"enable"),void 0):(this.refresh(),void 0)},refresh:function(){var e,i=this;this._addClass("ui-controlgroup ui-controlgroup-"+this.options.direction),"horizontal"===this.options.direction&&this._addClass(null,"ui-helper-clearfix"),this._initWidgets(),e=this.childWidgets,this.options.onlyVisible&&(e=e.filter(":visible")),e.length&&(t.each(["first","last"],function(t,s){var n=e[s]().data("ui-controlgroup-data");if(n&&i["_"+n.widgetName+"Options"]){var o=i["_"+n.widgetName+"Options"](1===e.length?"only":s);o.classes=i._resolveClassesValues(o.classes,n),n.element[n.widgetName](o)}else i._updateCornerClass(e[s](),s)}),this._callChildMethod("refresh"))}}),t.widget("ui.checkboxradio",[t.ui.formResetMixin,{version:"1.12.0",options:{disabled:null,label:null,icon:!0,classes:{"ui-checkboxradio-label":"ui-corner-all","ui-checkboxradio-icon":"ui-corner-all"}},_getCreateOptions:function(){var e,i,s=this,n=this._super()||{};return this._readType(),i=this.element.labels(),this.label=t(i[i.length-1]),this.label.length||t.error("No label found for checkboxradio widget"),this.originalLabel="",this.label.contents().not(this.element).each(function(){s.originalLabel+=3===this.nodeType?t(this).text():this.outerHTML}),this.originalLabel&&(n.label=this.originalLabel),e=this.element[0].disabled,null!=e&&(n.disabled=e),n},_create:function(){var t=this.element[0].checked;this._bindFormResetHandler(),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled),this._setOption("disabled",this.options.disabled),this._addClass("ui-checkboxradio","ui-helper-hidden-accessible"),this._addClass(this.label,"ui-checkboxradio-label","ui-button ui-widget"),"radio"===this.type&&this._addClass(this.label,"ui-checkboxradio-radio-label"),this.options.label&&this.options.label!==this.originalLabel?this._updateLabel():this.originalLabel&&(this.options.label=this.originalLabel),this._enhance(),t&&(this._addClass(this.label,"ui-checkboxradio-checked","ui-state-active"),this.icon&&this._addClass(this.icon,null,"ui-state-hover")),this._on({change:"_toggleClasses",focus:function(){this._addClass(this.label,null,"ui-state-focus ui-visual-focus")},blur:function(){this._removeClass(this.label,null,"ui-state-focus ui-visual-focus")}})},_readType:function(){var e=this.element[0].nodeName.toLowerCase();this.type=this.element[0].type,"input"===e&&/radio|checkbox/.test(this.type)||t.error("Can't create checkboxradio on element.nodeName="+e+" and element.type="+this.type)},_enhance:function(){this._updateIcon(this.element[0].checked)},widget:function(){return this.label},_getRadioGroup:function(){var e,i=this.element[0].name,s="input[name='"+t.ui.escapeSelector(i)+"']";return i?(e=this.form.length?t(this.form[0].elements).filter(s):t(s).filter(function(){return 0===t(this).form().length}),e.not(this.element)):t([])},_toggleClasses:function(){var e=this.element[0].checked;this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",e),this.options.icon&&"checkbox"===this.type&&this._toggleClass(this.icon,null,"ui-icon-check ui-state-checked",e)._toggleClass(this.icon,null,"ui-icon-blank",!e),"radio"===this.type&&this._getRadioGroup().each(function(){var e=t(this).checkboxradio("instance");e&&e._removeClass(e.label,"ui-checkboxradio-checked","ui-state-active")})},_destroy:function(){this._unbindFormResetHandler(),this.icon&&(this.icon.remove(),this.iconSpace.remove())},_setOption:function(t,e){return"label"!==t||e?(this._super(t,e),"disabled"===t?(this._toggleClass(this.label,null,"ui-state-disabled",e),this.element[0].disabled=e,void 0):(this.refresh(),void 0)):void 0},_updateIcon:function(e){var i="ui-icon ui-icon-background ";this.options.icon?(this.icon||(this.icon=t(""),this.iconSpace=t(" "),this._addClass(this.iconSpace,"ui-checkboxradio-icon-space")),"checkbox"===this.type?(i+=e?"ui-icon-check ui-state-checked":"ui-icon-blank",this._removeClass(this.icon,null,e?"ui-icon-blank":"ui-icon-check")):i+="ui-icon-blank",this._addClass(this.icon,"ui-checkboxradio-icon",i),e||this._removeClass(this.icon,null,"ui-icon-check ui-state-checked"),this.icon.prependTo(this.label).after(this.iconSpace)):void 0!==this.icon&&(this.icon.remove(),this.iconSpace.remove(),delete this.icon)},_updateLabel:function(){this.label.contents().not(this.element.add(this.icon).add(this.iconSpace)).remove(),this.label.append(this.options.label)},refresh:function(){var t=this.element[0].checked,e=this.element[0].disabled;this._updateIcon(t),this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),null!==this.options.label&&this._updateLabel(),e!==this.options.disabled&&this._setOptions({disabled:e})}}]),t.ui.checkboxradio,t.widget("ui.button",{version:"1.12.0",defaultElement:"").button({label:t("").text(this.options.closeText).html(),icon:"ui-icon-closethick",showLabel:!1}).appendTo(this.uiDialogTitlebar),this._addClass(this.uiDialogTitlebarClose,"ui-dialog-titlebar-close"),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("").uniqueId().prependTo(this.uiDialogTitlebar),this._addClass(e,"ui-dialog-title"),this._title(e),this.uiDialogTitlebar.prependTo(this.uiDialog),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title?t.text(this.options.title):t.html(" ")},_createButtonPane:function(){this.uiDialogButtonPane=t("
    "),this._addClass(this.uiDialogButtonPane,"ui-dialog-buttonpane","ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("
    ").appendTo(this.uiDialogButtonPane),this._addClass(this.uiButtonSet,"ui-dialog-buttonset"),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this._removeClass(this.uiDialog,"ui-dialog-buttons"),void 0):(t.each(i,function(i,s){var n,o;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,o={icon:s.icon,iconPosition:s.iconPosition,showLabel:s.showLabel},delete s.click,delete s.icon,delete s.iconPosition,delete s.showLabel,t("",s).button(o).appendTo(e.uiButtonSet).on("click",function(){n.apply(e.element[0],arguments)})}),this._addClass(this.uiDialog,"ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){i._addClass(t(this),"ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,o){var a=o.offset.left-i.document.scrollLeft(),r=o.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(a>=0?"+":"")+a+" "+"top"+(r>=0?"+":"")+r,of:i.window},i._removeClass(t(this),"ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(o))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}var i=this,s=this.options,n=s.resizable,o=this.uiDialog.css("position"),a="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:a,start:function(s,n){i._addClass(t(this),"ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,o){var a=i.uiDialog.offset(),r=a.left-i.document.scrollLeft(),l=a.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(l>=0?"+":"")+l,of:i.window},i._removeClass(t(this),"ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(o))}}).css("position",o)},_trackFocus:function(){this._on(this.widget(),{focusin:function(e){this._makeFocusTarget(),this._focusedElement=t(e.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var e=this._trackingInstances(),i=t.inArray(this,e);-1!==i&&e.splice(i,1)},_trackingInstances:function(){var t=this.document.data("ui-dialog-instances");return t||(t=[],this.document.data("ui-dialog-instances",t)),t},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(e){var i=this,s=!1,n={};t.each(e,function(t,e){i._setOption(t,e),t in i.sizeRelatedOptions&&(s=!0),t in i.resizableRelatedOptions&&(n[t]=e)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(e,i){var s,n,o=this.uiDialog;"disabled"!==e&&(this._super(e,i),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:t("").text(""+this.options.closeText).html()}),"draggable"===e&&(s=o.is(":data(ui-draggable)"),s&&!i&&o.draggable("destroy"),!s&&i&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(n=o.is(":data(ui-resizable)"),n&&!i&&o.resizable("destroy"),n&&"string"==typeof i&&o.resizable("option","handles",i),n||i===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("
    ").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=!0;this._delay(function(){e=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(t){e||this._allowInteraction(t)||(t.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=t("
    ").appendTo(this._appendTo()),this._addClass(this.overlay,null,"ui-widget-overlay ui-front"),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var t=this.document.data("ui-dialog-overlays")-1;t?this.document.data("ui-dialog-overlays",t):(this._off(this.document,"focusin"),this.document.removeData("ui-dialog-overlays")),this.overlay.remove(),this.overlay=null}}}),t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{options:{dialogClass:""},_createWrapper:function(){this._super(),this.uiDialog.addClass(this.options.dialogClass)},_setOption:function(t,e){"dialogClass"===t&&this.uiDialog.removeClass(this.options.dialogClass).addClass(e),this._superApply(arguments)}}),t.ui.dialog}); \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery.autocomplete.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery.autocomplete.js deleted file mode 100644 index bbacf00c116..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery.autocomplete.js +++ /dev/null @@ -1,831 +0,0 @@ -/** -* Ajax Autocomplete for jQuery, version 1.2.9 -* (c) 2013 Tomas Kirda -* -* Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license. -* For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete -* -*/ - -/*jslint browser: true, white: true, plusplus: true */ -/*global define, window, document, jQuery */ - -// Expose plugin as an AMD module if AMD loader is present: -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['jquery'], factory); - } else { - // Browser globals - factory(jQuery); - } -}(function ($) { - 'use strict'; - - var - utils = (function () { - return { - escapeRegExChars: function (value) { - return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - }, - createNode: function (containerClass) { - var div = document.createElement('div'); - div.className = containerClass; - div.style.position = 'absolute'; - div.style.display = 'none'; - div.style.cursor = 'pointer'; - return div; - } - }; - }()), - - keys = { - ESC: 27, - TAB: 9, - RETURN: 13, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40 - }; - - function Autocomplete(el, options) { - var noop = function () { }, - that = this, - defaults = { - autoSelectFirst: false, - appendTo: 'body', - serviceUrl: null, - lookup: null, - onSelect: null, - width: 'auto', - minChars: 1, - maxHeight: 300, - deferRequestBy: 0, - params: {}, - formatResult: Autocomplete.formatResult, - onPreSelect: noop, - delimiter: null, - zIndex: 9999, - type: 'GET', - noCache: false, - onSearchStart: noop, - onSearchComplete: noop, - onSearchError: noop, - containerClass: 'autocomplete-suggestions', - tabDisabled: false, - dataType: 'text', - currentRequest: null, - triggerSelectOnValidInput: true, - lookupFilter: function (suggestion, originalQuery, queryLowerCase) { - return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1; - }, - paramName: 'query', - transformResult: function (response) { - return typeof response === 'string' ? $.parseJSON(response) : response; - } - }; - - // Shared variables: - that.element = el; - that.el = $(el); - that.suggestions = []; - that.badQueries = []; - that.selectedIndex = -1; - that.currentValue = that.element.value; - that.intervalId = 0; - that.cachedResponse = {}; - that.onChangeInterval = null; - that.onChange = null; - that.isLocal = false; - that.suggestionsContainer = null; - that.options = $.extend({}, defaults, options); - that.classes = { - selected: 'autocomplete-selected', - suggestion: 'autocomplete-suggestion' - }; - that.hint = null; - that.hintValue = ''; - that.selection = null; - - // Initialize and set options: - that.initialize(); - that.setOptions(options); - } - - Autocomplete.utils = utils; - - $.Autocomplete = Autocomplete; - - Autocomplete.formatResult = function (suggestion, currentValue) { - var pattern = '(' + utils.escapeRegExChars(currentValue) + ')'; - - return suggestion.value.replace(new RegExp(pattern, 'gi'), '$1<\/strong>'); - }; - - Autocomplete.prototype = { - - killerFn: null, - - initialize: function () { - var that = this, - suggestionSelector = '.' + that.classes.suggestion, - selected = that.classes.selected, - options = that.options, - container; - - // Remove autocomplete attribute to prevent native suggestions: - that.element.setAttribute('autocomplete', 'off'); - - that.killerFn = function (e) { - if ($(e.target).closest('.' + that.options.containerClass).length === 0) { - that.killSuggestions(); - that.disableKillerFn(); - } - }; - - that.suggestionsContainer = Autocomplete.utils.createNode(options.containerClass); - - container = $(that.suggestionsContainer); - - container.appendTo(options.appendTo); - - // Only set width if it was provided: - if (options.width !== 'auto') { - container.width(options.width); - } - - // special on() plugin code for 'autocomplete' - // http://api.jquery.com/on/#on-events-selector-data - // Listen for mouse over event on suggestions list: -// container.on('mouseenter.autocomplete', suggestionSelector, function () { -// that.activate($(this).data('index')); -// }); -// -// // Deselect active element when mouse leaves suggestions container: -// container.on('mouseleave.autocomplete', suggestionSelector, function () { -// that.selectedIndex = -1; -// container.children('.' + selected).removeClass(selected); -// }); - - // Listen for click event on suggestions list: - container.on('click.autocomplete', suggestionSelector, function () { - that.select($(this).data('index')); - }); - - that.fixPosition(); - - that.fixPositionCapture = function () { - if (that.visible) { - that.fixPosition(); - } - }; - - $(window).on('resize.autocomplete', that.fixPositionCapture); - - that.el.on('keydown.autocomplete', function (e) { that.onKeyPress(e); }); - that.el.on('keyup.autocomplete', function (e) { that.onKeyUp(e); }); - that.el.on('blur.autocomplete', function () { that.onBlur(); }); - that.el.on('focus.autocomplete', function () { that.onFocus(); }); - that.el.on('change.autocomplete', function (e) { that.onKeyUp(e); }); - }, - - onFocus: function () { - var that = this; - that.fixPosition(); - if (that.options.minChars <= that.el.val().length) { - // that.onValueChange(); - } - }, - - onBlur: function () { - this.enableKillerFn(); - }, - - setOptions: function (suppliedOptions) { - var that = this, - options = that.options; - - $.extend(options, suppliedOptions); - - that.isLocal = $.isArray(options.lookup); - - if (that.isLocal) { - options.lookup = that.verifySuggestionsFormat(options.lookup); - } - - // Adjust height, width and z-index: - $(that.suggestionsContainer).css({ - 'max-height': options.maxHeight + 'px', - 'width': options.width + 'px', - 'z-index': options.zIndex - }); - }, - - clearCache: function () { - this.cachedResponse = {}; - this.badQueries = []; - }, - - clear: function () { - this.clearCache(); - this.currentValue = ''; - this.suggestions = []; - }, - - disable: function () { - var that = this; - that.disabled = true; - if (that.currentRequest) { - that.currentRequest.abort(); - } - }, - - enable: function () { - this.disabled = false; - }, - - fixPosition: function () { - var that = this, - offset, - styles; - - // Don't adjust position if custom container has been specified: - if (that.options.appendTo !== 'body') { - return; - } - - offset = that.el.offset(); - - styles = { - top: (offset.top + that.el.outerHeight()) + 'px', - left: offset.left + 'px' - }; - - if (that.options.width === 'auto') { - styles.width = (that.el.outerWidth() - 2) + 'px'; - } - - $(that.suggestionsContainer).css(styles); - }, - - enableKillerFn: function () { - var that = this; - $(document).on('click.autocomplete', that.killerFn); - }, - - disableKillerFn: function () { - var that = this; - $(document).off('click.autocomplete', that.killerFn); - }, - - killSuggestions: function () { - var that = this; - that.stopKillSuggestions(); - that.intervalId = window.setInterval(function () { - that.hide(); - that.stopKillSuggestions(); - }, 50); - }, - - stopKillSuggestions: function () { - window.clearInterval(this.intervalId); - }, - - isCursorAtEnd: function () { - var that = this, - valLength = that.el.val().length, - selectionStart = that.element.selectionStart, - range; - - if (typeof selectionStart === 'number') { - return selectionStart === valLength; - } - if (document.selection) { - range = document.selection.createRange(); - range.moveStart('character', -valLength); - return valLength === range.text.length; - } - return true; - }, - - onKeyPress: function (e) { - var that = this; - - // If suggestions are hidden and user presses arrow down, display suggestions: - if (!that.disabled && !that.visible && e.which === keys.DOWN && that.currentValue) { - that.suggest(); - return; - } - - if (that.disabled || !that.visible) { - return; - } - - switch (e.which) { - case keys.ESC: - that.el.val(that.currentValue); - that.hide(); - break; - case keys.RIGHT: - if (that.hint && that.options.onHint && that.isCursorAtEnd()) { - that.selectHint(); - break; - } - return; - case keys.TAB: - if (that.hint && that.options.onHint) { - that.selectHint(); - return; - } - // Fall through to RETURN - case keys.RETURN: - if (that.selectedIndex === -1) { - that.hide(); - return; - } - that.select(that.selectedIndex); - if (e.which === keys.TAB && that.options.tabDisabled === false) { - return; - } - break; - case keys.UP: - that.moveUp(); - break; - case keys.DOWN: - that.moveDown(); - break; - default: - return; - } - - // Cancel event if function did not return: - e.stopImmediatePropagation(); - e.preventDefault(); - }, - - onKeyUp: function (e) { - var that = this; - - if (that.disabled) { - return; - } - - switch (e.which) { - case keys.UP: - case keys.DOWN: - return; - } - - clearInterval(that.onChangeInterval); - - if (that.currentValue !== that.el.val()) { - that.findBestHint(); - if (that.options.deferRequestBy > 0) { - // Defer lookup in case when value changes very quickly: - that.onChangeInterval = setInterval(function () { - that.onValueChange(); - }, that.options.deferRequestBy); - } else { - that.onValueChange(); - } - } - }, - - onValueChange: function () { - var that = this, - options = that.options, - value = that.el.val(), - query = that.getQuery(value), - index; - - if (that.selection) { - that.selection = null; - (options.onInvalidateSelection || $.noop).call(that.element); - } - - clearInterval(that.onChangeInterval); - that.currentValue = value; - that.selectedIndex = -1; - - // Check existing suggestion for the match before proceeding: - if (options.triggerSelectOnValidInput) { - index = that.findSuggestionIndex(query); - if (index !== -1) { - that.select(index); - return; - } - } - - if (query.length < options.minChars) { - that.hide(); - } else { - that.getSuggestions(query); - } - }, - - findSuggestionIndex: function (query) { - var that = this, - index = -1, - queryLowerCase = query.toLowerCase(); - - $.each(that.suggestions, function (i, suggestion) { - if (suggestion.value.toLowerCase() === queryLowerCase) { - index = i; - return false; - } - }); - - return index; - }, - - getQuery: function (value) { - var delimiter = this.options.delimiter, - parts; - - if (!delimiter) { - return value; - } - parts = value.split(delimiter); - return $.trim(parts[parts.length - 1]); - }, - - getSuggestionsLocal: function (query) { - var that = this, - options = that.options, - queryLowerCase = query.toLowerCase(), - filter = options.lookupFilter, - limit = parseInt(options.lookupLimit, 10), - data; - - data = { - suggestions: $.grep(options.lookup, function (suggestion) { - return filter(suggestion, query, queryLowerCase); - }) - }; - - if (limit && data.suggestions.length > limit) { - data.suggestions = data.suggestions.slice(0, limit); - } - - return data; - }, - - getSuggestions: function (q) { - var response, - that = this, - options = that.options, - serviceUrl = options.serviceUrl, - data, - cacheKey; - - options.params[options.paramName] = q; - data = options.ignoreParams ? null : options.params; - - if (that.isLocal) { - response = that.getSuggestionsLocal(q); - } else { - if ($.isFunction(serviceUrl)) { - serviceUrl = serviceUrl.call(that.element, q); - } - cacheKey = serviceUrl + '?' + $.param(data || {}); - response = that.cachedResponse[cacheKey]; - } - - if (response && $.isArray(response.suggestions)) { - that.suggestions = response.suggestions; - that.suggest(); - } else if (!that.isBadQuery(q)) { - if (options.onSearchStart.call(that.element, options.params) === false) { - return; - } - if (that.currentRequest) { - that.currentRequest.abort(); - } - that.currentRequest = $.ajax({ - url: serviceUrl, - data: data, - type: options.type, - dataType: options.dataType - }).done(function (data) { - that.currentRequest = null; - that.processResponse(data, q, cacheKey); - options.onSearchComplete.call(that.element, q); - }).fail(function (jqXHR, textStatus, errorThrown) { - options.onSearchError.call(that.element, q, jqXHR, textStatus, errorThrown); - }); - } - }, - - isBadQuery: function (q) { - var badQueries = this.badQueries, - i = badQueries.length; - - while (i--) { - if (q.indexOf(badQueries[i]) === 0) { - return true; - } - } - - return false; - }, - - hide: function () { - var that = this; - that.visible = false; - that.selectedIndex = -1; - $(that.suggestionsContainer).hide(); - that.signalHint(null); - }, - - suggest: function () { - if (this.suggestions.length === 0) { - this.hide(); - return; - } - - var that = this, - options = that.options, - formatResult = options.formatResult, - value = that.getQuery(that.currentValue), - className = that.classes.suggestion, - classSelected = that.classes.selected, - container = $(that.suggestionsContainer), - beforeRender = options.beforeRender, - html = '', - index, - width; - - if (options.triggerSelectOnValidInput) { - index = that.findSuggestionIndex(value); - if (index !== -1) { - that.select(index); - return; - } - } - - // Build suggestions inner HTML: - $.each(that.suggestions, function (i, suggestion) { - html += '
    ' + formatResult(suggestion, value) + '
    '; - }); - - // If width is auto, adjust width before displaying suggestions, - // because if instance was created before input had width, it will be zero. - // Also it adjusts if input width has changed. - // -2px to account for suggestions border. - if (options.width === 'auto') { - width = that.el.outerWidth() - 2; - container.width(width > 0 ? width : 300); - } - - container.html(html); - - // Select first value by default: - if (options.autoSelectFirst) { - that.selectedIndex = 0; - container.children().first().addClass(classSelected); - } - - if ($.isFunction(beforeRender)) { - beforeRender.call(that.element, container); - } - - container.show(); - that.visible = true; - - that.findBestHint(); - }, - - findBestHint: function () { - var that = this, - value = that.el.val().toLowerCase(), - bestMatch = null; - - if (!value) { - return; - } - - $.each(that.suggestions, function (i, suggestion) { - var foundMatch = suggestion.value.toLowerCase().indexOf(value) === 0; - if (foundMatch) { - bestMatch = suggestion; - } - return !foundMatch; - }); - - that.signalHint(bestMatch); - }, - - signalHint: function (suggestion) { - var hintValue = '', - that = this; - if (suggestion) { - hintValue = that.currentValue + suggestion.value.substr(that.currentValue.length); - } - if (that.hintValue !== hintValue) { - that.hintValue = hintValue; - that.hint = suggestion; - (this.options.onHint || $.noop)(hintValue); - } - }, - - verifySuggestionsFormat: function (suggestions) { - // If suggestions is string array, convert them to supported format: - if (suggestions.length && typeof suggestions[0] === 'string') { - return $.map(suggestions, function (value) { - return { value: value, data: null }; - }); - } - - return suggestions; - }, - - processResponse: function (response, originalQuery, cacheKey) { - var that = this, - options = that.options, - result = options.transformResult(response, originalQuery); - - result.suggestions = that.verifySuggestionsFormat(result.suggestions); - - // Cache results if cache is not disabled: - if (!options.noCache) { - that.cachedResponse[cacheKey] = result; - if (result.suggestions.length === 0) { - that.badQueries.push(cacheKey); - } - } - - // Return if originalQuery is not matching current query: - if (originalQuery !== that.getQuery(that.currentValue)) { - return; - } - - that.suggestions = result.suggestions; - that.suggest(); - }, - - activate: function (index) { - var that = this, - activeItem, - selected = that.classes.selected, - container = $(that.suggestionsContainer), - children = container.children(); - - if(that.selectedIndex === index) - return null; - - container.children('.' + selected).removeClass(selected); - - that.selectedIndex = index; - - if (that.selectedIndex !== -1 && children.length > that.selectedIndex) { - activeItem = children.get(that.selectedIndex); - $(activeItem).addClass(selected); - that.options.onPreSelect(that.suggestions[index], activeItem); - return activeItem; - } - - return null; - }, - - selectHint: function () { - var that = this, - i = $.inArray(that.hint, that.suggestions); - - that.select(i); - }, - - select: function (i) { - var that = this; - that.hide(); - that.onSelect(i); - }, - - moveUp: function () { - var that = this; - - if (that.selectedIndex === -1) { - return; - } - - if (that.selectedIndex === 0) { - $(that.suggestionsContainer).children().first().removeClass(that.classes.selected); - that.selectedIndex = -1; - that.el.val(that.currentValue); - that.findBestHint(); - return; - } - - that.adjustScroll(that.selectedIndex - 1); - }, - - moveDown: function () { - var that = this; - - if (that.selectedIndex === (that.suggestions.length - 1)) { - return; - } - - that.adjustScroll(that.selectedIndex + 1); - }, - - adjustScroll: function (index) { - var that = this, - activeItem = that.activate(index), - offsetTop, - upperBound, - lowerBound, - heightDelta = 25; - - if (!activeItem) { - return; - } - - offsetTop = activeItem.offsetTop; - upperBound = $(that.suggestionsContainer).scrollTop(); - lowerBound = upperBound + that.options.maxHeight - heightDelta; - - if (offsetTop < upperBound) { - $(that.suggestionsContainer).scrollTop(offsetTop); - } else if (offsetTop > lowerBound) { - $(that.suggestionsContainer).scrollTop(offsetTop - that.options.maxHeight + heightDelta); - } - - that.el.val(that.getValue(that.suggestions[index].value)); - that.signalHint(null); - }, - - onSelect: function (index) { - var that = this, - onSelectCallback = that.options.onSelect, - suggestion = that.suggestions[index]; - - that.currentValue = that.getValue(suggestion.value); - that.el.val(that.currentValue); - that.signalHint(null); - that.suggestions = []; - that.selection = suggestion; - - if ($.isFunction(onSelectCallback)) { - onSelectCallback.call(that.element, suggestion); - } - }, - - getValue: function (value) { - var that = this, - delimiter = that.options.delimiter, - currentValue, - parts; - - if (!delimiter) { - return value; - } - - currentValue = that.currentValue; - parts = currentValue.split(delimiter); - - if (parts.length === 1) { - return value; - } - - return currentValue.substr(0, currentValue.length - parts[parts.length - 1].length) + value; - }, - - dispose: function () { - var that = this; - that.el.off('.autocomplete').removeData('autocomplete'); - that.disableKillerFn(); - $(window).off('resize.autocomplete', that.fixPositionCapture); - $(that.suggestionsContainer).remove(); - } - }; - - // Create chainable jQuery plugin: - $.fn.autocomplete = function (options, args) { - var dataKey = 'autocomplete'; - // If function invoked without argument return - // instance of the first matched element: - if (arguments.length === 0) { - return this.first().data(dataKey); - } - - return this.each(function () { - var inputElement = $(this), - instance = inputElement.data(dataKey); - - if (typeof options === 'string') { - if (instance && typeof instance[options] === 'function') { - instance[options](args); - } - } else { - // If instance already exists, destroy it: - if (instance && instance.dispose) { - instance.dispose(); - } - instance = new Autocomplete(this, options); - inputElement.data(dataKey, instance); - } - }); - }; -})); diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery.history.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery.history.js deleted file mode 100644 index caeb7aa4b53..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/jquery.history.js +++ /dev/null @@ -1 +0,0 @@ -(function(e,t){"use strict";var n=e.History=e.History||{},r=e.jQuery;if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");n.Adapter={bind:function(e,t,n){r(e).bind(t,n)},trigger:function(e,t,n){r(e).trigger(t,n)},extractEventData:function(e,n,r){var i=n&&n.originalEvent&&n.originalEvent[e]||r&&r[e]||t;return i},onDomLoad:function(e){r(e)}},typeof n.init!="undefined"&&n.init()})(window),function(e,t){"use strict";var n=e.console||t,r=e.document,i=e.navigator,s=e.sessionStorage||!1,o=e.setTimeout,u=e.clearTimeout,a=e.setInterval,f=e.clearInterval,l=e.JSON,c=e.alert,h=e.History=e.History||{},p=e.history;try{s.setItem("TEST","1"),s.removeItem("TEST")}catch(d){s=!1}l.stringify=l.stringify||l.encode,l.parse=l.parse||l.decode;if(typeof h.init!="undefined")throw new Error("History.js Core has already been loaded...");h.init=function(e){return typeof h.Adapter=="undefined"?!1:(typeof h.initCore!="undefined"&&h.initCore(),typeof h.initHtml4!="undefined"&&h.initHtml4(),!0)},h.initCore=function(d){if(typeof h.initCore.initialized!="undefined")return!1;h.initCore.initialized=!0,h.options=h.options||{},h.options.hashChangeInterval=h.options.hashChangeInterval||100,h.options.safariPollInterval=h.options.safariPollInterval||500,h.options.doubleCheckInterval=h.options.doubleCheckInterval||500,h.options.disableSuid=h.options.disableSuid||!1,h.options.storeInterval=h.options.storeInterval||1e3,h.options.busyDelay=h.options.busyDelay||250,h.options.debug=h.options.debug||!1,h.options.initialTitle=h.options.initialTitle||r.title,h.options.html4Mode=h.options.html4Mode||!1,h.options.delayInit=h.options.delayInit||!1,h.intervalList=[],h.clearAllIntervals=function(){var e,t=h.intervalList;if(typeof t!="undefined"&&t!==null){for(e=0;e")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/leaflet_numbered_markers.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/leaflet_numbered_markers.js deleted file mode 100644 index 2ab1983b9a9..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/lib/leaflet_numbered_markers.js +++ /dev/null @@ -1,30 +0,0 @@ -L.NumberedDivIcon = L.Icon.extend({ - options: { - iconUrl: './img/marker_hole.png', - number: '', - shadowUrl: null, - iconSize: new L.Point(25, 41), - iconAnchor: new L.Point(12, 40), - popupAnchor: new L.Point(0, -33), - shadowSize: new L.Point(50, -64), - shadowAnchor: new L.Point(4, -62), - className: 'leaflet-div-icon' - }, - - createIcon: function () { - var div = document.createElement('div'); - var img = this._createImg(this.options['iconUrl']); - var numdiv = document.createElement('div'); - numdiv.setAttribute ( "class", "number" ); - numdiv.innerHTML = this.options['number'] || ''; - div.appendChild ( img ); - div.appendChild ( numdiv ); - this._setIconStyles(div, 'icon'); - return div; - }, - - //you could change this to add a shadow like in the normal marker if you really wanted - createShadow: function () { - return null; - } -}); \ No newline at end of file diff --git a/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js b/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js deleted file mode 100644 index 2a029de39d2..00000000000 --- a/web-bundle/src/main/resources/com/graphhopper/maps/js/main-template.js +++ /dev/null @@ -1,1002 +0,0 @@ -var Flatpickr = require('flatpickr'); -require('flatpickr/dist/l10n'); - -var L = require('leaflet'); -require('leaflet-contextmenu'); -require('leaflet-loading'); -require('leaflet.heightgraph'); -var moment = require('moment'); -require('./lib/leaflet_numbered_markers.js'); - -global.jQuery = require('jquery'); -global.$ = global.jQuery; -require('./lib/jquery-ui-custom-1.12.0.min.js'); -require('./lib/jquery.history.js'); -require('./lib/jquery.autocomplete.js'); - -var ghenv = require("./config/options.js").options; -console.log(ghenv.environment); - -var GHInput = require('./graphhopper/GHInput.js'); -var GHRequest = require('./graphhopper/GHRequest.js'); -var host = ghenv.routing.host; -if (!host) { - if (location.port === '') { - host = location.protocol + '//' + location.hostname; - } else { - host = location.protocol + '//' + location.hostname + ":" + location.port; - } -} - -var AutoComplete = require('./autocomplete.js'); -if (ghenv.environment === 'development') { - var autocomplete = AutoComplete.prototype.createStub(); -} else { - var autocomplete = new AutoComplete(ghenv.geocoding.host, ghenv.geocoding.api_key); -} - -var mapLayer = require('./map.js'); -var nominatim = require('./nominatim.js'); -var routeManipulation = require('./routeManipulation.js'); -var gpxExport = require('./gpxexport.js'); -var messages = require('./messages.js'); -var translate = require('./translate.js'); -var customModelEditor = require('custom-model-editor/dist/index.js'); - -var format = require('./tools/format.js'); -var urlTools = require('./tools/url.js'); -var tileLayers = require('./config/tileLayers.js'); -if(ghenv.with_tiles) - tileLayers.enableVectorTiles(); - -var debug = false; -var ghRequest = new GHRequest(host, ghenv.routing.api_key); -var bounds = {}; -var metaVersionInfo; - -// usage: log('inside coolFunc',this,arguments); -// http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/ -if (global.window) { - window.log = function () { - log.history = log.history || []; // store logs to an array for reference - log.history.push(arguments); - if (this.console && debug) { - console.log(Array.prototype.slice.call(arguments)); - } - }; -} - -$(document).ready(function (e) { - // fixing cross domain support e.g in Opera - jQuery.support.cors = true; - - gpxExport.addGpxExport(ghRequest); - // we start without encoded values, they will be loaded later - var cmEditor = customModelEditor.create({}, function (element) { - $("#custom-model-editor").append(element); - }); - - cmEditor.validListener = function(valid) { - $("#custom-model-search-button").prop('disabled', !valid); - }; - ghRequest.cmEditor = cmEditor; - ghRequest.cmEditorActive = false; - var toggleCustomModelBox = function(sendRoute) { - $("#custom-model-box").toggle(); - ghRequest.cmEditorActive = !ghRequest.cmEditorActive; - // avoid default action, so use a different search button - $("#searchButton").toggle(); - mapLayer.adjustMapSize(); - cmEditor.cm.refresh(); - cmEditor.cm.focus(); - cmEditor.cm.setCursor(cmEditor.cm.lineCount()); - if (sendRoute) - sendCustomData(); - }; - $("#custom-model-button").click(function() { - toggleCustomModelBox(true); - // we only show the gpx button when the custom model box is closed, because the gpx export does not work for custom model routes (#2635) - $("#gpxExportButton").toggle(); - $("#gpx_dialog").dialog('close'); - }); - function showCustomModelExample() { - cmEditor.value = - "{" - + "\n \"speed\": [" - + "\n {" - + "\n \"if\": \"road_class == MOTORWAY\"," - + "\n \"multiply_by\": \"0.8\"" - + "\n }" - + "\n ]," - + "\n \"priority\": [" - + "\n {" - + "\n \"if\": \"road_environment == TUNNEL\"," - + "\n \"multiply_by\": \"0.5\"" - + "\n }," - + "\n {" - + "\n \"if\": \"max_weight < 3\"," - + "\n \"multiply_by\": \"0.0\"" - + "\n }" - + "\n ]" - + "\n}"; - cmEditor.cm.focus(); - cmEditor.cm.setCursor(0); - cmEditor.cm.execCommand('selectAll'); - cmEditor.cm.refresh(); - } - $("#custom-model-example").click(function () { - showCustomModelExample(); - return false; - }); - - $("#export-link").click(function (e) { - try { - e.preventDefault(); - var url = location.href; - if(url.indexOf("?") > 0) - url = url.substring(0, url.indexOf("?")) + ghRequest.createHistoryURL() + "&layer=" + encodeURIComponent(tileLayers.activeLayerName); - if(ghRequest.cmEditorActive) { - var text = cmEditor.value.replaceAll("&","%26"); - url += "&custom_model=" + new URLSearchParams(JSON.stringify(JSON.parse(text))).toString(); - } - navigator.clipboard.writeText(url).then(() => { alert('Link copied to clipboard'); }); - } catch(e) { console.warn(e); } - }); - - var sendCustomData = function () { - ghRequest.ignoreCustomErrors = false; - mySubmit(); - }; - - var sendCustomDataIgnoreErrors = function () { - ghRequest.ignoreCustomErrors = true; - mySubmit(); - } - - cmEditor.setExtraKey('Ctrl-Enter', sendCustomDataIgnoreErrors); - $("#custom-model-search-button").click(sendCustomData); - - if (isProduction()) - $('#hosting').show(); - - var History = window.History; - if (History.enabled) { - History.Adapter.bind(window, 'statechange', function () { - // No need for workaround? - // Chrome and Safari always emit a popstate event on page load, but Firefox doesn’t - // https://github.com/defunkt/jquery-pjax/issues/143#issuecomment-6194330 - - var state = History.getState(); - initFromParams(state.data, true); - }); - } - - $('#locationform').submit(function (e) { - // no page reload - e.preventDefault(); - mySubmit(); - }); - - var urlParams = urlTools.parseUrlWithHisto(); - - var customModelJSON = urlParams.custom_model; - if(customModelJSON) { - toggleCustomModelBox(false); - cmEditor.value = customModelJSON; // if json parsing fails we still have the partial custom model in the box - try { - var tmpObj = JSON.parse(customModelJSON); - cmEditor.value = JSON.stringify(tmpObj, null, 2); - } catch(e) { - console.warn('cannot pretty print custom model: ' + e); - } - - } else { - // todo: the idea was to highlight everything so if we start typing the example is overwritten. But unfortunately - // this does not work. And not even sure this is so useful? - showCustomModelExample(); - } - - $.when(ghRequest.fetchTranslationMap(urlParams.locale), ghRequest.getInfo()) - .then(function (arg1, arg2) { - // init translation retrieved from first call (fetchTranslationMap) - var translations = arg1[0]; - autocomplete.setLocale(translations.locale); - ghRequest.setLocale(translations.locale); - translate.init(translations); - - // init bounding box from getInfo result - var json = arg2[0]; - var tmp = json.bbox; - bounds.initialized = true; - bounds.minLon = tmp[0]; - bounds.minLat = tmp[1]; - bounds.maxLon = tmp[2]; - bounds.maxLat = tmp[3]; - nominatim.setBounds(bounds); - var profilesDiv = $("#profiles"); - - function createButton(profile, hide) { - var vehicle = profile.vehicle; - var profileName = profile.name; - var button = $("
     

    Rz%_0X+YO=z(V!a3h>j|{h55)>$HY$Sm(NQSA z=Obu^p2gF-XpF9^6aA?6S|$2!*CCJF0@hc%s6cN|S4;yKFBQmKm7vmEln#NS9Ek}Z zITy#`i+EBLglt?b)J5gj5Wj(%HXr>a^&oZ~6m#Ai>^KseZeZwQ-^6u)#a!?mZl~)p zkiq&DH|78DFxnP5phuvBZlNPkda4DuZOpP^A(Vyn#9)VTFq6ARMw{Pdf6iW?@jvueno*V-vIud%q|^zno3|3LdMetSFL$#?K=eH-7(xAaYY6JjjovZ}*usNyT2a4!-$ z4T`bEY4|Vh$`9dG^G}Ek_fi$S&1dwtiiPeSJ%l&&{AQR3a$Hsnb_a@hx$*t!eRN+w z<#vCx}^K=q&w%XinZXb68T8OwBMa@S43;~>3mlI zpnuc`x!>F@$SCx!V{R{1xNUA9BzE=x9kHn|q7^&uF58ruVRvPN?tUL+)QoWs*I>F| za@S%`?gI74gg|d$^hSDCrX14;^eZ zangL^q6t(ASK~#PbPX;;)usH{DyU)WdA^pOfbVVDtDrs1B2t}5-@sh@3`g7YMdg$` zj0otH+&JDz81OyOmnT$rMOB@Nw?4S>yai;e8uSyYi|`$LR3XAroF#=;DOVKV=loDa z3q-}cm<%G0z69U>WoYlu+8`~~>o!&~SI*U0LZ27`a<3%o≪&vvM-&1B3+HNz4(=F??_y-zeMZakFApT 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 z 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%0AJM+%8e%{so_X)~?t90!{k|I~ZUv7jBcS$J- z`syrtSH?{IlP6LFQi9op3jCruBOY}2)k51#C<{T>LAQaq1v1iZmLyTuOx0QrOQ_*!b;N? z``!HlAJpP2i_uND`#tn3D zxc=^S*VpxQopFkO+SSLAu&L|j#<@@3*Sf}1x5#}ZQ)G~ImlyHX=qxSdS!svXXgi%c zzzJ$DE#*1=)Ef_uSM*z3$~5|#NgMsH70A{G^03sE`(Op#L*1~N)R#x3hExJs8fpZF zfGk8tpE5TS@hn`|Z+{T*f@7aDB^Rc!(rhD55+*BudTgJf> z?;%gXXl#gIUOO^zt#z5VWRfh9MKVo~pu6sIYw0GVbly7e==5^vJpycqStQJK%A z{ooY_h4&Z9Vuc8+DISAQp_^o02(|J2tQ=#kyQmJ{j?QmIqO1z!vF`D8FZ17M;-4Xt z)eM#QX83fpz;nH;e+AWm*Yvkv1CjLxisPeV9AN0B4^Sys0(#N7w|QbK8QQFc_K``b zf*LPyf_x;4Wu5Gi^Ts2TblE4r%UYfDjeMd#q_?(6OLUpq;45Aa^`V=w8nrZ4)M~Y=!P^UBI73$8%>Rx5J}|M#Q59e zBg%a&D6ny8WA)(P_n3cx_Uf$r@-ADO3eL+^z{h}B9iyKsHnESf1c|42%W~sbeSj1wDz+9eH+ZsoSc-7^#99+5>PJE1^|Y0~FLXum|&#+44MLo7(W9OuvRB z(f#V6zB>^Wh0jEe@mb=n4DwxRXceD{dM@c)=}-EL`py)KEhlC5z6;vBO+ChHgV%xz z@aFqyRY&q-$Em3EE=LVR^0vo;ry=x1XVN}^6y zP!-Lh3;&z5%7}Tdj2K^?j$SmOx_2g`+5__HY^?uXBvU2Cm`Rj;z;I=aIIkR_<+DVj zd?ILpqo|Pd)=Uf zSnj+a+^>)N`!_^&`)fdDRf0MG0Q!iPeR*HiKjK^ZcD|W^9G8eL+BYU^FZ^9c$aykH zm%v)3n1d$#_RaoBo>Q%cJx_b=r}}w4an~|9JRgH2or?0p5-?V#e>H-8lxhET&|cO< z``j?R4(I858+oR?sAK6Sbc`$qQyb0FTrfZO;%@gBSmdwt_oiwOeGVnJYAEF1f>&k< zRAloJ5t$-d34fcfK|QdQe?pJ8iZ6#M!@YW><}_v~#KFG3e^SpyS)WtS_AhRwTkd|; zHaOzawddqSxwbHMzT4o0Rl?WORPrD6cl)cg*Zre?cPH`gUbIX%pnJ7SUzU?RsI70# z2ZA2gDfqS9+#0vQ&2h8ceD^;$&y7c$^mRAL4Rn2757*hXbkDd3uAXb<+PN3q8*Y;O zLbrU7{=ZMg$s5v3dP)!S{H=AeY)}t;Bs$3RI=v)ab>0iG4*T#;H+(r>L-VFR@m07k z*VXAkuAeofmj0~`()LcNBvs`OI83E^a=jW3P)R9)W?*rc*~yxrRWXXk`0IMmRh3Z& zZ3eq(sJ?pejQza6pD6voSDDtrVwohpbzka86q~J=)Q_ePbK`BwOX69F`sOi>#DSby_A1 zbRW8D4{IjR=suZx&W(8J9nc=Xnp(nq?O&tf)ib#0yoR4fSGe2esSzTqCQ@+mEOib)h=+AbHIPP`D~fmDqIeOh>o?*??o*t2XOs{F~_NPck#>h$4Q4HLx00 z(Ph!sd0x~_2{;J9^KYVFF(AfSA**HI4b6Q ze>xGR{Rw_1S`mhRmsI#R< zMVsS9TY|nx3R)&Pv{mnv2J$3YyG>AgeG*NDS~_NHpqWq&O*^X#*8_#wUdK>h9Zlw~ zvq(OdFZ8t(Hp4s}8TM@RjttY$I8X*_>rc?WVv1OObOc(|)en#5$B3}Zefdf48#Y#q zLvtVKf{Ij*3z7NFf-1skxDA%e+|B=c@EZ-j4hO*pn)2{zD#|CxWW~%Cp0YuiIGxI2 z8g8Vgx$YZE{hVu6BSkIquIPYYt02WWqjQ)Vjgxe_dCmFjY4N7Fnukq zdNZs$@)*jD|w=V|y=`WvxQaDviqKX(E>J|C!71>p>&+ zT%5ppkuge%k!AMixtKemy@IkuF0kjpF-T&5?Hu*O%e@y5gMi-)V{j8LEb(YC=+AWfz5KJjk$=)R_SJnwJ%&>881tfTmYeL=b$X;#d_DcmK6*TT zeG`8_I-#al(#&_$qnx6nshe)e6yU4)QhFBGyRY3cw?ooQ4ELTJ>H4_luAzI-)pO6e4(?U`ZYC8+<0a!WBaC_F zn73J1;;ol>*GJxxUd-vI%e;fXTz`3u?_VH)WjU^v(GexYTIMHK1Kq<)WP&Qd62Aqd zqf&C6wuRwcuh0BcjEq&0h|wy>ch})!W_)u~T4*dCbU&ub5}7aW%F8%_Oq2yOPhTJD zyzk{xo&Tz|)#c5*>}44%v*ZIkwgEbS2K9}NvQp;A$GXmJd0(dE^)XAv>+y7u$K*a; zv#GS!V|rER7^1r)X#aN7SGP4^*2)pn*p%~fK>n5;vRn4?6#p>@uQ4)2&rx$da&wR_ zEGgR0Hu|679L*yd7z65J08gO3(FpB~CRQslPEFxvKaL7vJv?-b36xZHzMZ%#{H=i6 zZ+V!zl~H=O`*uD5SoGuw&a#gaZv{+7E5>4b9Va$**0E{a!lZ)304n+8b>!H%`vMNz zdcR9YP;serpKZ z3TfqG%m;TQb5F_{_4|*36WD;>?@#_0a#j{ItYv%#@4;m->=uA(4?Mn9YJ*c^EiNFg z#>6R!Z68Y16k?}AdW-`yb-~_VpGh?g~{2djyHHNC{yVUOjzG@;<5=%dx z81LN}i;ar$)jJVSKZ4xY5Z_(f;7KqD_xT3Cjh_2q`hDOqPAA*ZU-x7jNUtgI&@A^g z73`N)4VQzg{+4>-SD79@D`~5BsAcVfU3eJRs1rmV$MG_>98k#r7-mB7lDSvMQyrF5pD|p#emZFiVj#D2 zOFqNf>w5d)uUnjTNw>LG``|{ay6V>K>;{D3In=JL;%M06Rd^B3qNR*uHJeztkx7*hJ(OoS?>%=YQ202>$MpzlKei-szmog));K7(bYTxHYcdJNLgs@*s zdN3yIk!exqAzA4=7!}}ma&ESx$Z#~OF`S7RuftJ8>>u#`r_jR6Fb(&J(syy|mvAM% z0+hQ|1xxs=s7?hPu;Tc5mp}{3v>R^o<^A2-)(w4Y-&dz@)XwIS_5Q;DtRuu!u>SCe zQPwqXwy_EK8?F$w$ix0m?Rg(@9a{{#^Cw+z8VIXJXj^@$Tbcl3*Xo1q@cA+n*4yz( zVJYg%EA+Q^=?E$;x9T{qE;mad9YH7J^UpqXp?|@vcd_>S;l8bJ?mMClXc(%>zMLM> zm7IOk!@U}H3Uh?2>6_|Eu=>C_J+_7@!!^`-9d%5Y8(DXKUzaHDMxWE|1AYFv`^tUq z*13(^TMxn3JPXb(uP#%`KLk?wIUPN{bT4Yc&@|`E|LT^@`CL>D|G?j9hql#8s>H{% zU4M6L+zR)ZTgo&K?W~b*fP2dg*4L{zL=SNzz_fR9&$xQ-A@{g@&b4+OU2iu`mtLgX zIHzs+A9+tk$zZ%%`+&5uSgN-SjLsMRcs_kYKabHRr^>s`?}mF=XX!!|))D86r%`aI zCv~L`@l|zP+wM=u|8eylU{V#?_f@w9$w@F^SP=zX35ud(K-dLQL1l3P z2?~g!z=9wkISpxGWXKtY3=)PkM9DeloTCJR0cJ=;{GWTOy7l+}-q+o)yI-uj_1=B= zo_kJ4c>#S_PHLg|$Dp+q%Vzqq6J-E%uIptN+I}zE@~|9}eX&!cu=V9$akE>@uYH7@?Cs~X8hPY#&kU1P0 z{J243zdjc@B=}c8cI8Vf|LmiNJutct169BqHb#YT}~elR`nKFllW zmirRfJcOJ|sth)RSG8s2cwZj$dgfC{a(mz-Jxz7!i{!RYovADKJUx^@@Qdf|)%ev@ z7+G3>QiNK5?~~0z)r&qO9$mRsUL|j*qS6bqPDP_w^@v~ZB7I~u)pV5QY?utjI2kIV zFj7=wXA;K99E_4pu#$D;nVkSjnTjzuKzcBfUXAJy|DsJ4qEg3e%&9-cI+yHZXi&zg z`{W!>V~zRsp!;{4=W-O&aq7RHAtzYmY*U#Pd_WA>Ei%(8%H$-^{5JFTs^@qCwtYky zfS5tK6|_(91b^#NU|i5@&C`rp9kUzl4!mnb>^Oc^@9qkfK+dpL|HRhzuzpbWYey2% zK9P(aTA`{r>|q@7an$)9X{R#dyT)#?>#)vJyU->wdO0wluewp=Duz!3ad@?-H`S8L z?M=u|tO!eGWKr$kdVDIYN*=6Fs1U7{$DU)cw0*}GwlCTzZT8?_J&bx-9^-vCu&HOJ zMd9L^q?DDv!rXA7yATM6cie8{d2?8Bx`jN{RY5Hv;$k^`P@}J6bb% zHz2VbBUtKVWe=RDxr2_Q$J}IRU0*uSpb(9--Qk{70#oV5sE>7?>_{gRh|># zCOy6goBTB%&)p~%EFB|=kMi6e;kT?IOZE@4*FP3;S^3b11<2@Lke?;UGg_P8bsboR zUf~k#e7nt_AV=tRjG9Z#QlDV%Jk2Htro0TSrcEIq_H0h20%V3L}@IIPMiKEFn zt$FWZ*tRmTHKT8$9##j~V{bdk&Vt>pvD-1WR8vBkAD$x{(<_pdsQLrUKpe6M1Fy~s zY;6$ix&?6&BWxdRsiCdR3c`Od3;Hb1tT4~4T;OAlV;p}ZKI_1iH49UpI@Uul9%{kb zOW2ofZuI9l*xXj~F03^>$%t{5wG|iH-gnTd&!El9*qT_sHL;4Vm|y&e>Yr8cYfbD~ zs|$}Y#(I^J&h+Hoy@suygoST1i_A1L-i$E)O+5Xp7}LqLH=Ru@)7Uh{)B>O1n2P30 zdRO(y(C`bE>0_pt_1MN;`=m^ekN-rGt$=_&*9>mZ526o-EY%Osg1qcIml zF2WXEN~^Pfq;{d!i+zcyBC+lsjpcb9N|7_`z3_ZoL|&Cb^Y9+mf_3PkxdIp|(MFEYI<+4|H$O0KgKC20`N{-0|IV>Awwv3T3QWtyw97oj& zOHW{wYQD^sHCXDl%jPmVp_bZlS&6gJs9hVZ6N5APnHi1&GG1mf2R2uR;`~S8%!kS} zZ2hdWF0ae2>pO9I+_UZ}_qfa9(n*?JW-M!#B%rN+rsi8d$;Ld`DZ9lkwn?n;AI+zN z_C#Sd=T))+YYD#%9#&P>5>^a~=^qDv_mUw~_y+NTuLU)Q!u%|1-?XKu534$`6@tQ< zMzgBW!>W$0e$COSoDM%=f0|L(EMXhlF(5tq(OVcs)#2s#Fh(Kkw=g2}p})#XWoazK z(T=L-yq-2N9POs8qpR`DLbUoqwB;7Gu-;Wip-`|Iyhk#NeFE;QchuAB z5g0nYMXyw#-rVQtbFDk*%_m7;_o&)Ro|C^f&a5B(y#c&yd-X((E-Guo61I@)`6%Px zS|Z-}kQ-K`J!gq%`y*(jpP_$sRkLUIA@w=45tF41uaC3ZP%)ADIUfH>y#wV>P~2ky zKH(H0gVk3U-%T*qd!grNV)SiCUoVu&u!26++L=z>!fhBaYcMiT%Aax(V{J3W!%A68 z3mF5OXhn8Cy+VA%oZt&ovC`)$t=N5*>~eX?LY#>nc!UMdu_jlw7}ftd$!Fuk%!Xdz z^e4TiKbhIHtWSMNmc{eLq@6??C|}h%a*ycse=pWermrcibh@C=_Sl2sMl?&kn>?Zi z7!BM{2C|*7P;JS*RN%fqpYLE`biaVDZ70%w7UPcN7?0}92xtN|0Y;M1U3+yf`f)+< zua?oalVI25(A$0a+~s4e-H0e2KrVQ-otQ9A+t@~-;`lq}`#?9VlqKM_Jo4QT z_jN1qzF(l<>A9{>(*r$CjQg3O#;E?@t*A22-Qb&DC$Fnx1T7=^D6)}{K3h-#QuUvw zs2HSdtGRLis%n+J`P`t)GIKF1 z&PfKc>J{W&`d?H)Q2nSg*xw2={%j|LR-^8VsUnqRmlKgS5f=T8{m8zFGkcxP^_mB) zWNX^m&OK4WSPF_wzh^yr=QRLy*Vd5w!cL|-Z6!!`8r zHnYG?G{ejwGZ51VOk?nU96tM*9;UTvY<@I#OjT1EpKVPyY83urI-4#g&I~tmaCAq^ zO>zo$WiGG>)sL0^W&krmlki_J86=Zs79;jcF)Vb2+elI~}Yf-$45EEX6&$5N27_}usSNRupV|u8LdB3XtVShvk9}`Io-9RU zwI;t#FZx%bqTB;h>^zK$Q}$-y!p<*mqbF;lWo8h0vsUKA7SuZ0QBP&5%$4!5ic!oT zYFr~h`oT7uV4ceHG5Y*1Mk}8sXTW1*Wy)ah+GI}Z2^^+|^Co8NS204pBxuF>D9udj z{b}rKJn>Hn(cGMm7)6l5aerfD=owJ#y`tzVpCOE)chw;<47Cef_nM7q&&Za~n0DjR zT>~n<2cucuYx8lbe%xa`zx$|Je2AGvaLSS6iI4hNu^8d?iAz!rBGoH$OuyRIBAo^?`tNxQ%^*I-n1Ns~E=Y=TZx!JVu6KbgdwF z`%#RgSu#T6Ve3QC=L;}aPGH2W!|#8(M=?6G$X)pZ<8lqgjxssKOKY<0Rid7$*1Z&B zCE@erUwN5TF!@>Yl84L<89gf&^=Q(l?0${k)zi|<;SsXhUty;1f<4dp);WChHHK+q zZn(w#^GSOQlVWaTc0YEcWX=8SEr$5j>MyaHaTAzzVE>TvY) z5IwI$!Sgy97@-u6m26VD|GPm8(KCJCV8rQ8I5G+Go%8_}6^SO@`kQ}sg?tFtqN+Hl zfn6b$-){wUmiKrdz0 zghA{aSw)p!>=r8-sS1R>`e<63vXwJ#n2q_dJY=x|eq4Hp99eGJU zmucMPEA)Fm`y1m-L#brC5!S60A*ac$a}&0I6LYF1GJ{X2b1{F$rjZ%$64^f|6XiLI z^%8>u?smG3XFY{JImR%*(Tv`EHCS6S+sXFj^YauJMR+<&Bu zmPDCP7Q%tj7yl?esROfTnk7^;yfUS0BE(tTk!|?4QBKHBXCzq; z$r4GBmQoi-rmASIr9X~(ne3CRa$7E8t(@)^_YBs(j&(N4bZXsB<2_;(&UBbeWTfjH zwtZhx?wN)7I(%b8^_=FxziL2Mh1vm|UMtm0t7(Z*p+NAExtdHY;dj?}7Gsz;i zo3*@J)vhSU&(QV>XqSz6ZIL->)3&V9Y{zKd1lUY0&N`m)zIet2e+m2yo@Mq~-Zyhe z1|qE;xkNA1yE<);F+Zr7lvU(tUmCK4-m{t(ysL?U@9O`uwD$=p_FnX7V(Cf62DLVS zr}~xH;Yeg4CRA~@qgT}?@Z7f{(xokb^&VCXm-llqL}~eL_2%AmuW|I^dIh$JczRzE z28cLD&Uyu(EI#;MssY{9)(vdL@1u|E1XZJstmagvZ#{B{5!owMuz%o%E2g=y}yA+=y|rLFU3D;-w3IAB-`xSa!)~D(W1TJMIxD z7>y}%kQ!7Iutco1m*&*qs)^BDT8hit)C4TVjAS9|BNm~WU=FeiX9|dX%Su41Wr?U) zNWbX{?m`i3(@doS3 zk7KD@ygTfNEoz2(9huqp(8HQ#S7PmR#I|oDkI50Nzn6E7HQ3q_w)74xzlxO@${#WX zqiP`QM~2Y9>Iu7@MI_x)sv<3A^+F<_(<8MM@geT1Ty?4xI+bH`A~EoBjC?DfXkGg? zMs!26GE~PX|1UKizM(F}H$icy0&B1e+kA{+We!~EE})*$qIf6u0q&A7AYHh-sG7_r z`ah}kY^+J80*+TcK1ko`XoyH1`BD;N07nne z^L{;K^`O@we4IG;=jahUNmNoc#?+p%ukfl~98)RkJ6GZJcTMzgb6ChM@>Z#Kz`TDkJW8tg{X4YRq5bt+BAEZgx1;(uNZ?ub8e_aw;gA zMDx$J>EpDtU9tQeY-b0rFGsNbG}fbO#r#cXg|>e`mef4jWW;=G#7}Of~K2>>Kto<_MeHHdMz>z_Bf69m)iZwwCxu^N_FDtc+1! zqkpyAY%`m&#pPzPS!!084Q3~mrPq?heHW(P_`cR8nF*$!X>aP9D&%jkZ`zo_RFIB0 z0vC*3Qc&nTOWVy2S=kg_*IJJM``%Hp;b%@5Wn&PuT zR0FmO>j=N(Q>n(F)Jyu5QUCYoVQGf2a6nK3`=wV=SDscO(~iM&CuBc9Z$CTh_~FSuG=} zilX<*2I%>&Xlcy}{>=Fpw0&d7GBs=bxs*b`zR2j6#;#mY^uA4$@HuTcaLl0{$ z^MVVR2TP)-HK@*^hscxnv^;h=hM234oH|6k ztJcI3wJocI*&gCU)GWdP5gV-tiwk~MFGls7 zqc5tXSIeQVN~6CuhSdc7)&JU&f4>oH5Smf5y9fEZN0Ff`o|>zZnPnbt6R6XzEaA(D zR@)dfj&{Pj^oj8VQA#JMU$~wAz{!BnQdOPXH)rrk@*2J?X~&5 z^gTK8zQt(jg;A9#vt$m&(n6VzF*SlpNbO+@ePukx&r1BOxxzifIG&VK7?npcvX;m= zUNQPgEVG1Fq#Uf`eJP7cd5M+ZPHSP_q%w0}$x1zk3{)G{$uN?dJ!t1-kVl9=Po_t8 zlz1s$ZFq|4tZVeH9tn}T?950M+?#Jrn$SW(Xtt&yL3v;ZMI7MW_4tmG`YYf0yT~ zG6AQ5hx}a;l#`Dt{e^PB%B@`uuVngjsr10^M7iT12}}*?Ld9Z4nI|h-%PUUjVLT}t zV_ca-O`~VZ@(MdQm`6QNtwmpLcm>})iY+ai$vw7jMn=ifF@7e2?MrJ1pJ1fwMfzAz zu;w5q*%=Dk;>`7G4&!t5bVFVfTF}$ceAzPC>?vCAR*Zes)Y<^sy+KCav((De=ZdYc zF|Ei^#=|AB+gVgan+$tw!sv6beH`vXz{>}J(qK##)PxVNC z;x$w?3cC`KI-Gg--=b<{6B)^!L{)?hRwxJfh<%s4Euo%%W}%v>zLl^Q3i zbfP&P^{*z#XimfN`$D3)6J;E}4U_&7PqqX_#rMQqH)$J~v>H%X<{MTLekuPYt4`&B z%=&`pcSUBsPo;XjrWU8B$2(*WeVtP=<_-(<+4cje$IQfJ98;_`$F>`g=W>qhkrbD~ z<)-J8$7OOE@&3HaE;r?vti|yvJAHpil0{f^sLYbha#Sv3xuWh}SI9l-j9ilwvQgH_ zRyiWKBw2Q0n@8j@mb;2A7jPfB+U_g&DLy}Om0T5974QFcZ@I$mWxU>S1>FtBT)*6{EV`K!{N4>h{Xoc!HbFF7ohRx@x2IK5~Vvg3sTKd}dK{Zg(IrZsbDUVGR z#`=97;paqEeP+wDI;aF=#lE8OH6pQeD#TjC;#4b)cv$6_Gf>4UMYz|uKf;0<^3{m= zSjEk@C&E3JyodeBAm>#Ome_T$VtrmuBUjKr(LW!{k1~*Wt7T~2$3z*)}w$s9YI*%MX% zn;aNg5?H}Eh`vT7C)X!28- zu2#$zb_kxB&m?vU_^mG7Q}^IS_2jm@hrEtPuVO>3qWAVRzZe&tdQp9_1#>#p(7T`7 z571X%GA6E=gZAi^dQ^jG$?7qG6dt+rYdE8xREZwV`|ucgp3@lrUt|}P!(jut8uk#! zeUvILhgl=Eh0OeisjqX!Ub5GSXS%|g!gT1BJn{@#M+;)~mBlEngwb1vTrIW8jrFbk zES;pEjK#Q8hAXWb?88c8t$_W8fpY{e`d-02MEv_b_WC2?Kpglz_zzXJXXW_L7ThMz}59(BPN1x3im)SmgaH>q3J`8rhnGJ#0oiM$UkChMDWz9pdVeVt(pIj|Z=wW5E3RrMrRs{?a}b*Q?f zym*TCd&?FgTf<}Y8FGX>yl3US5u!g{k5B@yyT)a-PEI2;ms#Ov`0F`yA}~KiaP3D! z-JoUy_lG>8_q6=~>SZ0`cb_vn&U~8Z;Ji$(ZO@gE4af9={+{=fl8LFhuH2(hR#FMM z%?IRKzenDMhm1Jfh@Qt4`e&(usUbCR7+oP3RWkp*%7_*-qu6q~D961GI)>?kW@9F1 z@O(5Y2Ys!aY`q+TRUl&&1OI@iuVi{y9_6K4#g`bvO7j(i^ankwsN(7~MftZfhgwF} z7k<{hK;Ek->CNS(24OK~2FuwmYyeq6roUzM^-s1vdGeGWdJ^nHdD+!cHO9J->hPQN z`2x0{%if0_uO@a-?Rl9UZ~MYV2HL5xs7bJ-5wNyi^vjj`x+$zFmI#qyu%q@=SyI2f z23bE;%de5`!kFr0st~Tm9uL_|7-N|kAwGlstb*mQhD|Gi@ps}7XYmw>v+|02mmZl7rZ)jU$&HiM+QB?F;oNrrOk7(s@aJDaETWQQ( z-$8%+n%7juJ@2uu_AEK!6j{HDo>hVwYI>U&$j@N*2j7SwIZ)AmXnk$TWOY26V6JI!z|Yc>L>`1mnr<&>NpUm@jNgW-PBr zR*#xG)dG8Ab*UjW$xB+33=Uqs{zJ0smtY-JNhuvz9aPou9ina3$NIN?EA1sg=JB{R zC((|zOe4t=aFUuGFSs|{Tkc)=fh*!3lN)kWR^Z6{NF0`5B3sFFHH+%R>0Ms;o-5;u zyMpdH_k`S%gK|#p6EmVX_504TGVmYn9aqKu>^iu1uDxsHT427B`@z+6|8*a^53#Re zEHLB>VLaZe$MwLSEUwyzjqB8bltY3*y z<=Vt}dBs9yYG}v^NlU5|#?Zrx4;&4Xm?_j~@*aEIrihc=@{+uceo?m71lY$6SV0o{ zTe-!WQIE2`l$B5MS)EGYTFtN8O5c(Z%-1x$jPuUH?9M~hg=uBI&+42dx2TRuAHiB3 zkiW{upqas`99>>Rc?21+`-eKgUqc=)HpHxa1~5|N-j&`}S57fRwRZ{#E01SyM-N8z zw|`;ess$PK)YEN2Y+7q_Sok`5U9wX&Z|IR+-2y(VYv6n6&MB6@mG|*{hB20rtDYf_ zrbzcjL{_SY^$B{Z1m3^LuZ`&i*P%*b7b5Z7(Bo?vkYb)sL-!HS$lXBVu_h7Yt~G^g z$ZDa??h!?uLsS-1-*ppN;CG^xj|E(oV!{=5bd!FF))qY_`K2H^a*Inj_N3POm6s~$ zS7ohgz{RCvxc;qdio~V_YW1B$LTWHJvXp{&J7lEbn0* zBKOlivj@|@kQY1}@`76HzMuc@!`!|Q@6ulmk^%lC>$?=)ew!>2x$SfIY5Szjg`*Pe zCBk=pk-VMiqui#CWdf@~gbOQR;5nDZGf82#&NCu-FX~3L((p>~+Ah=6y2gKQM>Tt> z+vD{O8P}4)bDx>`tgPYPN3gQezseT8t}LFx6~}Rtd%y1WesGi;1-u;bu&6%mRjnO4 zBC-Tu&GQo|FXr=97=FpVY+tbj@m;;Hrx?|G8U0s|HQ_bUuk~$X+sek;5q1GRmUXO7 zSM}xJU@aSAyVo&F@=6|9=zdyG60Z$QV7ViBof-$59zh+Pe#`>aVmwqU%saz|`ceh6 zH<=Lh3B9TkHeP4x8LekLi%Tq;(<~WoI$=mT)A@XAXQ3Y;hEpT#Ms5 zYIorXRx;$Gk<5+SS4_LOd#u@jvdd*<8@%C5Fasz^^3c)oiWtj zQD5*Kq75^l4>bR*{d~$CgY{lT>pyBAL%Y65-uue7o^6S>dZPt&bR}Z%ZLy8-aDH#1 zi7dxUvE>V7j?9)sdRgOS43-%n z{bdk68O3iYw?R+Nb&*ceL0S{%Ttli!EnZWbNK5G`t$2-9Zg0&OdM-o7dQ_Au9Lz5~ZHo_mhR`!pQeA-UzUxP0zISH*qd3cIXwNw(v-l}%zc z&gQ73$YFAVZkAKdxffkoEcqW--j#Mmv2=<&a8J8J?hSk^jOle(!j*CrU40khes#TE ztn2DJx|XhytLN&t>aLRe1p9i!y^1a6ch9>#a#zmDPV8y9Y{H%{N~)ZfV{!z)DdSc@ ziIEoJK2lWjNfvv>?xViRCRj}z?CWQ8jp}{3CbNT;>0f=pdO)oR{DfHd2wQ_rZ<4D) z^%M$IH%EP|63ifa-NKR_6=k?)rNA^=EAWlh57|Pm0Ns%&_uk|KP&R;x;kv#S1`ej^pg#ZgK=W?jQa%nFw$dt~8IrItrA%VHRN z&|J-V#SYIw-J*{u+3#dIV3Wd%#L{33kS=`X*quhql)FZ;BFEo`ad#%b@LtgjI^s&5$rD&rAcq!guH4$3-iP%0xb^+DTK5lPN?>IZT=kmfb zU%*rhy;gy7=d$GXRqd;CRF=|AVLf62zGGxspPOn^!=WzqKHHNYPxT6uWT~u@)kN%V z#Hg4Fs~LlF(4Eg4t)v6y;>a4O>g#Gf?=gC$xI(LK>glEXdskL-ohwmTE zjH&PUDC1|hqgbZPA(G{}4I;{c_k(Bn7t83a=)3o@yl-|ToK+;U<$2b<+KuO=x*ZgB z?tB03FWu?j2|XHOSXlyZW#$lX%0iVypFhmS%xk8AUAx2c@=A}&Bc>V92cZr!W8h>+ zAMouS&;AU~{{`aMBmB{CFyiin%wzMjg6RXQ_kC)s+V5?1+Z|T2hCP+$cDlt*hn-BKEe^n1tza>V9q&stL`T~g+p9o!>RPr5bpkpwqOMWW zresoArXbCode$;Mz86zu`eF(eXhVd~PHaZPkAI(_Q7#!Ocvd3s` zR}z(O)vub1*Ft{IWDa~bwlT_ZfW(fHe#eHB48ty z?`Rw1*tM#ow0#CWaLHWP_C}AN!s`ZFKNnl@1N#M*(#i_2OVDn?a#Iv{`nZK zo|QT~J|lh~eWkUeS&2V9&rIPCTJ}1#(j=KVW{FvD)|!Q8su^awnI@)=sfMYxX>Pik z!Da$;gBn9SMFpQUY$uI5#xz++rU6xIoh}PldwocD$x?b)zsq7w^JFHOyeG)1PQ$Z(kQnoPOm5Aj| zx^ym&Jd{7M+yS}nvb!Sgb63++A-*p_m4^ zUapI4er$?!^W3V1q$tktUGkp2L1m=;H6t{eyS*rug%xnvsqAQt~SrGWGC$oy=FSe^efwj|T1-mh-)YW#5<^VfI zSr|GoV%0Gkv1%VOZtee;8Eh52t7g<2X-3A3CVVwx9P1ZGwVIL5qAk6$2tKP*$TfDR z@=yoHx4MN~q|YTrmg*9+mp;zcnHiiP(bwLS{v7@E7P0Pi_`NE7s5UV)^>93G=(A}Q zYyfK}hcU)6o)ME-%%aY>3+)oL*it?tYW4rt5R>1>cHK!|LjC2<#Fri+;_UzsUs3O%jr5Q~ z7;hTGRjlTwkQ-bsE97_ln#k(X;lypmV?>OV!I)FUDy=j9my~5b`BSPsyvA&$RxW;x z=}Y`poGf|&#QPKS7+Hw3lDXj~v&@%>FF!)&A4U0YAtLHeR!u4v{=7{gmwg7w$Q_sUGi@u?W9jrgY3mj|(>HN*t!^?fYw8p9aFI)y#o!d~}LeIKULa)}04kVMAS1K7v9+2VmuV%7eRToO@7nWlQ zeX^fHHne&4s^{5pL?aF(^W%K}rtz@xL~;#)-L$Yj*sqB7dxzR2&)S@UuR&u$k=$Bp z@UE_e3|nf*u3h2X;RrJ#7nxJLMP&D7aswSB@@fw~tQ}@oc;7?c%KKiCd5vJ{+(A|l zDjHnX2(5WQuOla`<~&oEa=YIPxFw&Zyv$hEm4Fh9uvtYo)&D+u#?fm*%SI9UK30{? zoZ;2z@0SAeXEGypw*!a5y%43l6TbPnzeuHDW>yFMh0@AIze~|sicf!nF{tdsW@Xe! z6|q)i7Gu`)e&89)!OFyJ0ZE^O91MAFJ~D?EwZ)lz_<-JU32O8y=hfqkpXFlyuprq* zE7!@ zvp&sx}TZGB$%8rhn#9*;~ZWk01Vk3ONdgcWN|-(rlA6pSlnlheAv z4LByRDK>}<%Hy%`6}+Y^@6J4|F`apdMA)m=LF=>-R=b){2I@P_BPwwLeaEe|`b2tH ziCia%6}MBc)wRrgD$m_I?5~4uLS3D*HotPYp{H`%Te$W5 zjT476P*1P}&Z!KQwe!IiPLYp4nfST;=~t9b~^IR-o4W>%SnW`UW5Dbb8I<5*2N z)BI*em>#C7`OeffHB2qj#I!ZN%t$latTp?XW7j8@%jTx9b1-*h6OmTa$#}F^PRJQK zAZsK^X5klA;ae@sF}Hx8R+7w=u`*glNdozsC&^U&I-gOm1!VkeO{Kzm(n@;DV3{ln zsil&DZ_S9((J0oZ^0hRkszyiV4U{c<02y|)7VrysUrI|2X(X{&e~Vlt>M2=vV>`-J zwM$OQMM-myyJGHBO!=I{_d_`P#f&N)k_YZNSI}jZG)Z>G6>#NUU02IhbroG1_YT&2 z-TmABKeoOC%&Y2o|C|{@MG!$+SP=<91rbadq(M;ROLy=H{X-Rf`VJ?Hbm|MUEx`+V~DJ#+4zGxN^-HsUTkkVo+d9xl^pp2Ra`n#>b9 zo`2-N+>@g@l0&%-H{<&JHP_^-vUWKx$?tM5PRGot`DOWhNsjI@-IXIqq|a>{CiZS*bYHp=g=}{l!?EOC6}#eM2oNlp=w~(wIkK3IQ)lVXz$KL`Ek))VniM zdi&ho0!PzzFt}d>`_&<22X}&@L7yoa@m>!9>UZSb6@4`k>bCL74G#0X?B4@9{GDg9 z>H~kO_kVnj-5!vBuK6z$RPE^qh(o%NlMhXwL? zeZ0rj-}`pG@w>m*HW>&nYmodOZ97V@{?^u&_N{@I{KoT-I;2HAk5g8z{l36WOoZCu zWMKR!Lt}atA|ngz5@fH|08zaOnmIe+U+hPf++kp_x8n(|l}3lb;&c!`*lAQ5-6un7 zrF}9>3#$TPYWbB}+U;F%)V)PTsUp>qmaax6rA3RIhQ&swwI#6#KAicUHwUX~W zQQi9+_)vDz4%!7a+HLeF&8K-Z6PT@;$ncM&2^gD=q&Uy*UPCOW5%S96(#Km+b=g-@ zDkuHEq4fItRFlde4q6Bt#Rb9Zkb_l}{?cV1mpTOWx+2bYdSB-TII6CIgY>D! zPl=FOyl0buwcU&>w^hFB6+13#?Lu}uK`b;yY&8jf+cxQ`8emnFTpTM_z1(~?l!0QRG&u1qediIF>$WvYe|3QEU{hqG_bSU<_-gCO; zkN>vU3cT&(Sjm3f6pwIs+X;ABH-kJ`kG=Me`+Njn(y`1_P;~`bJsuUG#@8BV@EN{r z@RYIx4X=zCX~6yPy61$KYc1<&EGjDy>~Hw`#B4UV&2QfWioG1}+GUZ4&|hWb-;aRv zC~0#6cdt13x1oYuMOrk{4o2OJj@`zBS!cK%DDA$02w2HB?QDHHbbdAKiKRca;53`c-o|*8E~o%G6rO7O<}&;`&tD z>P`E;oJA>H!G2|%$Qkzcl|wUR%?SCgxU`M>#@EG0k0RfF0rvk8HHfd-w9;E{%l{kA zA7+l3Cetrwg!#z~HKWW(Gu#X|-A$-zYg(8lrm<;f;^e>aX1-Z(wwS%L#XV-5^oL98 zYm0?lqYbpi^BpNZ=@K2M9r*80;8qXOQ94Ek=rA3jeY9KtTZM|E1&DBM0uRn%S@RIB zr0L)mR76e;IIPqk+D|)WjX5-mx>5rm-fL15`92hS8$;d+we$;{LQ7QU> za+0+t>;`1PG$S_7_J+j=^avXuPZ+?tt8blUj_Q-i}#9H-sJ~t zq6$$Fi%u~|nMPZKYcw28qj9Ki(popI3)koPG#|m*2!!HUd)YpqG!#Og(bv?CX3#R4 z0OgZr(st#M->o6-*a$TYU&?Q-oXm!}NDjpU0F!K0AC8#PLU%L)5rZV?jJTZ4Zg94* z!#!acqRERfa?uRoGDE2sTQ8={ti>Q_Jt6~sG z2xJDGPZfdBaIoBIC0~TE=ZnH}v6#9AvFE+~dynAcI38Rs(j8MT)F1}(hYoeG?=j%+ zs|!>>C2$AUvh@+GR8K1!XYn15HBQcS93oc}z)Ine&VmI=#`636$=}SReeNXP%Zh^RBW!A^#4*|&ie%4l&`ore z|4xECK{4tFP#=C0DF5R&5qi&e;AcIQ&nI{)BmxVmIH=XQ)9(fPb}QmvSCH+y4kp}0 zVB)p6P6D6*Tv_Hk>Mt)#4_PBNyAD-ZU8?0ILq-|D9n=F@Bnj&`VJnKlrs#}Xa zIpuFf)<%QN-)R8+2u|)lr1z}{ui1X^=FI~tOF4j-qE2kHT>unTJgQU2BepdY_?3yM zv-nA@E*24pwon(ZW=q?mHXrK$6*c780-hs!6TmMy1e3!kT}KwpDefg826YxA@q4~H z@2-E{2RGw+nST_uRyyrP9oK$y5PsDWcwdK+Bh*-!)?eNCI*6|VKc3#EMPBeRIOJ12 zW9Wlm6fNK>T?4B_3Vf_Uj4hD;yW!Pnoaf{`tm}Tg>&O^7zwrj9WMJ&wa(9r$d*o{Y z9cx8EspmOzhmIq{dKUbDJrX`G5L&L{Fg@5DvUp7!=f$Q&j4B(VTdyLbl>u5Xu1Zi9 z2DNJN1N*7ZGgLrcq9hQtpV+dv)0YOiyp+w28pm`t1Z;<;?bkNU4uM4suo1{R50UoP zD&%Qm!#BJ(!Bw&TKfn<<4z&@ACl3RbT^T$Y<4Mz8-kaDu*n4&4HW~ourFveDfl)Qv zDglpD!Pd1c#ij-WTeVVp%2_B+JqC-m)-9h9yVSe(Wboqlmwir#ZtQOuA1WU4S5!YM z3dQN&{t3S19n#;lJ|r1=`E$@r+b@0bp!|CpI#jDrC$0B5&1)<`&vKe!hrKG$a_J4d z#NHdpaTbu{{SsC8xuqRdyZlwT>Z+lwF~D+i9_{673%MzhJRH-DIkCfBh$dNG2y1C z86tmu|GN_*)9oulKln-0-mbeIm%LHI?R<^4Eapv!cP zlISYkM4aY0?Ssnl2HJ*blKy{7K6gQ%Zy-fcC`HpxG?P}zme0sCYiSPsOg~U3aAkc( z^{E}j(HQ7&%mN?8E;)jew1URb0P2WJqn5IznP9)V&*{OJkb_^Mr?Q_Dbc<7Q2$$pv z+=64cC4a$hvV~UQ6?!Dcn8JoLaBeQfwPcB=T#q~Q_dJrv^Ee*OgSi)X<-RuLJd> zQIRy13akvOjQ0=NvK_DJL7>S|j7Rm%2yihfrfGoB z)5ZBZz!mYrk@MeS}lmg(Yi zi7(<%N>Gf`d#W-B*1@y4k5`{| zEDtZ(>6LkMs;{S+1rJMO=ZoZuX{3EMe5}nt7Af<%tJm2I1(#*;AT}bCsQ6UJx|v{a zNNfB}sVD<<*3(Pt+_!hYxA~kb5iwBZZ%BKFK$-nr*g!|>0oGxMSy#6HP_c`?G#>oA zKhP+eE*3HkwJFz`LV1b_Dm~1bHbR>18lw zJ%TdMRd8b+g4g2i*}G8PuJNlR-1if~U8)(E-9TYY28Y62Xuc^+wd!9@!SiDV^xWfY zKQQq3Ma9=7j0u$0UH$GZV2|z~_N1u6Ffdrvl|DICY6Ta9y9;#G9mI~bmi?qTY!1M;+5;bJzgNgT;Qgyp zKww<}&-pEQNZ?bK_b0x}Pxt5;7a6e$id;5$gU^{83-Snr@lv zsIgDRTFE|Il@dI!YnbPJtQQRM_x^*6_nOSWW)W%ypQCp1Z_l6QxKA~M_!2y=^k7}j z3QScVo7;O)ZptCoJhS(~a@f2;Tq&Bmgy#;e43twj`Td@>P(GR7$346>vWDeknY^-n z4p#df9i zpyhTvatkiD-%pNn45Fzc&}URr%;iUx*kvANy9_zP-N01cwa@HxAS<7MIYn!rZh}|k z5Y&9POP^Z|-qb(ww9wq*ZXhoA%m49+Vzq>4RSy;Ub!-v)3PumlrKK`JZ8D#n)wgm5 zdxK?A@6l~+4Y{sw+t;Pd6U{NP-mPYvyq`t|?0IutY#^OYBQ}vN^UunhRc5Z4B(J4r zA@~`Fn4#uJ^MmPXTAF6^3Nu|ytm$R?%6}uwXfx4FHM7hHSvMJx*kp5t&QmfyrmNsB zI7OEzNv6MO7wwZdH|QSSr|0x9v+|jPt@#LTqAl`%iEglkI^Q!{`#5c&nKYQXP!#o| z@wA-wQ=%-hj~3HJ`hmKF)wv$Bf3eh$#?dn57k1D^+5UYxhZ>|sG?Jp}8)`t^DV}E0 zR@vXboSjQ>Y5tsZ$#JG|D$c{jxC~e4w%natb18nG-{P0(AAVVu%*tsw4d>twxth$2 z;aKj;Kk`&w#d~qT)Wx8o*2 z(^mls>oeJE5iSgFcva2G%&&4PIr@8aMUMXn?E%l0;?BkZqc(t=Qbl@?vWguYw`;^& zW`OZVBe}z*H$XVr)ZVH&!b;L7KS3N+ z5nI&|yJ`TQoF?$ETEe>uMSlzf(x@vqF2D0QA%}BUez#d*!*cQ3gcXx;H)jODv{0_OpzP_sQ zd(R>t0Uj*%uPWFtz_3x;eranSYLQg~1bSmyui;*Q< zg(#Jaxo-gz{$_X=TM=7X1m8;|EgKQnItW#r^U|)*z+{tFCW{)oyNFh1fI@6W`Any{ zC2&t=rrcBzwGLWQ*n@kC95xuM&2)4EMt_|`!IPQBJavC+7I}4U27cb zfOSpfNoyzlelTKMGwB!lQGT@r=Bgr9r#k5KO`ss(5!Hsu8_|lI%O2}eW%@$wu^{Dv znrRj}{yP{0CwtAp^U%^f1}ysyuZ*UX`d=r!RVxSlO;j8vL;Y5LCRHFzhJKTd1NNc* z@+h)?XXX2HjGt$MH)A}i_I`!3+DNa2sTSH5BbQKcu5?9Krj=O1a6~&@mBj$h`V%fa zQ?vJ-!F)IzBZ7g_x>^n9@b;UaZ>TJ!W1zL8*_Ux(%?kK%y@S}9{!lXM<9(|JK={>0 z_3>xE+BiQn?lO7Qc3RIT^*5qeE*|6*_OARtzKZ%-r@^_PYR1=~qmaEPTR@Zzq@7A|;3EvHy`8EP|k{V}Phl!%)7 ztB7Q|NZZXIN-MC$RX-(xP2Kri*D&A3v##K`JGW%Nl@z=j#^3pMkDOwlS1q(&jXL0C z{p~s6$$MDof}B}dkOd5Zm-LQ(8}TZgR8KIs%>iY>w`@WCuJrlOP>WRFYi@iAPwFF? zlgH+jmMRX;og%0Z&nsKE;L6A*%QQuvuD|VK+lyT_2kIkCY-_OC<6^OM<$^nanh51; zA0svq0bYVGVuyNvYa(0d2v4h?t!&F;6kZAJ)n)L^s0a?lD$u}H>{VGDRdHG7f3_3i zWIub>oZmbjwelOUv6GuK~VM?@Ifm|6P<` z_m3aZWur{=DwMJaD(mM^C#($cYjKy`;FW5(`LW1aJIBULf9N9pPWj>5;hx{o){vIS zU)L#OEwoufNU$b)6%9Q+pN<1F+yJgoh|Yu!UVpX$)up|i*>&ZPm= zm14oGu$=bNdD+eunuB|BJLHy{Q8@Ldu{1&c-AajcixTLe>?0j=ZAr9~rc)nkMgOA? zvd$2iMY||j=Dy2S_-p=L_NK_EH~BNJ%Wb$D|HOScf?IKAevgZBS@|r-pUAg&W!VNC z%R_lAPv;eUfY0$IPUHmn{EH9D?-P8S5AiPE!W(%dFXnkXgMZ;s{Jm_iBe&FZyBA?%4gi+k9ke7g`RRx%<+F&Sk znCbTL7TO^8+a4;h5x$17m#>Q(gwgK=Jhi8xf@vZ09*T@UX3wkk0;Q!qRFvw{Kw3rz zI%NrW|S`RZlLn^bJ*}%1If(_oZx*k0=$TMIJ{niKu^6>S`&g69`~`A>T@ka2M8wMBt)daLa$Z%q z=LHLcFXbXv9pGWL_ly={K3~`wOGkQ62j{89c(raU^wq z$at*-9%~C2@twBLe8fK1czv?t_JXv;ZTlGNgk+yVXX6g?gBd7`v|s^fD-;DYRfzn~ zD($a&W3{Nh^w>5~#%cx@2dyVm45jLp{zy^OR$f2QAnJ*!FIXMIp>P@toru9uRu7|S zcw8e;7ZWdQ>T>O5OJ7k<`i7cQCs{_(^WVwTU*;;KaW7w)tW~S34-f)H#XOV^4ASZ| zIb3@p)NxKDI<*a6=MJAYJqZSeJ;*L3Lq#V6HH0UStxzSMI~Wf*&4n$f)7lJ==LkI3 zO<-!%`?*#!^gtfBuUMseJj&YJ7itO0I@iiJLlwN{Svrc<#-ZP-Vy;%ZYdv8fS@vt( z@B3j4p}$oFWhS0E>!rPBLjhc)%i8)w5RDiN)qo$77wU#1=;HZ2G@h%^n5OWrYJerX zjQtokR?HT*Z`)kJ2`SS+fXC?{V6h&-XSxlflCoc20n4b18r=le>KK?7&O)jACj60G zzS8d|ST-*J%YHBz$I^V^K4e=IfpuEuUo$D{xyWAA+nn|-n-6u3R@T4ZRdr5zHm#Fj z*h=tJ{As}Xo1Jq`$9SsH9 zeW)7VB-S|rwW>qK8p3T`nY6a18PMyEZC%tW{|`?U#hH8o3sJAGEc~m_JZJSM_5)y0 z3fcT(J!P>c)xZn~vyiIU_Cx*6bi~M~h;7DTbP)l4#GV*+4n=K_)2p9~JJwv}NB#hg zY9nIp>!GM~#N&NmmcE=98l_q2RWgWXT}4d#4C+$0gWY5s^bL0c4{^YcL=;gq5S)S$ z(ieV`UZOeFDyj)>(?AU>y;~UmrKa}*XbUepf&V6c&oI=Xadcr9dwpX(H8lpdWO+JS+t>WjCmK(RystN zWeb`4CCf59Jf0nW}D*wAfgO`oJQbd2_)c4{Rp zr$10H)gRZO8}-05CyH88P5O{B*hgYDD^WqKD04-z{%Qw_Z7QF4JD_2;rmUg;+Ezz| zs+9c_K2{?r3pPijx2)JjA>^2gNDq8pmZ^*Uq9Uf70CCj;UP3sw8V>J5bAvA!$_IPK zam^7bKlp4^&no_YA9zfz+IwUvBjuw{r42?&YaFBvGzJx-4S`cuIhy0r@I~C40Hd7dJilN+9WPk7Ug4M z0W4QHkMD{_2C)Y!Gy@1R7scv_ETQIs8`#>mGLUr2%U@J_c3ElPZ=seI3$Iss8hW4x z@dw-~;(h(3GQy6=^_Tz;YbKEHi|sOh6<5QUl=Q@z$muS%lc8X# zx|9>~Y?>r%^+e3-d-zvT&}7i3T4(tAiYHW*L32Dqwf?*ko}cCHm$ria)V>c^_e`ja zd)cY`1tT;MkZ-$*I8PFMEa#~>_2SE@q&fzqdh&m8N6W7acDCjO_Ii@_fngvGiyXaa@V;k(};d zQtX`ra{ED8s|w zUTcRuXQ*Spcp2)#>SKj~H8e!N<$!;c4H)?Bo|i%WC`HDy?4~Kt;F)wmd1*8Y=-}_1{HZDaW5Jm*3|)dkVf*^5?0t6 z8cKDc)}<_q<-wBnzAY>*Qb>+P8Gb$iceS=pK{>*FINlN zh9WzyjPR|*65|l(QmsE7yN^X>&LrTkX8Y)s-leok*7e3+P*%SzJ@+4ag|b1{Fu(Nc ztkSR3dZo|=jF|pH4a+X+nLDu7KF_PH%A&`mPiqeu2K<+D4$ZWqrLQ!WYnubr9WTo@ zFKA238P<`0*je7+1OJ+;AZ0;Yd}wn>%Q~H$y=J{xY8IIlW|LUs6=b&6!@h;l#%b8* z1+m!eveZ;F#tb%nOlQ;DbTZMVo9SVC%I~4(7c<)|F*~3Tbx^i?3vslU%q@P6b81Du!V`C~ha8-||=7lsj-Qp3EzF1`j~gDUQd=_c=U|f92skif8jqJ`cYt zk+1S)zR0KfFdyK(yq|aTcHYEm`A=RYuf;r{XYo|on)9$CxUuZ7wCwdgE(*UYn@kz# z5nZLTbeML~ay$o={eG%^n@p2{>+O$BifT`P4VEaazAH`dQx5wKJe%9Vl%v|3gHWeE z0M$Qj;2CvBRlnAl)kH-1bFj5nl3(?3XIAuTVd;7AAh%xtBcD&C|24y%y*ct+j!nsN z4@4m|sO$`bef)N~M>Y+|{eBD-6=tDQVLZ|?$EtWm4`;4Vrd{U-t0nZHmU;t<7a;a4pLc5wl)SHDBic^dK{<57n` z((CvQ@!0kO$cXeoCa&9mY5^k=lj@9fbv{%Ce5!zV74E0bJ}T7-{*!)py6Wu_>+6VU zUn^vGS|b+W;#i&hw}{}DBmDLwyw~M&lrh1`Ssc(<0ewTq>YxnV?WKJbFIPrd?{n$X zh2^sr*vi7-q4fmEXr#~H{shHn)d5ydcqHyz?tV2BW5ESLk}g8E|4Kxt*2oo|foS{` zM7pM+>Tm&+R*yiX@TlDdA7dLh3XY)O@T4;Llc5~a&UwW;OG0Pib1E-3t6affQc>LZ z3PYt(QFmWK{i+sXSPjI&J4sLeUiy1~>P(Hne%D0$tSVBrpyuF9Q{^4?w7Q^5So_D% zG+g?AFN%_NBEgWQBaz;+ok280dXH*#&4h-;HhG_g%;P|rA0u|CN(o<68L_-9P{m0N z497Eg^;)Z%=rOaWz{aggLanFK_a&cRy==;WM|Z#TSu<$RZ` zhz6+#bjBP9JC??=cAGswV;um);uULc7Ua)DY<8OmQTMzy9atQ%nTtX0(nG!`@gV9D zk9p<8i`d5%994o>G)(lWhKWIcD$)B_m!Kzo32`omfY%sXqMzI{Nj{r+4H&Ikz|TMM zm4r_{+A0vcdf+Q49ryixu!TMH>|D=0o7TVZwO;ZJ4C+a}CFhq1QLLQsva-T^QvXS{ zcQPXC^@hyLZ3`m{p-W~#b)xb>WS8~x$Z{{s)*nI1C^aH5?_ebTA#msFmyfi+pz3rx zDu(}r4#2Orzt~uFv5rW@x~hxS)ki+88Cd>R7o>)*0&hy0XiG?26v8v42>iX0-nVl8 zVJ^hs3fPZrWm^p>l$v0_{t7JEs+8MM?5-2oXIhF4_Qg|Vx}9r(v+;P&3pnS_zs?S~m%HxYulh z4&f5>yIEwm0*81>mQ0N})=jU3lp+@DFj*ta0MpZin${-F#F`$akLf4>jFELWNl!Q` zmiS0>-qy%o^4YBBDHjCuW>GH5<+v)B=R*7n-KGaXn5%|N8*a*VxU~GQEK`4TYR<^{ z_!BP9Z?NT;=m{M~O@DtHL}O_dEvL_t8vgMxKSHO3x^f4$?+ByV-JqkOGM{yPPagS6l%V`mQBvV23 zfjpQ(q(2u%rm(DSfOt$t#9-9p(ED*0Ag+146C-N<8p$R%4xU0Ed)%Z8?wvP|;iVg#E@<*V0zyA-jm5USwB1(~n z5rlfIdguT6Q{g@f_##>r$ObyhvA#O^m{nV^I;p)F4~5^l~&eTLe*#1wyq)nIK|PXUa_GOHJAPzNqtbu(UR&Q zo7fU4EjKTk;$*HO-G|XQv7<3GRDSgqn^Io*?lNyU@`Z{Om`}gc3R+L=q;DOdi*#CS zZZ)lvX@yJ+X(s(flWBl#wHg(stdv1Ldtf&H26{ckUX$}W4?fj1&=T3>>jhT4(D2MU95r!JKJ+j%?HcX3EpjLK4JntfpK&QvdzQobf_z= zk>i;F-JKXjqa$#SP$WT9_*6}R+id6+NE`Xzb!`>s1b<^|i^UbT+3YK>E)Fr5G*B;o zh8WGgARGEMcqvXb@S;aY>2wy)nd8uAyB3ULImA{Vnsmneg(%kEAm06uIVM|pXw%y_ z?K?8Pg+ui%IhydQNQzEpzus4jph z{-R9I3rq4o)Kwf=LeLv?Ue+~Vo9J?#Dd25*6pUXz_Z0w-y?=ENb(8meoXh!H554#G z7|Z|T8Q?SEX&r*t&)eS1$}MM`3vsKgz`H9dD+^ezGRmC%wxBE(;L=Kqxw`{eT{lZoRdsQc~y)hU^sfDaT&E6QqJY&V;zJgL(UF7{V4_O(bI30P{ z2ItQgwgj|zw1Tl1vLGRH6#2dSS^@c;Q;t?+Zux;h(btF2zEu=?8194ZF#cEV!uIgz zdP6EjF3LnN+kX&` zejxLn$`UsaYd(w&zh?UnB64-wSFh+cp32fm9(n1M64uC-=_l9WOGMp@OM8@(-Vp{& zZVOvl&X=Hb^c37B_r=B!LeF`N*=Sapb!L;iR8?@X*(v}3Wl}UZEEaNAEbbn)W8t^fp7~_gM3zy#HZVnGI&QNsu0=mXS-Y-)GX^>A4nv!?pPb&c;Q!iu~7=Be)4y=TG@9&d6CfKbPP#T#7^3fMxRtt)uBQghoO;V=Wz{ zE6Agrp`Gx&dQvELq;S+9Euw9*yrSeEaV9Rw^|_=; zqJQN$YI0MK;gLL#H}Ym)!ZUagZ{>Z6N^R#2yq1^pLf*tl{6wbPe1{*&^gupS_y#BQ z6`2zF4A56cc|RZEL-N|i>v#cA;?evA_u<~$i@)cAU>l9%*4&WmaSg7B{NM+iUe0Ql z9RGOgMXkZwQ;v$$$5e}&fV;gM7=&^=eGhQwoV0(T?pqNuOTlI{35bp!@TDRVTL}Yp zI}CWlaIj!T+cwfy%7e@O1K=rK)Ph1$nD}W+z!j`p49yiQ|SkP zWe}>u^@%+m_WuibET=)^PMIuM+KqOX*mDwaRLYK2j2cOM&Xe=KL3e1cw8IdJre=s? zd_&dfGb$oIBfDq6N{i~QL}bsM67NYo=k|a{U^h63G@qrK2=lz+)C^#_e+4hYSkHSk z6jg(cvAzF)VprWg0;-DuazKs0M^tr2KF`JM!v2FpMB5z{uks5 zyLyCHD9*pDVeI8|g*`owL@(LrS~8MF!2nqZ9#%nH9$XrZKcgf1>xQd!S0KH5A^tT8 z{4(PamzsqtfO-C|a2d4kR*5~W#GRwou1!b%zWaV1#_}YX3^XeF!2XAd!6#sTeFg5# zX#0keP$tSpWo4Xyq24r%M$$ldOl`s1Ujz7a)m*45OSF)0+spX(pq>;;&B5%iepDN3 zMYZV%vHc42Tmzc#iqiU7mK#aaX%0;TUqcvJ?>YjZ)fM^0$uyG|%3NAUyT!Wp(+Rpn zmw`QqmgiG+nl3=qJyM>}(m`55BdDe9&lh5w>A~a`&wE&^s(#hSufoA+8>|&npMD3B z9~(V?)D|%D9087F3A8yBf4Cl3iQV9-(-|^f&aEn!O+`KH7_WUa2o(&9FFq(etg~}~ zk((=XM_J%!!B5f(&#A!H4U;i!BV+%qtqi3%&Ej+e7pUr6X>3c`A06(!FX{rji#2qW z8L$YdJabT!rB(31dCjHfUi~2i5p6|f{s;tS6)3CJgCbK!pf|sR=1BpY#U`}@M66$3b|1((5%2NBJH6f`u^GlA@Xwr2=kj?s-^&PIfv*(_Z_2gH zK*?XmHXGx zdC$j64{VRC8&p3l3-oY4f&NV%C~;)9X^^=}2F|R+az0{t8-~fM&D#E;A zR9AK6hR8z?5R2-K7-y*1gsOy(lW+RqpI@=widJ`61m%OMjH>cF$RF4AN?q>$F2C$c zKARJ`{14#oX?{|@zD#lyAAvif98jZWz>KUlg^gvK{lpekxoaq@Ee3<1a2#q~SAd^y z4e+5W!J#_`x;OJZhwfh7*W7@X=oK4nUs3`}3M@%h$_6w-GMUS4U+Mpoufll>)+?u~ zb`xjXmbPTZ9TbAN8jKXL(1 z&nY+um*7%dj%#yA?jw&{T!!;-b}r17;CB?_)bxVR(PsLKX3|I+P4j3I?WL1oql%Aw z;z=+tbf+j#7!*}ySrHgO>xphujM zE69F@@eE$cdpMl0^A&lHI+VpaX3&hRLD zLjSh`uJQGu22dJ2qMEbMg4*D8sQS$fO}na?JuPu>+u7q^yTmFEDkHegfPv6+83A?Y z2|jM+YSZSR&O@2pm*cv;-foqdaMngckuVz-po%gAbLCji(mi@i;k2Hn$x(MhuGdv| zHfrCg9gb-sHh)9?chFKw{`;Cz5zKxJtOnLkvJ3n=A>9&(J@{XXONHK zxEj4~o@L!JE;vM08~8mfyub7=uYL923a(QUdTkLwia{j7_$TlTLPH51z_f*f^n{1ZQij`&TF zb3ZS~te%!rWpwqb>roZ36Z{}+>`JIP{*8Al5%F6DB;aaUUh9|Ef^A`@&p3oZn`XRx zw*(c1ig8Kvl&Ng7tliPpM5XT!wzk+-h%E&j zl*0BKAKOxH?bguq7=&suMP=z2{{ehvH+b8MJ?wxCVRO`yX}+eqw5q5e{tnu88pWy( zCigGEMEteQXS3N4RAbG&@E$`n6bN5KJI^V~xQe@5-iy&VRwS6)BhW6u!%}bP1g=OC zz&PFVxN-G&9IL~>h(jGR2c#V_XUt9W0ueLSnU3*nTK5qty9EF01U#~%hbMI1(DVFKWKoX$;po56l)KZehe8})ca zZCM~`zn3w|0d!D2;JAXGu13&a$%h2Mt0hJJ>Ob?`CbC&%9E;i#;K!Fj}=EXAHHLJ4C1}G&ig(mu6K#Zz3 zdX#-Z@s%afzM=r7q>M6uKl1pi9F&#P%Xdk%{)Q+PW2rH$22H2BolRSL z9%ZJ;@@vdrW|2G}5c_=~){#l(U;!|66tr1*3eV?R(k5{)uFs`7CuiVKxER;uCO|v& z=Hc9v8*^p;hQH?;T%C(^E>6otSLqO~gktm*@LKJmOB93XS2}t_7r?$Snfg;F>PS6g znZM~gMWJ@^Q|Y5Ncjkc{$|3wYr{d)Np=>oVouwr-0{Dz+w1v(yaY_D#$Mc`OjgRvc zzR6J>DX)m*hURlw*}EK^fUeO#T2BjTDvgw*sY=CU zbd$j{0`?8~48vud9R_3_5Ho6VOMsJ6uVw-6dl%sTcNDZ&dH^G>YR3I+Pnk8r{9q+8 zm;4Aeta36^%CM3SN>(|MTdt2NZK!7v=;c`g9AasJ_o{+g$*wN#UDf{_L_(IJErn{7 zYHw_}N5!UNC@!U=JXD_A(0Do4GjyGz=@H$eleA2}=}Rr?XQ+GErb=E{E|1KUw3NWU zvXAT?IRi(5Npwo;s-L?R3NIURRa*{!(=lF6M!nPo?U2y=sD0qY$F>ig+lDf3SLBnr#e^t})`6 zy?}Ke3LMr1R6r9gCzmT+2*!pL;H{mG=*nQ|Osfw)2fUTLQEhYFo(5Li#jhTN zck?;8+?7`}g}fR{K$)p9RitV%mg@P00=+(xhR`@^17-dxujnY5gQ}A?fo8}&Urlr6 zw*mC4*hfohLN%$1*h*0U4pSsOVM}l6nONIHc|_A)nQswvgm%cRJ0Wcw&5?a-i1=wPO6l)Mr-R37YUeZKI65X6_I`k%Lg&$ zs#O?{2$tfo4w!wYcE13u(|vd-w|o@ovX6#o3_zDZ49u4E$(*01?+>9O@dOyQqrAU! zBNpKv%oA#C?NY1{c*%QMkv>)x<$bU#-dl|F9@cg5U)}ZU(2qSI*h8ET_seaMhQABN z9^L;NVCuRJ#tFCHGxG)rtbo^YPT(sGlLK*;4tOl}u=3f@fd&XcHC`PVEyv7|8eW!# z8sZZ~#a;k&mB1!6Z)6)WsJv9}cdbuUFRiqUY*S>48`$b#@6i#jk9sE6iTDon<)y*l zuM8bu!@|nSx3!?c)l{}#6O2FKf-gQ7B5PTY#Y_#{RYov)r9m7ntL*nT$Tv0yrv5k7 zB>n(~iCS_bZINZ^YlnbSW|&vz`5g)dlc43Z8C-pP!DY1-EM14~4T?h#^Tgof=AYb8I ze21S0;sg=|k_J)-QU#I)5(VM~h+lCGNAp!a$EWyT4(ESl-L*WQX9CMLl>2dC4wHA& z<@lyan<{O*d_RDDaW~{fTgbkJ$o7kH5;{#AX&UvW_SBq0s4Nu`8%bav+bA$T9k&Nj z^>7SUrS+&+z+rd-ez>cF*n!BYs-vr#({Qm=WkFL6>=@f0K2}q3SvAMCyOq2T!Tm`# zpe8e;)|LMLbyO{L+~5A|Xlfz~NaMP=Eni1Q`@Ly_VXPucy@ zQs0foHlT&p;F{+AtGQkybbKtM=x}6Vh5~uz@Zmw<%3WW6@zs5<_OH2Dm~qG{m(y$h zUX;qUrtra<;JLAnPPx_)b(sy}Te)XN3IF7u>wx9Bo?oINGKfu36V}$FyxMxaR|l`X z(*c|gK@ZFEk#_T3@H(Q^fq^JszqDV-*nMV;0wYlmca|Yw<7gsl_e8|2Kaiqh;T!*s z*xq<`mEItcvvVwywa#17QUQnjl# zR9ozzFcqX?R8DN7xqPR1#Aeh`K2=4QQ8`3w%5u#R#hyx2qz}yxuA$|$g4RpF$0&lL z=_S-X@6#>1L-*(g{HqN#L+0FKS!%uPS6^shmK3W?Y2Vr>s3W}Lxf;TOFgq)AO;H>F zc=U$e|DFOG@DO~TRbZEPcNmLsud&`9vDd+S_(0a)2+LH~5Uu8%1#RaO;D~=FXYT_r zTNIRYRS!p3Le6G;7>WOgX{0{9bECbwkwDRT?C7Q(|JA%B$i_mRg6`*=XSX2BVHE} zlR9b+AdBL%gzAqu28Q#9aXBW()80!v4&UmawEfcdVJ&^#_nwEP==wX@=U@!Wp}(TA zmlu5w^CB{uksb%{5bcq%S;HuQR9AeC@D@D3ckHE#LUU2Fpr`4oDX)7p{4LM0bsKD` zj{V)C;uYl{7ZqvAprRARv!{W-k`?H5^>iF#bcl?*Dxj5s;@O8bsd)tk`)Ba;Vt|@g z#ho}9rI$7!?^8)nAA5Bj9orhVo~MfV z1K1+!K;^3?s;N4m8oDp=SPM}xrP_iAW!5>?P(`#y%53Tb+Oy>3#FbV%FO?BEI*ck9DM$2q{D>E)G;#lb^HB_kgU`DS2 z8^jVjNcK+=i=FIXJ5*+1CpjPg1J*4L)VVLh9-Xb8K!$sp*Lnop}}C!MA1^q3Rz zC!B|~ae9tJcj*l6qLnm_hU1>L2aN`<>KH{*45#3{vaL?i_eky!_VgxPk#ov=m!((z zf1e=h9-}AV4lT()$`S*3lA8J!hlrCcD&5v*Th*{PPN!IOYvpNdHC0%=QdRauJohaz^?0h_W3N;!w@X_*I_-+qNE!mp^l zjMi-Wn@-3GDkH@?I!GI7v5d-SIez7mY)=iL4P2P=$(cwAedoJk=Qr#bFf;6co|@_( ztcG{B!sD;zA%Zp4;XpE5SiHp>=*WP`x&a%ivd69?kg4P+z6TCZt#r0qm7+5AJvE|s;76H78)yf#-q+GUGOKUU6$%H}+Xh-D^L>IW)15lYeC|%IsVWth zUJ6kKszD*rYEyOO3o8SeRg3CT18I$^1$ChQG!A+?Q)q$AB(1_-f~pu*eu!qnmj093 ze?+!*0_?qOWQmc~SJs&=wx=3YRb=0l+dV02SRGSC6k=HCQMu}nSQn5hJnQwY70;p7 z7JIx;GxbBfjS3UMB5Vq5V8OI z&|y=o`w(zKE90By1~=M$G86Bi3O7>b;4?}j^WnaIF0UD>D1A@=qmL<#YDo~wY*E$u zOu+M|kx$9tcWDeO4iw&InC@2DgiBg>zp2OOWXa3QY54Y((dMm%W%x8#~!fIIWcG8!m?-8xtX-u+?am`3cU$;Kx5tI^KyjSc`L8t*|N=E+>b}d>i`awqieubrS}?KUyib^Y@rrc=AxXR^Kov@ z%E@GZwU+P(9i*icM)j!-<)q{?)|wZ)W$z>BqKYHR(pVaL9~DturOL>vEK`EMqKq~M ziU4QrRax_v-E9{^>3b5g+mpdvFd00XPT|;jT3T^bP3%6MO(xB$G<=AA6~!znw_q`u zY4vc`SKZ*=z(kI<(}854i|ph))C)S^w>6jto55G9j6r+B<9^$|#x*#t*zA|kN$E*b zXdUgR!!ll{<+!)gdKs1Z;G^h9o#0_r!jTn`WB!QZ%8a-HeYoSmr)=}pZjSY8DbOzS zus<__ApRY7ga03S)f*8#$9UBdxsmohdgWNFn)!%SusXdSa(j(DZYtP<=&HsZzaI3b z9KOnVRW3L9lkdYtu7Z!6h%3F*b8HFBdn@3(evU=F2f0bxd$!Y{E>EcEmGACZM74UX zj4gocU{0GuMyw=a?v-sNTU~nS<~g+bqHb~^DiT~Y&uQp5Wh3S9n+3mWkUv{J5jE=z z?spgAnuDr^HQ;pJiAYwEPxCbq#ie-QPfjl*oD*I_S^AECpdTrOYT?mT#&rNJRb*UcM)+<1(vLKa$eqd>@>s}q)cde)$g@QS> zkIeq=U=i&`ztU)$CfgY=4~=H+prc}C*THnG%A=d19lc6k^?#t3SmQ4=n1)GDA<+2z zNGvrzcvGKZ242H|>v?+_x`NU2T{Losm+_Aq4$tcpB3UQE`KI+po4^~g5t>5hfWXyi z*ej?I-z76;CeT#JpyYhm-jOqylrmCoDkMi&nd(pjc~qpY<(NajRq+FrmtV?KVfqyJ z=;~*wLeIbGZ4UTFTLa1071bx5Z55fn*}%Dy8@Qd~&;i$oW=r7yngB6S3;w^e${J7( zuLj?|s#uSzh?lirNiQGz+OV`XF)9WfBf~ot!UtX*=cZ@vyzW^#-{Gzt2fIVN2a#Ck zJ!8Wur2wwru6(QB?P2CL!@vG+R^SG8$nKHZa9 zqll|Sl#o8A;#8e#P!UQ`Z0~|^^ev(h$z|z`($dMSP6ZU!TbVnK;VxWe^+g*A4j}{f zzO$M=$%S?#_ zXfxBS zmUWIwPmj$j>FJ2sXx4)H;emhP4$(GRL7V6lU88#x!|^#Q7m;O($ZI@$OqXdlt)x}7ftJ&B8czKwjQ*s3 z;2F)tx%n$D&rP`x58!UxjKAUh(tBd*{Q%9QaWq+;*FvxG65U|KnK`?xQ;th88@%-4bV81F77d^#RG#vSJ+OTtBO3?$G6kt56{Qjs z0^ej9^`#-GM*oAx$}#t(pQ*B}%nR50O19KEw-)m_p&7etg{8~SzSge|I%z0ts ziZwJ~YY4X|5gk5gw*c*;n4#sUgLmlm8J<^kq8#IJFmw$C_9|F47-Vb@@>#X@nl>$b zWXj>vU973Dk3-dmH`FlJhjRF;M*h2>;8E4{KADSE)%C45T3tj1>i7tOHhrxJudRtk z(zo!L$d-s$E>yF1)_Xe=tLn=GTVS~)jzfU7~3y7fP}l5DvHufwEJS)>^v*l{Xs8xdeT^Xw*hO zwa@GeWC}GFpAxykys+9z)EInIn%h$*;3c#Ns-!1TkMfEMy5_10rAk>#Xd)Qef2Kxa z>lLUB?kB#bVq)E2%A>IK_$}3tUt39keQ2o6`ccr+nE-58XCSj$P&eu?Gh_@+qd#dS zt)nesVTa($@0D4$M7~#c(kV0*YNpMp3jHM8Y$N?vqi-mW%)W%Un|%g0tQ+vL^l1M> zjgkJ-YL?+1w4ARXTkq~~HL7(@&dhPU6O|WRJ!{wvIZJQEh95&!c8^^r=W>gz@m$W_ z1u&Cd)7%6lp{z2`zk^p*3mMSb;Hap9h@jS9mXqJ}&Vi{Uts(N&lz*_X3=Xt0FeyfVW^3?RoS=GSXUKXmQrNIuax}?fLoDs2z zbT);Juj~w-x&0}Wnjd<9;(^Cs1(lxPA)79EkLnWeOP69}SmE%o6p3{LYzoJ5SAGJz z&@T2B4&H_1@S^s6&uOpOg|^pwUBNh&B3^dm{a(D^h2{0vgRx$i^RXh}5d|^s!74|G zWxwPznCB6FaKBxT#pyfry~Ailcm`AFGu`xD?>9ZF>aOQ?c;~%cgpYa6^J?AqiaIf# zi}WS5a{|D%Cq+vEb^}GW=K}8PbNI7x5;fH=`q?Gn_9*! zJyZ-cgBdFxbnxz=;xi!2Io+K!vRq1O8O2r#;$Oox%`xYbt!0NQqB8d~1I1=X zf;}+|_rN{DklX>vJz5pA+-^t2{1nhvmt~fumKl%_HTB6U2NkEU@lR7lW=ef3PdO=> z%%$T{thy#kC#4MZF?1R=)TwNOvS*lW5B)_&IadOAcV;&z-M$4oRs&2Of=>1Dc^P+;7leuw2X5AaHol|Cu zS!Vt++r_43w(ueTi^uZ-?!s-j8MorTJPjV#5bn&)`Fk$I1vo3`=0Z?dzD=iSFKwhX zw3ar}E;kp5su=Qfdqjhf#g10_>}MPRldY$_%N^JsXT|5@oL`4+jtYNmE)YxzjGgM&o$*Z zzm$E?#u+#{z3|+kyWt@&p+9L5G6VmkY+?)QduNhSE=HB9Av8f+Nb5na=524;56LiYuS&8 zrT<5ah^^iid@n~cR7PM0IEwbjxj&Axuv(5Sj5<iKM7(4TT^)It8QHgYYsePo~}kisFp)kLcki*^qp-W}SjrPnWP<(V5= zL6xXuEI*d>wcc@&{)&80T~zVp0@F-M++Ti=EU!i$Lu2t~&M)f@jJ)zrjz%@x5O4*A zAzL^IRb}nK?$8gTIR&w+`OsEf0o|~Dz#Azp^s>FC@l~ksJ+Lpx;(sUwcw*B~S{b|i zRE9!;J|9El<)I4B>t$x|6&v0{hv*i)VWQV`7xVpZnFn)d1a+sD&=*xE-NMrTM>+byg!DOs=Az94duU(!g_=_XVBS@sa6B!N88VwDiDk{A`7&QN%jYRH zoJP|)c?^Jtd<&{hUrEoUee9?fm6F+$#J+{XMzkE;omfSnIC6X+Q69=mStz+I5e*jH z8&Jqp{pSnFIGjdx>wf5PoB?+0mYg33$I3l0jBc`j+Xy*h87Q@V0*=IosKnGv;b*cp zx-TJ60BcIE!S`_B;Q{VXs{D&Fy(aEDv{-k8(M^!W;0O?s_JOtG?zi(q~5_ecsV!6dwXH z<=7d5`p@yeGMdt7*HXh1%Hnf_IwD#jSW2Y1La%c!rgM8T$r2*7{%56g5?y zY;WM&hvUvz?})qEzIL3Q3$E&8_L|JTH}(;@K;KX%`dsG2H&lj-Qw1>XDT}dk7KhNc zGCNt8KMbaR z%*hncR84_Ay)tV(fI9Sk*~W6a2E5FRQD4{yGpRD}VnXDMWRr7XafTBEnXa57(O%_T zqgz+Snohy~_m~xCDp;`kn=vNL3^RkwP&3)AGHZa^nlE;)JSFjEJV+y`gioi&oGi8b zYsj7m*;=L2LPb(Zt2GpnM6wggk|o>w+SiaJer5N6&NJV8`J2z&_nJHNotZo5+&Od3 zbDrm*9L8)+W#8dUM&es|lt}49lA9g#Nkqvm=7c$#Z?a4SFZjdMb6q(#Mz$>o7!Ykmstatp9`&-iBeQCy#m8HJ4CX>D4 z%zD79J4i$9H#3gsG;?OgNc|hU`5iJCy~AFsx8Z$H`womQ@K&q;)N;*W~SLBn3cKd9KYiFH4VuU1pX zZ4Ljf_U~5t`QB&ix&B74X}E(d?;)rA5g%dw6~pGA_PDP@KE4WLtPq=j!dE+^QBv3o z8LpAcYGK$@c!sE|3+xUIBe!E7uXWgCyHb1~;t7x1I>(Bl;n9s@G{WE95I2>X{0t$w zJwG`bN>X>QDs$A$U1#O&?6i-SsG^eT+5Et0b_3o{R8cY%y9JM5tfBQWb$t?C}ZWH_#Rv>0PlwA@xLvSO8D zEjg@n8kc-&>JgS?y}AT)M%thr!{?vSg9G@Z8MwzRMWr zB1SWwhIMW+JZOenWZj7D)k#N=(y|z(618!yu9!#iOLj?veP3ag%efn@&hKGA*;c%+ zcT3$YH_5$BRnP{^`r3Drn=EZt$=7}(xNA%triK*Ufrngx@7%>Tut@wAH3*gmUj*ZW z*Mc{KiNVZZZZIqOESSu^)rMekFgsWZ3;qk+=Xbd4y&cx{Z*WczP^<5E z-K5KPrhctI>Pr1a-_>E-Lt7E)U0CDfrut(B)mRp)hb7}$2CO70F{+COu zXlw1K1BqELulY0wKFvZV(eLDAnIK=u&$3)r$v&)I0He0kQTmELt(~-?KByVwnjDwS zvVc#tKa+*H+co;LE@XuDiB9ke(oeEuvbEOMTsW`OvX*L# z!z58^uqVAbtfjv6kWn&TCd!96vu$#enY!OF+0kyrv{6=2sc?bJ!?}DWljI#4Bg3VS zw3mAFup~%h*h*Sh!#>!+LN^_jYdUmO@NO2lq717P>hrzkM!Mdvy=wyheTe*{)-RNf zjKHb+gj0%l?nL;3MOYKbclfd!&Wd>#MkR*ZHg%>^@QrD_Bd;aKeJ4@w7vUEnle=l8 z^pdw_y8ME(uu9Q&eA|a*6V7F!Op&3|&S&D%NC0cTO+@b{_D&hArE$4$CA!O$a!hSx zCgZEmyz1aYp3yx;oY65<|1i%dI)L#;A65ptc}!K<@0Y}gD2Y0^ZK;vfAy(B(Vw}~1 zjKf_$-*pF%3r>o~QekYB#Mea6-Iz#jp;kn;wC3NoJ{Q*2_ZvpL7N7Ecihb_mXJQGv!v6$-_KFO9RVxv5+lX2X%B+qv*o?Q>09~(k8En|zd$STaok78CY z%!Umit9OXwd6Q3*Q+%#+E*UqhH}pqlvX-$^dadUoTT6AAKV1rWMl<6YSCz-4fwYj0 zxYC2jbY)$G9};BwmWk zLu7|4mHavGIvJpE5hYcCPqYQ80#u7nFnJ|CZS+5P7t<~F z`WaL7X1CiNa~C`s{g$XWjC0-Hp=!rz_`?x*4i;`bmXE+oOGs|^E)~ExXUdIFcy&hW zC$_3+0$vlOt`x_3$!-l9_kV`nkB8qH9(XiybwlD ztn7wguFm_V)c`9p8&S>G$5e-y<`N!PZ8awA{?AB0rZ^&}<6MT|4jJ1od6vv8jHJ$b zM)UJtk?*q4LB(%9M+u&fNV5lgc- zu^RrD4`Z8xbyo5-6yvysJ^Oq-EU!7a;5+bn(-db$Qm0}Vv8T@w|8BiC##%keedNC4 z^W8e)8B^R}tcK)-$JCIP(p#RB=jB;Rf*%!x2U$m9A$d^Z;Du}50{5+3?+&_4WXXyU z$D2akHhaq1NFHG0TK>Up!P0->t;-+9JmhBGC;(N{SvS7-vYDjRbmEuj@tKr(1Qq z9@G^5RTt@3?5rE1J+z^g*DP{fPRk+2JBL)XuvXUwnxMrsy{6T4`T&{N2k1!5?X|wv z)Q7bMnM8NV_e51Jl0PL`wn?%^w4}Dw;rfZr&`H>$9Y%3-Mz+f@G8>asD~`);xrwbW z67_XZj>us-Dd+M3E0|0fF^lHIQB=^!w3+tCkxs)=pTy-V94Q?sf!92dY>_m2RnO=# zwT{WtdR9;95i+~~q3d*|F4nm^OFzSLOd@Z@%Q{Mj>9gdpFRf{?pKUny2{KSxOII1i z%7rQVye%_jH9p&mV>-ibs}w%%@0A0Xci=l($^4rs1Wlu6q4iL`gsq>HhEh}NV!XPN z2X?g|cDBfU16%rp&%9Ru`OGWzeav`iG_?zj{jECHTnjQgoRO0~RmEXRb=MSYn9A%6 zOF0VDH+_5ILRwz;R{Wr56^Bn&h7{!EaO@I zo*9f+i72ZgMaj?*z_P9Wa)v#G|GAsw6xvBX@q_rgmYl28$rkY`&*lTxKEwFxHIHq- zR~;P0d`=&a^bI>#o{Z(9qM4_*jD!-IlZw{)!b)FKEU(qkKYvB5erNxk1Hq>EmBdsKX>QJSL#49C_VtIG?#?##Tbs6n72S1SMGLO03 zY4V*c#WY9W$6hTyNs#)OjR(H9^pX+S*UQ*Gk*LOo@)#_w3`Q4GsXEM2S+=e;#>psoSXX^Q8cPGr_WB5`qt*#k5K~5X8MeO^*W)8Mi5=p- znV0H7rpV#co_q!NQlHFdmOZEqd+YA=mruja+A@F8h*h3)L>-r7j=^#gRrtOXnM89i zvyqAZub9#>gB9@Cz>%Nf5@V>pJ^t!Ed4Dp@m!Q zW9}~5Gd-LnF8-WnfDiLnx2Zjpj#Y!KRC2cHD&8|B)OAf=d2(JP+S z#rm!R=Etcv{R)x2b&K5^s->ToKnnBT)`QBUBZ&)WE)Plu z_@Cv{Z;|u(5V7dfu-!U%;~DDY93yMpA^h(Myl4$se~oW>HazM###kW^tF)Bm6ff!6 zxo+IQYsg^t9eIIglOOmy>V{0gagQN#%v3{L;EWPnx!^8iD6`yfQnp}WOf-H*FcMD zGkr?iXhqG(TvjoyMgI5En1*XVyl*J}=o8undz_51 z_UV;Ku1NVvg-FRrL7Y))b`<`nSM-AZL*~(wdI)R%soQmvuErV8*BSabb69WctNJ3w z8O$tPEzOA|Js?ZvLm43h^&AoWp+B30E-d z^DWN$3z>p3-esNS8R-g(t0Og~fi!~UrFG|A3M^`+`_avHlVQ(xPaVttu_?^^ybH@7 z;JUfi?oo1r7p1;|J-udt|Cyev>35fQb;$LcM2@>ItiRWDwLOBi30cJZ!~aKHtfq#s`5ii3v*eAzvPMc(bd@N&R7&CCDSyu_`WtWJ%=FUhe~S?=b;&hP0Cz8~uze2vOJp;pXuo>%G_uX7Xfg!b@?)}1|e zsvR>O-q`b6khEJMh#)gzY23X%6wt>}KlV?E=QqMyd6{TX2m!quqnDiZ^1dH!m+hSq1)oIH_< zJR?J6y+F>`7kp$jl#yB(ZT2GTL=Wb>x{~v6Fu5H@kl$g9XTzFIw9hBx=rB#NFWBJ_ zvJtE!GucibVZ}>TNsuPe26ku~&7GtjD_({q9K;U6Bu^L9~P5$>`@}j&!=CmQ?e)yF5s+F=@*2)I>#n14d2{M?S5>;?C z)tGTgAoFQ=990`wnDN+FmeR!eWyhRb^5L)5q|;c&iQK7Kh$zd9<%TGGm{_npmbH@9 zSXKo8v&gJ8GhP|p9V(vPrt-i(%jaQ~Oj1zFNICL{=D{cyEfrzCGauP|T1!u2`s>5m z^I~Zkcx_{RcZNZ)G#Wz2dxM1U(?ME)7#x4O@x)1q*pLA7; zPA=qXz^b2i!>DID99On0Y%zg#o>1YW3|T%(^4?m+-wyzIK!?8zvC}>~aWv^IZ)F%E zBMHZAz??ST1=m^WIP0U8duqtX7?GUw-E?O?()+0I!Q0P>YL~zJgvufz!hI(*Slbz0 z{m!mH!>8|L++~w7hOTFXwbmoBqLI~F%quY6%WJJ+^tFyP!p&ZjFjONvPKJbgyj>x$ z``=y#`k?164X6D+9y;!i|Dab=OeR-q6hjuR6^6CPqds!_%XbhSjVS|#XtRC3pYl|U zdGr!H1w#J!8^LYzG^8Uw+;Hv|_msvpstJ#_D{0x~vE%@@>Vff@Sw7MjW{VIf7w6LA zLfxbS;w2oz-$b_`V!q^Gr(`^gXT7mBqv?2J;6pA`V_&x{crjCWB6>`93Wn(o zR>tQAcy}?!}&t;F_*qCDa@V%chHrXFxx+!8k%`?3s!;gi?8L+&a(JB~78vGQ@3uXi#1|I}7gKvZR!S}HJ;}&mQo!4c;_Z5MKSpUQ=T&bci z3$E#LSl?>uL(gU};m%-*ey1Dsu-=GdkCcv7j#R-^Dw0YM=wkgqhieag!f;h`mzrUF zC4(&ORCB_*(qyev8I83>)*J4^ouPnZ(^*I8R9&No^iCum=TIS1G?F8d&N>Mr5)r+jH}#rc(Q|r|717*PQOQJL|KeGs*8ZfcM<7ylYzK z=Y1^e;}YSkj}U`Vh+HNQ#3HOTWEjpu+-xmaQYW&dB#?>4dJH>K&8#zP5l_1p-Fxn9 zDjUopL!2oR8at{nCxv{Yr6mDJ`JsF-D`lhnjB@0`Hmq@mXv5QGUq)`@R6b zNv4Nz4*!#!S&Yei?{@eG(SEIag@<8?g54bO;h-R$6Y>XDnSB244b1GXjaZR~(JI~tC(c|Tx zjHyE3s}zQ6hP}KpPsoln!2h*(7K!y|Hmj|x?w>wO<9b*I%buee61Uuf>a50&^g6zc z;hwjCkjMG=WA9{_`_N_Gd4)nj^Yf^(&ME(09QO6WeVq3)&O7A!-~VR*FO012ko)2mC*yQa z%XlQeD@$FRX09DPbqKjuOqt_3*ViSn4jl5W*K`lL0xmN%jh2y0>jYQmZyd{+;2OCv zld;DeRC^AyPu0kBW%|s8i1M;1s4z7S?bko#%)CLh$(yi&;#A5pw$LK%FgNap+{|`W zAo?>eorPh4qiN}sCKGO3*lkDV*A3PF30Yz0yCr0) zwr<c5P{jk{e{uy9puq;>_ET^5Wrj1&^#;Ra(upsy*n2Gs|U~(`q z_<&pt>!@9@3AS<`-(mskW>>%!3OoBPCtWbOi|c6>#5uwH!MNaajA?n{1sV1 zNf#*>sS~LYsTwIBiRb}crgL<%j@EAaxE7TEk#H%2f=)KRymHAb(7tqN&5OvNxiu8p(~rpL9D_QF29Y8xC!k`BOG%-28kQY1&D zB#u9SBzq(q`Q6h{snF2wm-Vb3*A(5YTXj9oZXvaDrZc`8udnM17{xMg z6UYZPM0&Cpud0+KdZjQkL4U)l!j8gmZYV6;@*92JDDpd7)@QiuLKH?V*ooB$bF)ei zM{hMWRw`m9^SY|UVp&I0T{5NAfSd#SMLe{j zA-a(_d4%UO4Xdd`sSZ8b*9*roFZh<{{+mptu(@sl@jySaYtEh>Pq|x+OH384FzaYF zr6O}YWuyvh@(JqSJWR$XLs&hA&y9)nF-9K7ebtD%%htV9z+|`L(?8evdmV6~Y$S<-CKD`3gG#B15K}NxznoBM2y_A%M&6UJ^%L+Y+xjc?1zhsp- z*6i$`Y5f=rbXF`eRaj$I$cAmI#^otg7*_>rCV` z%*u-4f9xwX*21vssVeqv%&QG?me0!bG8EQsjCM_NR(2j;**V!#+DUtyX$PFC>DYJ1 zo~vQIT9}HHRXUl^DaSqM;XKwUzJ~3;<_5!F8nVu3_;zDisfhpg#}zaVf9po+Pi>Xz zUi+jB<_CT5Dj%`XRuc?!Ct1lA@Bqfh%~&f9xfx88*m}?`!ur>1zC<~qjuO8e%~TyG z?~la~rrUCkTvE{*;hy_+nZxSfAD$;Pioe>-XzEw?0Y;T?Hu^rn)%T&UR*@rn`F+z$ zVy`wZa}_eVhgvy1m^HhHmI~QH|B6Lc$2}%J#j7Ch@>R?|WX?LmT3@K9lj1X2`+UEB zh}J*ASSux_rgJ>jlNch;_7Tq?=I!>71>zL*R~PZ^{Et2ScNmk13y8%^OBSoJn${9t zYRJgZWK13dzwF`KldY;Ikx+(>Doa#)4kF$2vPyUZdpLyiyyj8|cX77+$^30KLhCRr zM#NMNA2nH5Ls4pZ6lMN0FZBzr5n*=|>*vPkmTRgGd&$SlrrAjj+Sr3Q#`4%Q2bN}I z^k!?MW?eZ{R!l`iRwi~eX2+V=?`+3d+BJ4hk+uCf{;rL1g&y<6;-xphP_CbLs- zBXdhxh=F_ro-tg;%DeIse5M(^*lPO5MIG{vUV>k&By-PvH_LtGCQ>zhqx;ou!HBD| zY_gkyF;}=n*w-gyH5rTfJvRlPEy8|xvU}%%JL0a1vaWaw*_iL0_J_$inkObW&XuLR>U<_hfT2OX~O>bJU8 z&qdOb6FpNTbHwRCnxboTy1u5}wYp}OE4Vbdw5V3nsv57^wV2kXa^W*NQ2XQcb^Tc9 z=&yQ6|J3FBg}$lJYD0~e>#P#4l9QTAA0{IGDQ&Brbf`|$Wx81x>U-J`W961xa!j_7 z8|SFp)#BP1P7ceTvPo9RLYXVGOoWuc*K!S14v@v<|nWKF6eRAVMMr>_#E zBg=~Q^#+*ZnbU1RbZjXy$kpRGUEJUpOxM2KvJ-Cl}Tl##dj! z>fa}iY82uAn(rSBy9Yz{>u0>ypyh|UF}~{HBdoTJlUh)-p(#6&t#7>vpAVb*>{D|e zD@7wFdu`4bEX+?e_frdw6K1Pyj26Cc#+E!m4c#^|#8x6X8#=R-rfZCA>q)8z_8|7Y z2U#RSUFklakF=j>ndpPhjVtmgj9uOp^mvD`+sOQ}KK9lIqlWnQ5$r!4;3KP$i$2WX zwZa~Uc&4yX9tR&XT)a(Pq;ZT@!(PL;nZut(W$mx1>b-#cqlQAY=fn$C^)4w7dfgn; z%PB?G)x18gDa}tyuwSl>lx6Mh5oU-IarKRdssL+qnI#T$4rV)BOG`{i(nY#s>O}U^ zwphQj3??_rEJjtPdb3Do%DeKS43cirOdi9y<%zN?Ms}P0)X&I89*G>-3!^J{*WH9| z8rI7Cv8}h_y1Pt$@;tvH*VXozM)U7JceU2@T5Vy>6-HZYnE_bAN?;Uq73Qy&GtT;% zce1d8xY0*fTX?Ut{8h5YOC61=G@oL8b({=cCp^2U9p7G`W82B7Y#&(}!l*GCU+rhC zwAXV??DZOpQRaqFzwj7Gi{kY6`q(P0j~*ZgM2G;pU^>i}!(w$X1G#cC^6HgvHQ~WY zd=4H%HkB6`iC7-eexK^&^D;!Fmm(8vF)}t-*LPfS7uUvO!b=!e+0Ax{G1f`!@f!1E zIruadBJWDFXS5LJ0_;c3=u(q~<6`hXb~fb3evHHYQTGt7C4-Bwc4au-eC|PfYHVDF z9?M0>|I~~UL*`VAt}@fU@-wch;4$yH@cs$c&%Frye3Q?_Z@ACgVs;Jgb$_@+)%^otqX%W!7NN)2UCMD@%Kkq?i#X>8n4xo zU;}LCJfCCI;#)WNj3#{Y?m!-(wyq(3Hyy5OGPYS9Obf;Zqk>n0Nx@ufJym<^Nc}+P z>u-8mujnyNp|*0eZq~UvUZ2*+`kDP0;7lLVTKXuCr>fS#t5qWFW2%e) zRb(d3Vy&8t_8Q=`N3mWdEUly!w5;aQv{XtqhSJ|;9nO1^%$CVS5f7H$(p)ObgGBA7 zp@R4>*v#+jCY%C`?hUVP;;|Ukb=HV|M-B15GM{NnFmIg0*9TG)gQbSTfGt&^PFZ=+ z3Sj&u7GHH_H^?~mfoDm0i);Xs+-$epZE`z_pt`}Q`G=&ERAV1{7kN&`$(J%kMlvRB zBGuWU-ifi+V_2_*#JMZ5?Y(Xb{BDg~zP02;o zm{SvO(UeNtPcY_b$?o}9#B+6Kj=aNt%%)vE(|ed>3mLP*N?~u$+|bXnky?c>i7`|& zSJ6L%mf$m`vCdfUf%QW7zRy0)I)1Jxnd7sssL}lnHL_@s8 z=e#$#^b=yQjO}A4f43}x-p}ruWa_@;m2y&n8J!%GU2+o#o>4MWf5I65Ebb~Oc`)UZ zLS#oMCspK8R_|)yvz%BvourYpSfi{wEVWrRYePnOtD7~Fy08wzRCSgYL*8Imsktnq(1C-~D%k9e(WiqbAuE_Ey*vL3SM3<7B03 zi`QDPNYl}=U;bNoJ?Z|FI2>&ToLL2&MKR{wGD#|oa>ZTe_{QRJmla6M+#13vk?KBu zq$gS0+mJc67nvih=iIceEt{1nNqB9Bv#pP9no2z>Em_G!ZJb+2sRwxg{_q2N;H>w+ z5VxaXNA+;^O`R@>D*#LA2rrmG1&5cYp<{K#vdmZ%b_H1-D#WL$EcErXtnNfG2`8)b zWFs%PsXN~euCqTdL<||zXo$l)<)evv{8syY*IdX+@E7B&Bc9X!U`!?F<{q2djX; zc~zTDp6O}>tA|@WL;G6aD;U-SS25DE_{t(ItHM}}wG2yE6Q{M2ahZ*`oiWf}pK%J= zsE)Ie7b^Q4Wz-eb!rAXLO}o4b&n{mrJaAwCU^4k5{`B)6KYECK4?6|#*SC&xQtY8R z-Jc$Bf0XfOsK|4cYR|XXO_a^+%b21@b$DiXa&o>wcIX%2rQvg6eLm+lakb(1MaURx z6}rOw)po2mUd7l4d9Sw~PmAJC;3!gzHHr7{Y*^cP;wyQ+vx3ZG<|cnuI*f6heQ^Ka zs3KTW5NjC+Z7tR!E#elJiCu`Ph`+K-XC|WOvtU+?AFy5-M;ulm?5P47ZyzVN{SoXt z7nWAVxpZUq&D*RGPIWWf3b&7lsSBnJN3Ly=fGTTc;qhH$Fwx4bndi1ik2 zF1L=Hq-)%_ZZg(3HL4D-uB+@ylCd>A85!;{uX_t;oe9gz(9a&gmH3O1_bGb8e%R#F zU{Ua0uppQp`~)lhmDaf**0zrQt~+qmE;@%Xi&Bx>81wBu)qv`t)$pB_bZKyHj>58+ z1~Y?k!Lz~OV0j&S9rRg!Tc_&^-K~3cjed`5J{huJ)jrx>t7u*o4K$q=(3;vw zN9sUriFd~H-bJ6+FLa5n*ByF7&+1;?pi42<^V(LcYJQE#N!ciC_Q-KLE!Q+N`L4R@OZt`$)j@duR6oGHggt<(^>-rH zck6!Lj%9OoHm0BP{&XZ&B!476QiKs!mPlMAZ6wg^tPvi?HrsfF7M*>gGxTGO`GyYG zu9&(|JExC6qy6+L@-}qUjySqj+7w4pM{8?6Rw=dw?JBeHiYd(`duy%RG)MI^nu3JcleHoLWM8M&jraqq)Z`{Sy$fWO$&Y#FLa zRb%gV8UFSbVx>H*&tKUuu8=h)lV=w;By36QHYC8y+qy2U55^qNyRp^H7r4)8+aI~< zZZ7Qq7uaVq`6x3;Zi$Dl)R0EfSzg8wei@X<4*05y=li=emlBGhgcdqT?;S~~q4z2s zK|qSApd!5qA|gcv#X=Vg;unz?5Re)Wq}KovIwX)#6GG=Vb9Ud;|NnD8@8y+S_TJsi zJ9p;HIX2SO3g0$!xT+1$}^zfL?hduTNr zEbn~~a)+;@E=>6t<)v>5A|_E5b@v*>Y6!mE5b)0e$`p3L9fR?=w(tWUgeo-k(9x`* z>d`32bTK>%zlQ^W<+goh=1Jc!G0V*=DECK8->UPfx_PC*Ei(+Un!J=n<2>Y<=kTlu zrA(AwdOtH55umjVrQy(;3IA8q$OxzoFTz*kQ5CGL8uGUi zRRFK4J&lmjK3g6W=mQ!`AJXSEhi1`KdRN9)SGXp(qSn+#_FhN!qr7&Fo>>jSTxe4o zU@BFrx(|&UtyxWyXLWkM0iUycR8o%Bikedcswtx~8$3d z=K^wGzIh?fMJOB88&ZL>^2o8PQEh3DaPWG)#`4G9%=a4Z!j?DQUcv9_=*{v!XOQny-g7vN{-^!${AmeNdR7fYF z?yQ51ii*f-6o48-I3m@`w^W2>xt0dM6;E+T{!HFm+?5VoO#S7(<+R9C!Nj^9)Ga?B zWPqP?F&i8GIUiJ!I^#Y$4FnUY9<&vN)^l*5%LvARZM6q@%SNy)uiav*O~6=N9KPBD zd=>5ef!F$p#<+F`YY6uPC!Gq``(1SIgBE37a+yP`ZTc_A-PSH1h0^>{ps3T%p*q$* z0vJo*1!@oNzRm|18}T|B^N zf=K3AU76Ky(h%r9=7gtUy!itP)B3x!!yH6@P-~p$o6mtsCn56wF*1SEz(xEJp0xJY zLG>ZV17UqC$NyTk{S$f+$7OyUmc8wV;>rbN7uU61hIt=(AA2Lcx1i$w6*y7KP};~p@(iBLWBEPq z!;QHH7vZd&ma}nQSu{7;i{F%QI>}==e}L><3}59toWy5&2QNU@O+BQ`b2>_(ziA(x zqeN!T&(*oTY_mj;bcyfs1>VZv%2C>KIev+r%DSgyxhAh3v&Xr(3b*37c^15FK9g3( z$acG>jaN91Z}SU3ouAgv>}TQ>*^??R|*4rW-Ph zL*OI(iTPH>pgIt2H_M@BItLMtpUfJwNk;B@lc1Sx=#7-8Na{c%rM(|PnIVG8$fx11 zPPVkX&JJe-y=Omb4#@1;EF)a~asG$=)FSf@e19}rHpR`O520l}5wk|s8O8+FMXh@K zK-A_1a7#DT0(Nu}B^#g8I9_Au=QYI4u@8%kngAm;bv2XC9PVlk@4w~_UD@yT*{;*n zMF*R?JvWBaL~}&2I{imCtIL0|RyXH`7*LAu0ld}QDO%b3Ld!(&E#G!@s_jjr|MH-6 ztSEAXmWdUG2=g1LIUMMi{TjdO1Po|d`90*Dq43ffk9xt`aIW|oRi+Dpua?10ewp;A zey4YuOU$p*8#Xg|So-IhNrBFJI25bYsXQIBSxK@yMm=77^GKFwaQ3pC@~qGvD2?o( zYWLTty5LM{>`OH~A0viU2s(k9(aQy|L(R1nmPZY0O}(H2F_8M9RXE!RpqFPSF=!04MrBzk>E{5;uM1cJ6_HEIi(liMhdap>og(_Xk3j9guC`M)zR`xoGd z9SS;2pFsTSv_nZYyLrl?t}}>T1<=*S|FF^mEcbxwSAg4pG>AUWLE9k-Y$sJ|$SQrK zwVjHtx_@9w=1--Y9q&6Uiwo1cb78xrSG)fFOB2RWsp8g1hP{$f2_;H z9*17Qb?>Q+iektQmy+$ZPN_ODRvFY3A`%5P%y=&u%3M}&x-fKl+CdQ}Ka`$Qkl9qH zAIHr{l_^8(-zw8Iv7GXrL*5{zGQgS@0b<;(y>GsB?eeqGO*R8`R$n zlfLO8=M*7VDT|zO2~)$>a@Urtnq98QZTK*ql+m=)TkWlr(YX_Bs|3vtLpdW2X4X@n z)=-(9svcGVTC-_oo~e801KEd0BOk!!@QTcub>0u&=iWGPfH%+^>J9eZ@ZRE2cmc2A zKlu>H@mb!(D|r@=;Qrj5TXO`L;rtxRx#X`h%*%0AZpdADFu%_q$d(Iv8E=%W9&$3r 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