// Firefox likes to cache form values during refresh
$( "form" )[ 0 ].reset( );
$( "form" ).submit( function( ) {
// also, we don't want the form to actually submit
return false;
} );
// set proj to null because we don't have the code for this projection
// and are working entirely in map units
$.geo.proj = null;
// define two shingled services
var services = [
// define a basemap service
{
id: "massgis_basemap",
type: "shingled",
src: "http://giswebservices.massgis.state.ma.us/geoserver/wms?LAYERS=massgis_basemap&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&SRS=EPSG%3A26986&BBOX={{=bbox}}&WIDTH={{=width}}&HEIGHT={{=height}}",
attr: "© 2011 Commonwealth of Massachusetts"
},
// define a second service as a layer on top of the basemap
// we use this service as the target when "target" is set to service in this demo
{
id: "massgis_hydrography",
type: "shingled",
src: "http://giswebservices.massgis.state.ma.us/geoserver/wms?LAYERS=massgis%3AGISDATA.MAJPOND_POLY,massgis%3AGISDATA.MAJSTRM_ARC&TRANSPARENT=true&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&SRS=EPSG%3A26986&BBOX={{=bbox}}&WIDTH={{=width}}&HEIGHT={{=height}}"
}
];
// create a map without a tilingScheme & with the two shingled services
var map = $( "#map" ).geomap( {
// add a cursor for our custom mode: remove
cursors: { remove: "crosshair" },
// use the services array defined above
services: services,
// you must set bboxMax for shingled services for the zoom property to mean anything
bboxMax: [ 31789.1658, 790194.4183, 337250.8970, 961865.1338 ],
// shingled services do not have a tilingScheme
tilingScheme: null,
// center & zoom values that fit MassGIS's projection
center: [ 235670.21967, 900771.290247 ],
zoom: 13,
bboxchange: function( e, geo ) {
// when the bbox changes, update the info section with new option values
updateInfo( );
},
shape: function( e, geo ) {
// when the user draws a shape, show it on the map
// the shape event triggers when the user finishes drawing a shape
// the geo argument is a GeoJSON object representing the shape
// for this example, we'll append it to the map forcing an
// individual style that matches the current drawStyle
// make a copy of the current drawStyle
var drawStyle = $.extend( { }, map.geomap( "option", "drawStyle" ) );
// grab the label (if any) from the input
var label = $( "#shapeLabels input" ).val( );
// append the shape using that style
// however, depending on which target is checked, we will append the shape to either the map widget itself or a specific map service
if ( $( "#clickTargetWidget" ).is( ":checked" ) ) {
// if the map is our target, just append the shape to the map
// if there's a label entered, used it
map.geomap( "append", geo, drawStyle, label );
} else {
// otherwise, grab a reference to a service
// ( by id in this case ) and append the shape to that
// the value of the remaining radio buttons matches the id of a service
// if there's a label entered, used it
var serviceToAppend = $( "#" + $( "input[name='clickTarget']:checked" ).val( ) );
$( serviceToAppend ).geomap( "append", geo, drawStyle, label );
// also note, that the label is controlled seperately from the shape, by CSS, rather than by jQuery Geo shapeStyle objects
// if you look at the CSS, you will notice:
//
// #massgis_hydrography { color: blue; }
//
// which makes all labels on the hydro service blue text
}
},
click: function( e, geo ) {
// when the user clicks the map while in our custom mode, remove,
// we will search for shapes on either the map widget itself
// ( and, by design, all map services) or a single, specific map service
// we'll use a nice, fat 5px radius for the searches here, that's what the (, 5) is below
// however, in this demo, we remove any shapes found from either the map or service
// if the map is our target, grab the map reference
// otherwise, grab a reference to a service, in this case, by id
var target = $( "#clickTargetWidget" ).is( ":checked" ) ? map : $( "#" + $( "input[name='clickTarget']:checked" ).val( ) );
// by design, calling find on the map itself returns all shapes at that location
// even if they have been appended to a service
// when target is the service, find is limited to shapes that have been appended there
var shapes = target.geomap( "find", geo, 3 );
// even though we potentially found service-level shapes with the find method,
// calling remove on the map does not remove from all services
$.each( shapes, function( ) {
target.geomap( "remove", this );
} );
}
} );
// jQuery UI for pretty buttons
$( "button, #togglePannable" ).button( );
$( ".modes, .scrollOptions, .clickTargets, .toggleTargets" ).buttonset( );
$( "#toggle-info" ).click( function( ) {
// show or hide some map info such as bbox, center and zoom
$( "#mapInfo" ).toggle( );
} );
$( "#togglePannable" ).click( function( ) {
// change the pannable option to allow users to pan or not pan your map
map.geomap( "option", "pannable", $( this ).is( ":checked" ) );
} );
$( ".scrollOptions input" ).click( function( ) {
// set the map's scroll option based on value of the input clicked
// currently, default and scroll are the same; the only other option is off
var scrollValue = $( this ).val( );
map.geomap( "option", "scroll", scrollValue );
} );
$( "#change-mode").click( function( ) {
// show or hide the mode options
$( "#modeOptions" ).toggle( );
} );
$( ".modes input" ).click( function () {
// set the map's mode option based on value of the input clicked
var modeValue = $( this ).val( );
map.geomap( "option", "mode", modeValue );
// if mode is one of the draw modes (or remove), show the target section, otherwise hide it
$( "#clickTarget" ).toggle( modeValue.substr( 0, 4 ) === "draw" || modeValue === "remove" );
// if mode is one of the draw modes,
// show the label inputs & shape style as well
$( "#shapeLabels, #drawStyle" ).toggle( modeValue.substr( 0, 4 ) === "draw" );
// also display the current mode on the button
$( "#change-mode .ui-button-text" ).text( modeValue );
// hide the mode options
$( "#modeOptions" ).hide( );
} );
$( "#drawStyle input" ).change( function( ) {
// when an input of the drawStyle area changes,
// immediately set the property of geomap's drawStyle option
// keep in mind that the three point-only styles (width, height & borderRadius)
// cannot be seen because with drawPoint, the shape event triggers immediately
// without drawing a shape
// this example, however, does use them when appending the shape after a click
// first, we can grab a jQuery reference to the input that changed
var $this = $( this );
// next, we can create an object that represents this change
// this example doesn't, but you can set more than one property
// on geomap's drawStyle option at a time
var styleOption = { };
styleOption[ $this.attr( "name" ) ] = $this.val();
map.geomap( "option", "drawStyle", styleOption );
} );
$( ".toggleTargets input" ).click( function( ) {
// when a service is toggled, we tell the geomap widget to toggle it
// the value of each checkbox input equals the id of a service
var checkboxClicked = $( this );
var serviceToToggle = $( "#" + checkboxClicked.val( ) );
// toggle the service, shapes on the service will also be toggled
serviceToToggle.geomap( "toggle" );
} );
$( "#zoomOut" ).button( "option", {
// just icons for the zoom buttons
icons: { primary: "ui-icon-minus" },
text: false
} ).click( function( ) {
// use the zoom method to zoom out
map.geomap( "zoom", -1 );
} );
$( "#zoomIn" ).button( "option", {
// just icons for the zoom buttons
icons: { primary: "ui-icon-plus" },
text: false
} ).click( function( ) {
// also use the zoom method to zoom in
map.geomap( "zoom", +1 );
} );
// update the info section with initial option values
updateInfo( );
function updateInfo( ) {
// update the info section with option values
$( "#mapInfo td" ).each( function( ) {
// a reference to the current option td element
var optionCell = $( this );
// since each td has a data-option attribute,
// jQuery can extract the option value via the data function
var optionValue = map.geomap( "option", optionCell.data( "option" ) );
if ( $.isArray( optionValue ) ) {
// display array values a little nicer
$.each( optionValue, function( i ) {
optionValue[ i ] = this.toFixed( 2 );
} );
optionCell.text( "[ " + optionValue.join( ", " ) + " ]" );
} else {
optionCell.text( optionValue );
}
} );
}
<div>
<div id="map">
</div>
<div class="info mobile-shrink">
<h1 class="not-mobile">shingled</h1>
<p class="not-mobile">The everything demo, shingled edition!</p>
<section class="not-mobile">
<h2>info</h2> <button id="toggle-info" type="button" title="click to view some map info">show / hide</button>
<table id="mapInfo" style="display: none;">
<tr><th>bbox</th><td data-option="bbox"></td></tr>
<tr><th>center</th><td data-option="center"></td></tr>
<tr><th>zoom</th><td data-option="zoom"></td></tr>
</table>
</section>
<form>
<section>
<h2>basics</h2>
<input type="checkbox" id="togglePannable" name="togglePannable" value="togglePannable" checked="checked" /><label for="togglePannable">pannable</label>
<div class="scrollOption-container not-mobile">
<h3>scroll</h3>
<div class="scrollOptions">
<input type="radio" id="scrollOptionDefault" name="scrollOption" value="default" checked="checked" /><label for="scrollOptionDefault">default / scroll</label>
<input type="radio" id="scrollOptionOff" name="scrollOption" value="off" /><label for="scrollOptionOff">off</label>
</div>
</div>
</section>
<section>
<h2>mode</h2> <button id="change-mode" type="button" title="click to change the mode">pan</button>
<div id="modeOptions" style="display: none;">
<div class="modes">
<input type="radio" id="static" name="mode" value="static" /><label for="static">static</label>
<input type="radio" id="pan" name="mode" value="pan" checked="checked" /><label for="pan">pan</label>
<input type="radio" id="zoom" name="mode" value="zoom" /><label for="zoom">zoom</label>
</div>
<div class="modes">
<input type="radio" id="drawPoint" name="mode" value="drawPoint" /><label for="drawPoint">drawPoint</label>
<input type="radio" id="drawLineString" name="mode" value="drawLineString" /><label for="drawLineString">drawLineString</label>
<input type="radio" id="drawPolygon" name="mode" value="drawPolygon" /><label for="drawPolygon">drawPolygon</label>
</div>
<div class="modes">
<!--
jQuery Geo supports custom modes by letting you set the mode option to
any string you want. You can set a cursor for your custom mode using the
cursors option. When on a custom mode, you will get the geomapclick event.
-->
<input type="radio" id="remove" name="mode" value="remove" /><label for="remove">remove</label>
</div>
<div class="modes">
<input type="radio" id="measureLength" name="mode" value="measureLength" /><label for="measureLength">measureLength</label>
<input type="radio" id="measureArea" name="mode" value="measureArea" /><label for="measureArea">measureArea</label>
</div>
</div>
</section>
<section id="shapeLabels" style="display: none;">
<label>
<h2>label</h2>
<input type="text" name="shapeLabel" />
</label>
</section>
<div class="not-mobile">
<section id="drawStyle" style="display: none;">
<h2>style</h2>
<div>
<label><span>color</span> <input type="color" name="color" value="#7f0000" /></label>
<label><span>opacity</span> <input type="text" name="opacity" value="1.0" /></label>
</div>
<div>
<label><span>fill</span> <input type="color" name="fill" value="" /></label>
<label><span>fillOpacity</span> <input type="text" name="fillOpacity" value=".2" /></label>
</div>
<div>
<label><span>stroke</span> <input type="color" name="stroke" value="" /></label>
<label><span>strokeOpacity</span> <input type="text" name="strokeOpacity" value="1" /></label>
</div>
<div>
<label><span>strokeWidth</span> <input type="number" name="strokeWidth" value="2" /></label>
</div>
<div>
<label><span>width</span> <input type="number" name="width" value="8" /></label>
<label><span>height</span> <input type="number" name="height" value="8" /></label>
</div>
<div>
<label><span>borderRadius</span> <input type="number" name="borderRadius" value="8" /></label>
</div>
</section>
</div>
<section id="clickTarget" style="display: none;">
<h2>target</h2>
<div class="clickTargets">
<input type="radio" id="clickTargetWidget" name="clickTarget" value="widget" checked="checked" /><label for="clickTargetWidget">widget</label>
<input type="radio" id="clickTargetBasemapService" name="clickTarget" value="massgis_basemap" /><label for="clickTargetBasemapService">basemap</label>
<input type="radio" id="clickTargetHydroService" name="clickTarget" value="massgis_hydrography" /><label for="clickTargetHydroService">hydro</label>
</div>
</section>
<section id="serviceToggle">
<h2>toggle</h2>
<div class="toggleTargets">
<input type="checkbox" id="toggleTargetBasemapService" name="toggleTarget" value="massgis_basemap" checked="checked" /><label for="toggleTargetBasemapService">basemap</label>
<input type="checkbox" id="toggleTargetHydroService" name="toggleTarget" value="massgis_hydrography" checked="checked" /><label for="toggleTargetHydroService">hydro</label>
</div>
<section>
<section id="zoomButtons">
<h2>zoom</h2>
<button id="zoomOut" type="button">out</button>
<button id="zoomIn" type="button">in</button>
</section>
</form>
</div>
</div>
.mobile-shrink
{
font-size: .6em;
}
.not-mobile
{
display: none;
}
@media only screen and (min-width: 800px)
{
.info
{
max-width: 45% !important;
position: absolute !important;
right: 16px;
top: 16px;
}
.mobile-shrink
{
font-size: 1em;
}
.not-mobile
{
display: block;
}
}
html
{
font:13px/1.231 Calibri,Arial,sans-serif; *font-size:small;
}
.info
{
background: #fff;
border-radius: 8px;
box-shadow: -4px 4px #444;
opacity: .8;
padding: 8px;
width: 95%;
}
fieldset { border: none; }
legend {
font-size: 14px;
font-weight: bold;
}
h2 { display: inline-block; }
@media only screen and (min-width: 800px)
{
h2 { display: inline-block; min-width: 8em; }
}
h3 { display: inline-block; margin-left: 2em; }
#map
{
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
/* a label CSS example: all text for labels on the hydro service will be blue! */
#massgis_hydrography
{
color: blue;
}
.modes { margin: .5em 0; }
#drawStyle label span { display: inline-block; font-weight: bold; text-align: right; width: 7em; }
#drawStyle input { width: 6em; }
.scrollOption-container, .scrollOptions, .clickTargets, .toggleTargets { display: inline-block; }
External resources loaded into this fiddle: