Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

My girlfriend is trying to create a webmap using OpenLayers that is similar to this one, which was done in ArcGIS Server. I thought I'd be able to help her as I have GIS and some coding experience but this is over my head.

She's wanting to use a WFS-capable template and already has a very basic page set up. She'd like users to be able to edit the data. Do you have any advice, know of any tutorials, or of any published maps that are similar to the Gender Map that we could take a look at? Neither of us have any real experience with webmaps and are panicking!

Thank you so much!!

Her current code is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-      strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>OpenLayers map preview</title>
    <!-- Import OL CSS, auto import does not work with our minified OL.js build -->
    <link rel="stylesheet" type="text/css"       href="http://southway.ddns.net:8888/geoserver/openlayers/theme/default/style.css"/>
    <!-- Basic CSS definitions -->
    <style type="text/css">
        /* General settings */
        body {
            font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
            font-size: small;
        }
        /* Toolbar styles */
        #toolbar {
            position: relative;
            padding-bottom: 0.5em;
            display: none;
        }

        #toolbar ul {
            list-style: none;
            padding: 0;
            margin: 0;
        }

        #toolbar ul li {
            float: left;
            padding-right: 1em;
            padding-bottom: 0.5em;
        }

        #toolbar ul li a {
            font-weight: bold;
            font-size: smaller;
            vertical-align: middle;
            color: black;
            text-decoration: none;
        }

        #toolbar ul li a:hover {
            text-decoration: underline;
        }

        #toolbar ul li * {
            vertical-align: middle;
        }

        /* The map and the location bar */
        #map {
            clear: both;
            position: relative;
            width: 1000px;
            height: 1000px;
            border: 1px solid black;
        }

        #wrapper {
            width: 512px;
        }

        #location {
            float: right;
        }

        #options {
            position: absolute;
            left: 13px;
            top: 7px;
            z-index: 3000;
        }

        /* Styles used by the default GetFeatureInfo output, added to make   IE happy */
        table.featureInfo, table.featureInfo td, table.featureInfo th {
            border: 1px solid #ddd;
            border-collapse: collapse;
            margin: 0;
            padding: 0;
            font-size: 90%;
            padding: .2em .1em;
        }

        table.featureInfo th {
            padding: .2em .2em;
            font-weight: bold;
            background: #eee;
        }

        table.featureInfo td {
            background: #fff;
        }

        table.featureInfo tr.odd td {
            background: #eee;
        }

        table.featureInfo caption {
            text-align: left;
            font-size: 100%;
            font-weight: bold;
            padding: .2em .2em;
        }
    </style>
    <!-- Import OpenLayers, reduced, wms read only version -->
    <script src="http://southway.ddns.net:8888/geoserver/openlayers/OpenLayers.js" type="text/javascript">
    </script>
    <script defer="defer" type="text/javascript">
        var map;
        var tiled;
        var pureCoverage = false;
        // pink tile avoidance
        OpenLayers.IMAGE_RELOAD_ATTEMPTS = 5;
        // make OL compute scale according to WMS spec
        OpenLayers.DOTS_PER_INCH = 25.4 / 0.28;

        function init(){
            // if this is just a coverage or a group of them, disable a few items,
            // and default to jpeg format
            format = 'image/png';
            if(pureCoverage) {
                document.getElementById('filterType').disabled = true;
                document.getElementById('filter').disabled = true;
                document.getElementById('antialiasSelector').disabled = true;
                document.getElementById('updateFilterButton').disabled = true;
                document.getElementById('resetFilterButton').disabled = true;
                document.getElementById('jpeg').selected = true;
                format = "image/jpeg";
            }

            var bounds = new OpenLayers.Bounds(
                -106.645652770996, 25.8371639251709,
                -93.5080337524414, 36.5007057189941
            );
            var options = {
                controls: [],
                maxExtent: bounds,
                maxResolution: 0.0513188242912289,
                projection: "EPSG:4326",
                units: 'degrees'
            };
            map = new OpenLayers.Map('map', options);

            // setup tiled layer
            tiled = new OpenLayers.Layer.WMS(
                "disability_project:county_dis_TX - Tiled",    "http://southway.ddns.net:8888/geoserver/disability_project/wms",
                {
                    LAYERS: 'disability_project:county_dis_TX',
                    STYLES: '',
                    format: format,
                    tiled: true,
                    tilesOrigin : map.maxExtent.left + ',' + map.maxExtent.bottom
                },
                {
                    buffer: 0,
                    displayOutsideMaxExtent: true,
                    isBaseLayer: true,
                    yx : {'EPSG:4326' : true}
                } 
            );


            map.addLayers([tiled]);

            // build up all controls
            map.addControl(new OpenLayers.Control.PanZoomBar({
                position: new OpenLayers.Pixel(2, 15)
            }));
            map.addControl(new OpenLayers.Control.Navigation());
            map.addControl(new OpenLayers.Control.Scale($('scale')));
            // map.addControl(new OpenLayers.Control.MousePosition({element: $('location')}));
            map.zoomToExtent(bounds);

            // support GetFeatureInfo
            map.events.register('click', map, function (e) {
                document.getElementById('nodelist').innerHTML = "Loading... please wait...";
                var params = {
                    REQUEST: "GetFeatureInfo",
                    EXCEPTIONS: "application/vnd.ogc.se_xml",
                    BBOX: map.getExtent().toBBOX(),
                    SERVICE: "WMS",
                    INFO_FORMAT: 'text/html',
                    QUERY_LAYERS: map.layers[0].params.LAYERS,
                    FEATURE_COUNT: 5000,
                    Layers: 'disability_project:county_dis_TX',
                    WIDTH: map.size.w,
                    HEIGHT: map.size.h,
                    format: format,
                    styles: map.layers[0].params.STYLES,
                    srs: map.layers[0].params.SRS};

                // handle the wms 1.3 vs wms 1.1 madness
                if(map.layers[0].params.VERSION == "1.3.0") {
                    params.version = "1.3.0";
                    params.j = parseInt(e.xy.x);
                    params.i = parseInt(e.xy.y);
                } else {
                    params.version = "1.1.1";
                    params.x = parseInt(e.xy.x);
                    params.y = parseInt(e.xy.y);
                }

                // merge filters
                if(map.layers[0].params.CQL_FILTER != null) {
                    params.cql_filter = map.layers[0].params.CQL_FILTER;
                } 
                if(map.layers[0].params.FILTER != null) {
                    params.filter = map.layers[0].params.FILTER;
                }
                if(map.layers[0].params.FEATUREID) {
                    params.featureid = map.layers[0].params.FEATUREID;
                }
                OpenLayers.loadURL("http://southway.ddns.net:8888/geoserver/disability_project/wms", params, this, setHTML, setHTML);
                OpenLayers.Event.stop(e);
            });
        }

        // sets the HTML provided into the nodelist element
        function setHTML(response){
            document.getElementById('nodelist').innerHTML = response.responseText;
        };

        // shows/hide the control panel
        function toggleControlPanel(event){
            var toolbar = document.getElementById("toolbar");
            if (toolbar.style.display == "none") {
                toolbar.style.display = "block";
            }
            else {
                toolbar.style.display = "none";
            }
            event.stopPropagation();
            map.updateSize()
        }

        // Tiling mode, can be 'tiled' or 'untiled'
        function setTileMode(tilingMode){
            if (tilingMode == 'tiled') {
                untiled.setVisibility(false);
                tiled.setVisibility(true);
                map.setBaseLayer(tiled);
            }
            else {
                untiled.setVisibility(true);
                tiled.setVisibility(false);
                map.setBaseLayer(untiled);
            }
        }

        // Transition effect, can be null or 'resize'
        function setTransitionMode(transitionEffect){
            if (transitionEffect === 'resize') {
                tiled.transitionEffect = transitionEffect;
                untiled.transitionEffect = transitionEffect;
            }
            else {
                tiled.transitionEffect = null;
                untiled.transitionEffect = null;
            }
        }

        // changes the current tile format
        function setImageFormat(mime){
            // we may be switching format on setup
            if(tiled == null)
              return;

            tiled.mergeNewParams({
                format: mime
            });
            untiled.mergeNewParams({
                format: mime
            });
            /*
            var paletteSelector = document.getElementById('paletteSelector')
            if (mime == 'image/jpeg') {
                paletteSelector.selectedIndex = 0;
                setPalette('');
                paletteSelector.disabled = true;
            }
            else {
                paletteSelector.disabled = false;
            }
            */
        }

        // sets the chosen style
        function setStyle(style){
            // we may be switching style on setup
            if(tiled == null)
              return;

            tiled.mergeNewParams({
                styles: style
            });
            untiled.mergeNewParams({
                styles: style
            });
        }

        // sets the chosen WMS version
        function setWMSVersion(wmsVersion){
            // we may be switching style on setup
            if(wmsVersion == null)
              return;

            if(wmsVersion == "1.3.0") {
               origin = map.maxExtent.bottom + ',' + map.maxExtent.left;
            } else {
               origin = map.maxExtent.left + ',' + map.maxExtent.bottom;
            }

            tiled.mergeNewParams({
                version: wmsVersion,
                tilesOrigin : origin
            });
            untiled.mergeNewParams({
                version: wmsVersion
            });
        }

        function setAntialiasMode(mode){
            tiled.mergeNewParams({
                format_options: 'antialias:' + mode
            });
            untiled.mergeNewParams({
                format_options: 'antialias:' + mode
            });
        }

        function setPalette(mode){
            if (mode == '') {
                tiled.mergeNewParams({
                    palette: null
                });
                untiled.mergeNewParams({
                    palette: null
                });
            }
            else {
                tiled.mergeNewParams({
                    palette: mode
                });
                untiled.mergeNewParams({
                    palette: mode
                });
            }
        }

        function setWidth(size){
            var mapDiv = document.getElementById('map');
            var wrapper = document.getElementById('wrapper');

            if (size == "auto") {
                // reset back to the default value
                mapDiv.style.width = null;
                wrapper.style.width = null;
            }
            else {
                mapDiv.style.width = size + "px";
                wrapper.style.width = size + "px";
            }
            // notify OL that we changed the size of the map div
            map.updateSize();
        }

        function setHeight(size){
            var mapDiv = document.getElementById('map');

            if (size == "auto") {
                // reset back to the default value
                mapDiv.style.height = null;
            }
            else {
                mapDiv.style.height = size + "px";
            }
            // notify OL that we changed the size of the map div
            map.updateSize();
        }

        function updateFilter(){
            if(pureCoverage)
              return;

            var filterType = document.getElementById('filterType').value;
            var filter = document.getElementById('filter').value;

            // by default, reset all filters
            var filterParams = {
                filter: null,
                cql_filter: null,
                featureId: null
            };
            if (OpenLayers.String.trim(filter) != "") {
                if (filterType == "cql") 
                    filterParams["cql_filter"] = filter;
                if (filterType == "ogc") 
                    filterParams["filter"] = filter;
                if (filterType == "fid") 
                    filterParams["featureId"] = filter;
            }
            // merge the new filter definitions
            mergeNewParams(filterParams);
        }

        function resetFilter() {
            if(pureCoverage)
              return;

            document.getElementById('filter').value = "";
            updateFilter();
        }

        function mergeNewParams(params){
            tiled.mergeNewParams(params);
            untiled.mergeNewParams(params);
        }
    </script>
