Skip to content

Instantly share code, notes, and snippets.

@frodrigo
Last active May 12, 2020 08:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frodrigo/afbb8e89da7dde0861c1485036d5b893 to your computer and use it in GitHub Desktop.
Save frodrigo/afbb8e89da7dde0861c1485036d5b893 to your computer and use it in GitHub Desktop.
Change a map's boundaries

Experiment on Disputed and Claimed OSM boundaries

I made an attempted to display boundaries according to some countries official point of view. Most of boundary are consensual. But some are de facto with no recognition from one or two of the neighbors. This facto are the ground mapped in OSM. But some countries have different political claims over the territories. Display this claim is often mandatory in these countries. So some boundaries or territories are disputed by countries. Disputed here meaning, that the country is not officially recognized the de facto ground status. Some other boundaries or territories are claimed. The idea here is partially based on the rejected proposed features “Mapping disputed boundaries”.

Consensual borders does not require more details.

Disputed boundaries are here treated as way level. As only a part of the de facto boundary is rejected.

Claim over territories are treated on boundary=claim relation as extent of the facto boundary relation. boundary=claim relation are not closed relation. De facto boundaries relation, minus disputed way, plus boundary=claim should done a closed relation.

In this experiment I do no try to rebuild this closed polygon. I based on osmborder to derive a modified version. Originally, the tool de-duplicate the border from the relations to ease the render.

So in the output of the tool, a way of boundary is marked as:

  • neutral, if is part of the standard de facto ground boundary framework, the standard OSM meaning of boundaries.
  • disputed, if has disputed=yes, dispute=yes, border_status=dispute, disputed_by or boundary=disputed tag, plus if is part of a boundary=claim relation. Typically can be rendered with dash. Note, a neutral de facto can be disputed.
  • disputed_by, list of countries code rejecting this way as a boundary.
  • claimed_by, list of countries code claiming this this way as boundary.

The de facto map can be show using the neutral marker. Additionally all ways marked as disputed and and not as neutral can be display with dash.

A political view according to a country can be display by:

  1. using the neutral ways where the country is not in the disputed_by list,
  2. using the ways where the country is in the claimed_by list.

To implement this on vector tiles I have to make a trick. The disputed_by and claimed_by lists can not be embedded on vector tiles and used by Mapbox GLS JS. I use an integer as bitmaps to flag a country in disputed_by and claimed_by.

demo

The demo: http://bl.ocks.org/frodrigo/raw/afbb8e89da7dde0861c1485036d5b893

The demo source: http://bl.ocks.org/frodrigo/afbb8e89da7dde0861c1485036d5b893

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Change a map's boundaries</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.9.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.9.1/mapbox-gl.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<style>
#buttons {
width: 90%;
margin: 0 auto;
}
.button {
display: inline-block;
position: relative;
cursor: pointer;
width: 20%;
padding: 8px;
border-radius: 3px;
margin-top: 10px;
font-size: 12px;
text-align: center;
color: #fff;
background: #1c70b8;
font-family: sans-serif;
font-weight: bold;
}
#explain {
display: block;
position: relative;
width: 30%;
padding: 8px;
border-radius: 3px;
margin-top: 10px;
font-size: 12px;
background: rgba(230, 230, 230, .5);
font-family: sans-serif;
}
</style>
<div id='map'></div>
<ul id="buttons">
<li id='button-' class='button'>Default</li>
<li id='button-MA' class='button'>Morocco</li>
<li id='button-EH' class='button'>Western Sahara</li>
<li id='button-RS' class='button'>Serbia</li>
<li id='button-XK' class='button'>Kosovo</li>
<li id='button-RU' class='button'>Russia</li>
<li id='button-UA' class='button'>Ukraine</li>
<li id='button-CN' class='button'>China</li>
<li id='button-IN' class='button'>India</li>
<li id='button-PK' class='button'>Pakistan</li>
<li id='button-BT' class='button'>Bhutan</li>
<li id='button-SD' class='button'>Sudan</li>
<li id='button-SS' class='button'>South Sudan</li>
<div id="explain">
<h2>Experiment on Disputed and Claimed OSM boundaries</h2>
<p>Boundaries exclusively from OpenStreetMap.</p>
<p>Last data update 2019-08-23.</p>
<p>Build with <a href="https://github.com/frodrigo/osmborder/tree/disputed_claim" target="_blank">modifier osmborder</a> and modified OpenMapTiles.</p>
<p>Partially based on <b>rejected</b> proposed features <a href="https://wiki.openstreetmap.org/wiki/Proposed_features/Mapping_disputed_boundaries">Mapping disputed boundaries</a>.</p>
<p>If the country is included on the way "disputed_by" tag the boundary is dashed. If the country is included on the relation "claimed_by" tag the boundary is plain.</p>
</div>
</ul>
<script>
var map = new mapboxgl.Map({
container: 'map',
style: 'https://vecto.teritorio.xyz/styles/teritorio-tourism-0.9/style.json',
center: [79.23, 32.73],
zoom: 4.1,
maxZoom: 6,
hash: true
});
map.on('load', function() {
map.addLayer({
"filter": [
"all", [
"!=", "maritime", 1
],
[
"==", "disputed", 1
]
],
"id": "boundary-land-disputed",
"layout": {
"line-cap": "round",
"line-join": "round"
},
"paint": {
"line-color": "hsl(248, 7%, 70%)",
"line-dasharray": [
1,
3
],
"line-width": {
"base": 1,
"stops": [
[
0,
0.6
],
[
4,
1.4
],
[
5,
2
],
[
12,
8
]
]
}
},
"source": "openmaptiles",
"source-layer": "boundary",
"type": "line"
}, 'boundary-land-level-2');
function set_border(country) {
if (country == '') {
map.setFilter('boundary-land-level-2', [
"all", [
"==", "admin_level", 2
],
[
"!=", "maritime", 1
],
[
"==", "neutral", 1
]
]);
} else {
var country_map = {
MA: 0,
EH: 1,
RS: 2,
XK: 3,
RU: 4,
UA: 5,
CN: 6,
IN: 7,
PK: 8,
BT: 9,
SD: 10,
SS: 11,
};
var country_code = 2 ** country_map[country];
map.setFilter('boundary-land-level-2', [
"all", [
"==", ["to-number", ["get", "admin_level"]],
2
],
[
"!=", ["to-number", ["get", "maritime"]],
1
],
[
"any", [
"all", [
"==", ["get", "neutral"],
1
],
[
"!=", [
"%", [
"floor", ["/", ["to-number", ["get", "disputed_by"]],
country_code
]
],
2
],
1
],
],
[
"==", [
"%", [
"floor", ["/", ["to-number", ["get", "claimed_by"]],
country_code
]
],
2
],
1
]
]
]);
}
}
set_border(0);
document.getElementById('buttons').addEventListener('click', function(event) {
var country = event.target.id.substr('button-'.length);
set_border(country);
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment