Geometry viewer
View GeoJSON or WKT geometries on a base map
by Adam Snyder
HTML
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css">
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="http://tombatossals.github.io/angular-leaflet-directive/dist/angular-leaflet-directive.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="http://cdn-geoweb.s3.amazonaws.com/terraformer/1.0.4/terraformer.min.js"></script>
<script src="http://cdn-geoweb.s3.amazonaws.com/terraformer-wkt-parser/1.0.0/terraformer-wkt-parser.min.js"></script>
<div ng-app="myapp">
<div ng-controller="MapController">
<div class="map-container">
<leaflet id="map" defaults="map.defaults" geojson="features.geojson" center="map.center"></leaflet>
</div>
<div class="form-container">
<form>
<textarea rows="8" ng-model="form.text" placeholder="Enter WKT or GeoJSON ..."></textarea>
<button class="btn btn-danger" ng-click="form.text=''" ng-disabled="form.text.length===0">Clear</button>
<button ng-if="form.curId==null" class="btn btn-primary" ng-click="addFeature(form.text, form.autoZoom)" ng-disabled="form.text.length===0">Add</button>
<button ng-if="form.curId!=null" class="btn btn-primary" ng-click="updateFeature(form.text, form.autoZoom, form.curId)" ng-disabled="form.text.length===0">Update</button>
<button class="btn btn-default" ng-click="zoomToFeatures()">Zoom to fit</button>
<input type="checkbox" ng-model="form.autoZoom">Auto fit</form>
</div>
<div class="feature-container">
<ul class="list-unstyled">
<li ng-repeat="f in features.original | orderBy:'id'" title={{f.text}}>
<input type="checkbox" ng-model="f.visible" ng-change="updateLayers()" ng-disabled="form.curId!=null"> <span class="name">[{{f.id+1}}] {{f.name}}</span>
...
CSS
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.map-container {
bottom: 0;
left: 0;
position: absolute;
right: 300px;
top: 0;
}
.form-container {
height: 200px;
padding: 5px;
position: absolute;
right: 0;
top: 0;
width: 300px;
}
.feature-container {
bottom: 0;
padding: 5px;
position: absolute;
right: 0;
top: 220px;
width: 300px;
overflow-y: auto;
overflow-x: hidden;
}
.angular-leaflet-map {
height: 100%;
}
form textarea {
width: 100%;
}
ul > li {
padding-bottom: 5px;
white-space: nowrap;
}
JavaScript
var app = angular.module('myapp', ['leaflet-directive']);
app.controller('MapController', function ($scope, $timeout, $window, leafletBoundsHelpers, leafletData) {
$scope.map = {
defaults: {},
center: {
lat: 0,
lng: 0,
zoom: 2
}
};
$scope.form = {
counter: 0,
text: '',
autoZoom: true,
curId: null
};
$scope.features = {
original: [],
geojson: {
data: {
type: 'FeatureCollection',
features: []
},
options: {
style: {
fillColor: 'green',
weight: 2,
opacity: 1,
color: 'black',
fillOpacity: 0.7
},
onEachFeature: function (f, l) {
$scope.featureGroup.addLayer(l);
}
}
}
};
$scope.makeFeature = function (text) {
try {
if (text.indexOf('{') < 0) {
return Terraformer.WKT.parse(text);
}
var geoJson = JSON.parse(text);
Terraformer.WKT.convert(geoJson);
return geoJson;
} catch (Exception) {
return;
}
};
$scope.updateLayers = function () {
var visibleFeatures = $scope.features.original.filter(function (f) {
return f.visible;
});
$scope.featureGroup = L.featureGroup();
$scope.features.geojson.data.features = visibleFeatures.map(function (f) {
return $scope.makeFeature(f.text);
});
};
$scope.validate = function (text) {
var feature = $scope.makeFeature(text);
if (!feature) {
$window.alert('Invalid geometry, try again');
return;
}
return feature;
};
$scope.refreshMap = function (zoom) {
$scope.updateLayers();
...