</head>
<body onload="init()">

    <div id="map">
    </div>
    <div id="wrapper">
        <div id="location">location</div>
        <div id="scale">
        </div>
    </div>
    <div id="nodelist">
        <em>Click on the map to get feature info</em>
    </div>
</body>

share|improve this question
add comment

3 Answers 3

I posted this answer on reddit as well, but I think it will be beneficial here too.

I've spent a lot of time with Geoserver setting up an application with OpenLayers, and I think I understand what you are looking for, here are my thoughts.

For web maps, it is best to use the web map service (wms). This essentially takes your spatial files (.shp, sql database...etc what have you) and creates image tiles to display in your map. While you are correct, the generated tiles are in raster format, the map can behave as if they are vector features.

I'll start with styling, each layer can have its own sld stylesheet. These are all stored on the Geoserver and managed through the Style editor (found under the data pane). You can learn more about these styles on geoserver website, another poster mentioned.

In order to make your map 'clickable' and access the data from your attribute tables through the web app, take a look at the Freemarker templates and GetFeatureInfo requests on the Geoserver website: http://docs.geoserver.org/latest/en/user/tutorials/GetFeatureInfo/index.html http://docs.geoserver.org/latest/en/user/tutorials/freemarker.html#tutorial-freemarkertemplate

These GetFeatureInfo requests are what show up when you click on the map in the 'preview link' from Geoserver. The reason they don't work in your html file locally is because of builtin browser XSS prevention. Domains and ports must match in the url making the request and the url being requested.

If you have any questions, feel free to pm me. Here's an example of a map I worked on using OpenLayers and Geoserver: campusmap.designbygregg.com

share|improve this answer
    
I might be wrong, but wouldn't a wms service only allow you to make the objects 'clickable' but not editable? To make it editable you would need to display your data as vector objects, e.g. via wfs service. –  pecoanddeco May 20 at 12:47
add comment

To be able to edit the data you might want to look at the WFS-T technology. Here is a nice tutorial for OpenLayers with GeoServer and PostGIS.
Note that you don't have to use PostGIS if you don't want to, this works also with simply loading some shape files to GeoServer

Hope this helps :)

share|improve this answer
add comment

This is quite a wide ranging question. It might be worth looking at some of the OpenLayers examples to give you an idea of where to get started. Probably the WFS Transaction Example would be the most useful.

Apart from how to handle the client side editing in OpenLayers you also need to think about how you're going to store the data. To do this you'll need something like GeoServer or MapServer to handle the requests on your server, and then somewhere to store the data, either in a spatial database or files on the server.

It's hard to point you to a single resource to do all this though as you'll need to use a range of technologies to achieve what you want.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.