Link to home
Start Free TrialLog in
Avatar of GreyHippo
GreyHippo

asked on

How to add popup box to GeoJSON layer using Openlayers?

Hello,

I have a web map based on Openlayers and it will have a few GeoJSON vector layers.  I am trying to get the popup function to work with my vector layer but I am having trouble.  I am able to select the feature but it does not show any popup.

GeoJSON file:

{
"type": "FeatureCollection",
                                                                                
"features": [
{ "type": "Feature", "id": 0, "properties": { "STRUCT_ID": "19-19E", "FIELD_ID": null, "Layer": "C-SSWR-MHOL", "13_165_79": "No Work" }, "geometry": { "type": "Point", "coordinates": [ -80.231324693555621, 40.66814758777484 ] } }
,
{ "type": "Feature", "id": 1, "properties": { "STRUCT_ID": "19-19D", "FIELD_ID": null, "Layer": "C-SSWR-MHOL", "13_165_79": "No Work" }, "geometry": { "type": "Point", "coordinates": [ -80.231300734788178, 40.668041857766056 ] } }
,
{ "type": "Feature", "id": 2, "properties": { "STRUCT_ID": "19-19C", "FIELD_ID": null, "Layer": "C-SSWR-MHOL", "13_165_79": "No Work" }, "geometry": { "type": "Point", "coordinates": [ -80.230900091347664, 40.667460525092594 ] } }

]
}

Open in new window


Index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<script src="http://openlayers.org/dev/OpenLayers.js"></script>
    <script type="text/javascript">
        var lon = -80.233,
            lat = 40.665,
            zoom = 15,
            epsg4326 = new OpenLayers.Projection('EPSG:4326'),
            epsg900913 = new OpenLayers.Projection('EPSG:900913');
        var arrayAerial;
        var select;
        
        
        
        
        function init(){
            var map = new OpenLayers.Map('map', {
                units: 'm',
                numZoomLevels: 19,
                controls: [
                    new OpenLayers.Control.Navigation(),
                    new OpenLayers.Control.ScaleLine(),
                    new OpenLayers.Control.MousePosition(),
                    new OpenLayers.Control.LayerSwitcher(),
                    //new OpenLayers.Control.OverviewMap(),
                    new OpenLayers.Control.PanZoomBar()
                ],
                projection: epsg900913,
                displayProjection: epsg4326 //Is used for displaying coordinates in appropriate CRS by MousePosition control
            });
            
            
            
            
            
                        
            arrayOSM = ["http://otile1.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg",
                    "http://otile2.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg",
                    "http://otile3.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg",
                    "http://otile4.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg"];
              
            
            arrayAerial = ["http://otile1.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg",
                        "http://otile2.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg",
                        "http://otile3.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg",
                        "http://otile4.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg"];
                        
            baseOSM = new OpenLayers.Layer.OSM("MapQuest-OSM Tiles", arrayOSM);                        
            baseAerial = new OpenLayers.Layer.OSM("MapQuest Open Aerial Tiles", arrayAerial);

            var mh_layer = new OpenLayers.Layer.Vector("Manholes", {
                styleMap: new OpenLayers.StyleMap({
                        "default": new OpenLayers.Style({
                        pointRadius: 5,
                        fillColor: "#9de24f",
                        strokeColor: "#0d4cd6",
                        strokeWidth: 1,
                        strokeOpacity: 0.8 } ),
                       
                    }),
            
                projection: epsg4326,
                strategies: [new OpenLayers.Strategy.Fixed()],
                protocol: new OpenLayers.Protocol.HTTP({
                    url: "./mh.geojson",
                    format: new OpenLayers.Format.GeoJSON({
                        extractAttributes: true
                    })
                })
            });
            
            map.addLayer(baseOSM);
            map.addLayer(baseAerial);
            map.addLayer(mh_layer);
            
            select = new OpenLayers.Control.SelectFeature(mh_layer);
            
            mh_layer.events.on({
                "featureselected": onFeatureSelect,
                "featureunselected": onFeatureUnselect
            });
            
            map.addControl(select);
            select.activate();  
            
            map.setCenter(new OpenLayers.LonLat(lon, lat).transform(epsg4326, epsg900913), zoom);
        }
        
        function onPopupClose(evt) {
            select.unselectAll();
        }
        function onFeatureSelect(event) {
            var feature = event.feature;
            popup = new OpenLayers.Popup.FramedCloud(
                "chicken", 
                feature.geometry.getBounds().getCenterLonLat(),
                null,
                "<h2>"+feature.attributes.STRUCT_ID + "</h2>",
                null, 
                true, 
                onPopupClose);
                
            feature.popup = popup;
            map.addPopup(popup);
        }
        
        function onFeatureUnselect(event) {
            var feature = event.feature;
            if(feature.popup) {
                map.removePopup(feature.popup);
                feature.popup.destroy();
                delete feature.popup;
            }
        }
    </script>
  </head>
  <body onload="init()">
    <div id="map" style="position: absolute; right: 0px; top: 0px; width: 100%; height: 100%"></div>
    
    <div id="tags">
          kml, popup, feature
      </div>
  </body>
