Skip to content

Instantly share code, notes, and snippets.

@ynunokawa
Last active May 11, 2018 01:11
Show Gist options
  • Save ynunokawa/3453b15b2b67422f2db4dcc089f81990 to your computer and use it in GitHub Desktop.
Save ynunokawa/3453b15b2b67422f2db4dcc089f81990 to your computer and use it in GitHub Desktop.
mapboxgl.accessToken = 'pk.eyJ1IjoieW51bm9rYXdhIiwiYSI6ImNpaDkxcXg3YzB0c3p1dWtpZTJrcTczYmIifQ.mDJcqEDs62VDMQd0iVtMRw';
const map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/light-v9', // stylesheet location
center: [139, 35], // starting position [lng, lat]
zoom: 5 // starting zoom
});
const countriesGeoJsonURL = 'https://raw.githubusercontent.com/datasets/geo-countries/master/data/countries.geojson';
const macdonaldsJsonURL = 'https://gist.githubusercontent.com/ynunokawa/7571b1bd14730eeb9e3149c008c97ab4/raw/25895947fa81eae5f2b22d6c15d6f17c59541fce/macdonald.json';
const getJapanBorder = (countries) => {
let japanBorder = {};
countries.features.forEach(c => {
if (c.properties.ADMIN === 'Japan') {
const japanWithoutIslind = c.geometry.coordinates[0].filter(p => turf.area([p]) > 2200 * 1000000));
japanBorder = turf.multiPolygon([japanWithoutIslind]);
}
});
console.log(japanBorder.geometry.coordinates.length);
return japanBorder;
};
const getMDPoints = (macdonalds) => {
const mPoints = macdonalds.map((d, i) => turf.point([d.longitude, d.latitude], { name: d.name, id: i }));
return turf.featureCollection(mPoints);
};
const makeVoronoi = (mdPoints) => {
voronoi = turf.voronoi(mdPoints, { bbox: [120, 20, 160, 50] });
return voronoi.features.filter(f => f.geometry);
};
const relateVoronoi = (voronoi, mdPoints) => {
const relatedVoronoi = [];
voronoi.forEach(v => {
mdPoints.features.forEach(m => {
if (turf.booleanPointInPolygon(m, v)) {
v.properties.mid = m.properties.id;
relatedVoronoi.push(v);
}
});
});
// console.log(relatedVoronoi.length, relatedVoronoi[0].properties);
return relatedVoronoi;
};
const intersectVoronoi = (voronoi, japanBorder) => {
const intersectedVoronoi = [];
voronoi.forEach(v => {
japanBorder.geometry.coordinates.forEach(b => {
const intersection = turf.intersect(turf.polygon(b), v);
if (intersection && intersection.properties) {
intersection.properties.mid = v.properties.mid;
intersectedVoronoi.push(intersection);
}
});
});
return intersectedVoronoi;
};
const searchFarthestSpot = (voronoi, mdPoints) => {
let maxDistance = 0;
let maxDistanceLine = {};
let md = '';
voronoi.forEach(v => {
mdPoints.features.forEach(m => {
if (v.properties.mid === m.properties.id) {
v.geometry.coordinates[0].forEach(c => {
if (Array.isArray(c) && c.length === 2) {
const from = m;
const to = turf.point(c);
const distance = turf.distance(from, to);
console.log(distance);
if (maxDistance < distance) {
console.log(distance, m.geometry.coordinates, c);
maxDistance = distance;
maxDistanceLine = turf.lineString([m.geometry.coordinates, c]);
md = m.properties.name;
}
}
});
}
});
});
console.log('maxDistance:', maxDistance, md);
return maxDistanceLine;
};
const japanBorderToMap = (japanBorder) => {
map.addSource('japan', {
type: 'geojson',
data: japanBorder,
});
map.addLayer({
'id': 'japan',
'type': 'fill',
'source': 'japan',
'layout': {},
'paint': {
'fill-color': '#ed6498',
'fill-opacity': 0.3,
}
});
};
const mdPointsToMap = (mdPoints) => {
map.addSource('macdonalds', {
type: 'geojson',
data: mdPoints,
});
map.addLayer({
'id': 'macdonalds',
'type': 'circle',
'source': 'macdonalds',
'layout': {},
"paint": {
"circle-radius": 2,
"circle-color": "#007cbf"
}
});
};
const voronoiToMap = (voronoi) => {
map.addSource('voronoi', {
type: 'geojson',
data: {
"type": "FeatureCollection",
"features": voronoi,
},
});
map.addLayer({
'id': 'voronoi',
'type': 'fill',
'source': 'voronoi',
'layout': {},
'paint': {
'fill-color': '#088',
'fill-opacity': 0.3
}
});
};
const lineToMap = (maxDistanceLine) => {
map.addSource('maxDistanceLine', {
type: 'geojson',
data: maxDistanceLine,
});
map.addLayer({
'id': 'maxDistanceLine',
'type': 'line',
'source': 'maxDistanceLine',
"layout": {
"line-join": "round",
"line-cap": "round",
},
"paint": {
"line-color": "#ff6400",
"line-width": 8,
}
});
};
const handleGetData = (err, countries, macdonalds) => {
console.log('handleGetData', err);
const japanBorder = getJapanBorder(countries);
const mdPoints = getMDPoints(macdonalds);
const voronoi = makeVoronoi(mdPoints);
const relatedVoronoi = relateVoronoi(voronoi, mdPoints);
const intersectedVoronoi = intersectVoronoi(relatedVoronoi, japanBorder);
const maxDistanceLine = searchFarthestSpot(intersectedVoronoi, mdPoints);
japanBorderToMap(japanBorder);
mdPointsToMap(mdPoints);
voronoiToMap(intersectedVoronoi);
lineToMap(maxDistanceLine);
}
d3.queue()
.defer(d3.json, countriesGeoJsonURL)
.defer(d3.json, macdonaldsJsonURL)
.await(handleGetData);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment