Fix handling of MultiPolygon objects

This commit is contained in:
matt committed 2024-08-17 23:57:25 +10:00
1 parent 3718378545
commit 7436c808e3
2 files changed
+41 -16

No files matched your search

+1 -1
View File
@@ -16,7 +16,7 @@
\****************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var polylabel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! polylabel */ \"./node_modules/polylabel/polylabel.js\");\n\r\n\r\nfunction normaliseCouncilName(str) {\r\n const regex = /(.*?)(?:(?: Rural)?(?: City| Shire) Council)/g;\r\n const matches = str.matchAll(regex);\r\n\r\n // If we get a match, convert to slug format\r\n for (const match of matches) {\r\n return match[1].toLowerCase().replace(\" \", \"-\");\r\n }\r\n\r\n // If we didn't find any matches, try convert input to slug format\r\n return str.toLowerCase().replace(\" \", \"-\");\r\n};\r\n\r\nconst searchParams = new URLSearchParams(window.location.search);\r\nconst councilName = normaliseCouncilName(searchParams.get(\"council\"));\r\nconsole.log(councilName);\r\n\r\nmapboxgl.accessToken = 'pk.eyJ1IjoibWF0dHl3YXkiLCJhIjoiY2x6eG9vMzZyMHY2cDJqb3M1ODZnNjF4cyJ9.IX8CfYQZUaQhSjWgMXmsEA';\r\nconst map = new mapboxgl.Map({\r\n container: 'map',\r\n zoom: 10,\r\n style: 'mapbox://styles/mattyway/clzy2ozzf004k01pn840h9xdb',\r\n center: [145.00724,-37.79011]\r\n});\r\n\r\nfetch(\"wards_withboundaries.json\")\r\n .then(response => {\r\n response.json()\r\n .then((wardData) => {\r\n const filteredWardData = wardData.filter((ward) => normaliseCouncilName(ward.parentElectorateName) == councilName);\r\n\r\n var bounds = {\r\n \"west\": undefined,\r\n \"south\": undefined,\r\n \"east\": undefined,\r\n \"north\": undefined\r\n }\r\n\r\n var labelFeatures = [];\r\n\r\n filteredWardData.forEach(wardData => {\r\n const featureCollection = {\r\n 'type': 'FeatureCollection',\r\n 'features': [\r\n {\r\n 'type': 'Feature',\r\n 'geometry': JSON.parse(wardData.boundaryJson)\r\n }\r\n ]\r\n };\r\n\r\n featureCollection.features[0].geometry.coordinates[0].forEach(coordinate => {\r\n if (bounds.west == undefined || coordinate[0] < bounds.west) {\r\n bounds.west = coordinate[0];\r\n }\r\n\r\n if (bounds.south == undefined || coordinate[1] < bounds.south) {\r\n bounds.south = coordinate[1];\r\n }\r\n\r\n if (bounds.east == undefined || coordinate[0] > bounds.east) {\r\n bounds.east = coordinate[0];\r\n }\r\n\r\n if (bounds.north == undefined || coordinate[1] > bounds.north) {\r\n bounds.north = coordinate[1];\r\n }\r\n });\r\n\r\n // Add data\r\n map.addSource(\"data_\"+wardData.electorateId, {\r\n 'type': 'geojson',\r\n 'data': featureCollection\r\n });\r\n\r\n // Add a line along the data\r\n map.addLayer({\r\n 'id': \"outline_\"+wardData.electorateId,\r\n 'type': 'line',\r\n 'source': \"data_\"+wardData.electorateId,\r\n 'layout': {},\r\n 'paint': {\r\n 'line-color': '#0899fe',\r\n 'line-width': 3\r\n }\r\n });\r\n\r\n const centrePoint = (0,polylabel__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(featureCollection.features[0].geometry.coordinates, 0.000001);\r\n\r\n if (wardData.electorateName.includes(' ')) {\r\n // Breaking long names into newlines looks better\r\n const parts = wardData.electorateName.split(' ');\r\n // Special case if a ward starts with \"St\" (like \"St Albans East\")\r\n // Join the first two parts\r\n if (parts[0] == \"St\") {\r\n parts[0] = parts[0] + ' ' + parts[1];\r\n parts.splice(1, 1);\r\n }\r\n const wardNameNewLines = parts.join('\\n');\r\n labelFeatures.push({\r\n 'type': 'Feature',\r\n 'properties': {\r\n 'description': wardNameNewLines\r\n },\r\n 'geometry': {\r\n 'type': 'Point',\r\n 'coordinates'Line truncated
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var polylabel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! polylabel */ \"./node_modules/polylabel/polylabel.js\");\n\r\n\r\nfunction normaliseCouncilName(str) {\r\n const regex = /(.*?)(?:(?: Rural)?(?: City| Shire) Council)/g;\r\n const matches = str.matchAll(regex);\r\n\r\n // If we get a match, convert to slug format\r\n for (const match of matches) {\r\n return match[1].toLowerCase().replace(\" \", \"-\");\r\n }\r\n\r\n // If we didn't find any matches, try convert input to slug format\r\n return str.toLowerCase().replace(\" \", \"-\");\r\n};\r\n\r\nconst searchParams = new URLSearchParams(window.location.search);\r\nconst councilName = normaliseCouncilName(searchParams.get(\"council\"));\r\nconsole.log(councilName);\r\n\r\nmapboxgl.accessToken = 'pk.eyJ1IjoibWF0dHl3YXkiLCJhIjoiY2x6eG9vMzZyMHY2cDJqb3M1ODZnNjF4cyJ9.IX8CfYQZUaQhSjWgMXmsEA';\r\nconst map = new mapboxgl.Map({\r\n container: 'map',\r\n zoom: 10,\r\n style: 'mapbox://styles/mattyway/clzy2ozzf004k01pn840h9xdb',\r\n center: [145.00724,-37.79011]\r\n});\r\n\r\nfetch(\"wards_withboundaries.json\")\r\n .then(response => {\r\n response.json()\r\n .then((wardData) => {\r\n const filteredWardData = wardData.filter((ward) => normaliseCouncilName(ward.parentElectorateName) == councilName);\r\n\r\n var bounds = {\r\n \"west\": undefined,\r\n \"south\": undefined,\r\n \"east\": undefined,\r\n \"north\": undefined\r\n }\r\n\r\n function addToBounds(coordinate) {\r\n if (bounds.west == undefined || coordinate[0] < bounds.west) {\r\n bounds.west = coordinate[0];\r\n }\r\n\r\n if (bounds.south == undefined || coordinate[1] < bounds.south) {\r\n bounds.south = coordinate[1];\r\n }\r\n\r\n if (bounds.east == undefined || coordinate[0] > bounds.east) {\r\n bounds.east = coordinate[0];\r\n }\r\n\r\n if (bounds.north == undefined || coordinate[1] > bounds.north) {\r\n bounds.north = coordinate[1];\r\n }\r\n }\r\n\r\n var labelFeatures = [];\r\n\r\n filteredWardData.forEach(wardData => {\r\n const featureCollection = {\r\n 'type': 'FeatureCollection',\r\n 'features': [\r\n {\r\n 'type': 'Feature',\r\n 'geometry': JSON.parse(wardData.boundaryJson)\r\n }\r\n ]\r\n };\r\n\r\n if (featureCollection.features[0].geometry.type == \"Polygon\") {\r\n featureCollection.features[0].geometry.coordinates[0].forEach(coordinate => {\r\n addToBounds(coordinate);\r\n });\r\n }\r\n if (featureCollection.features[0].geometry.type == \"MultiPolygon\") {\r\n featureCollection.features[0].geometry.coordinates.forEach(polygon => {\r\n polygon[0].forEach(coordinate => {\r\n addToBounds(coordinate);\r\n });\r\n });\r\n }\r\n\r\n // Add data\r\n map.addSource(\"data_\"+wardData.electorateId, {\r\n 'type': 'geojson',\r\n 'data': featureCollection\r\n });\r\n\r\n // Add a line along the data\r\n map.addLayer({\r\n 'id': \"outline_\"+wardData.electorateId,\r\n 'type': 'line',\r\n 'source': \"data_\"+wardData.electorateId,\r\n 'layout': {},\r\n 'paint': {\r\n 'line-color': '#0899fe',\r\n 'line-width': 3\r\n }\r\n });\r\n\r\n var centrePoint;\r\n if (featureCollection.features[0].geometry.type == \"Polygon\") {\r\n centrePoint = (0,polylabel__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(featureCollection.features[0].geometry.coordinates, 0.000001);\r\n }\r\n if (featureCollection.features[0].geometry.type == \"MultiPolygon\") {\r\n // TODO: Find the biggest polygon in the multipolygon and use that to find the centre point \r\n // instead of just picking the Line truncated
/***/ }),
+40 -15
View File
@@ -38,20 +38,7 @@ fetch("wards_withboundaries.json")
"north": undefined
}
var labelFeatures = [];
filteredWardData.forEach(wardData => {
const featureCollection = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': JSON.parse(wardData.boundaryJson)
}
]
};
featureCollection.features[0].geometry.coordinates[0].forEach(coordinate => {
function addToBounds(coordinate) {
if (bounds.west == undefined || coordinate[0] < bounds.west) {
bounds.west = coordinate[0];
}
@@ -67,7 +54,33 @@ fetch("wards_withboundaries.json")
if (bounds.north == undefined || coordinate[1] > bounds.north) {
bounds.north = coordinate[1];
}
}
var labelFeatures = [];
filteredWardData.forEach(wardData => {
const featureCollection = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': JSON.parse(wardData.boundaryJson)
}
]
};
if (featureCollection.features[0].geometry.type == "Polygon") {
featureCollection.features[0].geometry.coordinates[0].forEach(coordinate => {
addToBounds(coordinate);
});
}
if (featureCollection.features[0].geometry.type == "MultiPolygon") {
featureCollection.features[0].geometry.coordinates.forEach(polygon => {
polygon[0].forEach(coordinate => {
addToBounds(coordinate);
});
});
}
// Add data
map.addSource("data_"+wardData.electorateId, {
@@ -87,7 +100,19 @@ fetch("wards_withboundaries.json")
}
});
const centrePoint = polylabel(featureCollection.features[0].geometry.coordinates, 0.000001);
var centrePoint;
if (featureCollection.features[0].geometry.type == "Polygon") {
centrePoint = polylabel(featureCollection.features[0].geometry.coordinates, 0.000001);
}
if (featureCollection.features[0].geometry.type == "MultiPolygon") {
// TODO: Find the biggest polygon in the multipolygon and use that to find the centre point
// instead of just picking the second polygon.
//
// The 2024 set of boundaries only uses 2 MultiPolygon objects (Cathedral in Murrindindi Shire Council and Island in Bass Coast Shire Council)
// Luckily, the second polygon for both objects results in a good label placement.
centrePoint = polylabel(featureCollection.features[0].geometry.coordinates[1], 0.000001);
}
if (wardData.electorateName.includes(' ')) {
// Breaking long names into newlines looks better