</html>

Open in new window

SOLUTION
Avatar of leakim971
leakim971
Flag of Guadeloupe image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of GreyHippo
GreyHippo

ASKER

I found my own solution



<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <meta name="apple-mobile-web-app-capable" content="yes">
    
    <style type="text/css">
        #controlToggle li {
            list-style: none;
        }
        p {
            width: 512px;
        }
        #options {
            position: relative;
            width: 512px;
        }
        #output {
            float: right;
        }

        /* avoid pink tiles */
        .olImageLoadError {
            background-color: transparent !important;
        }
        
        div.floating-menu4 {
        position:absolute;
        background:#d5e2f2;
        top:0px;
        left:100px;
        border:1px solid #a9b8cb;
        width:100%;
        height:2.5%;
        z-index:100;
    }
    
    div.result {
        position:fixed;
        background:white;
        top: 2.5px;
        right: 0px;
        border: 1px solid #a9b8cb;
        width: 20%;
        height: 20px;
        z-index: 100;
    }
    
    div.main-menu {
        position:fixed;
        background:#d5e2f2;
        top: 0px;
        left: 0px;
        border: 1px solid #a9b8cb;
        width: 80%;
        height: 2.5%;
        z-index: 100;
    }
    
    #stuff ul li { display: inline; }
    #navcontainer ul {
        margin: 0;
        padding: 0;
        list-style-type: none;
        text-align: left;
    }
    
    #navcontainer ul li { display: inline; }
    
    #navcontainer ul li a {
        text-decoration: none;
        padding: .2em 1em;
        color: #fff;
        background-color: #036;
    }

    #navcontainer ul li a:hover {
        color: #fff;
        background-color: #369;
    }
    
    div.floating-menu3 a, div.floating-menu h3 {display:block;margin:0 0.5em;}
    
    div.search-area {
        position: fixed;
        top:0px;
        left:400px;
        width:80%;
        height:10px;
        z-index:100;
    }
    
    
    </style>
    <script src="http://openlayers.org/dev/OpenLayers.js"></script>
    <script src="http://maps.google.com/maps/api/js?v=3.2&sensor=false"></script> 
    <script type="text/javascript">
    var lon = -80.233; //conway
        var lat = 40.665;
        var zoom = 15;
        var url_smh = "./conway_mh.geojson";
        var url_sp = "./conway_sp.geojson";
        
        var map, measureControls;
        var epsg4326 = new OpenLayers.Projection('EPSG:4326');
        var epsg900913 = new OpenLayers.Projection('EPSG:900913');
        function init(){
            //map = new OpenLayers.Map('map');
            //map = new OpenLayers.Map( $('map'), {controls: [] } );
            
             map = new OpenLayers.Map('map', {
                //units: 'ft',
                numZoomLevels: 23,
                controls: [],
                //projection: epsg900913,
                projection: epsg4326,
                displayProjection: epsg4326//4326 //Is used for displaying coordinates in appropriate CRS by MousePosition control
            });
            
            
            var wmsLayer = new OpenLayers.Layer.WMS( "OpenLayers WMS", 
                "http://vmap0.tiles.osgeo.org/wms/vmap0?", {layers: 'basic'}); 
                
            var gmap = new OpenLayers.Layer.Google(
                "Google Streets", // the default
                {numZoomLevels: 20}
            );
            
            var gsat = new OpenLayers.Layer.Google(
                "Google Satellite",
                {type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22}
                // used to be {type: G_SATELLITE_MAP, numZoomLevels: 22}
            );
        
            arrayOSM = ["http://otile1.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg",
                    "http://otile2.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg",
                    "http://otile3.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg",
                    "http://otile4.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg"];

            arrayAerial = ["http://otile1.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg",
                        "http://otile2.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg",
                        "http://otile3.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg",
                        "http://otile4.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.jpg"];
                        
            baseOSM = new OpenLayers.Layer.OSM("MapQuest-OSM Tiles", arrayOSM);                        
            baseAerial = new OpenLayers.Layer.OSM("MapQuest Open Aerial Tiles", arrayAerial);
            
            var mh_layer = new OpenLayers.Layer.Vector("Manhole", {
                searchfields: [ 'STRUCT_ID', 'OWNER_NAME', 'GPS_DATE' ], 
                titlefield: 'STRUCT_ID', 
                styleMap: new OpenLayers.StyleMap({
                    "default": new OpenLayers.Style({
                        pointRadius: 3,
                        fillColor: "#9de24f",
                        fillOpacity: 1,
                        strokeColor: "#2da725",
                        strokeWidth: 0.5,
                        //strokeOpacity: 0.8, 
                    }),
                }),
                //projection: map.displayProjection,
                projection: epsg4326,//4326,
                rendererOptions: { zIndexing: true },
                strategies: [new OpenLayers.Strategy.Fixed()],
                protocol: new OpenLayers.Protocol.HTTP({
                    //url: "./scott_mh.geojson",
                    url: url_smh,
                    format: new OpenLayers.Format.GeoJSON({
                        extractStyles: true,
                        extractAttributes: true
                    })
                })
            });
            
            var sp_layer = new OpenLayers.Layer.Vector("Pipes", {
                styleMap: new OpenLayers.StyleMap({
                        "default": new OpenLayers.Style({
                        //pointRadius: 5,
                        //fillColor: "#2da725",
                        //fillOpacity: 0.8,
                        strokeColor: "#34BF3F",
                        strokeWidth: 3,
                        strokeOpacity: 0.8 } ),
                       
                    }),
                //projection: map.displayProjection,
                projection: epsg4326,
                rendererOptions: { zIndexing: true },
                strategies: [new OpenLayers.Strategy.Fixed()],
                protocol: new OpenLayers.Protocol.HTTP({
                    
                    url: url_sp,
                    format: new OpenLayers.Format.GeoJSON({
                        extractStyles: true,
                        extractAttributes: true
                    })
                })
            });

            map.addLayers([gmap, gsat, baseOSM, baseAerial, sp_layer, mh_layer]);
            map.addControl(new OpenLayers.Control.LayerSwitcher());
            map.addControl(new OpenLayers.Control.MousePosition());
            map.addControl(new OpenLayers.Control.PanZoomBar());
            map.addControl(new OpenLayers.Control.ScaleLine());
            map.addControl(new OpenLayers.Control.Navigation());
            //select = new OpenLayers.Control.SelectFeature([mh_layer]);
            
            mh_layer.events.on({
                "featureselected": onFeatureSelect,
                "featureunselected": onFeatureUnselect
            });
            
            sp_layer.events.on({
                "featureselected": onPipeSelect,
                "featureunselected": onFeatureUnselect
            });
            
            //map.addControl(select);
            
            // style the sketch fancy
            var sketchSymbolizers = {
                "Point": {
                    pointRadius: 4,
                    graphicName: "square",
                    fillColor: "white",
                    fillOpacity: 1,
                    strokeWidth: 1,
                    strokeOpacity: 1,
                    strokeColor: "#333333"
                },
                "Line": {
                    strokeWidth: 3,
                    strokeOpacity: 1,
                    strokeColor: "#666666",
                    //strokeDashstyle: "dash"
                },
                "Polygon": {
                    strokeWidth: 2,
                    strokeOpacity: 1,
                    strokeColor: "#666666",
                    fillColor: "white",
                    fillOpacity: 0.3
                }
            };
            var style = new OpenLayers.Style();
            style.addRules([
                new OpenLayers.Rule({symbolizer: sketchSymbolizers})
            ]);
            var styleMap = new OpenLayers.StyleMap({"default": style});
            
            // allow testing of specific renderers via "?renderer=Canvas", etc
            var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;
            renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;

            measureControls = {
                line: new OpenLayers.Control.Measure(
                    OpenLayers.Handler.Path, {
                        persist: true,
                        geodesic: true,
                        //setImmediate: true,
                        //setImmediate: function(	immediate	),
                        immediate: true,
                        displaySystem: 'english',

                        handlerOptions: {
                            layerOptions: {
                                renderers: renderer,
                                styleMap: styleMap
                            }
                        }
                    }
                ),
                polygon: new OpenLayers.Control.Measure(
                    OpenLayers.Handler.Polygon, {
                        persist: true,
                        geodesic: true,
                        immediate: true,
                        displaySystem: 'english',
                        handlerOptions: {
                            layerOptions: {
                                renderers: renderer,
                                styleMap: styleMap
                            }
                        }
                    }
                ),
                select: new OpenLayers.Control.SelectFeature([mh_layer, sp_layer])
            };
            
            var control;
            for(var key in measureControls) {
                control = measureControls[key];
                control.events.on({
                    "measure": handleMeasurements,
                    "measurepartial": handleMeasurements,
                    //"featureselected": onFeatureSelect,
                    //"featureunselected": onFeatureUnselect
                });
                map.addControl(control);
            }
            
            //map.setCenter(new OpenLayers.LonLat(lon, lat), 3);
            map.setCenter(new OpenLayers.LonLat(lon,lat).transform(new OpenLayers.Projection("EPSG:4326"),map.getProjectionObject()), zoom);
            
            document.getElementById('noneToggle').checked = true;
        }
        
        function handleMeasurements(event) {
            var geometry = event.geometry;
            var units = event.units;
            var order = event.order;
            var measure = event.measure;
            var element = document.getElementById('output');
            var out = "";
            if(order == 1) {
                out += "measure: " + measure.toFixed(3) + " " + units;
            } else {
                out += "measure: " + measure.toFixed(3) + " " + units + "<sup>2</" + "sup>";
            }
            element.innerHTML = out;
        }

        function toggleControl(element) {
            for(key in measureControls) {
                var control = measureControls[key];
                 //alert ("test: " + control); 
                if(element.value == key && element.checked) {
                    control.activate();
                    //alert ("activated");
                } else {
                    control.deactivate();
                }
            }
        }
        
        
        function onPopupClose(evt) {
            select.unselectAll();
        }
        
        
        function onFeatureSelect(event) {
            var feature = event.feature;
            // Since KML is user-generated, do naive protection against
            // Javascript.
            var content = "Manhole ID:" + feature.attributes.STRUCT_ID;
            if (content.search("<script") != -1) {
                content = "Content contained Javascript! Escaped content below.<br>" + content.replace(/</g, "&lt;");
            }
            popup = new OpenLayers.Popup.FramedCloud("chicken", 
                                     feature.geometry.getBounds().getCenterLonLat(),
                                     new OpenLayers.Size(100,100),
                                     content,
                                     null, true, onPopupClose);
            feature.popup = popup;
            map.addPopup(popup);
        }
        
        function onPipeSelect(event) {
            var feature = event.feature;
            // Since KML is user-generated, do naive protection against
            // Javascript.
            var content = "Pipe Report: " + "<a href=" + feature.attributes.REPORT_FL + " target=_tab>" + feature.attributes.REPORT_FL + "</a>" + " <br> " +
                             "Pipe Video: " + "<a href=" + feature.attributes.VIDEO_FL + " target=_tab>" + feature.attributes.VIDEO_FL + "</a>";
                            
            
            if (content.search("<script") != -1) {
                content = "Content contained Javascript! Escaped content below.<br>" + content.replace(/</g, "&lt;");
            }
            popup = new OpenLayers.Popup.FramedCloud("chicken", 
                                     feature.geometry.getBounds().getCenterLonLat(),
                                     new OpenLayers.Size(100,100),
                                     content,
                                     null, true, onPopupClose);
            feature.popup = popup;
            map.addPopup(popup);
        }
        
        function onFeatureUnselect(event) {
            var feature = event.feature;
            if(feature.popup) {
                map.removePopup(feature.popup);
                feature.popup.destroy();
                delete feature.popup;
            }
        }
        
        function testResults (form) {
            var TestVar = form.inputbox.value; 
            alert ("You typed: " + TestVar); 
        }
        
        //layer = map.getLayersByName('mh_layer')[0] 
        //keyword = "Creek" 
        //titlediv = $('#search_title'); 
        //resultdiv = $('#search_results'); 
        //searchVector(layer,keyword,titlediv,resultdiv); 
        
        function searchVector(layer,searchterm,title_div,results_div) {
            // no features? hide the output section and bail 
            if (! layer.features.length) {
                title_div.hide(); 
                results_div.hide(); 
                handleNoResultsFound(); 
                return; 
            } 

            // iterate over each feature, assume it is NOT a match for the filter 
            // iterate over the filter fields, see if this feature's value for that field fits the filter 
            // if so, tag as a match and quit iterating for this feature 
            var findcount = 0; 
            searchterm = searchterm.toLowerCase(); 
            //alert ("searchterm: " + searchterm);
            
            for (var p=0, fl=layer.features.length; p<fl; p++) { 
                var feature = layer.features[p]; 
                var matched = false; 
                for (var q=0, sl=layer.searchfields.length; q<sl; q++) { 
                    var field = layer.searchfields[q]; 
                    
                    try { 
                    if (feature.attributes[field].toLowerCase().indexOf(searchterm) != -1) { 
                        matched = true; 
                        break; } 
                        } catch (e) { 
                    true; 
                    //console.error('Trying to use nonexistent searchfield:                     'Layer ' + layer.name + ', Field: ' + field); 
                    }
                }
                //alert ("matched:" + matched); 
                if (! matched) continue; 
                // if we got here, then the feature IS a match 
                findcount++; 
                var title  = feature.attributes[layer.titlefield]; 
                var bbox   = feature.geometry.getBounds(); 
                var feature_center = feature.geometry.getBounds().getCenterLonLat();
                //var feature_centroid = feature.geometry.getCentroid();
                                
                var content = "Manhole ID:" + feature.attributes.STRUCT_ID;
                popup = new OpenLayers.Popup.FramedCloud("chicken", 
                                     feature.geometry.getBounds().getCenterLonLat(),
                                     new OpenLayers.Size(100,100),
                                     content,
                                     null, true, onPopupClose);
                feature.popup = popup;
                map.addPopup(popup);
                
                document.getElementById("my_search_results").innerHTML=feature_center;
                map.setCenter(feature.geometry.getBounds().getCenterLonLat(),18);
                //alert ("fc: " + feature_center + "\n" + "centroid: " + feature_centroid);
                
            } 
            
            //alert ("matched:" + matched);
            
            // no matches? hide the output section and bail 
            //if (! findcount) { 
            //    title_div.hide(); 
            //    results_div.hide(); 
            //} 
        } 




        function addToSearchResults(results_div,title,bbox) { 
            // make up the basic HTML of the title 
            // optionally add something to do with the bbox, e.g. zoom the map 
            alert ("search function" + title);
            var row  = $('<tr></tr>'); 
            var cell = $('<td></td>').text(title); 
            alert (" -- " );
            row.append(cell); 
        } 
        
        function searchTest (form) {
            layer = map.getLayersByName(form.layer.value)[0];
            keyword = form.searchterm.value;  //"Creek" 
            titlediv = $('#tdiv'); //search_title
            resultdiv = $('#rdiv'); //search_results
            searchVector(layer,keyword,titlediv,resultdiv); 
            
        }
        
    </script>
  </head>
  <body onload="init()">
    
    <div id="map" style="position: absolute; right: 0px; top: 2.5%; width: 100%; height: 97.5%; z-index: 1"></div>
    <div id="options">
        
        <div id="output" class="result">
        </div>
        
        <div id="navcontainer" class="main-menu">
        <ul id="controlToggle" >
            <li>
                <input type="radio" name="type" value="none" id="noneToggle"
                       onclick="toggleControl(this);" checked="checked" />
                <label for="noneToggle">navigate</label>
            </li>
            <li>
                <input type="radio" name="type" value="line" id="lineToggle" onclick="toggleControl(this);" />
                <label for="lineToggle">measure distance</label>
            </li>
            <li>
                <input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" />
                <label for="polygonToggle">measure area</label>
            </li>
            <li>
                <input type="radio" name="type" value="select" id="selectToggle" onclick="toggleControl(this);" />
                <label for="selectToggle">select</label>
            </li>
            <!--
            <li>
                <input type="checkbox" name="geodesic" id="geodesicToggle" onclick="toggleGeodesic(this);" />
                <label for="geodesicToggle">use geodesic measures</label>
            </li>
            
            <li>
                <input type="checkbox" name="immediate" id="immediateToggle" onclick="toggleImmediate(this);" />
                <label for="immediateToggle">use immediate measures</label>
            </li>
            -->
        </ul>
        </div>
        <div id="search_div" class="search-area">
                <form name="myform" action="" method="GET">
                <input type="hidden" name="layer" value="Manhole">
                <input type="hidden" name="tdiv" value="my_title_results">
                <input type="hidden" name="rdiv" value="my_search_results">
                <input type="text" name="searchterm" value="">
                <input TYPE="button" NAME="button" Value="Search" onClick="searchTest(this.form)"> 
                </form>
            </div>
        
    </div>
  </body>
</html>

Open in new window

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
putting var map outside same as window["map"]