diff options
Diffstat (limited to 'js/dojo-1.7.2/dojox/geo/charting')
18 files changed, 2376 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/geo/charting/Feature.js b/js/dojo-1.7.2/dojox/geo/charting/Feature.js new file mode 100644 index 0000000..4bfc059 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/Feature.js @@ -0,0 +1,199 @@ +//>>built +define("dojox/geo/charting/Feature", ["dojo/_base/lang", "dojo/_base/declare","dojo/_base/array", + "dojo/_base/html","dojo/dom","dojo/_base/event", "dojox/gfx/fx", "dojox/color"], + function(lang, declare,arr, html,dom, event, fx,color) { + +return declare("dojox.geo.charting.Feature", null, { + // summary: + // class to encapsulate a map element. + // tags: + // private + + _isZoomIn: false, + isSelected: false, + markerText:null, + + + constructor: function(parent, name, shapeData){ + // summary: + // constructs a new Feature. + // tags: + // private + this.id = name; + this.shape = parent.mapObj.createGroup(); + this.parent = parent; + this.mapObj = parent.mapObj; + this._bbox = shapeData.bbox; + this._center = shapeData.center; + //TODO: fill color would be defined by charting data and legend +// this._highlightFill = ["#FFCE52", "#CE6342", "#63A584"][Math.floor(Math.random() * 3)]; + this._defaultFill = parent.defaultColor; + this._highlightFill = parent.highlightColor; + this._defaultStroke = { + width: this._normalizeStrokeWeight(.5), + color: "white" + }; + + var shapes = (lang.isArray(shapeData.shape[0])) ? shapeData.shape : [shapeData.shape]; + arr.forEach(shapes, function(points){ + this.shape.createPolyline(points).setStroke(this._defaultStroke); + }, this); + this.unsetValue(); + }, + unsetValue:function(){ + // summary: + // clears the numeric value on this Feature object (removes color). + + this.value = null; + this.unsetColor(); + }, + unsetColor:function(){ + this._defaultFill = this.parent.defaultColor; + var col = new color.Color(this.parent.defaultColor).toHsl(); + col.l = 1.2 * col.l; + this._highlightFill = color.fromHsl(col); + this._setFillWith(this._defaultFill); + }, + setValue:function(value){ + // summary: + // sets a numeric value on this Feature object (used together with series to apply a color). + // value: + // a number + this.value = value; + if (value == null) { + this.unsetValue(); + } else { + if (this.parent.series.length != 0) { + for (var i = 0; i < this.parent.series.length; i++) { + var range = this.parent.series[i]; + if ((value >= range.min) && (value < range.max)) { + this._setFillWith(range.color); + this._defaultFill = range.color; + var col = new color.Color(range.color).toHsv(); + col.v = (col.v + 20); + this._highlightFill = color.fromHsv(col); + return; + } + } + // did not found a range : unset color + this.unsetColor(); + } + } + }, + _setFillWith: function(color){ + var borders = (lang.isArray(this.shape.children)) ? this.shape.children : [this.shape.children]; + arr.forEach(borders, lang.hitch(this,function(item){ + if(this.parent.colorAnimationDuration > 0){ + var anim1 = fx.animateFill({ + shape: item, + color: { + start: item.getFill(), + end: color + }, + duration: this.parent.colorAnimationDuration + }); + anim1.play(); + }else{ + item.setFill(color); + } + })); + }, + _setStrokeWith: function(stroke){ + var borders = (lang.isArray(this.shape.children)) ? this.shape.children : [this.shape.children]; + arr.forEach(borders, function(item){ + item.setStroke({ + color: stroke.color, + width: stroke.width, + join: "round" + }); + }); + }, + _normalizeStrokeWeight: function(weight){ + var matrix = this.shape._getRealMatrix(); + return (dojox.gfx.renderer != "vml")?weight/(this.shape._getRealMatrix()||{xx:1}).xx:weight; + }, + _onmouseoverHandler: function(evt){ + this.parent.onFeatureOver(this); + this._setFillWith(this._highlightFill); + this.mapObj.marker.show(this.id,evt); + }, + _onmouseoutHandler: function(){ + this._setFillWith(this._defaultFill); + this.mapObj.marker.hide(); + html.style("mapZoomCursor", "display", "none"); + }, + _onmousemoveHandler: function(evt){ + if(this.mapObj.marker._needTooltipRefresh){ + this.mapObj.marker.show(this.id,evt); + } + if(this.isSelected){ + if (this.parent.enableFeatureZoom) { + evt = event.fix(evt || window.event); + html.style("mapZoomCursor", "left", evt.pageX + 12 + "px"); + html.style("mapZoomCursor", "top", evt.pageY + "px"); + html.byId("mapZoomCursor").className = this._isZoomIn ? "mapZoomOut":"mapZoomIn"; + html.style("mapZoomCursor", "display", "block"); + }else{ + html.style("mapZoomCursor", "display", "none"); + } + } + }, + _onclickHandler: function(evt){ + this.parent.onFeatureClick(this); + if(!this.isSelected){ + this.parent.deselectAll(); + this.select(true); + this._onmousemoveHandler(evt); + }else if(this.parent.enableFeatureZoom){ + if(this._isZoomIn){ + this._zoomOut(); + }else{ + this._zoomIn(); + } + } + }, + + select: function(selected) { + if(selected){ + this.shape.moveToFront(); + this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)}); + this._setFillWith(this._highlightFill); + this.isSelected = true; + this.parent.selectedFeature = this; + }else{ + this._setStrokeWith(this._defaultStroke); + this._setFillWith(this._defaultFill); + this.isSelected = false; + this._isZoomIn = false; + } + }, + + _zoomIn: function(){ + var marker = this.mapObj.marker; + marker.hide(); + this.parent.fitToMapArea(this._bbox, 15,true,lang.hitch(this,function(){ + this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)}); + marker._needTooltipRefresh = true; + this.parent.onZoomEnd(this); + })); + this._isZoomIn = true; + dom.byId("mapZoomCursor").className = ""; + }, + _zoomOut: function(){ + var marker = this.mapObj.marker; + marker.hide(); + this.parent.fitToMapContents(3,true,lang.hitch(this,function(){ + this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)}); + marker._needTooltipRefresh = true; + this.parent.onZoomEnd(this); + })); + this._isZoomIn = false; + dom.byId("mapZoomCursor").className = ""; + }, + + init: function(){ + this.shape.id = this.id; + this.tooltip = null; + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/geo/charting/KeyboardInteractionSupport.js b/js/dojo-1.7.2/dojox/geo/charting/KeyboardInteractionSupport.js new file mode 100644 index 0000000..ef3e887 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/KeyboardInteractionSupport.js @@ -0,0 +1,145 @@ +//>>built +define("dojox/geo/charting/KeyboardInteractionSupport", ["dojo/_base/lang","dojo/_base/declare","dojo/_base/event","dojo/_base/connect", + "dojo/_base/html","dojo/dom","dojox/lang/functional","dojo/keys"], + function(lang, declare, event, connect, html, dom, functional, keys) { + +return declare("dojox.geo.charting.KeyboardInteractionSupport", null, { + // summary: + // class to handle keyboard interactions on a dojox.geo.charting.Map widget + // + // The sections on the leading edge should receive the focus in response to a TAB event. + // Then use cursor keys to the peer sections. The cursor event should go the adjacent section + // in that direction. With the focus, the section zooms in upon SPACE. The map should zoom out + // on ESC. Finally, while it has the focus, the map should lose the focus on TAB. + // tags: + // private + _map: null, + _zoomEnabled: false, + + constructor: function(map, options){ + // summary: + // Constructs a new _KeyboardInteractionSupport instance + // map: dojox.geo.charting.Map + // the Map widget this class provides touch navigation for. + this._map = map; + if(options){ + this._zoomEnabled = options.enableZoom; + } + }, + connect: function(){ + // summary: + // connects this keyboard support class to the Map component + var container = dom.byId(this._map.container); + // tab accessing enable + html.attr(container, { + tabindex: 0, + role: "presentation", + "aria-label": "map" + }); + // install listeners + this._keydownListener = connect.connect(container, "keydown", this, "keydownHandler"); + this._onFocusListener = connect.connect(container, "focus", this, "onFocus"); + this._onBlurListener = connect.connect(container, "blur", this, "onBlur"); + }, + disconnect: function(){ + // summary: + // disconnects any installed listeners + connect.disconnect(this._keydownListener); + this._keydownListener = null; + connect.disconnect(this._onFocusListener); + this._onFocusListener = null; + connect.disconnect(this._onBlurListener); + this._onBlurListener = null + }, + keydownHandler: function(e){ + switch(e.keyCode){ + case keys.LEFT_ARROW: + this._directTo(-1,-1,1,-1); + break; + case keys.RIGHT_ARROW: + this._directTo(-1,-1,-1,1); + break; + case keys.UP_ARROW: + this._directTo(1,-1,-1,-1); + break; + case keys.DOWN_ARROW: + this._directTo(-1,1,-1,-1); + break; + case keys.SPACE: + if(this._map.selectedFeature && !this._map.selectedFeature._isZoomIn && this._zoomEnabled){ + this._map.selectedFeature._zoomIn(); + } + break; + case keys.ESCAPE: + if(this._map.selectedFeature && this._map.selectedFeature._isZoomIn && this._zoomEnabled){ + this._map.selectedFeature._zoomOut(); + } + break; + default: + return; + } + event.stop(e); + }, + onFocus: function(e){ + // select the leading region at the map center + if(this._map.selectedFeature || this._map.focused){return;} + this._map.focused = true; + var leadingRegion, + needClick = false; + if(this._map.lastSelectedFeature){ + leadingRegion = this._map.lastSelectedFeature; + }else{ + var mapCenter = this._map.getMapCenter(), + minDistance = Infinity; + // find the region most closing to the map center + functional.forIn(this._map.mapObj.features, function(feature){ + var distance = Math.sqrt(Math.pow(feature._center[0] - mapCenter.x, 2) + Math.pow(feature._center[1] - mapCenter.y, 2)); + if(distance < minDistance){ + minDistance = distance; + leadingRegion = feature; + } + }); + needClick = true; + } + if(leadingRegion){ + if(needClick) { + leadingRegion._onclickHandler(null); + }else{ + } + this._map.mapObj.marker.show(leadingRegion.id); + } + }, + onBlur: function(){ + this._map.lastSelectedFeature = this._map.selectedFeature; + }, + _directTo: function(up,down,left,right){ + var currentSelected = this._map.selectedFeature, + centerX = currentSelected._center[0], + centerY = currentSelected._center[1], + minMargin = Infinity, + nextSelected = null; + functional.forIn(this._map.mapObj.features, function(feature){ + var paddingX = Math.abs(centerX - feature._center[0]), + paddingY = Math.abs(centerY - feature._center[1]), + paddingSum = paddingX + paddingY; + if((up - down) * (centerY - feature._center[1]) > 0){ + if(paddingX < paddingY && minMargin > paddingSum){ + minMargin = paddingSum; + nextSelected = feature; + } + } + if((left - right) * (centerX - feature._center[0]) > 0){ + if(paddingX > paddingY && minMargin > paddingSum){ + minMargin = paddingSum; + nextSelected = feature; + } + } + }); + if(nextSelected){ + this._map.mapObj.marker.hide(); + nextSelected._onclickHandler(null); + this._map.mapObj.marker.show(nextSelected.id); + } + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/geo/charting/Map.js b/js/dojo-1.7.2/dojox/geo/charting/Map.js new file mode 100644 index 0000000..d0e966c --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/Map.js @@ -0,0 +1,604 @@ +//>>built +define("dojox/geo/charting/Map", ["dojo/_base/lang","dojo/_base/array","dojo/_base/declare","dojo/_base/html","dojo/dom", + "dojo/dom-geometry","dojo/dom-class", "dojo/_base/xhr","dojo/_base/connect","dojo/_base/window", "dojox/gfx", + "dojox/geo/charting/_base","dojox/geo/charting/Feature","dojox/geo/charting/_Marker","dojo/number","dojo/_base/sniff"], + function(lang, arr, declare, html, dom, domGeom, domClass, xhr, connect, win, gfx, base, + Feature, Marker, number, has) { + + return declare("dojox.geo.charting.Map", null, { + // summary: + // Map widget interacted with charting. + // description: + // Support rendering Americas, AsiaPacific, ContinentalEurope, EuropeMiddleEastAfrica, + // USStates, WorldCountries, and WorldCountriesMercator by default. + // example: + // | var usaMap = new dojox.geo.charting.Map(srcNode, "dojotoolkit/dojox/geo/charting/resources/data/USStates.json"); + // | <div id="map" style="width:600px;height:400px;"></div> + + // defaultColor: String + // Default map feature color, e.g: "#B7B7B7" + defaultColor:"#B7B7B7", + // highlightColor: String + // Map feature color when mouse over it, e.g: "#" + highlightColor:"#D5D5D5", + // series: Array + // stack to data range, e.g: [{name:'label 1', min:20, max:70, color:'#DDDDDD'},{...},...] + series:[], + dataBindingAttribute:null, + dataBindingValueFunction:null, + dataStore:null, + showTooltips: true, + enableFeatureZoom: true, + colorAnimationDuration:0, + _idAttributes:null, + _onSetListener:null, + _onNewListener:null, + _onDeleteListener:null, + constructor: function(/*HTML Node*/container, /*String or Json object*/shapeData){ + // container: + // map container html node/id + // shapeData: + // map shape data json object, or url to json file + + html.style(container, "display", "block"); + + this.container = container; + var containerBounds = this._getContainerBounds(); + // get map container coords + this.surface = gfx.createSurface(container, containerBounds.w, containerBounds.h); + + this._createZoomingCursor(); + + // add transparent background for event capture + this.mapBackground = this.surface.createRect({x: 0, y: 0, width: containerBounds.w, height: containerBounds.w}).setFill("rgba(0,0,0,0)"); + + this.mapObj = this.surface.createGroup(); + this.mapObj.features = {}; + + if (typeof shapeData == "object") { + this._init(shapeData); + } else { + // load map shape file + if (typeof shapeData == "string" && shapeData.length > 0) { + xhr.get({ + url: shapeData, + handleAs: "json", + sync: true, + load: lang.hitch(this, "_init") + }); + } + } + }, + + _getContainerBounds: function() { + // summary: + // returns the bounds {x:, y:, w: ,h:} of the DOM node container in absolute coordinates + // tags: + // private + + var position = domGeom.position(this.container,true); + var marginBox = domGeom.getMarginBox(this.container); + // use contentBox for correct width and height - surface spans outside border otherwise + var contentBox = domGeom.getContentBox(this.container); + this._storedContainerBounds = { + x: position.x, + y: position.y, + w: contentBox.w || 100, + h: contentBox.h || 100 + }; + return this._storedContainerBounds; + }, + + resize: function(/**boolean**/ adjustMapCenter/**boolean**/,adjustMapScale,/**boolean**/ animate) { + // summary: + // resize the underlying GFX surface to accommodate to parent DOM Node size change + // adjustMapCenter: boolean + // keeps the center of the map when resizing the surface + // adjustMapScale: boolean + // adjusts the map scale to keep the visible portion of the map as much as possible + + var oldBounds = this._storedContainerBounds; + var newBounds = this._getContainerBounds(); + + if ((oldBounds.w == newBounds.w) && (oldBounds.h == newBounds.h)) { + return; + } + + // set surface dimensions, and background + this.mapBackground.setShape({width:newBounds.w, height:newBounds.h}); + this.surface.setDimensions(newBounds.w,newBounds.h); + + this.mapObj.marker.hide(); + this.mapObj.marker._needTooltipRefresh = true; + + if (adjustMapCenter) { + + var mapScale = this.getMapScale(); + var newScale = mapScale; + + if (adjustMapScale) { + var bbox = this.mapObj.boundBox; + var widthFactor = newBounds.w / oldBounds.w; + var heightFactor = newBounds.h / oldBounds.h; + newScale = mapScale * Math.sqrt(widthFactor * heightFactor); + } + + // current map center + var invariantMapPoint = this.screenCoordsToMapCoords(oldBounds.w/2,oldBounds.h/2); + + // apply new parameters + this.setMapCenterAndScale(invariantMapPoint.x,invariantMapPoint.y,newScale,animate); + } + }, + + _isMobileDevice: function() { + // summary: + // tests whether the application is running on a mobile device (android or iOS) + // tags: + // private + return (has("safari") + && (navigator.userAgent.indexOf("iPhone") > -1 || + navigator.userAgent.indexOf("iPod") > -1 || + navigator.userAgent.indexOf("iPad") > -1 + )) || (navigator.userAgent.toLowerCase().indexOf("android") > -1); + }, + + + setMarkerData: function(/*String*/ markerFile){ + // summary: + // import markers from outside file, associate with map feature by feature id + // which identified in map shape file, e.g: "NY":"New York" + // markerFile: + // outside marker data url, handled as json style. + // data format: {"NY":"New York",.....} + xhr.get({ + url: markerFile, + handleAs: "json", + handle: lang.hitch(this, "_appendMarker") + }); + }, + + setDataBindingAttribute: function(/*String*/prop) { + // summary: + // sets the property name of the dataStore items to use as value (see Feature.setValue function) + // prop: + // the property + this.dataBindingAttribute = prop; + + // refresh data + if (this.dataStore) { + this._queryDataStore(); + } + }, + + setDataBindingValueFunction: function(/* function */valueFunction) { + // summary: + // sets the function that extracts values from dataStore items,to use as Feature values (see Feature.setValue function) + // prop: + // the function + this.dataBindingValueFunction = valueFunction; + + // refresh data + if (this.dataStore) { + this._queryDataStore(); + } + }, + + + + _queryDataStore: function() { + if (!this.dataBindingAttribute || (this.dataBindingAttribute.length == 0)) + return; + + var mapInstance = this; + this.dataStore.fetch({ + scope: this, + onComplete: function(items){ + this._idAttributes = mapInstance.dataStore.getIdentityAttributes({}); + arr.forEach(items, function(item) { + var id = mapInstance.dataStore.getValue(item, this._idAttributes[0]); + if(mapInstance.mapObj.features[id]){ + var val = null; + var itemVal = mapInstance.dataStore.getValue(item, mapInstance.dataBindingAttribute); + if (itemVal) { + if (this.dataBindingValueFunction) { + val = this.dataBindingValueFunction(itemVal); + } else { + if (isNaN(val)) { + // regular parse + val=number.parse(itemVal); + } else { + val = itemVal; + } + } + } + if (val) + mapInstance.mapObj.features[id].setValue(val); + } + },this); + } + }); + }, + + _onSet:function(item,attribute,oldValue,newValue){ + // look for matching feature + var id = this.dataStore.getValue(item, this._idAttributes[0]); + var feature = this.mapObj.features[id]; + if (feature && (attribute == this.dataBindingAttribute)) { + if (newValue) + feature.setValue(newValue); + else + feature.unsetValue(); + } + }, + + _onNew:function(newItem, parentItem){ + var id = this.dataStore.getValue(item, this._idAttributes[0]); + var feature = this.mapObj.features[id]; + if (feature && (attribute == this.dataBindingAttribute)) { + feature.setValue(newValue); + } + }, + + _onDelete:function(item){ + var id = item[this._idAttributes[0]]; + var feature = this.mapObj.features[id]; + if (feature) { + feature.unsetValue(); + } + }, + + setDataStore: function(/*ItemFileReadStore*/ dataStore, /*String*/ dataBindingProp){ + // summary: + // populate data for each map feature from fetched data store + // dataStore: + // the dataStore to fetch the information from + // dataBindingProp: + // sets the property name of the dataStore items to use as value + if (this.dataStore != dataStore) { + // disconnect previous listener if any + if (this._onSetListener) { + connect.disconnect(this._onSetListener); + connect.disconnect(this._onNewListener); + connect.disconnect(this._onDeleteListener); + } + + // set new dataStore + this.dataStore = dataStore; + + // install listener on new dataStore + if (dataStore) { + _onSetListener = connect.connect(this.dataStore,"onSet",this,this._onSet); + _onNewListener = connect.connect(this.dataStore,"onNew",this,this._onNew); + _onDeleteListener = connect.connect(this.dataStore,"onDelete",this,this._onDelete); + } + } + if (dataBindingProp) + this.setDataBindingAttribute(dataBindingProp); + + }, + + + + addSeries: function(/*url or Json Object*/ series){ + // summary: + // sets ranges of data values (associated with label, color) to style map data values + // series: + // array of range objects such as : [{name:'label 1', min:20, max:70, color:'#DDDDDD'},{...},...] + + if (typeof series == "object") { + this._addSeriesImpl(series); + } else { + // load series file + if (typeof series == "string" && series.length > 0) { + xhr.get({ + url: series, + handleAs: "json", + sync: true, + load: lang.hitch(this, function(content){ + this._addSeriesImpl(content.series); + }) + }); + } + } + + }, + + _addSeriesImpl: function(/*Json object*/series) { + + this.series = series; + + // refresh color scheme + for (var item in this.mapObj.features) { + var feature = this.mapObj.features[item]; + feature.setValue(feature.value); + } + }, + + + fitToMapArea: function(/*bbox: {x,y,w,h}*/mapArea,pixelMargin,animate,/* callback function */onAnimationEnd){ + // summary: + // set this component's transformation so that the specified area fits in the component (centered) + // mapArea: + // the map area that needs to fill the component + // pixelMargin: int + // a margin (in pixels) from the borders of the Map component. + // animate: boolean + // true if the transform change should be animated + // onAnimationEnd: function + // a callback function to be executed when the animation completes (if animate set to true). + + if(!pixelMargin){ + pixelMargin = 0; + } + var width = mapArea.w, + height = mapArea.h, + containerBounds = this._getContainerBounds(), + scale = Math.min((containerBounds.w - 2 * pixelMargin) / width, + (containerBounds.h - 2 * pixelMargin) / height); + + this.setMapCenterAndScale(mapArea.x + mapArea.w / 2,mapArea.y + mapArea.h / 2,scale,animate,onAnimationEnd); + }, + + fitToMapContents: function(pixelMargin,animate,/* callback function */onAnimationEnd){ + // summary: + // set this component's transformation so that the whole map data fits in the component (centered) + // pixelMargin: int + // a margin (in pixels) from the borders of the Map component. + // animate: boolean + // true if the transform change should be animated + // onAnimationEnd: function + // a callback function to be executed when the animation completes (if animate set to true). + + //transform map to fit container + var bbox = this.mapObj.boundBox; + this.fitToMapArea(bbox,pixelMargin,animate,onAnimationEnd); + }, + + setMapCenter: function(centerX,centerY,animate,/* callback function */onAnimationEnd) { + // summary: + // set this component's transformation so that the map is centered on the specified map coordinates + // centerX: float + // the X coordinate (in map coordinates) of the new center + // centerY: float + // the Y coordinate (in map coordinates) of the new center + // animate: boolean + // true if the transform change should be animated + // onAnimationEnd: function + // a callback function to be executed when the animation completes (if animate set to true). + + // call setMapCenterAndScale with current map scale + var currentScale = this.getMapScale(); + this.setMapCenterAndScale(centerX,centerY,currentScale,animate,onAnimationEnd); + + }, + + _createAnimation: function(onShape,fromTransform,toTransform,/* callback function */onAnimationEnd) { + // summary: + // creates a transform animation object (between two transforms) used internally + // fromTransform: dojox.gfx.matrix.Matrix2D + // the start transformation (when animation begins) + // toTransform: dojox.gfx.matrix.Matrix2D + // the end transormation (when animation ends) + // onAnimationEnd: function + // callback function to be executed when the animation completes. + var fromDx = fromTransform.dx?fromTransform.dx:0; + var fromDy = fromTransform.dy?fromTransform.dy:0; + var toDx = toTransform.dx?toTransform.dx:0; + var toDy = toTransform.dy?toTransform.dy:0; + var fromScale = fromTransform.xx?fromTransform.xx:1.0; + var toScale = toTransform.xx?toTransform.xx:1.0; + + var anim = gfx.fx.animateTransform({ + duration: 1000, + shape: onShape, + transform: [{ + name: "translate", + start: [fromDx,fromDy], + end: [toDx,toDy] + }, + { + name: "scale", + start: [fromScale], + end: [toScale] + } + ] + }); + + //install callback + if (onAnimationEnd) { + var listener = connect.connect(anim,"onEnd",this,function(event){ + onAnimationEnd(event); + connect.disconnect(listener); + }); + } + + return anim; + }, + + + setMapCenterAndScale: function(centerX,centerY,scale, animate,/* callback function */onAnimationEnd) { + + // summary: + // set this component's transformation so that the map is centered on the specified map coordinates + // and scaled to the specified scale. + // centerX: float + // the X coordinate (in map coordinates) of the new center + // centerY: float + // the Y coordinate (in map coordinates) of the new center + // scale: float + // the scale of the map + // animate: boolean + // true if the transform change should be animated + // onAnimationEnd: function + // a callback function to be executed when the animation completes (if animate set to true). + + + // compute matrix parameters + var bbox = this.mapObj.boundBox; + var containerBounds = this._getContainerBounds(); + var offsetX = containerBounds.w/2 - scale * (centerX - bbox.x); + var offsetY = containerBounds.h/2 - scale * (centerY - bbox.y); + var newTransform = new gfx.matrix.Matrix2D({xx: scale, yy: scale, dx:offsetX, dy:offsetY}); + + + var currentTransform = this.mapObj.getTransform(); + + // can animate only if specified AND curentTransform exists + if (!animate || !currentTransform) { + this.mapObj.setTransform(newTransform); + } else { + var anim = this._createAnimation(this.mapObj,currentTransform,newTransform,onAnimationEnd); + anim.play(); + } + }, + + getMapCenter: function() { + // summary: + // returns the map coordinates of the center of this Map component. + // returns: {x:,y:} + // the center in map coordinates + var containerBounds = this._getContainerBounds(); + return this.screenCoordsToMapCoords(containerBounds.w/2,containerBounds.h/2); + }, + + setMapScale: function(scale,animate,/* callback function */onAnimationEnd) { + // summary: + // set this component's transformation so that the map is scaled to the specified scale. + // animate: boolean + // true if the transform change should be animated + // onAnimationEnd: function + // a callback function to be executed when the animation completes (if animate set to true). + + + // default invariant is map center + var containerBounds = this._getContainerBounds(); + var invariantMapPoint = this.screenCoordsToMapCoords(containerBounds.w/2,containerBounds.h/2); + this.setMapScaleAt(scale,invariantMapPoint.x,invariantMapPoint.y,animate,onAnimationEnd); + }, + + setMapScaleAt: function(scale,fixedMapX,fixedMapY,animate,/* callback function */onAnimationEnd) { + // summary: + // set this component's transformation so that the map is scaled to the specified scale, and the specified + // point (in map coordinates) stays fixed on this Map component + // fixedMapX: float + // the X coordinate (in map coordinates) of the fixed screen point + // fixedMapY: float + // the Y coordinate (in map coordinates) of the fixed screen point + // animate: boolean + // true if the transform change should be animated + // onAnimationEnd: function + // a callback function to be executed when the animation completes (if animate set to true). + + + var invariantMapPoint = null; + var invariantScreenPoint = null; + + invariantMapPoint = {x: fixedMapX, y: fixedMapY}; + invariantScreenPoint = this.mapCoordsToScreenCoords(invariantMapPoint.x,invariantMapPoint.y); + + // compute matrix parameters + var bbox = this.mapObj.boundBox; + var offsetX = invariantScreenPoint.x - scale * (invariantMapPoint.x - bbox.x); + var offsetY = invariantScreenPoint.y - scale * (invariantMapPoint.y - bbox.y); + var newTransform = new gfx.matrix.Matrix2D({xx: scale, yy: scale, dx:offsetX, dy:offsetY}); + + var currentTransform = this.mapObj.getTransform(); + + // can animate only if specified AND curentTransform exists + if (!animate || !currentTransform) { + this.mapObj.setTransform(newTransform); + } else { + var anim = this._createAnimation(this.mapObj,currentTransform,newTransform,onAnimationEnd); + anim.play(); + } + }, + + getMapScale: function() { + // summary: + // returns the scale of this Map component. + // returns: float + // the scale + var mat = this.mapObj.getTransform(); + var scale = mat?mat.xx:1.0; + return scale; + }, + + mapCoordsToScreenCoords: function(mapX,mapY) { + // summary: + // converts map coordinates to screen coordinates given the current transform of this Map component + // returns: {x:,y:} + // the screen coordinates correspondig to the specified map coordinates. + var matrix = this.mapObj.getTransform(); + var screenPoint = gfx.matrix.multiplyPoint(matrix, mapX, mapY); + return screenPoint; + }, + + screenCoordsToMapCoords: function(screenX, screenY) { + // summary: + // converts screen coordinates to map coordinates given the current transform of this Map component + // returns: {x:,y:} + // the map coordinates corresponding to the specified screen coordinates. + var invMatrix = gfx.matrix.invert(this.mapObj.getTransform()); + var mapPoint = gfx.matrix.multiplyPoint(invMatrix, screenX, screenY); + return mapPoint; + }, + deselectAll: function(){ + // summary: + // deselect all features of map + for(var name in this.mapObj.features){ + this.mapObj.features[name].select(false); + } + this.selectedFeature = null; + this.focused = false; + }, + + _init: function(shapeData){ + + // summary: + // inits this Map component. + + //transform map to fit container + this.mapObj.boundBox = {x: shapeData.layerExtent[0], + y: shapeData.layerExtent[1], + w: (shapeData.layerExtent[2] - shapeData.layerExtent[0]), + h: shapeData.layerExtent[3] - shapeData.layerExtent[1]}; + this.fitToMapContents(3); + + + // if there are "features", then implement them now. + arr.forEach(shapeData.featureNames, function(item){ + var featureShape = shapeData.features[item]; + featureShape.bbox.x = featureShape.bbox[0]; + featureShape.bbox.y = featureShape.bbox[1]; + featureShape.bbox.w = featureShape.bbox[2]; + featureShape.bbox.h = featureShape.bbox[3]; + var feature = new Feature(this, item, featureShape); + feature.init(); + this.mapObj.features[item] = feature; + }, this); + + + // set up a marker. + this.mapObj.marker = new Marker({}, this); + }, + _appendMarker: function(markerData){ + this.mapObj.marker = new Marker(markerData, this); + }, + _createZoomingCursor: function(){ + if(!dom.byId("mapZoomCursor")){ + var mapZoomCursor = win.doc.createElement("div"); + html.attr(mapZoomCursor,"id","mapZoomCursor"); + domClass.add(mapZoomCursor,"mapZoomIn"); + html.style(mapZoomCursor,"display","none"); + win.body().appendChild(mapZoomCursor); + } + }, + onFeatureClick: function(feature){ + }, + onFeatureOver: function(feature){ + }, + onZoomEnd:function(feature){ + } +}); +});
\ No newline at end of file diff --git a/js/dojo-1.7.2/dojox/geo/charting/MouseInteractionSupport.js b/js/dojo-1.7.2/dojox/geo/charting/MouseInteractionSupport.js new file mode 100644 index 0000000..8c1b4d3 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/MouseInteractionSupport.js @@ -0,0 +1,335 @@ +//>>built +define("dojox/geo/charting/MouseInteractionSupport", ["dojo/_base/lang","dojo/_base/declare","dojo/_base/event", + "dojo/_base/connect","dojo/_base/window","dojo/_base/html","dojo/dom","dojo/_base/sniff"], + function(lang, declare, event, connect, win, html, dom, has) { + +return declare("dojox.geo.charting.MouseInteractionSupport", null, { + // summary: + // class to handle mouse interactions on a dojox.geo.charting.Map widget + // tags: + // private + + _map : null, + _mapClickLocation : null, + _screenClickLocation: null, + _mouseDragListener: null, + _mouseUpListener: null, + _mouseUpClickListener: null, + _mouseDownListener: null, + _mouseMoveListener: null, + _mouseWheelListener: null, + _currentFeature: null, + _cancelMouseClick: null, + _zoomEnabled: false, + _panEnabled: false, + _onDragStartListener: null, + _onSelectStartListener: null, + + + mouseClickThreshold: 2, + + constructor : function(/* Map */map,/*boolean*/options) { + // summary: + // Constructs a new _MouseInteractionSupport instance + // map: dojox.geo.charting.Map + // the Map widget this class provides touch navigation for. + // options: object + // to enable panning and mouse wheel zooming + this._map = map; + this._mapClickLocation = {x: 0,y: 0}; + this._screenClickLocation = {x: 0,y: 0}; + this._cancelMouseClick = false; + if (options) { + this._zoomEnabled = options.enableZoom; + this._panEnabled = options.enablePan; + if (options.mouseClickThreshold && options.mouseClickThreshold > 0) { + this.mouseClickThreshold = options.mouseClickThreshold; + } + } + }, + + setEnableZoom: function(enable){ + // summary: + // enables mouse zoom on the map + if (enable && !this._mouseWheelListener) { + // enable + var wheelEventName = !has("mozilla") ? "onmousewheel" : "DOMMouseScroll"; + this._mouseWheelListener = this._map.surface.connect(wheelEventName, this, this._mouseWheelHandler); + } else if (!enable && this._mouseWheelListener) { + // disable + connect.disconnect(this._mouseWheelListener); + this._mouseWheelListener = null; + } + this._zoomEnabled = enable; + }, + + setEnablePan: function(enable){ + // summary: + // enables mouse panning on the map + this._panEnabled = enable; + }, + + connect: function() { + // summary: + // connects this mouse support class to the Map component + + // install mouse listeners + this._mouseMoveListener = this._map.surface.connect("onmousemove", this, this._mouseMoveHandler); + this._mouseDownListener = this._map.surface.connect("onmousedown", this, this._mouseDownHandler); + + if (has("ie")) { + _onDragStartListener = connect.connect(win.doc,"ondragstart",this,event.stop); + _onSelectStartListener = connect.connect(win.doc,"onselectstart",this,event.stop); + } + + this.setEnableZoom(this._zoomEnabled); + this.setEnablePan(this._panEnabled); + }, + + disconnect: function() { + // summary: + // disconnects any installed listeners + + // store zoomPan state + var isZoom = this._zoomEnabled; + + // disable zoom (disconnects listeners..) + this.setEnableZoom(false); + + // restore value + this._zoomEnabled = isZoom; + + // disconnect remaining listeners + if (this._mouseMoveListener) { + connect.disconnect(this._mouseMoveListener); + this._mouseMoveListener = null; + connect.disconnect(this._mouseDownListener); + this._mouseDownListener = null; + } + if (this._onDragStartListener) { + connect.disconnect(this._onDragStartListener); + this._onDragStartListener = null; + connect.disconnect(this._onSelectStartListener); + this._onSelectStartListener = null; + } + + }, + + _mouseClickHandler: function(mouseEvent) { + // summary: + // action performed on the map when a mouse click was performed + // mouseEvent: the mouse event + // tags: + // private + + var feature = this._getFeatureFromMouseEvent(mouseEvent); + + if (feature) { + // call feature handler + feature._onclickHandler(mouseEvent); + } else { + // unselect all + for (var name in this._map.mapObj.features){ + this._map.mapObj.features[name].select(false); + } + this._map.onFeatureClick(null); + } + + }, + + _mouseDownHandler: function(mouseEvent){ + // summary: + // action performed on the map when a mouse down was performed + // mouseEvent: the mouse event + // tags: + // private + + + event.stop(mouseEvent); + + this._map.focused = true; + // set various status parameters + this._cancelMouseClick = false; + this._screenClickLocation.x = mouseEvent.pageX; + this._screenClickLocation.y = mouseEvent.pageY; + + // store map location where mouse down occurred + var containerBounds = this._map._getContainerBounds(); + var offX = mouseEvent.pageX - containerBounds.x, + offY = mouseEvent.pageY - containerBounds.y; + var mapPoint = this._map.screenCoordsToMapCoords(offX,offY); + this._mapClickLocation.x = mapPoint.x; + this._mapClickLocation.y = mapPoint.y; + + // install drag listener if pan is enabled + if (!has("ie")) { + this._mouseDragListener = connect.connect(win.doc,"onmousemove",this,this._mouseDragHandler); + this._mouseUpClickListener = this._map.surface.connect("onmouseup", this, this._mouseUpClickHandler); + this._mouseUpListener = connect.connect(win.doc,"onmouseup",this, this._mouseUpHandler); + } else { + var node = dom.byId(this._map.container); + this._mouseDragListener = connect.connect(node,"onmousemove",this,this._mouseDragHandler); + this._mouseUpClickListener = this._map.surface.connect("onmouseup", this, this._mouseUpClickHandler); + this._mouseUpListener = this._map.surface.connect("onmouseup", this, this._mouseUpHandler); + this._map.surface.rawNode.setCapture(); + } + }, + + _mouseUpClickHandler: function(mouseEvent) { + + if (!this._cancelMouseClick) { + // execute mouse click handler + this._mouseClickHandler(mouseEvent); + } + this._cancelMouseClick = false; + + }, + + _mouseUpHandler: function(mouseEvent) { + // summary: + // action performed on the map when a mouse up was performed + // mouseEvent: the mouse event + // tags: + // private + + event.stop(mouseEvent); + + this._map.mapObj.marker._needTooltipRefresh = true; + + // disconnect listeners + if (this._mouseDragListener) { + connect.disconnect(this._mouseDragListener); + this._mouseDragListener = null; + } + if (this._mouseUpClickListener) { + connect.disconnect(this._mouseUpClickListener); + this._mouseUpClickListener = null; + } + if (this._mouseUpListener) { + connect.disconnect(this._mouseUpListener); + this._mouseUpListener = null; + } + + if (has("ie")) { + this._map.surface.rawNode.releaseCapture(); + } + }, + + _getFeatureFromMouseEvent: function(mouseEvent) { + // summary: + // utility function to return the feature located at this mouse event location + // mouseEvent: the mouse event + // returns: dojox.geo.charting.Feature + // the feature found if any, null otherwise. + // tags: + // private + var feature = null; + if (mouseEvent.gfxTarget && mouseEvent.gfxTarget.getParent) { + feature = this._map.mapObj.features[mouseEvent.gfxTarget.getParent().id]; + } + return feature; + }, + + _mouseMoveHandler: function(mouseEvent) { + // summary: + // action performed on the map when a mouse move was performed + // mouseEvent: the mouse event + // tags: + // private + + + // do nothing more if dragging + if (this._mouseDragListener && this._panEnabled) { + return; + } + + // hover and highlight + var feature = this._getFeatureFromMouseEvent(mouseEvent); + + // set/unset highlight + if (feature != this._currentFeature) { + if (this._currentFeature) { + // mouse leaving component + this._currentFeature._onmouseoutHandler(); + } + this._currentFeature = feature; + + if (feature) + feature._onmouseoverHandler(); + } + + if (feature) + feature._onmousemoveHandler(mouseEvent); + }, + + _mouseDragHandler: function(mouseEvent){ + // summary: + // action performed on the map when a mouse drag was performed + // mouseEvent: the mouse event + // tags: + // private + + // prevent browser interaction + event.stop(mouseEvent); + + + // find out if this the movement discards the "mouse click" gesture + var dx = Math.abs(mouseEvent.pageX - this._screenClickLocation.x); + var dy = Math.abs(mouseEvent.pageY - this._screenClickLocation.y); + if (!this._cancelMouseClick && (dx > this.mouseClickThreshold || dy > this.mouseClickThreshold)) { + // cancel mouse click + this._cancelMouseClick = true; + if (this._panEnabled) { + this._map.mapObj.marker.hide(); + } + } + + if (!this._panEnabled) + return; + + var cBounds = this._map._getContainerBounds(); + var offX = mouseEvent.pageX - cBounds.x, + offY = mouseEvent.pageY - cBounds.y; + + // compute map offset + var mapPoint = this._map.screenCoordsToMapCoords(offX,offY); + var mapOffsetX = mapPoint.x - this._mapClickLocation.x; + var mapOffsetY = mapPoint.y - this._mapClickLocation.y; + + // adjust map center + var currentMapCenter = this._map.getMapCenter(); + this._map.setMapCenter(currentMapCenter.x - mapOffsetX, currentMapCenter.y - mapOffsetY); + + }, + + _mouseWheelHandler: function(mouseEvent) { + // summary: + // action performed on the map when a mouse wheel up/down was performed + // mouseEvent: the mouse event + // tags: + // private + + + // prevent browser interaction + event.stop(mouseEvent); + + // hide tooltip + this._map.mapObj.marker.hide(); + + // event coords within component + var containerBounds = this._map._getContainerBounds(); + var offX = mouseEvent.pageX - containerBounds.x, + offY = mouseEvent.pageY - containerBounds.y; + + // current map point before zooming + var invariantMapPoint = this._map.screenCoordsToMapCoords(offX,offY); + + // zoom increment power + var power = mouseEvent[(has("mozilla") ? "detail" : "wheelDelta")] / (has("mozilla") ? - 3 : 120) ; + var scaleFactor = Math.pow(1.2,power); + this._map.setMapScaleAt(this._map.getMapScale()*scaleFactor ,invariantMapPoint.x,invariantMapPoint.y,false); + this._map.mapObj.marker._needTooltipRefresh = true; + + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/geo/charting/TouchInteractionSupport.js b/js/dojo-1.7.2/dojox/geo/charting/TouchInteractionSupport.js new file mode 100644 index 0000000..6e2b7cd --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/TouchInteractionSupport.js @@ -0,0 +1,313 @@ +//>>built +define("dojox/geo/charting/TouchInteractionSupport", ["dojo/_base/lang","dojo/_base/declare","dojo/_base/event", "dojo/_base/connect","dojo/_base/window"], + function(lang,declare,event,connect,win) { + +return declare("dojox.geo.charting.TouchInteractionSupport",null, { + // summary: + // class to handle touch interactions on a dojox.geo.charting.Map widget + // tags: + // private + + _map : null, + _centerTouchLocation : null, + _touchMoveListener: null, + _touchEndListener: null, + _touchEndTapListener: null, + _touchStartListener: null, + _initialFingerSpacing: null, + _initialScale: null, + _tapCount: null, + _tapThreshold: null, + _lastTap: null, + _doubleTapPerformed:false, + _oneFingerTouch:false, + _tapCancel:false, + + constructor : function(/* dojox.geo.charting.Map */map,options) { + // summary: + // Constructs a new _TouchInteractionSupport instance + // map: dojox.geo.charting.Map + // the Map widget this class provides touch navigation for. + this._map = map; + this._centerTouchLocation = {x: 0,y: 0}; + + this._tapCount = 0; + this._lastTap = {x: 0,y: 0}; + this._tapThreshold = 100; // square distance in pixels + }, + + connect: function() { + // summary: + // install touch listeners + _touchStartListener = this._map.surface.connect("touchstart", this, this._touchStartHandler); + }, + + disconnect: function() { + // summary: + // disconnects any installed listeners. Must be called only when disposing of this instance + if (this._touchStartListener) { + connect.disconnect(this._touchStartListener); + this._touchStartListener = null; + } + }, + + _getTouchBarycenter: function(touchEvent) { + // summary: + // returns the midpoint of the two first fingers (or the first finger location if only one) + // touchEvent: a touch event + // returns: dojox.gfx.Point + // the midpoint + // tags: + // private + var touches = touchEvent.touches; + var firstTouch = touches[0]; + var secondTouch = null; + if (touches.length > 1) { + secondTouch = touches[1]; + } else { + secondTouch = touches[0]; + } + var containerBounds = this._map._getContainerBounds(); + var middleX = (firstTouch.pageX + secondTouch.pageX) / 2.0 - containerBounds.x; + var middleY = (firstTouch.pageY + secondTouch.pageY) / 2.0 - containerBounds.y; + return {x: middleX,y: middleY}; + }, + + _getFingerSpacing: function(touchEvent) { + // summary: + // computes the distance between the first two fingers + // touchEvent: a touch event + // returns: float + // a distance. -1 if less that 2 fingers + // tags: + // private + var touches = touchEvent.touches; + var spacing = -1; + if (touches.length >= 2) { + var dx = (touches[1].pageX - touches[0].pageX); + var dy = (touches[1].pageY - touches[0].pageY); + spacing = Math.sqrt(dx*dx + dy*dy); + } + return spacing; + }, + + _isDoubleTap: function(touchEvent) { + // summary: + // checks whether the specified touchStart event is a double tap + // (i.e. follows closely a previous touchStart at approximately the same location) + // touchEvent: a touch event + // returns: boolean + // true if this event is considered a double tap + // tags: + // private + var isDoubleTap = false; + var touches = touchEvent.touches; + if ((this._tapCount > 0) && touches.length == 1) { + // test distance from last tap + var dx = (touches[0].pageX - this._lastTap.x); + var dy = (touches[0].pageY - this._lastTap.y); + var distance = dx*dx + dy*dy; + if (distance < this._tapThreshold) { + isDoubleTap = true; + } else { + this._tapCount = 0; + } + } + this._tapCount++; + this._lastTap.x = touches[0].pageX; + this._lastTap.y = touches[0].pageY; + setTimeout(lang.hitch(this,function() { + this._tapCount = 0;}),300); + return isDoubleTap; + }, + + _doubleTapHandler: function(touchEvent) { + // summary: + // action performed on the map when a double tap was triggered + // touchEvent: a touch event + // tags: + // private + var feature = this._getFeatureFromTouchEvent(touchEvent); + if (feature) { + this._map.fitToMapArea(feature._bbox, 15, true); + } else { + // perform a basic 2x zoom on touch + var touches = touchEvent.touches; + var containerBounds = this._map._getContainerBounds(); + var offX = touches[0].pageX - containerBounds.x; + var offY = touches[0].pageY - containerBounds.y; + // clicked map point before zooming + var mapPoint = this._map.screenCoordsToMapCoords(offX,offY); + // zoom increment power + this._map.setMapCenterAndScale(mapPoint.x, mapPoint.y,this._map.getMapScale()*2,true); + } + }, + + _getFeatureFromTouchEvent: function(touchEvent) { + // summary: + // utility function to return the feature located at this touch event location + // touchEvent: a touch event + // returns: dojox.geo.charting.Feature + // the feature found if any, null otherwise. + // tags: + // private + var feature = null; + if (touchEvent.gfxTarget && touchEvent.gfxTarget.getParent) { + feature = this._map.mapObj.features[touchEvent.gfxTarget.getParent().id]; + } + return feature; + }, + + _touchStartHandler: function(touchEvent){ + // summary: + // action performed on the map when a touch start was triggered + // touchEvent: a touch event + // tags: + // private + event.stop(touchEvent); + this._oneFingerTouch = (touchEvent.touches.length == 1); + this._tapCancel = !this._oneFingerTouch; + // test double tap + this._doubleTapPerformed = false; + if (this._isDoubleTap(touchEvent)) { + //console.log("double tap recognized"); + this._doubleTapHandler(touchEvent); + this._doubleTapPerformed = true; + return; + } + // compute map midpoint between fingers + var middlePoint = this._getTouchBarycenter(touchEvent); + var mapPoint = this._map.screenCoordsToMapCoords(middlePoint.x,middlePoint.y); + this._centerTouchLocation.x = mapPoint.x; + this._centerTouchLocation.y = mapPoint.y; + // store initial finger spacing to compute zoom later + this._initialFingerSpacing = this._getFingerSpacing(touchEvent); + // store initial map scale + this._initialScale = this._map.getMapScale(); + // install touch move and up listeners (if not done by other fingers before) + if (!this._touchMoveListener) + this._touchMoveListener = connect.connect(win.global,"touchmove",this,this._touchMoveHandler); + if (!this._touchEndTapListener) + this._touchEndTapListener = this._map.surface.connect("touchend", this, this._touchEndTapHandler); + if (!this._touchEndListener) + this._touchEndListener = connect.connect(win.global,"touchend",this, this._touchEndHandler); + }, + + _touchEndTapHandler: function(touchEvent) { + // summary: + // action performed on the map when a tap was triggered + // touchEvent: a touch event + // tags: + // private + var touches = touchEvent.touches; + if (touches.length == 0) { + + // test potential tap ? + if (this._oneFingerTouch && !this._tapCancel) { + this._oneFingerTouch = false; + setTimeout(lang.hitch(this,function() { + // wait to check if double tap + // perform test for single tap + //console.log("double tap was performed ? " + this._doubleTapPerformed); + if (!this._doubleTapPerformed) { + // test distance from last tap + var dx = (touchEvent.changedTouches[0].pageX - this._lastTap.x); + var dy = (touchEvent.changedTouches[0].pageY - this._lastTap.y); + var distance = dx*dx + dy*dy; + if (distance < this._tapThreshold) { + // single tap ok + this._singleTapHandler(touchEvent); + } + } + }),350); + } + this._tapCancel = false; + + } + }, + + _touchEndHandler: function(touchEvent) { + // summary: + // action performed on the map when a touch end was triggered + // touchEvent: a touch event + // tags: + // private + event.stop(touchEvent); + var touches = touchEvent.touches; + if (touches.length == 0) { + // disconnect listeners only when all fingers are up + if (this._touchMoveListener) { + connect.disconnect(this._touchMoveListener); + this._touchMoveListener = null; + } + if (this._touchEndListener) { + connect.disconnect(this._touchEndListener); + this._touchEndListener = null; + } + } else { + // recompute touch center + var middlePoint = this._getTouchBarycenter(touchEvent); + var mapPoint = this._map.screenCoordsToMapCoords(middlePoint.x,middlePoint.y); + this._centerTouchLocation.x = mapPoint.x; + this._centerTouchLocation.y = mapPoint.y; + } + }, + + _singleTapHandler: function(touchEvent) { + // summary: + // action performed on the map when a single tap was triggered + // touchEvent: a touch event + // tags: + // private + var feature = this._getFeatureFromTouchEvent(touchEvent); + if (feature) { + // call feature handler + feature._onclickHandler(touchEvent); + } else { + // unselect all + for (var name in this._map.mapObj.features){ + this._map.mapObj.features[name].select(false); + } + this._map.onFeatureClick(null); + } + }, + + _touchMoveHandler: function(touchEvent){ + // summary: + // action performed on the map when a touch move was triggered + // touchEvent: a touch event + // tags: + // private + + // prevent browser interaction + event.stop(touchEvent); + + // cancel tap if moved too far from first touch location + if (!this._tapCancel) { + var dx = (touchEvent.touches[0].pageX - this._lastTap.x), + dy = (touchEvent.touches[0].pageY - this._lastTap.y); + var distance = dx*dx + dy*dy; + if (distance > this._tapThreshold) { + this._tapCancel = true; + } + } + var middlePoint = this._getTouchBarycenter(touchEvent); + // compute map offset + var mapPoint = this._map.screenCoordsToMapCoords(middlePoint.x,middlePoint.y), + mapOffsetX = mapPoint.x - this._centerTouchLocation.x, + mapOffsetY = mapPoint.y - this._centerTouchLocation.y; + // compute scale factor + var scaleFactor = 1; + var touches = touchEvent.touches; + if (touches.length >= 2) { + var fingerSpacing = this._getFingerSpacing(touchEvent); + scaleFactor = fingerSpacing / this._initialFingerSpacing; + // scale map + this._map.setMapScale(this._initialScale*scaleFactor); + } + // adjust map center on barycentre + var currentMapCenter = this._map.getMapCenter(); + this._map.setMapCenter(currentMapCenter.x - mapOffsetX, currentMapCenter.y - mapOffsetY); + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/geo/charting/_Marker.js b/js/dojo-1.7.2/dojox/geo/charting/_Marker.js new file mode 100644 index 0000000..28bf227 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/_Marker.js @@ -0,0 +1,66 @@ +//>>built + +define("dojox/geo/charting/_Marker", ["dojo/_base/lang","dojo/_base/array", "dojo/_base/declare","dojo/_base/sniff","./_base"], + function(lang, arr, declare, has) { +return declare("dojox.geo.charting._Marker", null, { + + _needTooltipRefresh: null, + _map: null, + + constructor: function(markerData, map){ + this._map = map; + var mapObj = map.mapObj; + this.features = mapObj.features; + this.markerData = markerData; + _needTooltipRefresh = false; + }, + + show: function(featureId,evt){ + this.currentFeature = this.features[featureId]; + if (this._map.showTooltips && this.currentFeature) { + this.markerText = this.currentFeature.markerText || this.markerData[featureId] || featureId; + dojox.geo.charting.showTooltip(this.markerText, this.currentFeature.shape, ["before"]); + } + this._needTooltipRefresh = false; + }, + + hide: function(){ + if (this._map.showTooltips && this.currentFeature) + dojox.geo.charting.hideTooltip(this.currentFeature.shape); + this._needTooltipRefresh = false; + }, + + _getGroupBoundingBox: function(group){ + var shapes = group.children; + var feature = shapes[0]; + var bbox = feature.getBoundingBox(); + this._arround = lang.clone(bbox); + arr.forEach(shapes, function(item){ + var _bbox = item.getBoundingBox(); + this._arround.x = Math.min(this._arround.x, _bbox.x); + this._arround.y = Math.min(this._arround.y, _bbox.y); + },this); + }, + + _toWindowCoords: function(arround, coords, containerSize){ + var toLeft = (arround.x - this.topLeft[0]) * this.scale; + var toTop = (arround.y - this.topLeft[1]) * this.scale + if (has("ff") == 3.5) { + arround.x = coords.x; + arround.y = coords.y; + } + else if (has("chrome")) { + arround.x = containerSize.x + toLeft; + arround.y = containerSize.y + toTop; + } + else { + arround.x = coords.x + toLeft; + arround.y = coords.y + toTop; + } + arround.width = (this.currentFeature._bbox[2]) * this.scale; + arround.height = (this.currentFeature._bbox[3]) * this.scale; + arround.x += arround.width / 6; + arround.y += arround.height / 4; + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/geo/charting/_base.js b/js/dojo-1.7.2/dojox/geo/charting/_base.js new file mode 100644 index 0000000..8a461da --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/_base.js @@ -0,0 +1,55 @@ +//>>built +define("dojox/geo/charting/_base", ["dojo/_base/lang","dojo/_base/array","../../main", "dojo/_base/html","dojo/dom-geometry", + "dojox/gfx/matrix","dijit/Tooltip","dojo/_base/NodeList","dojo/NodeList-traverse"], + function(lang, arr, dojox, html, domGeom, matrix, Tooltip, NodeList, NodeListTraverse) { + var dgc = lang.getObject("geo.charting", true, dojox); + + dgc.showTooltip = function(/*String*/innerHTML, /*dojox.gfx.shape*/ gfxObject, /*String[]?*/ positions){ + var arroundNode = dgc._normalizeArround(gfxObject); + return Tooltip.show(innerHTML, arroundNode, positions); + }; + + dgc.hideTooltip = function( /*dojox.gfx.shape*/gfxObject){ + return Tooltip.hide(gfxObject); + }; + + dgc._normalizeArround = function(gfxObject){ + var bbox = dgc._getRealBBox(gfxObject); + //var bbox = gfxObject.getBoundingBox(); + //get the real screen coords for gfx object + var realMatrix = gfxObject._getRealMatrix() || {xx:1,xy:0,yx:0,yy:1,dx:0,dy:0}; + var point = matrix.multiplyPoint(realMatrix, bbox.x, bbox.y); + var gfxDomContainer = dgc._getGfxContainer(gfxObject); + gfxObject.x = domGeom.position(gfxDomContainer,true).x + point.x, + gfxObject.y = domGeom.position(gfxDomContainer,true).y + point.y, + gfxObject.w = bbox.width * realMatrix.xx, + gfxObject.h = bbox.height * realMatrix.yy + return gfxObject; + }; + + dgc._getGfxContainer = function(gfxObject){ + if (gfxObject.surface) { + return (new NodeList(gfxObject.surface.rawNode)).parents("div")[0]; + } else { + return (new NodeList(gfxObject.rawNode)).parents("div")[0]; + } + }; + + dgc._getRealBBox = function(gfxObject){ + var bboxObject = gfxObject.getBoundingBox(); + if(!bboxObject){//the gfx object is group + var shapes = gfxObject.children; + bboxObject = lang.clone(dgc._getRealBBox(shapes[0])); + arr.forEach(shapes, function(item){ + var nextBBox = dgc._getRealBBox(item); + bboxObject.x = Math.min(bboxObject.x, nextBBox.x); + bboxObject.y = Math.min(bboxObject.y, nextBBox.y); + bboxObject.endX = Math.max(bboxObject.x + bboxObject.width, nextBBox.x + nextBBox.width); + bboxObject.endY = Math.max(bboxObject.y + bboxObject.height, nextBBox.y + nextBBox.height); + }); + bboxObject.width = bboxObject.endX - bboxObject.x; + bboxObject.height = bboxObject.endY - bboxObject.y; + } + return bboxObject; + }; +}); diff --git a/js/dojo-1.7.2/dojox/geo/charting/resources/Map.css b/js/dojo-1.7.2/dojox/geo/charting/resources/Map.css new file mode 100644 index 0000000..48409ee --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/resources/Map.css @@ -0,0 +1,38 @@ +.tundra .dijitTooltipAbove .dijitTooltipConnector, +.tundra .dijitTooltipLeft .dijitTooltipConnector, +.tundra .dijitTooltipBottom .dijitTooltipConnector, +.tundra .dijitTooltipRight.dijitTooltipConnector, +.dj_ie .tundra .dijitTooltipAbove .dijitTooltipConnector +.dj_ie .tundra .dijitTooltipLeft .dijitTooltipConnector, +.dj_ie .tundra .dijitTooltipBottom .dijitTooltipConnector, +.dj_ie .tundra .dijitTooltipRight .dijitTooltipConnector +{ + display: none; +} + +.dojoxLegendNode { + border: 1px solid #ccc; + margin: 5px 10px 5px 10px; + padding: 3px; + float:right; +} + +.dojoxLegendText { + vertical-align: text-top; + padding-right: 10px +} + +.mapZoomIn { + width: 21px; + height: 21px; + background: url(img/zoomin.png) no-repeat; + position: absolute; +} + +.mapZoomOut { + width: 21px; + height: 21px; + background: url(img/zoomout.png) no-repeat; + position: absolute; +} + diff --git a/js/dojo-1.7.2/dojox/geo/charting/resources/data/NOTICES b/js/dojo-1.7.2/dojox/geo/charting/resources/data/NOTICES new file mode 100644 index 0000000..5d62e07 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/resources/data/NOTICES @@ -0,0 +1,63 @@ +Mapping data in this directory was obtained from the United States Geological Survey (USGS) at http://nationalatlas.gov/atlasftp.html. +Data and information authored or produced by the USGS are in the public domain: http://nationalatlas.gov/policies.html. +The following notices and information are provided by the USGS: +----------------------------------------------------------------------------------------------------------------------------------------------- + + + Are there legal restrictions on access or use of the data? + + Access_Constraints: None + Use_Constraints: + None. Acknowledgment of the National Atlas of the United States + of America and (or) the U.S. Geological Survey would be + appreciated in products derived from these data. + + 1. Who distributes the data set? (Distributor 1 of 1) + + Earth Science Information Center, U.S. Geological Survey + 507 National Center + Reston, VA 20192 + + 1-888-ASK-USGS (1-888-275-8747) (voice) + + + Contact_Instructions: + In addition to the address above there are other ESIC offices throughout the + country. A full list of these offices is at + <http://mapping.usgs.gov/esic/esic_index.html>. + + 2. What's the catalog number I need to order this data set? + + 3. What legal disclaimers am I supposed to read? + + Although these data have been processed successfully on a computer system + at the U.S. Geological Survey, no warranty expressed or implied is made by the U.S. Geological Survey regarding the utility of the data on any other system, nor shall the act of distribution constitute any such warranty. No responsibility is assumed by the U.S. Geological Survey in the use of these data. + + 4. How can I download or order the data? + + Availability in digital form: + + Data format: ESRI Shapefile + Network links: <http://nationalatlas.gov/atlasftp.html> + + Data format: SDTS + Network links: <http://nationalatlas.gov/atlasftp.html> + + + Cost to order the data: + + There is no charge for the online option. For National Atlas files ordered on CD-ROM + there is a base price of $45.00 per disc, a handling fee of $5.00, and a per-file + charge based on file size. The charge for files less than 10 megabytes in size is + $1.00. The charge for files that range in size from 10 to 150 megabytes is $7.50. The + charge for files of 150 megabytes or larger is $15.00. The charge is $7.50 for the + Major Roads of the United States data set. + + + Special instructions: + + To order files on CD-ROM, please see <http://nationalatlas.gov/atlasftp.html#q12>. + +--------------------------------------------------------------------------------------------------------------------- + +This Shapefile data is then reformatted into a simple JSON format diff --git a/js/dojo-1.7.2/dojox/geo/charting/resources/data/USStates.json b/js/dojo-1.7.2/dojox/geo/charting/resources/data/USStates.json new file mode 100644 index 0000000..7014802 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/resources/data/USStates.json @@ -0,0 +1,262 @@ +{ + "layerExtent":[0.0, 0.0, 8036.4007820436855, 5262.578216533747], + "layerExtentLL":[-124.7342529296875, 23.725082397460938, 57.780250549316406, 25.66031265258789], + "featureNames":["RI", "VT", "HI", "ME", "VA", "MI", "DE", "ID", "IA", "MD", "MA", "AR", "IL", "UT", "IN", "MN", "AZ", "MO", "MT", "MS", "NH", "NJ", "NM", "AK", "TX", "AL", "NC", "ND", "NE", "NY", "GA", "NV", "TN", "CA", "OK", "OH", "WY", "FL", "SD", "SC", "CT", "WV", "DC", "WI", "KY", "KS", "OR", "LA", "WA", "CO", "PA"], + "features":{ + "RI":{ + "shape":[[7641, 1436, 7651, 1437, 7661, 1467, 7661, 1467, 7653, 1478, 7641, 1436], [7541, 1398, 7559, 1392, 7598, 1380, 7615, 1420, 7635, 1430, 7635, 1431, 7627, 1445, 7626, 1427, 7615, 1429, 7607, 1410, 7618, 1435, 7606, 1444, 7617, 1460, 7618, 1506, 7612, 1496, 7568, 1527, 7568, 1526, 7541, 1398], [7633, 1474, 7639, 1442, 7645, 1476, 7631, 1485, 7633, 1474]], + "center":[7585, 1442], + "bbox":[7541.023426203894, 1379.9911631012965, 120.38955278578123, 146.89851936205946] + }, + "VT":{ + "shape":[7427, 828, 7434, 848, 7424, 882, 7445, 909, 7444, 926, 7390, 984, 7404, 1022, 7383, 1128, 7402, 1236, 7394, 1266, 7414, 1289, 7393, 1294, 7309, 1313, 7302, 1314, 7267, 1166, 7255, 1151, 7239, 1162, 7241, 1126, 7216, 1076, 7218, 999, 7196, 969, 7184, 893, 7202, 888, 7427, 828], + "center":[7317, 1057], + "bbox":[7183.629180866541, 827.7125085121527, 261.2952454831775, 486.6287466336828] + }, + "HI":{ + "shape":[[2254, 4585, 2254, 4606, 2228, 4628, 2227, 4605, 2254, 4585], [2319, 4564, 2350, 4551, 2385, 4559, 2393, 4577, 2383, 4610, 2361, 4625, 2334, 4617, 2305, 4588, 2319, 4564], [2597, 4694, 2619, 4684, 2634, 4731, 2654, 4734, 2664, 4766, 2634, 4772, 2610, 4758, 2611, 4743, 2600, 4747, 2608, 4758, 2584, 4760, 2558, 4702, 2597, 4694], [2790, 4803, 2827, 4807, 2796, 4829, 2719, 4809, 2731, 4787, 2790, 4803], [2835, 4839, 2851, 4839, 2864, 4864, 2908, 4860, 2948, 4903, 2921, 4921, 2870, 4926, 2863, 4884, 2827, 4864, 2835, 4839], [2769, 4849, 2800, 4865, 2797, 4885, 2774, 4888, 2761, 4856, 2769, 4849], [2832, 4923, 2848, 4934, 2822, 4937, 2832, 4923], [2968, 4993, 3088, 5070, 3095, 5110, 3109, 5108, 3113, 5129, 3143, 5154, 3102, 5189, 3011, 5222, 2976, 5263, 2938, 5226, 2946, 5175, 2920, 5098, 2963, 5053, 2954, 5008, 2968, 4993]], + "center":[2703, 4833], + "bbox":[2226.7877701712587, 4551.091358635575, 915.9598550544888, 711.4868578981723] + }, + "ME":{ + "shape":[7610, 288, 7625, 320, 7647, 327, 7714, 269, 7794, 304, 7867, 514, 7872, 558, 7925, 560, 7935, 577, 7924, 583, 7942, 600, 7938, 620, 7951, 635, 7967, 644, 7989, 630, 8016, 661, 8002, 670, 8009, 678, 7997, 675, 8010, 692, 8012, 675, 8023, 684, 8018, 671, 8036, 683, 8015, 725, 7984, 720, 7990, 744, 7983, 731, 7983, 745, 7967, 737, 7971, 762, 7958, 759, 7952, 775, 7939, 756, 7937, 801, 7931, 783, 7932, 800, 7922, 784, 7916, 789, 7929, 803, 7920, 819, 7884, 779, 7876, 786, 7891, 801, 7874, 793, 7886, 804, 7872, 801, 7869, 821, 7862, 803, 7853, 807, 7864, 826, 7857, 814, 7846, 826, 7865, 857, 7819, 854, 7824, 832, 7838, 837, 7824, 821, 7816, 841, 7818, 807, 7801, 800, 7800, 786, 7813, 825, 7791, 840, 7802, 856, 7794, 904, 7803, 904, 7790, 940, 7780, 939, 7789, 913, 7775, 943, 7759, 920, 7749, 972, 7741, 935, 7744, 978, 7731, 971, 7729, 937, 7717, 970, 7725, 985, 7729, 976, 7726, 996, 7706, 936, 7698, 960, 7705, 956, 7724, 999, 7717, 1008, 7706, 976, 7697, 1010, 7698, 982, 7693, 1010, 7696, 983, 7677, 993, 7662, 1036, 7678, 1048, 7660, 1054, 7657, 1069, 7666, 1075, 7643, 1107, 7641, 1157, 7617, 1153, 7616, 1152, 7613, 1135, 7581, 1111, 7468, 758, 7469, 757, 7483, 747, 7500, 764, 7499, 725, 7522, 727, 7504, 706, 7544, 619, 7524, 564, 7542, 513, 7534, 459, 7590, 287, 7610, 288], + "center":[7710, 682], + "bbox":[7467.685076331587, 269.1289575024286, 568.7157057120985, 887.6751354524711] + }, + "VA":{ + "shape":[[7177, 2288, 7216, 2271, 7216, 2271, 7186, 2362, 7195, 2366, 7166, 2410, 7166, 2458, 7149, 2420, 7162, 2388, 7151, 2391, 7152, 2377, 7165, 2373, 7151, 2366, 7172, 2341, 7161, 2341, 7171, 2335, 7160, 2328, 7182, 2314, 7176, 2301, 7163, 2305, 7177, 2288], [6817, 2100, 6818, 2100, 6841, 2099, 6860, 2110, 6855, 2132, 6921, 2156, 6921, 2156, 6928, 2160, 6929, 2161, 6940, 2194, 6923, 2201, 6931, 2212, 6914, 2210, 6913, 2262, 6903, 2256, 6919, 2269, 6907, 2273, 6953, 2253, 6967, 2288, 7003, 2288, 7017, 2305, 7013, 2287, 7027, 2287, 7045, 2303, 7039, 2313, 7055, 2309, 7054, 2322, 7059, 2311, 7092, 2323, 7090, 2339, 7063, 2332, 7091, 2345, 7083, 2366, 7093, 2376, 7070, 2375, 7073, 2359, 7057, 2358, 7063, 2379, 7048, 2354, 7022, 2349, 7021, 2336, 7002, 2334, 6984, 2310, 6938, 2298, 6982, 2312, 7049, 2379, 7098, 2387, 7064, 2396, 7109, 2403, 7113, 2418, 7111, 2435, 7098, 2414, 7097, 2424, 7080, 2411, 7090, 2426, 7075, 2420, 7078, 2430, 7091, 2432, 7079, 2435, 7097, 2442, 7080, 2452, 7013, 2401, 6989, 2408, 7021, 2406, 7060, 2447, 7098, 2456, 7093, 2470, 7118, 2469, 7104, 2473, 7110, 2485, 7122, 2476, 7104, 2503, 7062, 2463, 7026, 2465, 7021, 2450, 7018, 2468, 7001, 2456, 6959, 2466, 7003, 2459, 7004, 2474, 7050, 2479, 7055, 2468, 7064, 2496, 7094, 2506, 7090, 2539, 7113, 2509, 7113, 2530, 7136, 2521, 7118, 2499, 7155, 2502, 7153, 2513, 7167, 2496, 7204, 2560, 7205, 2562, 7201, 2563, 7202, 2562, 7185, 2533, 7186, 2565, 7187, 2566, 7183, 2567, 7182, 2566, 7173, 2559, 7179, 2567, 7179, 2568, 6333, 2723, 6319, 2725, 6017, 2767, 6012, 2768, 6091, 2729, 6098, 2707, 6127, 2694, 6144, 2648, 6230, 2571, 6247, 2552, 6258, 2584, 6301, 2608, 6344, 2575, 6368, 2591, 6415, 2567, 6418, 2545, 6433, 2553, 6467, 2527, 6479, 2534, 6500, 2512, 6493, 2505, 6507, 2491, 6492, 2481, 6550, 2358, 6560, 2293, 6621, 2315, 6647, 2227, 6670, 2239, 6723, 2150, 6720, 2092, 6809, 2139, 6817, 2101, 6817, 2100]], + "center":[6750, 2455], + "bbox":[6012.441825481979, 2091.8790360725766, 1203.6208629785642, 675.6390679572082] + }, + "MI":{ + "shape":[[5098, 797, 5138, 760, 5201, 760, 5169, 771, 5115, 855, 5107, 841, 5115, 813, 5106, 835, 5083, 821, 5098, 797], [5071, 647, 5077, 644, 5024, 682, 5036, 684, 4995, 694, 5003, 677, 5095, 620, 5071, 647], [5296, 933, 5311, 924, 5362, 943, 5421, 886, 5578, 848, 5574, 904, 5628, 898, 5637, 911, 5670, 891, 5694, 937, 5683, 947, 5717, 955, 5713, 963, 5739, 981, 5654, 996, 5635, 982, 5627, 1025, 5589, 996, 5520, 987, 5503, 1014, 5421, 1028, 5412, 1058, 5384, 1077, 5382, 1099, 5366, 1086, 5386, 1065, 5386, 1043, 5354, 1051, 5349, 1079, 5333, 1091, 5328, 1042, 5319, 1084, 5302, 1099, 5256, 1208, 5255, 1208, 5236, 1192, 5244, 1157, 5213, 1163, 5225, 1135, 5217, 1122, 5222, 1098, 5173, 1078, 5176, 1057, 4898, 996, 4883, 965, 4855, 954, 4856, 954, 4932, 902, 4986, 891, 5042, 856, 5080, 810, 5112, 853, 5110, 899, 5152, 854, 5134, 885, 5160, 863, 5197, 865, 5228, 884, 5264, 934, 5296, 933], [5692, 916, 5674, 894, 5684, 881, 5695, 883, 5688, 904, 5701, 920, 5692, 916], [5703, 935, 5697, 942, 5688, 923, 5703, 935], [5754, 974, 5771, 954, 5795, 973, 5787, 989, 5741, 984, 5754, 974], [5651, 1025, 5682, 1031, 5666, 1041, 5651, 1025], [5532, 1243, 5544, 1203, 5551, 1205, 5541, 1245, 5560, 1215, 5557, 1143, 5615, 1113, 5585, 1089, 5605, 1052, 5595, 1044, 5632, 1034, 5671, 1056, 5704, 1054, 5725, 1079, 5809, 1094, 5826, 1109, 5849, 1154, 5831, 1146, 5822, 1161, 5846, 1182, 5856, 1214, 5858, 1289, 5833, 1305, 5832, 1346, 5796, 1363, 5790, 1415, 5831, 1437, 5871, 1373, 5860, 1368, 5916, 1331, 5940, 1335, 5973, 1379, 6023, 1528, 6019, 1596, 5993, 1588, 5977, 1599, 5984, 1608, 5971, 1625, 5972, 1650, 5944, 1676, 5939, 1730, 5907, 1786, 5906, 1787, 5718, 1819, 5717, 1806, 5428, 1839, 5429, 1838, 5456, 1808, 5487, 1732, 5497, 1651, 5488, 1595, 5468, 1551, 5486, 1540, 5467, 1549, 5433, 1481, 5442, 1416, 5426, 1394, 5454, 1335, 5449, 1268, 5471, 1256, 5470, 1224, 5505, 1212, 5535, 1158, 5527, 1175, 5535, 1187, 5526, 1205, 5532, 1243]], + "center":[5662, 1450], + "bbox":[4854.911490750158, 620.4912315367447, 1167.6361755384014, 1218.2194209192758] + }, + "DE":{ + "shape":[7082, 1965, 7100, 1940, 7132, 1937, 7133, 1938, 7135, 1938, 7119, 1976, 7130, 2008, 7129, 2009, 7158, 2039, 7187, 2099, 7225, 2115, 7236, 2145, 7222, 2135, 7217, 2144, 7232, 2147, 7205, 2160, 7219, 2166, 7236, 2147, 7246, 2177, 7246, 2178, 7242, 2179, 7242, 2179, 7239, 2180, 7234, 2181, 7150, 2199, 7082, 1965], + "center":[7157, 2107], + "bbox":[7082.430069572815, 1937.1742059381268, 163.18616844855842, 261.4809650452348] + }, + "ID":{ + "shape":[1428, 192, 1536, 217, 1550, 220, 1507, 416, 1537, 477, 1537, 498, 1526, 505, 1539, 522, 1521, 528, 1570, 572, 1620, 694, 1634, 689, 1638, 710, 1676, 715, 1641, 802, 1630, 805, 1638, 859, 1610, 874, 1616, 891, 1602, 915, 1628, 941, 1691, 907, 1704, 930, 1697, 943, 1706, 945, 1707, 996, 1731, 1041, 1724, 1076, 1764, 1103, 1769, 1166, 1787, 1189, 1802, 1167, 1854, 1183, 1871, 1163, 1982, 1188, 1979, 1168, 2000, 1150, 2037, 1210, 2037, 1210, 1959, 1681, 1903, 1671, 1536, 1604, 1535, 1604, 1118, 1512, 1117, 1512, 1197, 1168, 1231, 1110, 1195, 1080, 1194, 1057, 1234, 998, 1267, 976, 1276, 949, 1352, 851, 1346, 822, 1319, 800, 1309, 766, 1309, 764, 1304, 745, 1315, 731, 1306, 692, 1428, 192], + "center":[1499, 1209], + "bbox":[1116.7271597781803, 191.89745587373298, 920.1469178039938, 1488.964617046075] + }, + "IA":{ + "shape":[4779, 1552, 4779, 1554, 4782, 1580, 4804, 1599, 4789, 1625, 4809, 1695, 4860, 1714, 4871, 1739, 4871, 1740, 4911, 1792, 4944, 1810, 4945, 1869, 4908, 1927, 4825, 1952, 4817, 1986, 4843, 2012, 4843, 2044, 4825, 2066, 4822, 2096, 4782, 2118, 4789, 2150, 4781, 2154, 4781, 2154, 4734, 2111, 4171, 2132, 4143, 2131, 4125, 2102, 4136, 2071, 4126, 2040, 4131, 2018, 4119, 2014, 4127, 1995, 4115, 1986, 4121, 1965, 4095, 1948, 4099, 1898, 4089, 1865, 4074, 1860, 4059, 1827, 4054, 1768, 4045, 1765, 4044, 1765, 4018, 1718, 4047, 1642, 4026, 1613, 4035, 1591, 4025, 1570, 4045, 1570, 4097, 1570, 4775, 1553, 4779, 1552], + "center":[4463, 1860], + "bbox":[4018.187084563174, 1552.3336974056806, 926.7482669008059, 601.9610296119108] + }, + "MD":{ + "shape":[[7242, 2179, 7246, 2178, 7246, 2180, 7245, 2203, 7242, 2179], [6546, 2075, 6559, 2073, 7050, 1972, 7082, 1965, 7150, 2199, 7234, 2181, 7233, 2182, 7240, 2190, 7225, 2191, 7243, 2203, 7215, 2270, 7216, 2271, 7177, 2288, 7177, 2288, 7142, 2302, 7158, 2270, 7138, 2277, 7150, 2256, 7125, 2268, 7144, 2239, 7125, 2242, 7133, 2204, 7122, 2248, 7107, 2224, 7111, 2256, 7075, 2228, 7068, 2236, 7054, 2214, 7065, 2220, 7082, 2197, 7064, 2193, 7061, 2204, 7056, 2185, 7095, 2191, 7108, 2174, 7093, 2158, 7104, 2137, 7091, 2157, 7102, 2168, 7095, 2187, 7076, 2180, 7082, 2168, 7070, 2174, 7079, 2154, 7066, 2176, 7055, 2152, 7046, 2181, 7042, 2165, 7051, 2141, 7062, 2156, 7075, 2150, 7061, 2149, 7076, 2131, 7070, 2120, 7063, 2129, 7059, 2118, 7058, 2141, 7048, 2119, 7082, 2059, 7054, 2094, 7058, 2078, 7047, 2082, 7053, 2111, 7035, 2087, 7042, 2053, 7057, 2050, 7050, 2041, 7091, 2033, 7060, 2035, 7070, 2016, 7088, 2017, 7072, 2013, 7080, 1991, 7062, 2022, 7064, 1996, 7050, 2004, 7035, 2049, 7030, 2026, 7023, 2032, 7028, 2060, 7020, 2044, 7006, 2048, 7022, 2059, 7005, 2062, 7013, 2074, 6997, 2066, 7014, 2075, 7009, 2084, 6979, 2077, 6988, 2097, 6995, 2084, 6996, 2097, 7014, 2096, 7017, 2110, 7004, 2111, 7025, 2118, 6989, 2112, 7019, 2131, 6996, 2133, 7014, 2139, 7009, 2169, 7027, 2214, 7052, 2239, 7043, 2251, 7034, 2229, 7034, 2239, 7010, 2229, 6993, 2188, 6997, 2215, 7042, 2255, 7057, 2251, 7075, 2298, 7045, 2269, 7050, 2285, 7013, 2273, 7017, 2261, 7008, 2274, 7004, 2259, 7000, 2277, 6981, 2250, 6990, 2270, 6975, 2270, 6953, 2234, 6946, 2253, 6936, 2245, 6939, 2259, 6923, 2262, 6916, 2239, 6947, 2196, 6941, 2178, 6940, 2177, 6953, 2157, 6930, 2142, 6924, 2150, 6921, 2156, 6855, 2132, 6860, 2110, 6841, 2099, 6818, 2100, 6817, 2100, 6804, 2069, 6785, 2062, 6790, 2051, 6736, 2044, 6726, 2061, 6702, 2065, 6701, 2086, 6669, 2087, 6652, 2069, 6632, 2114, 6610, 2111, 6565, 2173, 6549, 2091, 6546, 2075]], + "center":[7052, 2222], + "bbox":[6546.235946891058, 1964.9808172764635, 699.4200881793276, 336.6030056060624] + }, + "MA":{ + "shape":[[7758, 1469, 7708, 1483, 7719, 1484, 7734, 1449, 7758, 1469], [7302, 1314, 7309, 1313, 7393, 1294, 7414, 1289, 7429, 1285, 7575, 1251, 7591, 1222, 7631, 1200, 7632, 1202, 7623, 1212, 7635, 1211, 7646, 1230, 7639, 1232, 7674, 1236, 7634, 1264, 7649, 1271, 7632, 1292, 7640, 1303, 7626, 1303, 7631, 1317, 7671, 1313, 7707, 1352, 7696, 1344, 7692, 1357, 7719, 1364, 7728, 1388, 7767, 1391, 7757, 1396, 7800, 1365, 7776, 1328, 7753, 1328, 7777, 1323, 7817, 1385, 7806, 1370, 7814, 1391, 7753, 1412, 7725, 1445, 7718, 1402, 7713, 1413, 7706, 1405, 7694, 1441, 7681, 1427, 7684, 1457, 7666, 1464, 7663, 1446, 7662, 1467, 7661, 1467, 7651, 1437, 7641, 1436, 7641, 1436, 7645, 1407, 7635, 1430, 7635, 1430, 7615, 1420, 7598, 1380, 7559, 1392, 7541, 1398, 7321, 1448, 7304, 1452, 7302, 1327, 7302, 1314], [7799, 1472, 7824, 1459, 7815, 1462, 7815, 1443, 7835, 1462, 7799, 1472]], + "center":[7490, 1333], + "bbox":[7301.785749503367, 1200.2581210721266, 533.1245306226901, 283.6107339386617] + }, + "AR":{ + "shape":[4323, 2915, 4351, 2914, 5015, 2888, 5031, 2925, 4986, 2986, 5087, 2978, 5089, 2978, 5089, 2979, 5102, 2996, 5083, 3000, 5093, 3013, 5055, 3032, 5073, 3047, 5057, 3059, 5065, 3073, 5046, 3067, 5048, 3098, 5038, 3082, 5026, 3095, 5041, 3100, 5028, 3122, 5045, 3148, 5009, 3177, 5009, 3178, 5020, 3191, 5011, 3206, 4986, 3199, 4990, 3227, 4974, 3219, 4972, 3234, 4988, 3238, 4978, 3250, 4969, 3241, 4974, 3291, 4961, 3311, 4944, 3302, 4932, 3333, 4919, 3328, 4939, 3340, 4915, 3350, 4930, 3357, 4928, 3369, 4897, 3380, 4914, 3418, 4890, 3428, 4909, 3437, 4877, 3438, 4893, 3452, 4878, 3462, 4878, 3485, 4888, 3473, 4897, 3481, 4886, 3495, 4907, 3483, 4894, 3504, 4900, 3521, 4911, 3516, 4905, 3542, 4887, 3545, 4900, 3558, 4894, 3568, 4879, 3569, 4464, 3582, 4426, 3583, 4424, 3481, 4369, 3483, 4354, 3465, 4352, 3464, 4352, 3449, 4356, 3126, 4327, 2945, 4323, 2915], + "center":[4662, 3220], + "bbox":[4322.829240491697, 2887.82523560477, 778.9827073906772, 694.879092657869] + }, + "IL":{ + "shape":[4871, 1739, 4872, 1739, 5275, 1711, 5276, 1714, 5277, 1759, 5328, 1857, 5328, 1858, 5370, 2310, 5358, 2319, 5366, 2336, 5355, 2353, 5379, 2385, 5386, 2426, 5342, 2519, 5321, 2525, 5333, 2543, 5316, 2567, 5323, 2594, 5311, 2594, 5322, 2613, 5322, 2614, 5305, 2642, 5320, 2674, 5261, 2698, 5266, 2759, 5185, 2735, 5158, 2769, 5164, 2782, 5166, 2783, 5147, 2769, 5138, 2770, 5143, 2784, 5127, 2775, 5103, 2732, 5116, 2710, 5098, 2652, 5045, 2615, 5030, 2621, 5032, 2605, 4964, 2560, 4960, 2538, 4992, 2437, 4940, 2417, 4915, 2433, 4895, 2364, 4796, 2279, 4770, 2203, 4780, 2155, 4781, 2154, 4789, 2150, 4782, 2118, 4822, 2096, 4825, 2066, 4843, 2044, 4843, 2012, 4817, 1986, 4825, 1952, 4908, 1927, 4945, 1869, 4944, 1810, 4911, 1792, 4871, 1740, 4871, 1739], + "center":[5115, 2145], + "bbox":[4770.196295410327, 1711.191338731059, 615.4388548089883, 1073.0606632626743] + }, + "UT":{ + "shape":[1536, 1604, 1903, 1671, 1959, 1681, 1956, 1693, 1927, 1871, 2214, 1915, 2213, 1925, 2105, 2676, 2039, 2667, 1351, 2546, 1345, 2545, 1536, 1604], + "center":[1781, 2167], + "bbox":[1344.750115055111, 1604.3978062032195, 869.4968003325662, 1072.015936358547] + }, + "IN":{ + "shape":[5428, 1839, 5717, 1806, 5718, 1819, 5721, 1845, 5778, 2313, 5777, 2313, 5768, 2324, 5779, 2338, 5773, 2350, 5788, 2355, 5786, 2374, 5734, 2399, 5695, 2396, 5701, 2433, 5675, 2455, 5666, 2484, 5645, 2489, 5637, 2538, 5620, 2553, 5585, 2539, 5567, 2513, 5574, 2523, 5553, 2530, 5550, 2566, 5531, 2585, 5501, 2558, 5472, 2578, 5462, 2603, 5385, 2574, 5383, 2602, 5340, 2587, 5340, 2610, 5323, 2613, 5322, 2613, 5311, 2594, 5323, 2594, 5316, 2567, 5333, 2543, 5321, 2525, 5342, 2519, 5386, 2426, 5379, 2385, 5355, 2353, 5366, 2336, 5358, 2319, 5370, 2310, 5328, 1858, 5329, 1858, 5367, 1872, 5428, 1839], + "center":[5553, 2130], + "bbox":[5310.914233466702, 1806.2693159343437, 476.59488846766635, 807.1441757493742] + }, + "MN":{ + "shape":[3957, 591, 3967, 564, 3950, 502, 3976, 503, 4218, 503, 4217, 428, 4242, 430, 4260, 439, 4284, 553, 4388, 573, 4395, 595, 4463, 568, 4503, 569, 4544, 585, 4534, 600, 4562, 603, 4581, 646, 4594, 641, 4593, 620, 4621, 617, 4635, 642, 4688, 664, 4687, 676, 4779, 632, 4793, 661, 4874, 652, 4906, 674, 4958, 667, 4798, 754, 4628, 929, 4629, 930, 4604, 948, 4609, 1063, 4558, 1095, 4534, 1135, 4532, 1162, 4550, 1165, 4566, 1188, 4551, 1218, 4548, 1321, 4585, 1355, 4614, 1357, 4667, 1391, 4690, 1430, 4744, 1458, 4772, 1499, 4779, 1552, 4775, 1553, 4097, 1570, 4045, 1570, 4047, 1222, 3992, 1163, 4029, 1123, 4033, 1100, 4033, 1099, 4028, 1023, 4001, 959, 4008, 907, 3997, 891, 3996, 776, 3959, 670, 3957, 591], + "center":[4328, 1050], + "bbox":[3950.4253913269413, 427.57079578020245, 1007.2005431623966, 1142.3275358037831] + }, + "AZ":{ + "shape":[2105, 2676, 1948, 3757, 1919, 3753, 1616, 3706, 1051, 3370, 1074, 3333, 1075, 3331, 1106, 3331, 1121, 3315, 1121, 3280, 1092, 3262, 1105, 3229, 1097, 3220, 1102, 3200, 1139, 3179, 1153, 3106, 1178, 3078, 1229, 3058, 1196, 3013, 1193, 2962, 1174, 2927, 1179, 2903, 1179, 2903, 1179, 2902, 1195, 2871, 1202, 2695, 1260, 2695, 1276, 2722, 1293, 2725, 1315, 2697, 1345, 2545, 1345, 2545, 1351, 2546, 2039, 2667, 2105, 2676], + "center":[1610, 3091], + "bbox":[1051.3556136955926, 2544.815557518358, 1053.5072639848177, 1212.212023750329] + }, + "MO":{ + "shape":[4781, 2154, 4780, 2155, 4770, 2203, 4796, 2279, 4895, 2364, 4915, 2433, 4940, 2417, 4992, 2437, 4960, 2538, 4964, 2560, 5032, 2605, 5030, 2621, 5045, 2615, 5098, 2652, 5116, 2710, 5103, 2732, 5127, 2775, 5143, 2784, 5138, 2770, 5147, 2769, 5166, 2783, 5167, 2783, 5161, 2817, 5171, 2825, 5159, 2831, 5160, 2860, 5137, 2853, 5129, 2880, 5128, 2881, 5118, 2882, 5118, 2880, 5110, 2865, 5109, 2880, 5110, 2881, 5115, 2907, 5100, 2914, 5113, 2927, 5089, 2931, 5107, 2950, 5089, 2978, 5087, 2978, 4986, 2986, 5031, 2925, 5015, 2888, 4351, 2914, 4323, 2915, 4322, 2863, 4321, 2819, 4319, 2406, 4282, 2393, 4274, 2360, 4241, 2331, 4262, 2293, 4277, 2292, 4266, 2264, 4242, 2269, 4210, 2245, 4211, 2244, 4195, 2236, 4185, 2197, 4159, 2184, 4159, 2139, 4142, 2133, 4143, 2131, 4171, 2132, 4734, 2111, 4781, 2154, 4781, 2154], + "center":[4649, 2529], + "bbox":[4141.599891262755, 2111.1869114797505, 1029.5962543407404, 874.9905328579766] + }, + "MT":{ + "shape":[3074, 458, 3023, 1050, 3022, 1057, 3005, 1232, 3001, 1232, 2053, 1110, 2042, 1174, 2037, 1210, 2000, 1150, 1979, 1168, 1982, 1188, 1871, 1163, 1854, 1183, 1802, 1167, 1787, 1189, 1769, 1166, 1764, 1103, 1724, 1076, 1731, 1041, 1707, 996, 1706, 945, 1697, 943, 1704, 930, 1691, 907, 1628, 941, 1602, 915, 1616, 891, 1610, 874, 1638, 859, 1630, 805, 1641, 802, 1676, 715, 1638, 710, 1634, 689, 1620, 694, 1570, 572, 1521, 528, 1539, 522, 1526, 505, 1537, 498, 1537, 477, 1507, 416, 1550, 220, 1560, 222, 3074, 458], + "center":[2366, 706], + "bbox":[1506.9365729336703, 219.959812182772, 1567.488761621926, 1012.1411673843539] + }, + "MS":{ + "shape":[5342, 3152, 5360, 3170, 5349, 3751, 5385, 4042, 5385, 4042, 5370, 4056, 5286, 4042, 5308, 4047, 5237, 4070, 5243, 4062, 5228, 4057, 5213, 4094, 5200, 4096, 5199, 4096, 5183, 4090, 5138, 4007, 5153, 3940, 4836, 3959, 4848, 3948, 4831, 3910, 4853, 3903, 4842, 3879, 4858, 3885, 4850, 3857, 4869, 3845, 4850, 3837, 4867, 3838, 4872, 3813, 4891, 3811, 4873, 3810, 4877, 3794, 4892, 3798, 4918, 3759, 4905, 3747, 4918, 3752, 4929, 3733, 4903, 3736, 4902, 3724, 4931, 3722, 4948, 3689, 4928, 3692, 4932, 3675, 4908, 3669, 4910, 3656, 4928, 3664, 4913, 3654, 4922, 3637, 4900, 3641, 4915, 3623, 4897, 3615, 4912, 3587, 4903, 3571, 4889, 3586, 4894, 3569, 4894, 3568, 4900, 3558, 4887, 3545, 4905, 3542, 4911, 3516, 4900, 3521, 4894, 3504, 4907, 3483, 4886, 3495, 4897, 3481, 4888, 3473, 4878, 3485, 4878, 3462, 4893, 3452, 4877, 3438, 4909, 3437, 4890, 3428, 4914, 3418, 4897, 3380, 4928, 3369, 4930, 3357, 4915, 3350, 4939, 3340, 4919, 3328, 4932, 3333, 4944, 3302, 4961, 3311, 4974, 3291, 4969, 3241, 4978, 3250, 4988, 3238, 4972, 3234, 4974, 3219, 4990, 3227, 4986, 3199, 5011, 3206, 5020, 3191, 5009, 3178, 5009, 3177, 5014, 3177, 5341, 3152, 5342, 3152], + "center":[5130, 3618], + "bbox":[4830.8439535221705, 3152.185506272538, 554.1423743161158, 943.8294240195419] + }, + "NH":{ + "shape":[7427, 828, 7425, 784, 7467, 758, 7468, 758, 7581, 1111, 7613, 1135, 7616, 1152, 7616, 1153, 7608, 1172, 7618, 1155, 7636, 1165, 7631, 1199, 7631, 1200, 7591, 1222, 7575, 1251, 7429, 1285, 7414, 1289, 7394, 1266, 7402, 1236, 7383, 1128, 7404, 1022, 7390, 984, 7444, 926, 7445, 909, 7424, 882, 7434, 848, 7427, 828], + "center":[7487, 1110], + "bbox":[7383.275752846597, 757.6279479694789, 253.13402332287387, 530.9874508377478] + }, + "NJ":{ + "shape":[7167, 1623, 7175, 1625, 7297, 1663, 7292, 1722, 7290, 1722, 7255, 1776, 7310, 1776, 7302, 1788, 7313, 1783, 7311, 1794, 7305, 1766, 7312, 1771, 7319, 1834, 7309, 1835, 7321, 1839, 7325, 1898, 7317, 1844, 7308, 1847, 7317, 1847, 7308, 1852, 7315, 1867, 7304, 1869, 7317, 1870, 7319, 1912, 7299, 1943, 7306, 1955, 7288, 1950, 7297, 1971, 7285, 1979, 7298, 1986, 7264, 2005, 7281, 2005, 7260, 2061, 7254, 2048, 7258, 2069, 7235, 2086, 7234, 2040, 7200, 2046, 7131, 2007, 7130, 2008, 7119, 1976, 7135, 1938, 7133, 1938, 7217, 1848, 7157, 1810, 7151, 1788, 7132, 1786, 7125, 1764, 7138, 1727, 7122, 1706, 7166, 1623, 7167, 1623], + "center":[7248, 1862], + "bbox":[7119.486993899072, 1622.7122776765768, 205.74226205555533, 463.7265235430323] + }, + "NM":{ + "shape":[2105, 2676, 2182, 2687, 3017, 2778, 3031, 2779, 3030, 2791, 3023, 2874, 3017, 2874, 2946, 3738, 2363, 3681, 2358, 3706, 2373, 3724, 2337, 3720, 2098, 3690, 2086, 3776, 1953, 3758, 1948, 3757, 2105, 2676], + "center":[2533, 3173], + "bbox":[1947.8141535882821, 2676.4137425617664, 1082.71177385349, 1099.5607135602122] + }, + "AK":{ + "shape":[620, 3939, 642, 3931, 650, 3935, 643, 3931, 675, 3922, 680, 3925, 667, 3924, 694, 3939, 689, 3941, 699, 3939, 714, 3945, 716, 3951, 700, 3957, 686, 3954, 692, 3958, 682, 3955, 685, 3953, 664, 3953, 690, 3958, 684, 3960, 693, 3962, 682, 3961, 693, 3964, 689, 3969, 696, 3965, 713, 3966, 721, 3973, 725, 3971, 714, 3968, 714, 3961, 731, 3962, 728, 3956, 734, 3954, 738, 3960, 738, 3953, 741, 3955, 737, 3962, 744, 3956, 760, 3968, 750, 3974, 776, 3987, 791, 3982, 827, 3987, 846, 3994, 850, 4005, 853, 4004, 848, 3997, 850, 4001, 853, 3998, 850, 3995, 871, 4003, 873, 4005, 853, 4012, 877, 4022, 850, 4017, 895, 4026, 880, 4032, 906, 4037, 917, 4045, 921, 4039, 923, 4053, 922, 4040, 943, 4043, 939, 4039, 953, 4044, 938, 4048, 938, 4051, 983, 4048, 1003, 4051, 1044, 4068, 1047, 4075, 1079, 4080, 1086, 4089, 1174, 4108, 1186, 4119, 1216, 4130, 1302, 4135, 1377, 4173, 1388, 4183, 1397, 4183, 1393, 4181, 1406, 4186, 1300, 4789, 1324, 4799, 1329, 4794, 1351, 4806, 1368, 4799, 1399, 4803, 1390, 4819, 1413, 4835, 1416, 4845, 1463, 4888, 1463, 4910, 1502, 4900, 1515, 4901, 1522, 4895, 1523, 4883, 1536, 4881, 1531, 4875, 1578, 4869, 1589, 4878, 1599, 4888, 1594, 4896, 1599, 4907, 1612, 4911, 1622, 4921, 1631, 4940, 1651, 4952, 1672, 4975, 1668, 4977, 1719, 5064, 1712, 5071, 1728, 5076, 1722, 5087, 1735, 5093, 1735, 5107, 1748, 5108, 1803, 5141, 1804, 5147, 1821, 5151, 1823, 5165, 1813, 5177, 1819, 5207, 1789, 5233, 1782, 5235, 1791, 5229, 1781, 5233, 1780, 5224, 1781, 5235, 1776, 5236, 1776, 5222, 1775, 5232, 1765, 5232, 1764, 5223, 1769, 5219, 1765, 5221, 1765, 5214, 1773, 5212, 1780, 5220, 1779, 5213, 1790, 5212, 1780, 5212, 1794, 5200, 1777, 5214, 1775, 5207, 1769, 5212, 1761, 5210, 1760, 5205, 1769, 5200, 1786, 5202, 1783, 5199, 1788, 5195, 1781, 5200, 1773, 5198, 1775, 5184, 1784, 5181, 1785, 5185, 1788, 5178, 1775, 5183, 1775, 5173, 1786, 5171, 1775, 5172, 1775, 5165, 1771, 5166, 1763, 5155, 1769, 5146, 1755, 5152, 1740, 5149, 1733, 5154, 1728, 5150, 1732, 5155, 1723, 5154, 1731, 5159, 1727, 5165, 1723, 5162, 1727, 5168, 1722, 5172, 1715, 5165, 1720, 5172, 1717, 5178, 1708, 5172, 1703, 5158, 1718, 5159, 1714, 5154, 1716, 5148, 1724, 5147, 1723, 5134, 1743, 5138, 1749, 5133, 1727, 5130, 1726, 5120, 1715, 5119, 1707, 5107, 1709, 5100, 1697, 5099, 1705, 5098, 1698, 5094, 1709, 5088, 1700, 5092, 1688, 5084, 1680, 5073, 1689, 5076, 1688, 5067, 1678, 5070, 1669, 5064, 1671, 5059, 1666, 5058, 1663, 5063, 1650, 5055, 1655, 5049, 1670, 5055, 1667, 5051, 1678, 5048, 1658, 5045, 1664, 5040, 1657, 5040, 1656, 5032, 1667, 5030, 1653, 5030, 1649, 5025, 1651, 5020, 1686, 5039, 1655, 5017, 1656, 5007, 1679, 5014, 1657, 5006, 1649, 5014, 1643, 5003, 1648, 5001, 1652, 5005, 1653, 5000, 1648, 4997, 1655, 4991, 1642, 5001, 1634, 4994, 1635, 4980, 1641, 4978, 1639, 4974, 1632, 4978, 1630, 4984, 1600, 4967, 1600, 4958, 1591, 4947, 1596, 4948, 1593, 4938, 1597, 4929, 1590, 4942, 1578, 4904, 1581, 4891, 1577, 4903, 1568, 4899, 1580, 4917, 1569, 4906, 1575, 4916, 1574, 4927, 1583, 4949, 1578, 4948, 1585, 4968, 1582, 4974, 1571, 4972, 1563, 4953, 1563, 4962, 1556, 4957, 1540, 4958, 1544, 4953, 1539, 4953, 1545, 4953, 1543, 4946, 1547, 4944, 1536, 4928, 1553, 4926, 1539, 4926, 1534, 4913, 1535, 4919, 1529, 4920, 1536, 4921, 1536, 4925, 1528, 4931, 1520, 4925, 1527, 4926, 1516, 4924, 1517, 4915, 1511, 4918, 1506, 4909, 1507, 4919, 1488, 4904, 1495, 4913, 1482, 4919, 1490, 4915, 1512, 4924, 1516, 4927, 1508, 4923, 1511, 4927, 1508, 4927, 1522, 4935, 1510, 4938, 1520, 4941, 1525, 4938, 1531, 4945, 1526, 4947, 1533, 4948, 1535, 4957, 1521, 4959, 1520, 4953, 1518, 4955, 1510, 4948, 1511, 4953, 1506, 4952, 1510, 4957, 1515, 4954, 1517, 4960, 1505, 4954, 1502, 4955, 1505, 4962, 1500, 4963, 1500, 4958, 1491, 4955, 1491, 4950, 1479, 4948, 1454, 4929, 1463, 4926, 1453, 4928, 1441, 4915, 1440, 4906, 1423, 4893, 1426, 4893, 1410, 4887, 1415, 4888, 1418, 4884, 1407, 4884, 1409, 4887, 1381, 4869, 1385, 4871, 1381, 4865, 1376, 4866, 1350, 4850, 1362, 4849, 1371, 4842, 1366, 4829, 1375, 4823, 1382, 4833, 1378, 4841, 1381, 4849, 1377, 4849, 1380, 4853, 1383, 4850, 1382, 4835, 1403, 4840, 1385, 4834, 1374, 4819, 1355, 4831, 1329, 4835, 1272, 4813, 1283, 4808, 1278, 4797, 1274, 4798, 1278, 4804, 1261, 4806, 1212, 4788, 1149, 4783, 1131, 4777, 1145, 4779, 1133, 4770, 1136, 4765, 1123, 4767, 1111, 4761, 1114, 4762, 1107, 4754, 1099, 4754, 1110, 4745, 1104, 4742, 1109, 4733, 1080, 4747, 1072, 4741, 1081, 4741, 1050, 4732, 1069, 4722, 1037, 4719, 1050, 4714, 1049, 4710, 1043, 4714, 1035, 4713, 1037, 4709, 1025, 4714, 1017, 4711, 1015, 4707, 1049, 4708, 1041, 4702, 1034, 4706, 1020, 4703, 1015, 4693, 1025, 4696, 1017, 4692, 1021, 4689, 1030, 4693, 1024, 4686, 1043, 4689, 1040, 4686, 1025, 4682, 1004, 4692, 1000, 4691, 1005, 4688, 999, 4686, 994, 4690, 992, 4684, 982, 4692, 979, 4688, 984, 4685, 979, 4686, 983, 4682, 974, 4688, 981, 4678, 979, 4672, 974, 4681, 969, 4680, 973, 4681, 968, 4684, 973, 4685, 971, 4691, 965, 4684, 960, 4687, 964, 4691, 959, 4691, 949, 4681, 971, 4668, 967, 4667, 971, 4663, 949, 4677, 947, 4668, 933, 4670, 935, 4672, 929, 4674, 945, 4672, 940, 4679, 935, 4677, 938, 4680, 935, 4685, 931, 4683, 933, 4686, 914, 4684, 927, 4686, 914, 4693, 930, 4688, 926, 4698, 938, 4690, 933, 4695, 938, 4700, 930, 4705, 927, 4700, 920, 4700, 910, 4706, 924, 4702, 932, 4708, 931, 4711, 942, 4702, 945, 4706, 942, 4707, 948, 4710, 941, 4712, 949, 4714, 923, 4720, 926, 4724, 920, 4726, 932, 4723, 928, 4726, 933, 4727, 931, 4731, 938, 4727, 927, 4732, 925, 4727, 917, 4741, 913, 4735, 907, 4741, 882, 4733, 887, 4728, 879, 4729, 873, 4737, 874, 4728, 869, 4720, 869, 4729, 855, 4736, 858, 4745, 853, 4742, 856, 4742, 852, 4739, 856, 4733, 851, 4727, 849, 4735, 843, 4732, 847, 4737, 847, 4747, 834, 4734, 836, 4744, 831, 4746, 827, 4740, 828, 4747, 810, 4752, 822, 4736, 806, 4751, 807, 4747, 802, 4746, 807, 4742, 798, 4744, 801, 4751, 780, 4756, 783, 4760, 778, 4763, 776, 4754, 761, 4752, 770, 4761, 757, 4753, 744, 4757, 746, 4759, 727, 4749, 731, 4742, 739, 4746, 734, 4739, 742, 4738, 744, 4743, 747, 4737, 764, 4746, 756, 4738, 762, 4742, 758, 4736, 771, 4737, 772, 4731, 788, 4725, 757, 4729, 760, 4732, 739, 4717, 751, 4702, 769, 4692, 780, 4673, 784, 4674, 778, 4670, 776, 4660, 832, 4650, 840, 4659, 863, 4661, 900, 4679, 892, 4669, 870, 4662, 849, 4646, 871, 4635, 896, 4634, 886, 4631, 889, 4630, 869, 4631, 855, 4642, 830, 4636, 826, 4627, 825, 4632, 807, 4632, 793, 4641, 761, 4643, 757, 4647, 760, 4657, 742, 4654, 739, 4661, 725, 4666, 729, 4672, 711, 4679, 684, 4670, 693, 4671, 707, 4691, 693, 4699, 669, 4697, 683, 4700, 679, 4708, 670, 4710, 659, 4707, 664, 4703, 659, 4698, 656, 4707, 651, 4707, 650, 4702, 644, 4705, 651, 4708, 649, 4711, 638, 4711, 640, 4718, 618, 4717, 628, 4720, 609, 4731, 613, 4733, 612, 4740, 637, 4741, 656, 4760, 636, 4771, 620, 4769, 617, 4776, 608, 4775, 611, 4783, 592, 4785, 604, 4788, 597, 4788, 602, 4792, 593, 4791, 597, 4796, 591, 4793, 591, 4798, 584, 4788, 584, 4796, 577, 4792, 577, 4799, 554, 4794, 548, 4798, 549, 4803, 535, 4803, 536, 4810, 521, 4802, 520, 4811, 510, 4810, 511, 4817, 496, 4812, 492, 4814, 494, 4820, 486, 4816, 466, 4822, 477, 4827, 470, 4829, 474, 4834, 467, 4838, 458, 4836, 461, 4844, 450, 4837, 447, 4846, 440, 4839, 441, 4843, 431, 4848, 427, 4844, 427, 4850, 412, 4842, 414, 4848, 403, 4848, 409, 4856, 398, 4855, 393, 4849, 373, 4854, 388, 4855, 386, 4861, 373, 4855, 372, 4859, 358, 4856, 340, 4865, 348, 4868, 355, 4863, 353, 4866, 366, 4869, 355, 4870, 357, 4875, 370, 4873, 356, 4878, 355, 4873, 350, 4876, 352, 4881, 348, 4877, 350, 4885, 344, 4882, 348, 4880, 342, 4880, 351, 4872, 343, 4870, 346, 4873, 337, 4871, 337, 4885, 329, 4879, 324, 4884, 300, 4882, 296, 4887, 295, 4879, 292, 4879, 292, 4887, 283, 4899, 276, 4895, 284, 4894, 279, 4891, 288, 4884, 276, 4877, 264, 4879, 262, 4885, 257, 4881, 257, 4886, 242, 4882, 245, 4887, 239, 4887, 235, 4893, 233, 4884, 222, 4886, 227, 4892, 216, 4885, 196, 4892, 182, 4888, 185, 4880, 193, 4875, 203, 4881, 182, 4871, 160, 4892, 152, 4890, 154, 4899, 146, 4897, 149, 4893, 141, 4895, 140, 4901, 137, 4896, 130, 4898, 126, 4891, 134, 4894, 122, 4878, 117, 4882, 123, 4889, 118, 4893, 122, 4901, 118, 4893, 113, 4899, 104, 4898, 92, 4881, 88, 4888, 97, 4895, 78, 4900, 84, 4894, 81, 4891, 87, 4893, 83, 4882, 103, 4876, 98, 4880, 109, 4882, 109, 4877, 124, 4872, 133, 4875, 133, 4870, 125, 4870, 174, 4850, 224, 4855, 224, 4859, 215, 4860, 224, 4874, 232, 4874, 227, 4863, 253, 4877, 250, 4873, 254, 4872, 238, 4864, 257, 4842, 287, 4833, 320, 4831, 317, 4829, 336, 4824, 352, 4833, 353, 4815, 373, 4803, 391, 4802, 387, 4799, 405, 4793, 412, 4792, 410, 4800, 415, 4803, 408, 4807, 415, 4803, 413, 4798, 425, 4804, 417, 4802, 429, 4797, 415, 4799, 415, 4789, 419, 4787, 411, 4788, 423, 4761, 429, 4754, 448, 4761, 440, 4753, 433, 4754, 431, 4741, 458, 4726, 483, 4736, 460, 4724, 468, 4712, 476, 4710, 477, 4703, 489, 4701, 482, 4700, 461, 4715, 402, 4720, 385, 4703, 395, 4694, 392, 4691, 409, 4694, 416, 4703, 393, 4679, 396, 4688, 378, 4696, 375, 4689, 379, 4688, 374, 4689, 378, 4693, 371, 4704, 368, 4701, 372, 4699, 363, 4699, 357, 4692, 363, 4699, 370, 4700, 367, 4703, 374, 4721, 363, 4725, 354, 4721, 341, 4694, 330, 4687, 334, 4681, 326, 4680, 325, 4686, 316, 4689, 313, 4680, 305, 4679, 307, 4675, 301, 4677, 298, 4664, 270, 4675, 268, 4669, 246, 4669, 251, 4672, 240, 4677, 244, 4677, 223, 4680, 219, 4680, 221, 4674, 220, 4678, 199, 4669, 214, 4672, 229, 4666, 222, 4666, 222, 4648, 238, 4647, 225, 4643, 222, 4647, 216, 4639, 216, 4630, 219, 4628, 218, 4633, 222, 4625, 236, 4620, 219, 4577, 220, 4568, 226, 4567, 220, 4565, 215, 4572, 211, 4560, 235, 4542, 227, 4542, 217, 4552, 213, 4549, 215, 4555, 204, 4555, 206, 4561, 198, 4559, 210, 4566, 203, 4578, 192, 4574, 190, 4578, 158, 4579, 121, 4568, 117, 4560, 124, 4558, 111, 4549, 100, 4531, 108, 4528, 108, 4523, 116, 4522, 112, 4517, 134, 4515, 139, 4510, 152, 4514, 150, 4525, 167, 4523, 171, 4518, 146, 4505, 167, 4507, 155, 4502, 159, 4499, 145, 4506, 85, 4484, 88, 4480, 98, 4483, 99, 4477, 108, 4479, 90, 4476, 88, 4472, 95, 4468, 93, 4464, 94, 4468, 89, 4471, 80, 4465, 89, 4463, 87, 4458, 94, 4453, 120, 4448, 114, 4443, 111, 4441, 118, 4448, 91, 4453, 92, 4457, 86, 4458, 88, 4463, 79, 4464, 77, 4473, 67, 4468, 69, 4456, 56, 4450, 55, 4444, 65, 4446, 64, 4439, 57, 4435, 47, 4436, 45, 4429, 49, 4421, 48, 4427, 72, 4431, 56, 4423, 53, 4416, 81, 4421, 74, 4414, 76, 4404, 114, 4384, 128, 4386, 126, 4390, 139, 4396, 131, 4399, 140, 4397, 135, 4394, 137, 4390, 127, 4390, 131, 4384, 131, 4371, 134, 4372, 130, 4370, 148, 4375, 132, 4367, 160, 4349, 194, 4357, 195, 4364, 202, 4365, 211, 4376, 247, 4370, 271, 4358, 270, 4354, 284, 4361, 275, 4364, 328, 4370, 350, 4358, 351, 4353, 348, 4327, 335, 4312, 339, 4312, 322, 4308, 331, 4302, 348, 4308, 346, 4305, 362, 4304, 362, 4289, 349, 4280, 358, 4282, 362, 4277, 327, 4287, 317, 4278, 321, 4282, 298, 4282, 301, 4283, 274, 4288, 259, 4298, 259, 4287, 249, 4281, 247, 4273, 234, 4274, 250, 4282, 242, 4289, 230, 4277, 210, 4269, 157, 4262, 156, 4259, 155, 4264, 164, 4265, 151, 4263, 86, 4232, 84, 4222, 90, 4218, 66, 4192, 74, 4186, 69, 4196, 86, 4200, 81, 4199, 98, 4193, 113, 4200, 129, 4217, 146, 4211, 121, 4205, 120, 4208, 104, 4192, 47, 4171, 17, 4146, 34, 4143, 20, 4148, 47, 4149, 50, 4148, 46, 4144, 53, 4145, 49, 4143, 64, 4141, 74, 4147, 83, 4145, 79, 4141, 118, 4137, 127, 4144, 156, 4150, 137, 4138, 153, 4133, 177, 4135, 182, 4140, 199, 4133, 216, 4135, 254, 4146, 239, 4141, 247, 4147, 238, 4154, 238, 4162, 219, 4162, 234, 4165, 240, 4176, 289, 4186, 291, 4193, 318, 4194, 333, 4206, 340, 4199, 336, 4200, 352, 4190, 374, 4198, 367, 4207, 377, 4200, 373, 4191, 354, 4182, 334, 4180, 337, 4186, 333, 4185, 337, 4169, 324, 4153, 311, 4149, 307, 4139, 316, 4135, 336, 4151, 331, 4159, 351, 4178, 373, 4177, 389, 4192, 417, 4198, 420, 4190, 416, 4183, 421, 4182, 418, 4180, 406, 4182, 377, 4171, 369, 4176, 357, 4174, 341, 4157, 353, 4145, 364, 4147, 357, 4140, 293, 4124, 299, 4128, 257, 4109, 255, 4089, 244, 4072, 152, 4004, 125, 3993, 147, 3993, 130, 3993, 157, 3998, 148, 3993, 158, 3986, 164, 3966, 256, 3987, 292, 3985, 321, 3970, 313, 3977, 321, 3975, 329, 3963, 326, 3959, 337, 3956, 335, 3951, 394, 3929, 406, 3935, 396, 3933, 402, 3937, 383, 3937, 439, 3938, 443, 3942, 441, 3939, 487, 3931, 497, 3935, 496, 3938, 481, 3939, 495, 3941, 482, 3949, 491, 3948, 498, 3962, 495, 3948, 501, 3942, 527, 3947, 504, 3943, 498, 3933, 487, 3930, 537, 3925, 528, 3925, 539, 3929, 521, 3927, 533, 3937, 531, 3931, 546, 3933, 541, 3930, 588, 3940, 620, 3939], + "center":[813, 4358], + "bbox":[17.226250526593294, 3922.1622828273585, 1806.1690621660666, 1313.3765572801585] + }, + "TX":{ + "shape":[[3960, 4548, 3926, 4590, 3956, 4534, 4038, 4483, 3960, 4548], [3765, 3367, 3774, 3393, 3796, 3396, 3793, 3416, 3813, 3422, 3840, 3397, 3880, 3431, 3914, 3413, 3927, 3451, 3950, 3405, 3986, 3430, 4014, 3417, 4009, 3427, 4053, 3458, 4085, 3428, 4145, 3427, 4173, 3408, 4222, 3421, 4233, 3404, 4291, 3445, 4352, 3464, 4354, 3465, 4369, 3483, 4424, 3481, 4426, 3583, 4426, 3596, 4431, 3781, 4468, 3822, 4467, 3859, 4487, 3873, 4481, 3881, 4500, 3900, 4492, 3912, 4519, 3935, 4524, 3965, 4488, 4061, 4497, 4154, 4459, 4204, 4475, 4227, 4474, 4229, 4432, 4233, 4316, 4293, 4369, 4255, 4315, 4261, 4329, 4237, 4323, 4210, 4296, 4236, 4284, 4227, 4275, 4256, 4294, 4268, 4282, 4276, 4310, 4294, 4298, 4288, 4297, 4303, 4263, 4330, 4241, 4321, 4255, 4349, 4233, 4348, 4247, 4349, 4238, 4364, 4258, 4351, 4229, 4378, 4162, 4418, 4119, 4424, 4115, 4438, 4160, 4418, 4045, 4481, 4112, 4432, 4068, 4448, 4060, 4430, 4018, 4451, 4040, 4474, 3994, 4498, 3973, 4481, 3973, 4514, 3933, 4533, 3902, 4593, 3888, 4582, 3868, 4592, 3870, 4608, 3892, 4619, 3845, 4737, 3850, 4754, 3834, 4754, 3850, 4780, 3833, 4783, 3859, 4840, 3847, 4861, 3873, 4881, 3876, 4927, 3897, 4936, 3873, 4955, 3896, 4954, 3903, 4938, 3905, 4957, 3879, 4958, 3854, 4981, 3816, 4943, 3718, 4936, 3676, 4902, 3636, 4898, 3613, 4872, 3559, 4859, 3533, 4775, 3504, 4740, 3506, 4694, 3490, 4681, 3496, 4633, 3435, 4586, 3426, 4549, 3370, 4492, 3362, 4445, 3335, 4412, 3309, 4324, 3247, 4252, 3215, 4237, 3218, 4218, 3207, 4226, 3194, 4188, 3081, 4178, 3040, 4157, 3027, 4179, 2978, 4179, 2937, 4252, 2938, 4277, 2915, 4284, 2892, 4321, 2863, 4319, 2783, 4256, 2738, 4240, 2665, 4174, 2641, 4116, 2644, 4054, 2622, 4023, 2615, 3980, 2540, 3924, 2459, 3816, 2420, 3792, 2396, 3737, 2373, 3725, 2373, 3724, 2358, 3706, 2363, 3681, 2946, 3738, 3017, 2874, 3023, 2874, 3487, 2903, 3471, 3276, 3484, 3274, 3520, 3312, 3565, 3315, 3571, 3299, 3595, 3323, 3598, 3347, 3692, 3360, 3710, 3380, 3729, 3362, 3765, 3367], [3892, 4640, 3925, 4591, 3867, 4713, 3892, 4640], [3880, 4832, 3866, 4788, 3868, 4714, 3868, 4773, 3902, 4937, 3880, 4832]], + "center":[3629, 3892], + "bbox":[2357.5862085056892, 2873.8949636291673, 2166.2516199112247, 2106.8870904247105] + }, + "AL":{ + "shape":[5342, 3152, 5751, 3113, 5757, 3137, 5866, 3512, 5911, 3591, 5907, 3611, 5927, 3621, 5902, 3649, 5896, 3708, 5919, 3762, 5916, 3831, 5939, 3865, 5910, 3869, 5508, 3912, 5506, 3942, 5548, 3975, 5545, 4009, 5544, 4009, 5552, 4017, 5539, 4037, 5516, 4037, 5518, 4048, 5534, 4045, 5527, 4052, 5450, 4070, 5500, 4054, 5480, 4029, 5466, 4030, 5458, 3981, 5441, 3978, 5426, 4000, 5435, 4008, 5430, 4053, 5386, 4042, 5385, 4042, 5349, 3751, 5360, 3170, 5342, 3152], + "center":[5617, 3547], + "bbox":[5342.095656308308, 3113.4827673729174, 596.451313025831, 956.3113443753509] + }, + "NC":{ + "shape":[[7201, 2563, 7205, 2562, 7205, 2563, 7287, 2693, 7245, 2651, 7201, 2563], [6319, 2725, 6333, 2723, 7179, 2568, 7180, 2569, 7175, 2579, 7200, 2600, 7202, 2588, 7236, 2649, 7199, 2610, 7200, 2632, 7214, 2636, 7164, 2617, 7193, 2645, 7174, 2653, 7155, 2639, 7171, 2659, 7130, 2648, 7157, 2663, 7130, 2669, 7142, 2671, 7119, 2688, 7091, 2665, 7093, 2636, 7052, 2626, 7089, 2638, 7098, 2707, 7206, 2677, 7191, 2684, 7209, 2684, 7198, 2697, 7209, 2714, 7198, 2716, 7215, 2729, 7199, 2731, 7207, 2736, 7221, 2731, 7215, 2690, 7234, 2690, 7224, 2680, 7239, 2671, 7264, 2716, 7255, 2721, 7260, 2741, 7239, 2733, 7244, 2746, 7212, 2802, 7178, 2792, 7173, 2806, 7168, 2785, 7162, 2804, 7151, 2800, 7144, 2792, 7154, 2788, 7138, 2782, 7161, 2779, 7151, 2766, 7116, 2785, 7138, 2787, 7145, 2804, 7057, 2791, 7084, 2815, 7089, 2804, 7128, 2813, 7118, 2828, 7130, 2815, 7140, 2816, 7137, 2828, 7148, 2815, 7167, 2824, 7127, 2856, 7161, 2848, 7127, 2892, 7076, 2863, 7086, 2873, 7072, 2883, 7086, 2874, 7112, 2907, 7127, 2896, 7138, 2910, 7143, 2889, 7156, 2898, 7153, 2881, 7174, 2896, 7160, 2880, 7175, 2883, 7175, 2859, 7185, 2890, 7203, 2865, 7203, 2890, 7192, 2892, 7181, 2928, 7161, 2914, 7166, 2933, 7152, 2917, 7140, 2930, 7153, 2934, 7093, 2956, 7082, 2940, 7089, 2954, 7077, 2954, 7084, 2960, 7063, 2986, 7048, 2983, 7060, 2970, 7038, 2953, 7051, 2971, 7040, 2980, 7056, 2994, 7003, 3047, 6991, 3097, 6976, 3076, 6979, 3133, 6944, 3128, 6892, 3152, 6891, 3152, 6686, 3010, 6511, 3038, 6509, 3016, 6480, 2987, 6465, 3002, 6461, 2982, 6249, 3003, 6143, 3060, 6140, 3060, 5983, 3084, 5953, 3088, 5952, 3042, 5989, 3028, 5990, 3001, 6009, 2978, 6067, 2961, 6114, 2916, 6140, 2910, 6147, 2879, 6165, 2877, 6186, 2847, 6202, 2866, 6229, 2830, 6278, 2822, 6293, 2785, 6322, 2773, 6319, 2725, 6319, 2725], [7183, 2567, 7187, 2566, 7187, 2566, 7203, 2576, 7183, 2567], [7288, 2695, 7308, 2729, 7313, 2798, 7281, 2813, 7311, 2788, 7306, 2729, 7288, 2695]], + "center":[6700, 2826], + "bbox":[5952.042953294017, 2562.1635913643336, 1361.0084056628302, 590.1898019127811] + }, + "ND":{ + "shape":[3950, 502, 3967, 564, 3957, 591, 3957, 592, 3959, 670, 3996, 776, 3997, 891, 4008, 907, 4001, 959, 4028, 1023, 4033, 1100, 4002, 1099, 3164, 1062, 3023, 1050, 3074, 458, 3116, 461, 3950, 502], + "center":[3524, 756], + "bbox":[3022.527264265822, 457.59212376958726, 1010.0102311329347, 641.9094378926393] + }, + "NE":{ + "shape":[2971, 1616, 2976, 1616, 3755, 1662, 3820, 1709, 3848, 1690, 3931, 1693, 4010, 1732, 4020, 1761, 4043, 1765, 4044, 1765, 4045, 1765, 4054, 1768, 4059, 1827, 4074, 1860, 4089, 1865, 4099, 1898, 4095, 1948, 4121, 1965, 4115, 1986, 4127, 1995, 4119, 2014, 4131, 2018, 4126, 2040, 4136, 2071, 4125, 2102, 4143, 2131, 4142, 2133, 4159, 2139, 4159, 2184, 4185, 2197, 4195, 2236, 4211, 2244, 4206, 2243, 3243, 2215, 3215, 2213, 3228, 2022, 3006, 2005, 2937, 1999, 2971, 1616, 2971, 1616], + "center":[3612, 1930], + "bbox":[2937.015040594679, 1615.8297803697847, 1273.652496708105, 627.6938449973413] + }, + "NY":{ + "shape":[[7362, 1671, 7357, 1658, 7401, 1659, 7402, 1642, 7477, 1620, 7517, 1573, 7481, 1633, 7506, 1626, 7517, 1598, 7550, 1598, 7581, 1575, 7480, 1659, 7339, 1731, 7361, 1728, 7312, 1749, 7333, 1725, 7294, 1740, 7303, 1702, 7327, 1700, 7328, 1680, 7341, 1689, 7346, 1667, 7362, 1671], [7184, 893, 7196, 969, 7218, 999, 7216, 1076, 7241, 1126, 7239, 1162, 7255, 1151, 7267, 1166, 7302, 1314, 7302, 1327, 7304, 1452, 7307, 1462, 7331, 1595, 7345, 1608, 7315, 1637, 7331, 1657, 7330, 1657, 7320, 1695, 7303, 1699, 7293, 1722, 7292, 1722, 7297, 1663, 7175, 1625, 7167, 1623, 7121, 1609, 7103, 1589, 7094, 1550, 7066, 1546, 7046, 1524, 6427, 1652, 6418, 1601, 6418, 1601, 6494, 1530, 6527, 1480, 6507, 1445, 6511, 1430, 6486, 1428, 6481, 1394, 6608, 1347, 6657, 1344, 6692, 1358, 6744, 1336, 6778, 1344, 6770, 1334, 6866, 1255, 6865, 1239, 6837, 1205, 6869, 1168, 6846, 1180, 6855, 1163, 6841, 1160, 6834, 1184, 6817, 1160, 6877, 1095, 6883, 1064, 6934, 987, 6991, 943, 7184, 893], [7409, 1706, 7398, 1711, 7469, 1664, 7409, 1706], [7382, 1718, 7363, 1729, 7406, 1703, 7382, 1718], [7292, 1741, 7269, 1767, 7272, 1740, 7292, 1741]], + "center":[6982, 1368], + "bbox":[6417.580786242645, 893.4859395487013, 1162.9619795113686, 873.4925980295768] + }, + "GA":{ + "shape":[6143, 3060, 6144, 3060, 6113, 3123, 6176, 3156, 6176, 3156, 6196, 3157, 6258, 3247, 6374, 3325, 6375, 3348, 6410, 3379, 6457, 3400, 6481, 3470, 6523, 3496, 6545, 3561, 6579, 3568, 6580, 3568, 6593, 3574, 6582, 3589, 6576, 3573, 6575, 3590, 6562, 3577, 6582, 3595, 6574, 3607, 6549, 3590, 6554, 3602, 6539, 3599, 6557, 3608, 6523, 3597, 6568, 3616, 6555, 3636, 6545, 3622, 6548, 3636, 6521, 3624, 6546, 3641, 6534, 3650, 6555, 3641, 6558, 3655, 6553, 3669, 6540, 3655, 6547, 3669, 6522, 3676, 6555, 3676, 6543, 3705, 6528, 3694, 6543, 3716, 6509, 3714, 6527, 3718, 6526, 3731, 6527, 3721, 6548, 3726, 6534, 3752, 6522, 3740, 6520, 3761, 6492, 3747, 6524, 3780, 6493, 3792, 6528, 3792, 6524, 3814, 6507, 3812, 6526, 3836, 6507, 3840, 6508, 3840, 6456, 3827, 6438, 3838, 6448, 3917, 6427, 3924, 6411, 3885, 5968, 3918, 5939, 3866, 5939, 3865, 5916, 3831, 5919, 3762, 5896, 3708, 5902, 3649, 5927, 3621, 5907, 3611, 5911, 3591, 5866, 3512, 5757, 3137, 5751, 3113, 5772, 3111, 5944, 3089, 5953, 3088, 5983, 3084, 6140, 3060, 6143, 3060], + "center":[6159, 3499], + "bbox":[5751.066659695458, 3059.735439125348, 842.1830852324074, 864.2944778928199] + }, + "NV":{ + "shape":[1536, 1604, 1345, 2545, 1345, 2545, 1315, 2697, 1293, 2725, 1276, 2722, 1260, 2695, 1202, 2695, 1195, 2871, 1179, 2902, 1179, 2903, 553, 1964, 701, 1416, 703, 1408, 722, 1413, 1117, 1512, 1117, 1512, 1118, 1512, 1535, 1604, 1536, 1604], + "center":[1045, 1927], + "bbox":[552.6877160601398, 1407.9247770441316, 982.9101261496735, 1495.0102889725422] + }, + "TN":{ + "shape":[6012, 2768, 6017, 2767, 6319, 2725, 6319, 2725, 6322, 2773, 6293, 2785, 6278, 2822, 6229, 2830, 6202, 2866, 6186, 2847, 6165, 2877, 6147, 2879, 6140, 2910, 6114, 2916, 6067, 2961, 6009, 2978, 5990, 3001, 5989, 3028, 5952, 3042, 5953, 3088, 5944, 3089, 5772, 3111, 5751, 3113, 5342, 3152, 5341, 3152, 5014, 3177, 5009, 3177, 5045, 3148, 5028, 3122, 5041, 3100, 5026, 3095, 5038, 3082, 5048, 3098, 5046, 3067, 5065, 3073, 5057, 3059, 5073, 3047, 5055, 3032, 5093, 3013, 5083, 3000, 5102, 2996, 5089, 2979, 5089, 2978, 5107, 2950, 5089, 2931, 5113, 2927, 5100, 2914, 5115, 2907, 5110, 2881, 5114, 2880, 5118, 2880, 5118, 2882, 5129, 2880, 5140, 2878, 5339, 2863, 5334, 2828, 6011, 2769, 6012, 2768], + "center":[5533, 2967], + "bbox":[5008.8876325677875, 2724.57469597311, 1312.8105366827986, 452.62423421965195] + }, + "CA":{ + "shape":[124, 1236, 703, 1408, 701, 1416, 553, 1964, 1179, 2903, 1179, 2903, 1174, 2927, 1193, 2962, 1196, 3013, 1229, 3058, 1178, 3078, 1153, 3106, 1139, 3179, 1102, 3200, 1097, 3220, 1105, 3229, 1092, 3262, 1121, 3280, 1121, 3315, 1106, 3331, 1075, 3331, 1073, 3331, 684, 3281, 675, 3245, 689, 3269, 691, 3255, 679, 3241, 671, 3251, 680, 3184, 663, 3123, 582, 3010, 537, 3005, 544, 2987, 533, 2946, 487, 2941, 442, 2909, 390, 2833, 254, 2790, 232, 2760, 261, 2654, 231, 2628, 243, 2608, 239, 2587, 191, 2528, 176, 2457, 133, 2383, 136, 2329, 157, 2327, 180, 2295, 168, 2261, 138, 2254, 112, 2214, 108, 2130, 123, 2084, 138, 2084, 133, 2123, 182, 2166, 167, 2153, 165, 2102, 151, 2088, 158, 2072, 145, 2055, 157, 2049, 254, 2078, 272, 2065, 268, 2080, 298, 2084, 273, 2064, 243, 2069, 268, 2048, 223, 2060, 209, 2039, 220, 2032, 188, 2052, 176, 2035, 182, 2009, 177, 2043, 159, 2021, 144, 2025, 130, 2078, 99, 2053, 79, 2009, 61, 2023, 80, 1997, 79, 1979, 94, 2014, 71, 1934, 12, 1822, 24, 1799, 22, 1739, 43, 1704, 47, 1650, 0, 1548, 4, 1513, 47, 1463, 45, 1477, 72, 1455, 65, 1446, 48, 1461, 77, 1424, 78, 1397, 118, 1329, 104, 1274, 124, 1236], + "center":[507, 2428], + "bbox":[0.0, 1235.8258093785118, 1228.720840043634, 2095.1776242661253] + }, + "OK":{ + "shape":[3178, 2791, 3178, 2791, 4284, 2819, 4321, 2819, 4322, 2863, 4323, 2915, 4327, 2945, 4356, 3126, 4352, 3449, 4352, 3464, 4291, 3445, 4233, 3404, 4222, 3421, 4173, 3408, 4145, 3427, 4085, 3428, 4053, 3458, 4009, 3427, 4014, 3417, 3986, 3430, 3950, 3405, 3927, 3451, 3914, 3413, 3880, 3431, 3840, 3397, 3813, 3422, 3793, 3416, 3796, 3396, 3774, 3393, 3765, 3367, 3765, 3367, 3729, 3362, 3710, 3380, 3692, 3360, 3598, 3347, 3595, 3323, 3571, 3299, 3565, 3315, 3520, 3312, 3484, 3274, 3471, 3276, 3487, 2903, 3153, 2884, 3023, 2874, 3030, 2791, 3031, 2779, 3134, 2787, 3178, 2791], + "center":[3930, 3108], + "bbox":[3023.197942403276, 2778.8561310642554, 1332.3624136691633, 685.566148248552] + }, + "OH":{ + "shape":[5911, 1786, 5991, 1817, 6004, 1801, 5999, 1814, 6023, 1808, 5975, 1832, 6041, 1829, 6027, 1817, 6061, 1832, 6123, 1797, 6162, 1796, 6219, 1734, 6320, 1675, 6321, 1675, 6364, 1929, 6364, 1929, 6345, 1942, 6363, 1991, 6345, 2130, 6303, 2183, 6281, 2195, 6267, 2184, 6254, 2214, 6237, 2217, 6224, 2255, 6236, 2284, 6216, 2296, 6209, 2275, 6192, 2271, 6172, 2320, 6184, 2354, 6168, 2361, 6166, 2388, 6127, 2398, 6127, 2398, 6084, 2371, 6074, 2341, 6017, 2380, 5981, 2364, 5961, 2382, 5927, 2360, 5874, 2358, 5831, 2303, 5780, 2312, 5778, 2313, 5721, 1845, 5718, 1819, 5906, 1787, 5906, 1787, 5911, 1786], + "center":[6096, 2082], + "bbox":[5718.242249393261, 1674.6267669674462, 645.9704766536042, 723.8687419559174] + }, + "WY":{ + "shape":[3005, 1232, 3004, 1235, 2971, 1616, 2971, 1616, 2937, 1999, 2924, 1998, 2225, 1917, 2214, 1915, 1927, 1871, 1956, 1693, 1959, 1681, 2037, 1210, 2037, 1210, 2042, 1174, 2053, 1110, 3001, 1232, 3005, 1232], + "center":[2487, 1535], + "bbox":[1926.8321924800312, 1110.197616627383, 1077.7683497025378, 889.2322221788561] + }, + "FL":{ + "shape":[6508, 3840, 6528, 3854, 6539, 3839, 6543, 3875, 6530, 3858, 6584, 4003, 6595, 4014, 6587, 3987, 6675, 4136, 6637, 4084, 6664, 4136, 6750, 4223, 6762, 4245, 6748, 4256, 6756, 4285, 6793, 4358, 6731, 4264, 6724, 4233, 6740, 4221, 6739, 4270, 6756, 4303, 6745, 4219, 6711, 4219, 6718, 4202, 6694, 4187, 6727, 4263, 6862, 4481, 6836, 4471, 6851, 4487, 6868, 4482, 6890, 4522, 6876, 4517, 6902, 4547, 6896, 4539, 6921, 4741, 6919, 4751, 6915, 4716, 6894, 4786, 6893, 4872, 6861, 4866, 6868, 4874, 6848, 4887, 6819, 4884, 6773, 4906, 6755, 4887, 6756, 4867, 6785, 4885, 6801, 4874, 6754, 4856, 6738, 4832, 6753, 4810, 6734, 4825, 6719, 4803, 6735, 4792, 6720, 4783, 6716, 4801, 6704, 4777, 6667, 4764, 6694, 4777, 6657, 4762, 6635, 4770, 6631, 4759, 6645, 4756, 6617, 4739, 6597, 4668, 6567, 4666, 6603, 4617, 6562, 4660, 6540, 4586, 6556, 4557, 6532, 4585, 6506, 4569, 6535, 4610, 6511, 4595, 6510, 4610, 6447, 4528, 6443, 4503, 6421, 4493, 6465, 4477, 6428, 4479, 6458, 4445, 6457, 4394, 6438, 4420, 6436, 4399, 6419, 4396, 6429, 4392, 6403, 4383, 6417, 4395, 6402, 4404, 6432, 4409, 6420, 4418, 6423, 4447, 6386, 4425, 6408, 4454, 6382, 4422, 6398, 4307, 6394, 4244, 6383, 4235, 6393, 4239, 6391, 4218, 6367, 4201, 6354, 4168, 6314, 4174, 6291, 4153, 6298, 4145, 6244, 4116, 6240, 4089, 6213, 4079, 6187, 4044, 6127, 4016, 6093, 4018, 6065, 4038, 6073, 4051, 6055, 4046, 6075, 4064, 6044, 4065, 5988, 4110, 5992, 4091, 5970, 4113, 5910, 4130, 5896, 4096, 5909, 4127, 5913, 4096, 5845, 4047, 5883, 4064, 5895, 4056, 5836, 4037, 5868, 4007, 5861, 3999, 5838, 4026, 5828, 4011, 5810, 4015, 5816, 4030, 5830, 4026, 5836, 4049, 5781, 4023, 5700, 4011, 5768, 4007, 5751, 3984, 5715, 3998, 5701, 3986, 5687, 4010, 5589, 4032, 5639, 4008, 5613, 3998, 5612, 3979, 5604, 4010, 5584, 3985, 5589, 4017, 5532, 4051, 5561, 4019, 5545, 4009, 5545, 4009, 5548, 3975, 5506, 3942, 5508, 3912, 5910, 3869, 5939, 3865, 5939, 3866, 5968, 3918, 6411, 3885, 6427, 3924, 6448, 3917, 6438, 3838, 6456, 3827, 6508, 3840], + "center":[6585, 4335], + "bbox":[5506.310458865219, 3827.186951564696, 1414.2469623466595, 1078.9271397334787] + }, + "SD":{ + "shape":[3023, 1050, 3164, 1062, 4002, 1099, 4033, 1100, 4029, 1123, 3992, 1163, 4047, 1222, 4045, 1570, 4025, 1570, 4035, 1591, 4026, 1613, 4047, 1642, 4018, 1718, 4044, 1765, 4043, 1765, 4020, 1761, 4010, 1732, 3931, 1693, 3848, 1690, 3820, 1709, 3755, 1662, 2976, 1616, 2971, 1616, 3004, 1235, 3005, 1232, 3022, 1057, 3023, 1050], + "center":[3544, 1347], + "bbox":[2971.124373651464, 1050.043615899464, 1075.661674971776, 715.2386540159926] + }, + "SC":{ + "shape":[6176, 3156, 6113, 3123, 6144, 3060, 6143, 3060, 6249, 3003, 6461, 2982, 6465, 3002, 6480, 2987, 6509, 3016, 6511, 3038, 6686, 3010, 6891, 3152, 6891, 3152, 6826, 3243, 6815, 3270, 6821, 3298, 6801, 3279, 6812, 3254, 6800, 3266, 6799, 3286, 6821, 3302, 6814, 3316, 6806, 3304, 6812, 3316, 6795, 3313, 6807, 3317, 6785, 3340, 6797, 3341, 6769, 3342, 6758, 3362, 6768, 3367, 6729, 3404, 6719, 3386, 6734, 3368, 6716, 3392, 6709, 3373, 6716, 3402, 6698, 3393, 6727, 3408, 6714, 3429, 6706, 3421, 6710, 3436, 6683, 3450, 6667, 3441, 6675, 3421, 6658, 3443, 6680, 3450, 6661, 3470, 6641, 3436, 6651, 3472, 6623, 3460, 6628, 3470, 6597, 3471, 6639, 3481, 6630, 3502, 6646, 3486, 6647, 3504, 6618, 3520, 6608, 3485, 6612, 3514, 6573, 3474, 6591, 3506, 6576, 3517, 6615, 3529, 6594, 3555, 6596, 3527, 6582, 3532, 6595, 3539, 6579, 3568, 6579, 3568, 6545, 3561, 6523, 3496, 6481, 3470, 6457, 3400, 6410, 3379, 6375, 3348, 6374, 3325, 6258, 3247, 6196, 3157, 6176, 3156, 6176, 3156], + "center":[6541, 3231], + "bbox":[6112.614477369485, 2981.961131844549, 778.5946861628072, 586.2283645094535] + }, + "CT":{ + "shape":[7541, 1398, 7568, 1526, 7567, 1528, 7539, 1536, 7531, 1523, 7535, 1539, 7521, 1547, 7504, 1553, 7491, 1539, 7496, 1559, 7426, 1581, 7424, 1569, 7401, 1605, 7331, 1655, 7331, 1657, 7315, 1637, 7345, 1608, 7331, 1595, 7307, 1462, 7304, 1452, 7321, 1448, 7541, 1398], + "center":[7442, 1505], + "bbox":[7304.222285771861, 1397.8167615354203, 263.7757107347343, 259.100971032168] + }, + "WV":{ + "shape":[6364, 1929, 6369, 1959, 6394, 2102, 6546, 2075, 6549, 2091, 6565, 2173, 6610, 2111, 6632, 2114, 6652, 2069, 6669, 2087, 6701, 2086, 6702, 2065, 6726, 2061, 6736, 2044, 6790, 2051, 6785, 2062, 6804, 2069, 6817, 2100, 6817, 2101, 6809, 2139, 6720, 2092, 6723, 2150, 6670, 2239, 6647, 2227, 6621, 2315, 6560, 2293, 6550, 2358, 6492, 2481, 6507, 2491, 6493, 2505, 6500, 2512, 6479, 2534, 6467, 2527, 6433, 2553, 6418, 2545, 6415, 2567, 6368, 2591, 6344, 2575, 6301, 2608, 6258, 2584, 6247, 2552, 6247, 2551, 6222, 2552, 6212, 2535, 6192, 2533, 6155, 2489, 6159, 2478, 6128, 2452, 6127, 2399, 6127, 2398, 6166, 2388, 6168, 2361, 6184, 2354, 6172, 2320, 6192, 2271, 6209, 2275, 6216, 2296, 6236, 2284, 6224, 2255, 6237, 2217, 6254, 2214, 6267, 2184, 6281, 2195, 6303, 2183, 6345, 2130, 6363, 1991, 6345, 1942, 6364, 1929, 6364, 1929], + "center":[6378, 2332], + "bbox":[6127.105822495098, 1928.5641252578148, 690.343968832166, 679.5274353689069] + }, + "DC":{ + "shape":[6928, 2160, 6921, 2156, 6921, 2156, 6924, 2150, 6930, 2142, 6953, 2157, 6940, 2177, 6939, 2177, 6944, 2161, 6928, 2160], + "center":[6934, 2153], + "bbox":[6920.506533181993, 2141.589247282631, 32.58943373685452, 35.901722553833224] + }, + "WI":{ + "shape":[[5338, 1169, 5315, 1247, 5302, 1264, 5292, 1258, 5286, 1242, 5305, 1190, 5314, 1193, 5326, 1164, 5338, 1169], [4702, 927, 4791, 882, 4806, 895, 4783, 954, 4818, 940, 4808, 931, 4855, 954, 4855, 954, 4883, 965, 4898, 996, 5176, 1057, 5173, 1078, 5222, 1098, 5217, 1122, 5225, 1135, 5213, 1163, 5244, 1157, 5236, 1192, 5255, 1208, 5256, 1209, 5255, 1232, 5227, 1244, 5210, 1289, 5214, 1313, 5205, 1316, 5221, 1322, 5264, 1256, 5284, 1246, 5301, 1264, 5282, 1331, 5285, 1384, 5268, 1401, 5261, 1434, 5268, 1483, 5246, 1566, 5251, 1612, 5276, 1656, 5275, 1711, 5275, 1711, 4872, 1739, 4871, 1739, 4860, 1714, 4809, 1695, 4789, 1625, 4804, 1599, 4782, 1580, 4779, 1554, 4779, 1552, 4772, 1499, 4744, 1458, 4690, 1430, 4667, 1391, 4614, 1357, 4585, 1355, 4548, 1321, 4551, 1218, 4566, 1188, 4550, 1165, 4532, 1162, 4534, 1135, 4558, 1095, 4609, 1063, 4604, 948, 4629, 930, 4629, 932, 4649, 944, 4702, 927]], + "center":[4969, 1326], + "bbox":[4532.3918561497785, 881.6938347091063, 805.2276107605994, 857.1162210960997] + }, + "KY":{ + "shape":[[5118, 2880, 5110, 2881, 5109, 2880, 5110, 2865, 5118, 2880], [5778, 2313, 5780, 2312, 5831, 2303, 5874, 2358, 5927, 2360, 5961, 2382, 5981, 2364, 6017, 2380, 6074, 2341, 6084, 2371, 6127, 2398, 6127, 2398, 6127, 2399, 6128, 2452, 6159, 2478, 6155, 2489, 6192, 2533, 6212, 2535, 6222, 2552, 6247, 2551, 6247, 2552, 6230, 2571, 6144, 2648, 6127, 2694, 6098, 2707, 6091, 2729, 6012, 2768, 6011, 2769, 5334, 2828, 5339, 2863, 5140, 2878, 5129, 2880, 5137, 2853, 5160, 2860, 5159, 2831, 5171, 2825, 5161, 2817, 5167, 2783, 5166, 2783, 5164, 2782, 5158, 2769, 5185, 2735, 5266, 2759, 5261, 2698, 5320, 2674, 5305, 2642, 5322, 2614, 5322, 2613, 5323, 2613, 5340, 2610, 5340, 2587, 5383, 2602, 5385, 2574, 5462, 2603, 5472, 2578, 5501, 2558, 5531, 2585, 5550, 2566, 5553, 2530, 5574, 2523, 5567, 2513, 5585, 2539, 5620, 2553, 5637, 2538, 5645, 2489, 5666, 2484, 5675, 2455, 5701, 2433, 5695, 2396, 5734, 2399, 5786, 2374, 5788, 2355, 5773, 2350, 5779, 2338, 5768, 2324, 5777, 2313, 5778, 2313]], + "center":[5828, 2581], + "bbox":[5109.050661398359, 2303.369688273179, 1137.790998421695, 577.2572832752585] + }, + "KS":{ + "shape":[3215, 2213, 3243, 2215, 4206, 2243, 4211, 2244, 4210, 2245, 4242, 2269, 4266, 2264, 4277, 2292, 4262, 2293, 4241, 2331, 4274, 2360, 4282, 2393, 4319, 2406, 4321, 2819, 4284, 2819, 3178, 2791, 3178, 2791, 3210, 2296, 3215, 2213], + "center":[3753, 2506], + "bbox":[3177.7941461662417, 2213.4066104839408, 1143.4447618402305, 605.7450113212822] + }, + "OR":{ + "shape":[477, 509, 504, 509, 532, 539, 534, 584, 521, 593, 534, 585, 521, 632, 526, 623, 577, 662, 633, 657, 633, 657, 691, 657, 734, 693, 810, 686, 863, 705, 955, 690, 1008, 704, 1037, 696, 1297, 762, 1309, 764, 1309, 766, 1319, 800, 1346, 822, 1352, 851, 1276, 949, 1267, 976, 1234, 998, 1194, 1057, 1195, 1080, 1231, 1110, 1197, 1168, 1117, 1512, 1117, 1512, 722, 1413, 703, 1408, 124, 1236, 124, 1235, 110, 1211, 113, 1167, 135, 1113, 125, 1067, 178, 985, 186, 997, 204, 973, 210, 988, 212, 967, 187, 981, 223, 930, 236, 921, 261, 943, 237, 918, 223, 929, 252, 869, 266, 879, 253, 868, 283, 797, 294, 802, 283, 796, 297, 762, 310, 772, 297, 760, 306, 728, 347, 665, 359, 605, 376, 607, 367, 590, 384, 570, 375, 575, 375, 554, 385, 520, 399, 511, 399, 466, 421, 501, 415, 480, 464, 485, 477, 509], + "center":[746, 1019], + "bbox":[110.42702484968872, 466.18654659455024, 1241.1399115078336, 1045.3897533373636] + }, + "LA":{ + "shape":[4426, 3583, 4464, 3582, 4879, 3569, 4894, 3568, 4894, 3569, 4889, 3586, 4903, 3571, 4912, 3587, 4897, 3615, 4915, 3623, 4900, 3641, 4922, 3637, 4913, 3654, 4928, 3664, 4910, 3656, 4908, 3669, 4932, 3675, 4928, 3692, 4948, 3689, 4931, 3722, 4902, 3724, 4903, 3736, 4929, 3733, 4918, 3752, 4905, 3747, 4918, 3759, 4892, 3798, 4877, 3794, 4873, 3810, 4891, 3811, 4872, 3813, 4867, 3838, 4850, 3837, 4869, 3845, 4850, 3857, 4858, 3885, 4842, 3879, 4853, 3903, 4831, 3910, 4848, 3948, 4836, 3959, 5153, 3940, 5138, 4007, 5183, 4090, 5199, 4096, 5199, 4096, 5184, 4098, 5169, 4129, 5151, 4128, 5149, 4144, 5187, 4158, 5192, 4133, 5214, 4118, 5210, 4139, 5227, 4140, 5214, 4144, 5226, 4153, 5217, 4151, 5220, 4166, 5236, 4172, 5224, 4178, 5205, 4161, 5201, 4170, 5216, 4168, 5205, 4182, 5181, 4182, 5214, 4204, 5175, 4191, 5191, 4208, 5164, 4211, 5210, 4237, 5204, 4249, 5243, 4248, 5231, 4254, 5255, 4255, 5255, 4268, 5266, 4253, 5282, 4271, 5277, 4286, 5298, 4277, 5284, 4290, 5298, 4291, 5293, 4306, 5277, 4294, 5281, 4325, 5260, 4300, 5236, 4340, 5256, 4293, 5246, 4288, 5249, 4301, 5235, 4307, 5222, 4276, 5187, 4272, 5197, 4273, 5197, 4253, 5179, 4236, 5195, 4263, 5159, 4269, 5171, 4258, 5160, 4239, 5102, 4232, 5106, 4203, 5101, 4219, 5092, 4198, 5101, 4216, 5089, 4233, 5120, 4242, 5125, 4273, 5111, 4266, 5122, 4296, 5087, 4319, 5091, 4288, 5070, 4275, 5065, 4289, 5054, 4267, 5049, 4281, 5041, 4267, 5043, 4282, 5026, 4277, 5031, 4297, 5013, 4285, 5023, 4312, 5012, 4300, 5017, 4314, 5001, 4319, 4987, 4304, 4982, 4317, 4972, 4309, 4996, 4297, 4991, 4288, 4948, 4273, 4939, 4285, 4912, 4244, 4864, 4246, 4862, 4223, 4846, 4224, 4858, 4201, 4810, 4212, 4813, 4188, 4751, 4205, 4770, 4215, 4769, 4232, 4786, 4231, 4740, 4249, 4582, 4207, 4476, 4226, 4475, 4227, 4459, 4204, 4497, 4154, 4488, 4061, 4524, 3965, 4519, 3935, 4492, 3912, 4500, 3900, 4481, 3881, 4487, 3873, 4467, 3859, 4468, 3822, 4431, 3781, 4426, 3596, 4426, 3583], + "center":[4688, 3984], + "bbox":[4426.055011069621, 3568.2982314605933, 872.2791142400201, 771.7208876645427] + }, + "WA":{ + "shape":[717, 0, 1411, 188, 1428, 192, 1306, 692, 1315, 731, 1304, 745, 1309, 764, 1297, 762, 1037, 696, 1008, 704, 955, 690, 863, 705, 810, 686, 734, 693, 691, 657, 633, 657, 633, 656, 586, 660, 539, 635, 528, 620, 541, 567, 535, 534, 510, 509, 483, 507, 446, 465, 392, 456, 416, 389, 407, 438, 415, 443, 422, 427, 431, 442, 422, 423, 431, 419, 429, 393, 435, 403, 437, 387, 456, 393, 444, 375, 417, 370, 422, 336, 433, 355, 435, 342, 468, 337, 434, 312, 419, 331, 430, 294, 436, 171, 419, 131, 423, 80, 442, 51, 436, 39, 446, 40, 517, 109, 605, 147, 627, 139, 615, 143, 630, 173, 629, 161, 645, 163, 644, 184, 653, 176, 650, 163, 668, 160, 659, 170, 672, 214, 660, 214, 639, 245, 646, 213, 638, 225, 637, 215, 622, 247, 572, 293, 617, 290, 579, 287, 610, 257, 641, 250, 671, 219, 674, 228, 674, 204, 684, 212, 682, 245, 671, 239, 664, 251, 659, 239, 657, 271, 644, 262, 652, 273, 641, 278, 663, 271, 665, 289, 645, 330, 633, 326, 635, 339, 627, 323, 643, 302, 626, 310, 612, 342, 618, 296, 592, 328, 572, 321, 591, 330, 568, 344, 593, 335, 575, 358, 590, 339, 587, 359, 592, 341, 602, 340, 601, 353, 605, 338, 618, 358, 648, 322, 659, 340, 660, 328, 678, 325, 678, 279, 690, 296, 681, 263, 713, 214, 735, 203, 717, 185, 721, 157, 705, 165, 713, 192, 698, 171, 702, 149, 726, 146, 709, 126, 712, 111, 696, 115, 695, 97, 720, 113, 717, 86, 735, 88, 728, 72, 736, 57, 712, 54, 718, 45, 706, 19, 714, 13, 706, 8, 717, 0], + "center":[952, 376], + "bbox":[391.5842598432282, 0.0, 1036.0850727961474, 764.2512207821578] + }, + "CO":{ + "shape":[2214, 1915, 2225, 1917, 2924, 1998, 2937, 1999, 3006, 2005, 3228, 2022, 3215, 2213, 3210, 2296, 3178, 2791, 3134, 2787, 3031, 2779, 3017, 2778, 2182, 2687, 2105, 2676, 2213, 1925, 2214, 1915], + "center":[2749, 2301], + "bbox":[2104.8628776804103, 1915.455020807188, 1122.9312587549507, 875.2906417521679] + }, + "PA":{ + "shape":[6321, 1675, 6417, 1602, 6418, 1601, 6427, 1652, 7046, 1524, 7066, 1546, 7094, 1550, 7103, 1589, 7121, 1609, 7167, 1623, 7166, 1623, 7122, 1706, 7138, 1727, 7125, 1764, 7132, 1786, 7151, 1788, 7157, 1810, 7217, 1848, 7133, 1938, 7132, 1937, 7100, 1940, 7082, 1965, 7050, 1972, 6559, 2073, 6546, 2075, 6394, 2102, 6369, 1959, 6364, 1929, 6321, 1675], + "center":[6777, 1802], + "bbox":[6320.668447791168, 1524.3096158541616, 896.2956547030162, 577.9314409361236] + } + } +} diff --git a/js/dojo-1.7.2/dojox/geo/charting/resources/data/series.json b/js/dojo-1.7.2/dojox/geo/charting/resources/data/series.json new file mode 100644 index 0000000..7d0b807 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/resources/data/series.json @@ -0,0 +1,20 @@ +{ + "series": [{ + name: "Low sales state(0~$3.0M)", + min: "0.0", + max: "3.0", + color: "#FFCE52" + }, + { + name: "Normal sales state($3.0M~$6.0M)", + min: "3.0", + max: "6.0", + color: "#63A584" + }, + { + name: "High sales state($6.0M~$10.0M)", + min: "6.0", + max: "9.0", + color: "#CE6342" + }] +} diff --git a/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomin.gif b/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomin.gif Binary files differnew file mode 100644 index 0000000..45fc12b --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomin.gif diff --git a/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomin.png b/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomin.png Binary files differnew file mode 100644 index 0000000..fed568a --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomin.png diff --git a/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomout.gif b/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomout.gif Binary files differnew file mode 100644 index 0000000..780b747 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomout.gif diff --git a/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomout.png b/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomout.png Binary files differnew file mode 100644 index 0000000..f62af36 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/resources/img/zoomout.png diff --git a/js/dojo-1.7.2/dojox/geo/charting/resources/markers/USStates.json b/js/dojo-1.7.2/dojox/geo/charting/resources/markers/USStates.json new file mode 100644 index 0000000..929dab3 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/resources/markers/USStates.json @@ -0,0 +1 @@ +{"AK":"Alaska","AZ":"Arizona","AR":"Arkansas","AL":"Alabama","CA":"California","CO":"Colorado","CT":"Connecticut","DE":"Delaware","FL":"Florida","GA":"Georgia","HI":"Hawaii","ID":"Idaho","IL":"Illinois","IN":"Indiana","IA":"Iowa","KS":"Kansas","KY":"Kentucky","LA":"Louisiana","ME":"Maine","MD":"Maryland","MA":"Massachusetts","MI":"Michigan","MN":"Minnesota","MS":"Mississippi","MO":"Missouri","MT":"Montana","NE":"Nebraska","NV":"Nevada","NH":"New Hampshire","NJ":"New Jersey","NM":"New Mexico","NY":"New York","NC":"North Carolina","ND":"North Dakota","OH":"Ohio","OK":"Oklahoma","OR":"Oregon","PA":"Pennsylvania","RI":"Rhode Island","SC":"South Carolina","SD":"South Dakota","TN":"Tennessee","TX":"Texas","UT":"Utah","VT":"Vermont","VA":"Virginia","WA":"Washington","WV":"West Virginia","WI":"Wisconsin","WY":"Wyoming"} diff --git a/js/dojo-1.7.2/dojox/geo/charting/widget/Legend.js b/js/dojo-1.7.2/dojox/geo/charting/widget/Legend.js new file mode 100644 index 0000000..f307d77 --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/widget/Legend.js @@ -0,0 +1,93 @@ +//>>built + +define("dojox/geo/charting/widget/Legend", ["dojo/_base/kernel", "dojo/_base/lang","dojo/_base/array", "dojo/_base/declare","dojo/_base/html","dojo/dom", + "dojo/dom-construct","dojo/dom-class", "dojo/_base/window", "dijit/_Widget"], + function(dojo, lang, arr, declare, html,dom,domConstruct,domClass, win, Widget) { + +return declare("dojox.geo.charting.widget.Legend",Widget, { + // summary: + // A legend widget displaying association between colors and Feature value ranges. + // + // description: + // This widget basically is a table comprising (icon,string) pairs, describing the color scheme + // used for the map and its associated text descriptions. + // + + // example: + // | var legend = new dojox.geo.charting.widget.Legend({ + // | map: map + // | }); + horizontal:true, + legendBody:null, + swatchSize:18, + map:null, + postCreate: function(){ + // summary: + // inherited Dijit's postCreate function + // tags: + // protected + if(!this.map){return;} + this.series = this.map.series; + if (!this.domNode.parentNode) { + // compatibility with older version : add to map domNode if not already attached to a parentNode. + dom.byId(this.map.container).appendChild(this.domNode); + } + this.refresh(); + }, + buildRendering: function(){ + // summary: + // Construct the UI for this widget, creates the underlying real dojox.geo.charting.Map object. + // tags: + // protected + this.domNode = domConstruct.create("table", + {role: "group", "class": "dojoxLegendNode"}); + this.legendBody = domConstruct.create("tbody", null, this.domNode); + this.inherited(arguments); + }, + + refresh:function(){ + // summary: + // Refreshes this legend contents when Map series has changed. + // cleanup + while(this.legendBody.lastChild){ + domConstruct.destroy(this.legendBody.lastChild); + } + + if(this.horizontal){ + domClass.add(this.domNode,"dojoxLegendHorizontal"); + this._tr = win.doc.createElement("tr"); + this.legendBody.appendChild(this._tr); + } + + var s = this.series; + if(s.length == 0){return;} + + arr.forEach(s,function(x){ + this._addLabel(x.color, x.name); + },this); + }, + _addLabel:function(color,label){ + var icon = win.doc.createElement("td"); + var text = win.doc.createElement("td"); + var div = win.doc.createElement("div"); + domClass.add(icon, "dojoxLegendIcon"); + domClass.add(text, "dojoxLegendText"); + div.style.width = this.swatchSize + "px"; + div.style.height = this.swatchSize + "px"; + icon.appendChild(div); + + if(this.horizontal){ + this._tr.appendChild(icon); + this._tr.appendChild(text); + }else{ + var tr = win.doc.createElement("tr"); + this.legendBody.appendChild(tr); + tr.appendChild(icon); + tr.appendChild(text); + } + + div.style.background = color; + text.innerHTML = String(label); + } +}); +}); diff --git a/js/dojo-1.7.2/dojox/geo/charting/widget/Map.js b/js/dojo-1.7.2/dojox/geo/charting/widget/Map.js new file mode 100644 index 0000000..dc28e7d --- /dev/null +++ b/js/dojo-1.7.2/dojox/geo/charting/widget/Map.js @@ -0,0 +1,182 @@ +//>>built + +define("dojox/geo/charting/widget/Map", ["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare","dojo/_base/html","dojo/dom-geometry", + "dijit/_Widget","dojox/geo/charting/Map"], + function(dojo, lang, declare, html,domGeom, Widget, Map) { + +return declare("dojox.geo.charting.widget.Map", Widget, { + // summary: + // A map viewer widget based on the dojox.geo.charting.Map component + // + // description: + // The `dojox.geo.charting.widget.Map` widget combines map display together with charting capabilities. + // It encapsulates an `dojox.geo.charting.Map` object on which most operations are delegated. + // Parameters can be passed as argument at construction time to specify map data file (json shape format) + // as well as charting data. + // + // The parameters are : + // + // * `shapeData`: The json object containing map data or the name of the file containing map data. + // * `dataStore`: the dataStore to fetch the charting data from + // * `dataBindingAttribute`: property name of the dataStore items to use as value for charting + // * `markerData`: tooltips to display for map features, handled as json style. + // * `adjustMapCenterOnResize`: if true, the center of the map remains the same when resizing the widget + // * `adjustMapScaleOnResize`: if true, the map scale is adjusted to leave the visible portion of the map identical as much as possible + // + // example: + // + // | var map = new dojox.geo.charting.widget.Map({ + // | shapeData : 'map.json', + // | adjustMapCenterOnresize : true, + // | adjustMapScaleOnresize : true, + // | }); + + shapeData : "", + dataStore : null, + dataBindingAttribute : "", + dataBindingValueFunction: null, + markerData : "", + series : "", + adjustMapCenterOnResize: null, + adjustMapScaleOnResize: null, + animateOnResize: null, + onFeatureClick: null, + onFeatureOver: null, + enableMouseSupport: null, + enableTouchSupport: null, + enableMouseZoom: null, + enableMousePan: null, + enableKeyboardSupport: false, + showTooltips: false, + enableFeatureZoom: null, + colorAnimationDuration: 0, + mouseClickThreshold: 2, + _mouseInteractionSupport:null, + _touchInteractionSupport:null, + _keyboardInteractionSupport:null, + constructor : function(/* Object */options, /* HtmlNode */div){ + // summary: + // Constructs a new Map widget + this.map = null; + }, + + startup : function(){ + this.inherited(arguments); + if (this.map) { + this.map.fitToMapContents(); + } + + }, + + postMixInProperties : function(){ + this.inherited(arguments); + }, + + create : function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){ + this.inherited(arguments); + }, + + getInnerMap: function() { + return this.map; + }, + + + buildRendering : function(){ + // summary: + // Construct the UI for this widget, creates the underlying real dojox.geo.charting.Map object. + // tags: + // protected + this.inherited(arguments); + if (this.shapeData) { + this.map = new Map(this.domNode, this.shapeData); + if (this.markerData && (this.markerData.length > 0)) + this.map.setMarkerData(this.markerData); + + if (this.dataStore) { + if (this.dataBindingValueFunction) { + this.map.setDataBindingValueFunction(this.dataBindingValueFunction); + } + this.map.setDataStore(this.dataStore,this.dataBindingAttribute); + } + + if (this.series && (this.series.length > 0)) { + this.map.addSeries(this.series); + } + + if (this.onFeatureClick) { + this.map.onFeatureClick = this.onFeatureClick; + } + if (this.onFeatureOver) { + this.map.onFeatureOver = this.onFeatureOver; + } + if (this.enableMouseSupport) { + + if (!dojox.geo.charting.MouseInteractionSupport) { + throw Error("Can't find dojox.geo.charting.MouseInteractionSupport. Didn't you forget to dojo" + ".require() it?"); + } + var options = {}; + options.enablePan = this.enableMousePan; + options.enableZoom = this.enableMouseZoom; + options.mouseClickThreshold = this.mouseClickThreshold; + this._mouseInteractionSupport = new dojox.geo.charting.MouseInteractionSupport(this.map,options); + this._mouseInteractionSupport.connect(); + } + + if (this.enableTouchSupport) { + if (!dojox.geo.charting.TouchInteractionSupport) { + throw Error("Can't find dojox.geo.charting.TouchInteractionSupport. Didn't you forget to dojo" + ".require() it?"); + } + this._touchInteractionSupport = new dojox.geo.charting.TouchInteractionSupport(this.map,{}); + this._touchInteractionSupport.connect(); + } + if (this.enableKeyboardSupport) { + if (!dojox.geo.charting.KeyboardInteractionSupport) { + throw Error("Can't find dojox.geo.charting.KeyboardInteractionSupport. Didn't you forget to dojo" + ".require() it?"); + } + this._keyboardInteractionSupport = new dojox.geo.charting.KeyboardInteractionSupport(this.map,{}); + this._keyboardInteractionSupport.connect(); + } + this.map.showTooltips = this.showTooltips; + this.map.enableFeatureZoom = this.enableFeatureZoom; + this.map.colorAnimationDuration = this.colorAnimationDuration; + + + } + }, + + + resize : function(b){ + // summary: + // Resize the widget. + // description: + // Resize the domNode and the widget to the dimensions of a box of the following form: + // `{ l: 50, t: 200, w: 300: h: 150 }` + // box: + // If passed, denotes the new size of the widget. + + var box; + switch (arguments.length) { + case 0: + // case 0, do not resize the div, just the surface + break; + case 1: + // argument, override node box + box = lang.mixin({}, b); + domGeom.getMarginBox(this.domNode, box); + break; + case 2: + // two argument, width, height + box = { + w : arguments[0], + h : arguments[1] + }; + domGeom.getMarginBox(this.domNode, box); + break; + } + + if (this.map) { + this.map.resize(this.adjustMapCenterOnResize,this.adjustMapScaleOnResize,this.animateOnResize); + } + } +}); +}); |
