[mapguide-commits] r7794 - trunk/MgDev/Doc/samples/ol2samples/selection
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Wed Aug 21 08:40:33 PDT 2013
Author: jng
Date: 2013-08-21 08:40:32 -0700 (Wed, 21 Aug 2013)
New Revision: 7794
Added:
trunk/MgDev/Doc/samples/ol2samples/selection/index.html
Log:
#2344: Add OpenLayers selection sample. This uses v2.6 CREATERUNTIMEMAP and QUERYMAPFEATURES operations to allow for an OpenLayers MapGuide viewer with interaction and inspection of selected features without any .net/Java/PHP glue code required on the Web Tier.
Added: trunk/MgDev/Doc/samples/ol2samples/selection/index.html
===================================================================
--- trunk/MgDev/Doc/samples/ol2samples/selection/index.html (rev 0)
+++ trunk/MgDev/Doc/samples/ol2samples/selection/index.html 2013-08-21 15:40:32 UTC (rev 7794)
@@ -0,0 +1,354 @@
+<html>
+ <head>
+ <title>Basic Sheboygan un-tiled map example with selection</title>
+ <link rel="stylesheet" href="../assets/theme/default/style.css" />
+ <style type="text/css">
+ body { font-family: Verdana; font-size: 0.9em; }
+ #error { color: red; }
+ #wrap { width: 1150; }
+ #map { width: 650; height: 500; float: right; }
+ #details { width: 250; height: 500; overflow: auto; display: block-inline; float: left; }
+ #selInfo { width: 250; height: 500; overflow: auto; display: block-inline; float: right; }
+ #rootList { list-style-type: none; margin-left: -20px; }
+ #rootList li { list-style-type: none; }
+ #selInfoTree { list-style-type: none; margin-left: -20px; }
+ #selInfoTree li { list-style-type: none; margin-left: -20px; }
+ #selMessage { color: red; font-weight: bolder; }
+ .olControlMousePosition { background: #ffff66; font-size: 0.6em !important; padding: 2px; }
+ </style>
+ <script type="text/javascript" src="../assets/jquery-1.10.2.min.js"></script>
+ <script type="text/javascript" src="../assets/OpenLayers.js"></script>
+ <script type="text/javascript" src="../assets/legend.js"></script>
+ <script type="text/javascript">
+
+ //This sample is assumed to be hosted at http://servername/mapguide/ol2samples/untiled/index.html
+ var mapAgentUrl = "../../mapagent/mapagent.fcgi";
+
+ //Various features you can include in the CREATERUNTIMEMAP response.
+ var REQ_NONE = 0; //Nothing. This the default.
+ var REQ_LAYER_STRUCTURE = 1; //Information about layers and groups (required for the mask values below to have any effect)
+ var REQ_LAYER_ICONS = 2; //Icons for each layer (has no effect if REQ_LAYER_STRUCTURE is not in the bitmask)
+ var REQ_LAYER_FEATURE_SOURCE = 4; //Feature Source information for each layer (has no effect if REQ_LAYER_STRUCTURE is not in the bitmask)
+
+ var gMimeType = null;
+ var map = null;
+ var mgLayer = null;
+ var selLayer = null;
+ var selRectControl = null;
+ var sessionId = null;
+ var mapName = null;
+ var legend = null;
+ var ptBuffer = 2;
+ var bSelecting = false;
+ var navControl = null;
+ var zoomControl = null;
+ var wktFormat = null;
+
+ $(document).ready(function() {
+ OpenLayers.Control.DragPan.prototype.enableKinetic = false;
+ //Have a play with the bitmask values to see the differences in JSON payload size
+ //and to see how our legend control gracefully handles such situations
+ //createMap(REQ_NONE);
+ //createMap(REQ_LAYER_STRUCTURE);
+ createMap(REQ_LAYER_STRUCTURE | REQ_LAYER_FEATURE_SOURCE | REQ_LAYER_ICONS);
+ });
+
+ function createMap(reqFeatures) {
+ $.getJSON(mapAgentUrl, {
+ "OPERATION": "CREATERUNTIMEMAP",
+ "VERSION": "2.6.0",
+ "MAPDEFINITION": "Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition",
+ "USERNAME": "Anonymous", //Or you can use "SESSION": "<my session id>"
+ "REQUESTEDFEATURES": reqFeatures,
+ //Optional parameters you can specify and/or experiment with
+ //"ICONFORMAT": "GIF", //Uncomment to override desired image format (default: PNG)
+ //"ICONWIDTH": 32, //Uncomment to override desired icon width (default: 16)
+ //"ICONHEIGHT": 32, //Uncomment to override desired icon height (default: 16)
+ //"ICONSPERSCALERANGE": 3, //Uncomment to observe theme compression for themes exceeding this number of rules (default: 25)
+ //"TARGETMAPNAME": "MyRuntimeMapForOpenLayers", //Uncomment if you require a specific map name be given (default: inferred from Map Definition)
+ "FORMAT": "application/json"
+ }, function(data, textStatus, jqXHR) {
+ loadMap(data);
+ }).error(function(jqXHR, textStatus, errorThrown) {
+ $("#error").html(jqXHR.responseText);
+ });
+ }
+
+ function loadMap(rtMapInfo) {
+ var extent = new OpenLayers.Bounds(
+ parseFloat(rtMapInfo.RuntimeMap.Extents[0].LowerLeftCoordinate[0].X[0]),
+ parseFloat(rtMapInfo.RuntimeMap.Extents[0].LowerLeftCoordinate[0].Y[0]),
+ parseFloat(rtMapInfo.RuntimeMap.Extents[0].UpperRightCoordinate[0].X[0]),
+ parseFloat(rtMapInfo.RuntimeMap.Extents[0].UpperRightCoordinate[0].Y[0]));
+
+ wktFormat = new OpenLayers.Format.WKT();
+ navControl = new OpenLayers.Control.Navigation();
+ zoomControl = new OpenLayers.Control.ZoomBox({alwaysZoom:true});
+
+ OpenLayers.Control.CustomNavToolbar = OpenLayers.Class(OpenLayers.Control.Panel, {
+ /**
+ * Constructor: OpenLayers.Control.NavToolbar
+ * Add our two mousedefaults controls.
+ *
+ * Parameters:
+ * options - {Object} An optional object whose properties will be used
+ * to extend the control.
+ */
+ initialize: function(options) {
+ OpenLayers.Control.Panel.prototype.initialize.apply(this, [options]);
+ this.addControls([
+ navControl,
+ //Here it come
+ zoomControl
+ ]);
+ // To make the custom navtoolbar use the regular navtoolbar style
+ this.displayClass = 'olControlNavToolbar'
+ },
+ /**
+ * Method: draw
+ * calls the default draw, and then activates mouse defaults.
+ */
+ draw: function() {
+ var div = OpenLayers.Control.Panel.prototype.draw.apply(this, arguments);
+ this.defaultControl = this.controls[0];
+ return div;
+ }
+ });
+ var mapOptions = {
+ theme: null,
+ maxExtent: extent,
+ maxResolution: 'auto',
+ controls: [
+ new OpenLayers.Control.Navigation(),
+ new OpenLayers.Control.Attribution(),
+ new OpenLayers.Control.Zoom(),
+ new OpenLayers.Control.ScaleLine(),
+ new OpenLayers.Control.MousePosition(),
+ new OpenLayers.Control.CustomNavToolbar({alwaysZoom:true})
+ ]
+ };
+
+ if (rtMapInfo.RuntimeMap.CoordinateSystem[0].EpsgCode[0].length > 0) {
+ mapOptions.projection = "EPSG:" + rtMapInfo.RuntimeMap.CoordinateSystem[0].EpsgCode[0];
+ }
+
+ var options = {
+ isBaseLayer: true,
+ transitionEffect: "resize",
+ buffer: 1,
+ useOverlay: true,
+ useAsyncOverlay: true,
+ singleTile: true
+ };
+ var selOptions = {
+ isBaseLayer: false,
+ buffer: 1,
+ useOverlay: true,
+ useAsyncOverlay: true,
+ singleTile: true
+ };
+
+ mapName = rtMapInfo.RuntimeMap.Name[0];
+ sessionId = rtMapInfo.RuntimeMap.SessionId[0];
+ var params = {
+ mapname: mapName,
+ session: sessionId,
+ behavior: 2
+ };
+ var selParams = {
+ mapname: mapName,
+ session: sessionId,
+ selectioncolor: '0xFF000000',
+ behavior: 5
+ }
+
+ //Adjust the scale assumptions for MapGuide layers
+ //Tiled layers MUST use a DPI value of 96, untiled layers can use a
+ //different DPI value which will be passed to the server as a parameter.
+ //Tiled and untiled layers must adjust the OL INCHES_PER_UNIT values
+ //for any degree-based projections.
+
+ //You'll still need to do these adjustments manually, but CREATERUNTIMEMAP
+ //now provides the necessary meters-per-unit value for you to do this.
+ var metersPerUnit = parseFloat(rtMapInfo.RuntimeMap.CoordinateSystem[0].MetersPerUnit[0]);
+ var inPerUnit = OpenLayers.INCHES_PER_UNIT.m * metersPerUnit;
+ OpenLayers.INCHES_PER_UNIT["dd"] = inPerUnit;
+ OpenLayers.INCHES_PER_UNIT["degrees"] = inPerUnit;
+ OpenLayers.DOTS_PER_INCH = 96;
+
+ map = new OpenLayers.Map('map', mapOptions );
+ mgLayer = new OpenLayers.Layer.MapGuide( "MapGuide (from CREATERUNTIMEMAP)", mapAgentUrl, params, options );
+ selLayer = new OpenLayers.Layer.MapGuide( "MapGuide Selection Overlay", mapAgentUrl, selParams, options );
+ map.addLayer(mgLayer);
+ map.addLayer(selLayer);
+
+ var boxLayer = new OpenLayers.Layer.Vector("Selection Rectangles");
+ map.addLayer(boxLayer);
+ selRectControl = new OpenLayers.Control.DrawFeature(boxLayer,
+ OpenLayers.Handler.RegularPolygon, {
+ handlerOptions: {
+ sides: 4,
+ irregular: true
+ }
+ }
+ );
+ boxLayer.events.register("beforefeatureadded", this, onSelBoxAdded);
+
+ map.addControl(selRectControl);
+
+ map.zoomToMaxExtent();
+
+ legend = new Legend({
+ legendSelector: "#rootList",
+ stdIconRoot: "../../stdicons",
+ runtimeMap: rtMapInfo,
+ map: map,
+ mgLayerOL: mgLayer
+ });
+ legend.update();
+
+ $("div.olMap").css("background-color", "#" + rtMapInfo.RuntimeMap.BackgroundColor[0].substring(2));
+ $(".olMapViewport").append($("<img class='selOverlay' />"));
+ map.events.register("click", this, onMapClick);
+
+ startKeepAlive();
+ }
+
+ function doSelect() {
+ setSelectionState(true);
+ navControl.deactivate();
+ zoomControl.deactivate();
+ }
+
+ function onSelBoxAdded(e) {
+ sendSelectionQuery(e.feature.geometry.getBounds());
+ return false;
+ }
+
+ function getImageUri(mimeType, imgBase64) {
+ return "data:" + mimeType + ";base64," + imgBase64;
+ }
+
+ function onMapClick(e) {
+ if (bSelecting) {
+ var llPt = map.getLonLatFromViewPortPx({ x: e.xy.x - ptBuffer, y: e.xy.y - ptBuffer });
+ var urPt = map.getLonLatFromViewPortPx({ x: e.xy.x + ptBuffer, y: e.xy.y + ptBuffer });
+ var box = new OpenLayers.Bounds();
+ box.extend(llPt);
+ box.extend(urPt);
+ sendSelectionQuery(box);
+ navControl.activate();
+ zoomControl.deactivate();
+ }
+ }
+
+ function sendSelectionQuery(bounds) {
+ var reqQueryFeatures = 1; //Attributes
+ var wkt = wktFormat.extractGeometry(bounds.toGeometry());
+ $.getJSON(mapAgentUrl, {
+ "OPERATION": "QUERYMAPFEATURES",
+ "VERSION": "2.6.0",
+ "PERSIST": "1",
+ "MAPNAME": mapName,
+ "SESSION": sessionId,
+ "GEOMETRY": wkt,
+ "SELECTIONVARIANT": "INTERSECTS",
+ "SELECTIONCOLOR": "0xFF000000",
+ "SELECTIONFORMAT": "PNG8",
+ "MAXFEATURES": "-1",
+ "REQUESTDATA": reqQueryFeatures,
+ "FORMAT": "application/json"
+ }, function(data, textStatus, jqXHR) {
+ processQueryResult(data);
+ selLayer.setVisibility(true);
+ selLayer.redraw(true);
+ }).error(function(jqXHR, textStatus, errorThrown) {
+ $("#error").html(jqXHR.responseText);
+ });
+ }
+
+ function setSelectionState(sel) {
+ bSelecting = sel;
+ if (bSelecting) {
+ selRectControl.activate();
+ $("#selMessage").html("Selection mode active. Click or drag a selection rectangle on the map");
+ } else {
+ selRectControl.deactivate();
+ $("#selMessage").html("");
+ }
+ }
+
+ function processQueryResult(json) {
+ if (json.FeatureInformation) {
+ var fi = json.FeatureInformation;
+ setSelectionState(false);
+ var total = 0;
+ var html = "<ul>";
+ if (fi.SelectedFeatures) {
+ var selection = fi.SelectedFeatures[0];
+ for (var i = 0; i < selection.SelectedLayer.length; i++) {
+ var selLayer = selection.SelectedLayer[i];
+ total += selLayer.Feature.length;
+ var layerHtml = "<li><p>" + selLayer["@name"] + " (" + selLayer.Feature.length + " features)</p><ul>";
+
+ for (var j = 0; j < selLayer.Feature.length; j++) {
+ var feat = selLayer.Feature[j];
+ layerHtml += "<li><p>Feature</p><ul>";
+ for (var p = 0; p < feat.Property.length; p++) {
+ var prop = feat.Property[p];
+ layerHtml += "<li><strong>" + prop.Name[0] + "</strong>: " + (prop.Value ? prop.Value[0] : "(null)") + "</li>";
+ }
+ layerHtml += "</ul></li>";
+ }
+
+ layerHtml += "</ul></li>";
+ html += layerHtml;
+ }
+ }
+ html += "</ul>";
+ $("#selCount").html(total);
+ if (total > 0)
+ $("#selInfoTree").html(html);
+ else
+ $("#selInfoTree").html("");
+ }
+ }
+
+ function startKeepAlive() {
+ var keepAlive = function() {
+ $.get(mapAgentUrl, {
+ "OPERATION": "GETSESSIONTIMEOUT",
+ "VERSION": "1.0.0",
+ "SESSION": sessionId
+ }, function(data, textStatus, jxXHR) {
+ $("#mgSession").html("MapGuide session ID: " + sessionId + " (last checked at: " + (new Date()) + ")");
+ setTimeout(keepAlive, parseInt(data) * 1000);
+ });
+ };
+ keepAlive();
+ }
+
+ </script>
+ </head>
+ <body>
+ <p>This example demonstrates selection via QUERYMAPFEATURES. The map is created with CREATERUNTIMEMAP</p>
+ <div id="error">
+ </div>
+ <button onclick="doSelect()">Select</button><span id="selMessage"></span>
+ <div id="wrap">
+ <div id="details">
+ <strong>Layer and Groups</strong>
+ <ul id="rootList">
+ </ul>
+ </div>
+ <div id="selInfo">
+ <strong>Selection Info</strong>
+ <div id="selInfoTree">
+ </div>
+ </div>
+ <div id="map">
+ </div>
+ </div>
+ <p><span id="selCount">0</span> features selected</p>
+ </body>
+</html>
\ No newline at end of file
More information about the mapguide-commits
mailing list