Skip to content

Instantly share code, notes, and snippets.

@nrenner
Last active March 24, 2023 11:40
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save nrenner/5371796 to your computer and use it in GitHub Desktop.
Save nrenner/5371796 to your computer and use it in GitHub Desktop.
Inverse fill area (GeoJSON)
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="'Clipping'/highlighting an area by creating a filled outside polygon with area as hole">
<title>Inverse fill area (GeoJSON)</title>
<link rel="stylesheet" href="http://openlayers.org/api/2.12/theme/default/style.css">
<style>
html, body, #map {
margin: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="http://openlayers.org/api/2.12/OpenLayers.js"></script>
<script src="index.js"></script>
</body>
</html>
(function() {
var map;
// load admin. boundary
// GeoJSON from http://www.file-upload.net/download-7458340/62428.gjson.html
var request = OpenLayers.Request.GET({
url : "62428.geojson",
async : false
});
var format = new OpenLayers.Format.GeoJSON({
"internalProjection": "EPSG:900913",
"externalProjection": "EPSG:4326"
});
var boundary = format.read(request.responseText)[0];
var bounds = boundary.geometry.getBounds();
map = new OpenLayers.Map({
div : "map",
projection : "EPSG:900913",
displayProjection : "EPSG:4326",
controls : [],
restrictedExtent : bounds.scale(1.3)
});
map.addControl(new OpenLayers.Control.ArgParser());
map.addControl(new OpenLayers.Control.Attribution());
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
map.addControl(new OpenLayers.Control.Navigation({
// disabled, fill rendered too slow when panning fast (base map appears)
dragPanOptions : {
enableKinetic : false
}
}));
map.addControl(new OpenLayers.Control.PanZoomBar());
map.addControl(new OpenLayers.Control.Permalink());
// base map with restricted extent and limited zoom
var zoomOffset = 11;
var osm = new OpenLayers.Layer.OSM("OSM Mapnik", null, {
zoomOffset : zoomOffset,
maxResolution : 156543.03390625 / Math.pow(2, zoomOffset),
numZoomLevels : 18 - zoomOffset + 1,
attribution : "&copy; <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors",
});
map.addLayer(osm);
// vector overlay for "clipping"/highlighting an area
var style = {
strokeColor : 'purple',
strokeWidth : 2,
strokeOpacity : 0.6,
fillColor : '#FFF',
fillOpacity : 1.0
};
var boundaryLayer = new OpenLayers.Layer.Vector("Boundary", {
displayInLayerSwitcher : false,
style : style,
// extend polygon clipping around map view, so that base map is always covered when panning
ratio : 3.0,
// SVG renderer has a clipping issue at high zooms (polygon disappears)
renderers : [ "VML", "Canvas" ], // "SVG",
attribution : '<br>data licensed under <a href="http://opendatacommons.org/licenses/odbl/">ODbL</a>'
});
// Create polygon with an outer outside of the viewable extent and the actual boundary as inner hole.
// disabled world-wide outer, does not work with Firefox 19 (fill disappears at zoom 16 and higher).
// var inversePolygon = map.getMaxExtent().toGeometry();
var features = [];
var inversePolygon = bounds.scale(5.0).toGeometry();
features.push(new OpenLayers.Feature.Vector(inversePolygon));
var geom = boundary.geometry;
if (geom instanceof OpenLayers.Geometry.MultiPolygon) {
// add as holes to outer polygon (admin boundary with exclaves)
for (var i = 0; i < geom.components.length; i++) {
var polygon = geom.components[i];
var linearRing = polygon.components[0];
inversePolygon.addComponent(linearRing);
}
} else if (geom instanceof OpenLayers.Geometry.Polygon) {
var linearRing = geom.components[0];
inversePolygon.addComponent(linearRing);
if (geom.components.length > 1) {
// convert inner holes to separate, standalone polygons (enclaves within admin boundary)
for (var i = 1; i < geom.components.length; i++) {
var poly = new OpenLayers.Geometry.Polygon([geom.components[i]]);
features.push(new OpenLayers.Feature.Vector(poly));
}
}
}
boundaryLayer.addFeatures(features);
map.addLayer(boundaryLayer);
if (!map.getCenter()) {
map.zoomToExtent(bounds);
}
})();
@indus
Copy link

indus commented Nov 19, 2022

@mnowaczyk thanks for sharing your code 🙇 I didn't even expected an answer after all the time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment