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();

  ...