var DMP_AUTH_STATUS ='VALID'; //Generated:11/9/2016 2:50:04 PM //ver0_81 /** * CONFIDENTIAL AND PROPRIETARY * This document is confidential and contains proprietary information. * Neither this document nor any of the information contained herein * may be reproduced or disclosed to any person under any circumstances * without the express written consent of Digital Map Products. * All Rights Reserved. * * Copyright: Copyright (c) 2008 * Company: Digital Map Products **/ // a collection of fieldname-value pairs // This file depends on: // - XMLUtils.js // The purpose of the query control will be to provide a way to query for records from resources // (layers) on the server. A resource on the server can be a database table or a database view. // geometry return types // these values are specified in the servlet. // don't change the order of these values. var ReturnGeometryType = { "NONE": 2, "CENTRIOD": 3,//deprecate "CENTROID": 3, "GEOMETRY": 1, "LATLON": 4 } /** * @ignore **/ function DMCException(systemMsg, msgCode){ this.msgCode = msgCode; this.description = systemMsg; this.message = systemMsg; this.getMessage = getMsg; this.toString = getMsg; function getMsg(){ return systemMsg; } } /** * Creates a new DMCQueryControl instance that will be used to query for information * @class DMCQueryControl is a class that is used to query for information * @constructor * @param {string} queryServiceUrl queryServiceUrl is an optional paramter for the url to send parameters to. * @param {string} DataSourceName Optional parameter that specifies the data source to query. */ function DMCQueryControl(queryServiceUrl, dataSourceName) { // the query service url should be formmatted as follows // http://bddev.digitalmapcentral.com/queryService var _queryServiceUrl = "http://parcelstream.com/Query.aspx"; if(queryServiceUrl != null) _queryServiceUrl = queryServiceUrl; var latField = "y_coord"; var lonField = "x_coord"; var _dataSourceName = dataSourceName; var SELECT_ALL_ATTRIBUTES = null; var ALL_RECORDS = -1; var ASC = 1; var DESC = 0; var ATTR_CONDS_DELIMITER = "@@@@"; var _selectAttributes = SELECT_ALL_ATTRIBUTES; var _maxOutputRecords = 200; var _orderByAttribute = null; var _whereClause = null; var _andCond = null; var _outputType = "json"; var _minRecords = 0; var _noSchema = false; var _noRecordsIfOverN = -1; var _isTileOutSearch = false; var _maxRadius = 20; // in miles. var _id = null; //@deprecated //instead use ID. var _apn = null; var _fips = null; // the following properties are used for geometry queries. var _geometryFilter = null; var _spatialReference = null; var _geometryBufferDistance = 0; var _returnGeometryType = ReturnGeometryType.GEOMETRY; var _geocoder = null; var _keyField = null; /** * Sets the the primary key field for the records. Default is APN. * @return The keyField of the layer. * @type String */ this.setKeyField = function(k){ _keyField = k; } /** * Returns the primary key field for the records * @return the primary key field for the records * @type String */ this.getKeyField = function(){ return _keyField; } /** * @ignore **/ this.setLatitudeField = function(f){ latField = f; } /** * @ignore **/ this.setLongitudeField = function(f){ lonField = f; } /** * @ignore **/ this.getSelectAttributeName = function(){ return "attr"; } /** * @ignore **/ this.getAttributeCondName = function(){ return "attrConds"; } /** * Sets the selected attributes. Default are all attributes of the record. * @type void */ this.setSelectAttributes = function(selectAttributes) { _selectAttributes = selectAttributes; } /** * Returns the selected attributes. Default are all attributes of the record. * @type string */ this.getSelectAttributes = function(){ return _selectAttributes; } /** * Sets the maximum number of records the query will return. Maximum is 500. Default is 200. * @type void **/ this.setMaxOutputRecords = function(maxOutputRecords) { _maxOutputRecords = maxOutputRecords; } /** * @ignore **/ this.setOrderByAttribute = function(orderByAttribute) { _orderByAttribute = orderByAttribute; } /** * @ignore **/ this.setWhereClause = function(whereClause, andCond) { _whereClause = whereClause; _andCond = andCond; } /** * Sets the APN and FIPS filter. Setting this filter returns parcels that match this APN, FIPS * @type void * @deprecated */ this.setAPNFilter = function(apn, fips){ _apn = apn; _fips = fips; } /** * Sets the ID filter. * @type void */ this.setID = function(id){ _id = id; } /** * Sets the geometry filter. This should be a wkt string. * @type void */ this.setGeometryFilter = function(geometryFilter) { _geometryFilter = geometryFilter; } /** * @ignore **/ this.setSpatialReference = function(spatialReference) { _spatialReference = spatialReference; } /** * Sets the buffer distance around the geometry. The query area will include the geometry plus the buffer distance. * @type void **/ this.setGeometryBufferDistance = function(geometryBufferDistance) { _geometryBufferDistance = geometryBufferDistance; } /** * Sets the type of the geometries returned. Default is centroid. * @type void **/ this.setReturnGeometryType = function(returnGeometryType) { _returnGeometryType = returnGeometryType; } /** * Sets the type of the returned data. Supported types are json and xml. Default is json. * @type void **/ this.setOutputType = function(outputType) { _outputType = outputType; } /** * @ignore **/ this.setMinRecords = function(val) { _minRecords = val; } /** * @ignore **/ this.setNoSchema = function(val) { _noSchema = val; } /** * @ignore **/ this.setNoRecordsIfOverN = function(val) { _noRecordsIfOverN = val; } /** * @ignore **/ this.setIsTileOutSearch = function(val) { _isTileOutSearch = val; } /** * @ignore **/ this.setMaxRadius = function(val) { _maxRadius = val; } /** * Returns the url that will be queried on. * @type string */ this.getQueryServiceUrl = function() { return _queryServiceUrl; } /** * Returns the name of the DataSource being queried on. * @type string * @deprecated (Instead use getDataSource()) */ this.getResourceName = function() { return _dataSourceName; } /** * Returns the name of the DataSource being queried on. * @type string */ this.getDataSource = function() { return _dataSourceName; } /** *Sets the DataSource * @type string */ this.setDataSource = function(d) { _dataSourceName = d; } /** * Returns the query that will be sent. * @return the query that will be sent. **/ this.getQuery = function(){ var url = _queryServiceUrl + "?"; if (_whereClause != null && _whereClause.length > 0) { url += 'attrConds='; if(typeof(_whereClause) == 'string'){ url += this.encodeParameter(_whereClause); }else{ //multiple select caluses for(var i = 0; i < _whereClause.length; i++){ var cond = _whereClause[i]; if (cond==null || cond=="") continue; url += this.encodeParameter(cond); if(i != _whereClause.length - 1){ url += ATTR_CONDS_DELIMITER; } } } } if (_andCond!=null){ url += '&andCond='+this.encodeParameter(_andCond); } //get select attribtues in a local variable, which can change if application requests //a LATLON type of return geometry var useSelectAttributes = _selectAttributes; if (_returnGeometryType != null && _returnGeometryType >= 0) { //check for LATLON. If geometry requested is LATLON, relace GEOMETRY in a select //string with lattitude and longitude field if (_returnGeometryType == ReturnGeometryType.LATLON){ useSelectAttributes = useSelectAttributes.toUpperCase(); //what if user requested * ? useSelectAttributes = ReplaceString(useSelectAttributes, "GEOMETRY", latField+" AS _LATFIELD,"+lonField + " AS _LONFIELD"); }else{ url += '&returnGeoType=' + _returnGeometryType; } } if (useSelectAttributes != null) { url += '&attr=' + this.encodeParameter(useSelectAttributes); } if (_maxOutputRecords != null) { url += '&maxRecords=' + _maxOutputRecords; } if (_dataSourceName != null && _dataSourceName.length > 0) { url += '&DataSource=' + this.encodeParameter(_dataSourceName); } if (_orderByAttribute != null) { url += '&orderBy=' + this.encodeParameter(_orderByAttribute); } if (_spatialReference != null && _spatialReference.length > 0 ) { url += '&srs=' + this.encodeParameter(_spatialReference); } if (_geometryBufferDistance != null && _geometryBufferDistance > 0 ) { url += '&geoBufferDist=' + _geometryBufferDistance; } if (_geometryFilter != null) { url += '&geoFilter=' + this.encodeParameter(_geometryFilter); } if (_id){ url += '&ID=' + this.encodeParameter(_id); }else if (_apn && _fips){ url += '&APN=' + this.encodeParameter(_apn); url += '&FIPS=' + this.encodeParameter(_fips); } if (_outputType != null && _outputType.toLowerCase() != "json") { url += '&output=' + this.encodeParameter(_outputType); } if (_minRecords != null && _minRecords > 0) { url += '&minRecords=' + this.encodeParameter(_minRecords); } if (_noSchema != null && _noSchema == true) { url += '&noSchema=true'; } if (_noRecordsIfOverN != null && _noRecordsIfOverN > 1) { url += '&noRecordsIfOverN=' + this.encodeParameter(_noRecordsIfOverN); } // it should have an accompany geometry. if (_isTileOutSearch != null && _isTileOutSearch == true && _geometryFilter != null) { url += '&isTileOutSearch=true'; if (_maxRadius != null && _maxRadius > 1) { url += '&maxRadius=' + this.encodeParameter(_maxRadius); } if (latField != null) { url += '&latField=' + this.encodeParameter(latField); } if (lonField != null) { url += '&lonField=' + this.encodeParameter(lonField); } } return url; } /** * Executes the query and notifies the observer success or error method when the results are returned. * @param {object} observer The object that will be notified when the query returns * @param {string} onSuccessMethod The success method name in the observer to call * @param {string} onErrorMethod The error method name in the observer to call * @param {string} Deprecated parameter. Pass NULL. * @param {string} address The address line which include . Optional * @param {string} city The city name of the address. Optional * @param {string} state The state of the address. Optional * @param {string} zip The zipcode of the addres Optional * @type void */ this.geocode = function( observer, onSuccessMethod, onErrorMethod, location, address, city, state, zip, minScore, includeGeo) { if(_geocoder == null) _geocoder = new DMPGeocoder(); _geocoder.geocodeByAddress( observer, onSuccessMethod, onErrorMethod, address, city, state, zip, minScore, includeGeo); } var queryID = 0; /** * Executes the query and notifies the observer success or error method when the results are returned. * @param {object} observer The object that will be notified when the query returns * @param {string} onSuccessMethod The success method name in the observer to call * @param {string} onErrorMethod The error method name in the observer to call * @param {string} queryId An Id to give the query. Optional * @type void */ this.execute = function(observer, onSuccessMethod, onErrorMethod, queryId ) { var url = this.getQuery(); try{ var queryControlObserver = new _DMCQueryControlObserver(observer, onSuccessMethod, onErrorMethod, this.getResourceName(), _keyField); if(queryId == null || typeof(queryId) == 'undefined') queryId = "query" + queryId++; gLoadJSON(url, queryControlObserver, "onSuccess", "onError", queryId); }catch(ex){ alert("Error DMCQueryCOntrol:"+ex.description); } }//execute /** * @ignore **/ this.encodeParameter = function (value) { if (value != null) { return encodeURIComponent(value); } return ""; } /** * the purpose of the DMCQueryControlObserver handles the query that is returned from * a query to the queryServlet. It will then notify an observer that is waitiing for the results * with a record set object. * plo October 6th, 2006 * @ignore **/ }//DMCQueryControl /** * @ignore **/ function _DMCQueryControlObserver(observer, onSuccessMethod, onErrorMethod, dataSourceName, keyField) { if(observer == null) throw new DMCException("DMCQueryControlObserver: observer is undefined"); if(observer[onSuccessMethod] == null){ throw new DMCException("DMCQueryControlObserver: observer must have a success method '"+onSuccessMethod+"()' "); } if(observer[onErrorMethod] == null){ throw new DMCException("DMCQueryControlObserver: observer must have an error method '"+onErrorMethod+"()' "); } var _self = this; /** * @ignore **/ this._observer = observer; /** * @ignore **/ this._onSuccessMethod = onSuccessMethod; /** * @ignore **/ this._onErrorMethod = onErrorMethod; /** * @ignore **/ this._dataSourceName = dataSourceName; /** * @ignore **/ this.onSuccess = function(jsonObj, url, responseText) { if (keyField==null && typeof(observer.getKeyField) != 'undefined') keyField = observer.getKeyField(); var layerName = _self._dataSourceName; // if obsever has a getLayerName method, use it if (observer["getLayerName"]){ layerName = observer.getLayerName(); } var recordSet = JSON2RecordSet(jsonObj, keyField, layerName); observer[onSuccessMethod](recordSet, dataSourceName); } /** * @ignore **/ this.onError = function(errorMessage, status, url) { observer[onErrorMethod](errorMessage, status, url); } /** * @ignore **/ this.tryParse = function(type, value) { if(type == null || value == null) return value; if(type == 'int') return parseInt(value); else if(type == 'double' || type == 'float') return parseFloat(value); else if(type == 'bool') { if(value == '1' || value == 'true') return true; else return false; } else return value; } }//DMCQueryControlObserver /** * @ignore **/ function DMPGeocoder(queryServiceUrl) { var queryID = 1; var _queryServiceUrl = "http://parcelstream.com/Geocode.aspx"; if(queryServiceUrl != null) _queryServiceUrl = queryServiceUrl; //var _keyField = ["Key", "APN", "FIPS", "DATASOURCE", "ADDRESS", "SCORE", "CITY"]; var _keyField = ["ID", "DATASOURCE", "ADDRESS", "ZIP"]; /** * @ignore **/ this.geocodeByAddress = function( observer, onSuccessMethod, onErrorMethod, address, city, state, zip, minScore, includeGeo) { if(includeGeo != null && includeGeo == true) includeGeo = "true"; else includeGeo = ""; var url = _queryServiceUrl + "?"; url += getQueryParameter("address", address); url += getQueryParameter("city", city); url += getQueryParameter("state", state); url += getQueryParameter("zip", zip); url += getQueryParameter("includeGeo", includeGeo); url += getQueryParameter("minScore", minScore); try{ var queryControlObserver = new _DMCQueryControlObserver(observer, onSuccessMethod, onErrorMethod, '', _keyField); queryID = queryID++; gLoadJSON(url, queryControlObserver, "onSuccess", "onError", queryID); }catch(ex){ alert("Error DMPGeocoder:"+ex.description); } } function getQueryParameter(name, value) { if(typeof(value) != 'undefined' && typeof(name) != 'undefined' && name != null && name != '' && value != '' && value != null) { return "&" + name + "=" + encodeURIComponent(value); } return ''; } } /** * @class * @constructor * @ignore **/ function CPriority(){ this.LOW = 1000; this.MEDIUM = 20; this.HIGH = 2; this.HIGHEST = 1; } var Priority = new CPriority(); //Define global namespace. if (typeof(Dmp)=='undefined') Dmp = new Object(); /** * @class * @constructor * @ignore **/ Dmp.Event = function (evtStr, sourceObj, data) { this.eventType = evtStr; // STRING IDENTIFIES THE TYPE OF EVENT this.consumed = false; // true - indicates an observer has used the event this.source = sourceObj; // source object for event this.data = (data? data : sourceObj); this.cancel = false; // true - indicates observer request cancelation of the event this.getSource = function(){ return this.source; } this.getStatus = function(){ return this.eventType; } this.getEventType = function(){ return this.eventType; } this.getData = function(){ return this.data; } } /** * @class * @constructor * @ignore **/ Dmp.EventManager = function(){ //assuming that an event will be notified more frequently than adding observers this._event2PriorityArray = new Array(); //some events are already executed and observers which are added later should be dispatched immediately. this._eventPassed = new Array(); this.notify = function (evtObj){ if (evtObj==null) throw new DMCException("Event object is NULL"); if (evtObj.eventType==null) throw new DMCException("evtObj.eventType is NULL"); if (evtObj.deadEvent){ this.setDispatchedEvent(evtObj.eventType, evtObj); } //Get an array sorted by priority var priorityArray = this._event2PriorityArray[evtObj.eventType]; //nobody listening if (priorityArray==null) return null; //now notify everyone in the list for ( var i=0; ib if (a.priority==null) a.priority = 20; if (b.priority==null) b.priority = 20; if (a.priorityb.priority){ return 1; }else{ return 0; } }//sortByPrirityMethod this.indexOf = function(priorityArray, observer){ if (priorityArray==null || observer==null) return -1; for ( var i=0; i 0) { recordSetResourceName = resourceName } var columnNames = []; // check if we need to put default index plo if(includeDefaultIdx) columnNames.push(keyField[0]); for(var name in columnNameTypeMapping){ columnNames.push(name); } var recordSet = new Dmp.RecordSet(keyField, columnNames); //recordSet.setCompositeKeyField(keyField); recordSet.addRecordCollection(recordCollection); return (recordSet); } /** * @ignore */ function tryParse (type, value) { if(type == null || value == null) return value; if(type == 'int'){ return parseInt(value); }else if(type == 'double' || type == 'float'){ return parseFloat(value); }else if(type == 'bool'){ return (value == '1' || value == 'true'); }else if (type =='wkt'){ //convert from wkt string to geometry object return WKT(value); }else if (type =='date'){ if (value=="") return null; ///convert sql string to javascript string value = value.replace(/00:00:00.0/,""); value = value.replace(/-/g,"/"); value = new Date(value); if ((value+"")=="NaN"){ return null; } return value; }else if (type =='string'){ return value; }else{ return value; } } function deepCloneJSON(obj){ //check is associative array or normal 1D array if (obj==null) return obj; var cloneObj = null; var dt = getDataType(obj); if (dt=="associative array"){ cloneObj = []; for (var k in obj){ cloneObj[k] = deepCloneJSON(obj[k]); }//for k return cloneObj; }else if (dt=="array"){ cloneObj = []; for (var i=0; i0){ if (obj[0]!=null) return "array"; } return type; } // yz: TRY NOT to add features to me!!! // An implementation of of NamedAccessor using Javascript array. function OrderedHashtable() { this._columnNames = []; // an array of column names: staying by order (given an index, find the column name) this._columnNameIndices = []; // a hashtable of column index for each name: name-index pair. (given a name, find the column index) this._fieldArray = []; // a hashtable of field value for each name: name-value pair (given a name, find the value) this._dataTypes = []; this.setByName = function(/*String*/ name, /*anything*/ obj, /*String*/dataType) { if (name!=null) name = (""+name).toUpperCase(); this._fieldArray[name] = obj; if (dataType && this._dataTypes[name]==null){ if(dataType=="wkt") this._dataTypes[name] = "geometry"; else this._dataTypes[name] = dataType; } if( this._columnNameIndices[name] == null ) { this._columnNameIndices[name]=this._columnNames.length; this._columnNames.push(name); } } this.getByName = function(/*String*/ name) { if (name!=null) name = (""+name).toUpperCase(); return this._fieldArray[name]; } this.getDataTypeByName = function(name){ return this._dataTypes[name]; } this.clear = function(){ this._fieldArray = []; this._columnNameIndices = []; this._columnNames = []; } this.getCount = function() { return this._columnNames.length; } this.contains = function(/*String*/ name) { if (name!=null) name = name.toUpperCase(); return this._columnNameIndices[name] != null; } this.remove = function(/*String*/ name) { if (name!=null) name = (""+name).toUpperCase(); var colIndex; if( (colIndex = this._columnNameIndices[name]) == null) throw new DMCException("GridControl.remove: trying to remove an inexisting field : " + name); delete this._fieldArray[name]; delete this._columnNameIndices[name]; this._columnNames.splice(colIndex,1); for(var i=colIndex;i0) { var message="GridControl.removeAll: failed to remove " + notRemoved.join() + "\n\twhen removing: " + names.join(); throw new DMCException( message ); } } this.getByIndex = function(/*int*/i) { return this._fieldArray[ this._columnNames[i] ]; } this.getNameByIndex = function(/*int*/ i) { return this._columnNames[i]; } this.getNames = function() { var keys = []; var k; for( k in this._fieldArray) keys.push(k); return keys; } } // a collection of fieldname-value pairs // This file depends on: // - OrderedHashTable.js Dmp.Record = function(/*String[]*/ keyFieldArr, /*(optional)String*/ resName) { this.base = OrderedHashtable; this.base(); this.FIELD_DELIMITER="+*+"; this._resourceName = resName; // unique key for a record, let it be a string. this._keyArray = keyFieldArr; this._properties = []; this.setResourceName = function(/** String **/ val){ this._resourceName = val; } this.getKeyField = function() { return this._keyArray[0]; } this.getResourceName = function() { return this._resourceName; } this.getRowNumber = function() { return this.getProperty("RowNumber"); } this.setKeyField = function(/*String */ keyField) { this._keyArray = [keyField]; } this.setCompositeKeyField = function(/*String[] */ keyFields) { this._keyArray = keyFields; } this.getCompositeKeyField = function() { return this._keyArray; } this.getKey = function() { var key = this.getByName( this._keyArray[0] ); for(var i=1;i _maximumRecords){ alert(_exceedMaxRecordsMessage); return; } var key = r.getKey(); var existed = this._records.contains( key ); var oldRecord = null; if (existed && !dontSend){ oldRecord = this._records.getByName(key).clone(); } //if the recordset is empty, passed in record will //set the fields metadata this._records.setByName( key, r); if(!dontSend){ if(existed){ var evt = new Dmp.Event("recordUpdated", this, r); evt.oldRecord = oldRecord; evt.newRecord = r; this.notify( evt ); }else{ this.notify( new Dmp.Event("recordAdded", this, r) ); } } return r; } this.getRecord = function(/*String*/ key) { var record=this._records.getByName(key); if(!record) return null; else return record; } this.removeRecord = function(/*String*/ key, /*boolean (optional)*/ dontSend) { var r = this._records.getByName( key ); if (!r) return; this._records.remove( key ); if(!dontSend) // send message if record is removed and allowed to send message { this.notify( new Dmp.Event("recordRemoved", this, r) ); } return r; } this.clone=function() { var newRecordSet=new Dmp.RecordSet( this._keyArray, this.getColumnNames() ); for(var i=0;i _maximumRecords){ alert(_exceedMaxRecordsMessage); break; } newRecords.push(newRec); } } if(newRecords.length>0) this.notify( new Dmp.Event("recordCollectionAdded", this, newRecords) ); // yz: commented - too slow for HTMLGridControl to change all the table entries. // if(updatedRecords.length>0) // this.notify( new Dmp.Event("recordCollectionUpdated", this, updatedRecords) ); return updatedRecords; } this.toArray = function(){ var arr = []; for(var i=0;i1) record.setCompositeKeyField( this._keyArray ); for(var tName in nameTypeMap) { var value = rNode.getAttribute( tName ); if(value!=null) { var type = nameTypeMap[tName]; value = tryParse (type, value); } record.setByName( tName, XMLAbstraction.decode(value), type); } importedRecords.push(record); this.setRecord(record,DONTSEND); }//end for data rows // get the properties var propNodes = xmlDom.selectNodes("Xml/Properties/Properties"); for(var j=0;j section var r = this.getByIndex(0); var columnNameSet = []; for(var j=0;j=0 || v.TYPE == "POINT" ) { type = "wkt"; } else throw new DMCException("RecordSet.exportData(): not supported value type : " + v); var dataTypeNode = xmlDoc.createElement("Datatype"); dataTypeNode.setAttribute("type", type); attrNode.appendChild(dataTypeNode); schemaNode.appendChild( eleNode ); } } // generate section for(var i=0;i section for(var i=0;i0){ urlWithOid += "&"; }else{ urlWithOid += "?"; } urlWithOid += "obsId=_gDMCObserverLounge[\""+observerId+"\"]"; urlWithOid += "&obsSuccessMethod="+onSuccessMethod; urlWithOid += "&obsErrorMethod="+onErrorMethod; urlWithOid += "&output=JSON"; //append script node _gDmcLoadScript(urlWithOid, _loadedURL, srcId); }//gLoadJSON var _gDMCLOGIN_URL = "http://maps.digitalmapcentral.com/production/init"; /** * @ignore */ function ProcessError(msg){ //current JSON servlet is not very sophisticated. //we have to listen for some hardcoded values here. if (msg.indexOf("User not found")>=0){ //User not logged in document.location.href = _gDMCLOGIN_URL; return; } alert(msg); } /** * simulating lounge object to support old JSON servlet. * The output of JSON filter or servlets expect global lounge object. **/ var _gDMCObserverLounge = new Array(); /** * @ignore */ function _gDMCNotifyJSON(obsID){ var observer = _gDMCObserverLounge[obsID]; if (observer==null){ //in this case obsID is an observer observer = eval(obsID); } return observer; } // plo todo move to xmlUtils. /** * @ignore */ function _gDmcLoadScript(url, callback, srcId) { if (document.all){ _gDmcLoadScriptIE(url, callback, srcId); }else{ _gDmcLoadScriptMOZILLA(url, callback, srcId); } } // plo todo move to xmlUtils. /** * @ignore */ function _gDmcLoadScriptMOZILLA(url, callback, srcId){ var head = document.getElementsByTagName("head").item(0); // Create object var oScript = document.createElement("script"); oScript.setAttribute("language","JavaScript1.2"); oScript.setAttribute("src",url); if (srcId) oScript.setAttribute("id", srcId); var _loaded = 0; if (callback){ oScript.addEventListener("load", callback, false); }else{ //this is a sync call function _callBack(){ _loaded = 100; } oScript.addEventListener("load", _callBack, false); } head.appendChild(oScript); if (!callback){ //check for existance of the appended js file try{ //to simulate synchronous loading in mozilla, there is no other way except following. //Brace yourself, here comes the hack of all: I will go in a loop and check //the variable which will be set in the callback method. while (_loaded<50){ //Lets sleep for a while before checkin gSleep(200); _loaded++; } }catch(ex){ //i wouldn't worry too much about the exception } } } // plo todo move to xmlUtils. /** * @ignore */ function _gDmcLoadScriptIE(url, callback, srcId){ var head = document.getElementsByTagName("head").item(0); // Create object var oScript = document.createElement("script"); oScript.setAttribute("src",url); if (srcId) oScript.setAttribute("id",srcId); if (callback==null){ //this is a sync call if (oScript.readyState!="loaded"){ var _loaded = 0; oScript.onreadystatechange = function(){ //DEBUG_LOG("this.readyState :"+this.readyState ); if (this.readyState == "loaded"){ oScript.onreadystatechange = null; _loaded = 100; } } while (_loaded<50 && oScript.readyState!="loaded" && oScript.readyState!="complete"){ //DEBUG_LOG(url+" _loaded:"+_loaded + " oScript.readyState:"+oScript.readyState); //Lets sleep for a while before checkin Dmp.Utils.pause(100); _loaded++; } } }else{ if (oScript.readyState=="loaded" || oScript.readyState=="complete"){ callback(); }else if (oScript.readyState!="loaded") { oScript.onreadystatechange = function() { if (this.readyState == "loaded") { callback(); oScript.onreadystatechange = null; } } }else{ alert("Cannot load data url:"+url); } } head.appendChild(oScript); }//_gDmcLoadScriptIE /** * @ignore */ function _gDmcRemoveScriptTagById(srcId){ var head = document.getElementsByTagName("head").item(0); var scrtNode = document.getElementById(srcId); if (scrtNode){ head.removeChild(scrtNode) //alert("Script removed : "+srcId + " / "+document.getElementsByTagName("script").length); return; }else{ //alert("Script not found : "+srcId + " / "+document.getElementsByTagName("script").length); } /* var scripts = document.getElementsByTagName("script"); for ( var i=0; i0) { this.xMin = this.xMax = points[0].x; this.yMin = this.yMax = points[0].y; for(var i=1;i this.xMax) this.xMax = points[i].x; if(points[i].y < this.yMin) this.yMin = points[i].y; else if(points[i].y > this.yMax) this.yMax = points[i].y; } } /** * Sets the bounds * @param {float} xMin minimum x value * @param {float} yMin minimum y value * @param {float} xMax maximum x value * @param {float} yMax maximum y value * @Author: JPeng 11/21/2007 */ this.setBounds = function(xMin, yMin, xMax, yMax) { this.xMin = xMin; this.yMin = yMin; this.xMax = xMax; this.yMax = yMax; } /** * @ignore */ this.min = function() { return new DMCPoint(this.xMin,this.yMin); } /** * Returns the minimum point in the bounds * @return the minimum point in the bounds. * @type DMCPoint */ this.getMin = this.min; /** * @ignore */ this.max = function() { return new DMCPoint(this.xMax,this.yMax); } /** * Returns the maximum point in the bounds * @return the maximum point in the bounds. * @type DMCPoint */ this.getMax = this.max; /** * Returns true if the bounds are equal and false otherwise. * @param {DMCBounds} bounds A DMCBounds object * @return true if the bounds are equal and false otherwise * @type bool */ this.equals = function( bounds) { return bounds.xMin == this.xMin && bounds.xMax == this.xMax && bounds.yMin == this.yMin && bounds.yMax == this.yMax; } /** * Returns true if the point is contained in the bounds and false otherwise * @param {DMCPoint} point A DMCPoint object * @return true if the point is contained in the bounds and false otherwise * @type bool */ this.contains = function(/*DMCPoint*/ point) { return point.x >= this.xMin && point.x <= this.xMax && point.y >= this.yMin && point.y <= this.yMax; } /** * Returns true if the bounds is contained in this bounds. * @param {DMCBounds} bounds A DMCBounds * @return true if the bounds is contained in this bounds. * @type bool */ this.containsBounds = function(/*Bounds*/ bounds) { return bounds.xMin>=this.xMin && bounds.xMax<=this.xMax && bounds.yMin>=this.yMin && bounds.yMax<=this.yMax; } /** * Returns true if the bounds intersects this bounds. * @param {DMCBounds} bounds A DMCBounds * @return true if the bounds intersects this bounds. * @type bool */ this.intersects = function(/*Bounds*/ bounds) { if ( (!((this.xMax < bounds.xMin) || (this.xMin > bounds.xMax))) && (!((this.yMax < bounds.yMin) || (this.yMin > bounds.yMax))) ){ return true; } return false; } /** * Extends the bounds so that it includes the point passed in * @param {DMCPoint} point Point to extend bounds * @type void */ this.extend = function(/*DMCPoint*/ point) { if(point.x>this.xMax) this.xMax = point.x; else if(point.xthis.yMax) this.yMax = point.y; else if(point.y= this.xMin && bounds.xMin <= this.xMax) { xMin = bounds.xMin; ++n; } if(bounds.xMax >= this.xMin && bounds.xMax <= this.xMax) { xMax = bounds.xMax; ++n; } if(n<2) { if(this.xMin >= bounds.xMin && this.xMin <= bounds.xMax) { xMin = this.xMin; ++n; } if(this.xMax >= bounds.xMin && this.xMax <= bounds.xMax) { xMax = this.xMax; ++n; } } if(n<2) return new DMCBounds( [new DMCPoint(0,0), new DMCPoint(0,0)] ); n=0; if(bounds.yMin >= this.yMin && bounds.yMin <= this.yMax) { yMin = bounds.yMin; ++n; } if(bounds.yMax >= this.yMin && bounds.yMax <= this.yMax) { yMax = bounds.yMax; ++n; } if(n<2) { if(this.yMin >= bounds.yMin && this.yMin <= bounds.yMax) { yMin = this.yMin; ++n; } if(this.yMax >= bounds.yMin && this.yMax <= bounds.yMax) { yMax = this.yMax; ++n; } } if(n<2) return new DMCBounds( [new DMCPoint(0,0), new DMCPoint(0,0)] ); return new DMCBounds( [new DMCPoint(xMin,yMin), new DMCPoint(xMax,yMax)] ); } /** * Returns the southEast corner point * @return the southEast corner point * @type DMCPoint */ this.getSouthEast = function() { return new DMCPoint(this.xMax, this.yMin); } /** * Returns the SouthWest corner point * @return the SouthWest corner point * @type DMCPoint */ this.getSouthWest = function() { return new DMCPoint(this.xMin, this.yMin); } /** * Returns the NorthEast corner point * @return the NorthEast corner point * @type DMCPoint */ this.getNorthEast = function() { return new DMCPoint(this.xMax, this.yMax); } /** * Returns the NorthWest corner point * @return the NorthWest corner point * @type DMCPoint */ this.getNorthWest = function() { return new DMCPoint(this.xMin, this.yMax); } /** * Returns a DMCPoint which represents the size of this rectangle. * @return a DMCPoint which represents the size of this rectangle. * @type DMCPoint */ this.toSpan = function() { return new DMCPoint(this.xMax - this.xMin , this.yMax - this.yMin); } /** * Returns true if the the bounds contains valid latitude coordinates * @return true if the the bounds contains valid latitude coordinates * @type bool */ this.isValidLat = function() { return this.yMin <= -90 && this.yMax >= 90; } /** * Returns true if the the bounds contains valid longitude coordinates * @return true if the the bounds contains valid longitude coordinates * @type bool */ this.isValidLng = function() { return this.max <= -180 && this.yMax >= 180; } /** * Returns true if the bounds are valid and not empty and false otherwise * @return true if the bounds are valid and not empty and false otherwise * @type bool */ this.isEmpty = function() { return this.xMin >= this.xMax || this.yMin >= this.yMax; } /** * Returns the center of the bounds * @return the center of the bounds * @type DMCPoint */ this.getCenter = function() { // JPeng 11/01/2007 : always return unbounded point, assuming that // the input points to construct this bounds are bounded themselves(if there was a need) return new DMCPoint((this.xMax + this.xMin)/2 , (this.yMax + this.yMin)/2, true ); } /** * Returns an Array of DMCPoint which represents the bounds. * @return an Array of DMCPoint which represents the bounds. * @type DMCPoint[] */ this.getPoints = function() { return [new DMCPoint(this.xMin,this.yMin), new DMCPoint(this.xMin,this.yMax), new DMCPoint(this.xMax,this.yMax), new DMCPoint(this.xMax,this.yMin), new DMCPoint(this.xMin,this.yMin)]; } /** * Returns the WKT representation of the bounds * @return the WKT representation of the bounds * @type string */ this.toString = function(){ var polygon = new DMCPolygon( this.getPoints() ); return polygon.toString(); } } /** * Constructs a DMCPoint * @class DMCPoint is a class that represents an x y point or a latLong point. * @constructor * @param {float} x X coordinate * @param {float} y Y coordinate * @param {bool} unbounded if true then do not constrain to latitude longitude coordinates. */ function DMCPoint(x,y, unbounded) { /** * Geometry type of the object ("POINT") * @type string */ this.TYPE="POINT"; /** * X coordinate * @type float */ this.x = x; /** * Y coordinate * @type float */ this.y = y; if(!unbounded) { this.y = Math.max(-90, this.y); this.y = Math.min(90, this.y); this.x = Math.max(-180, this.x); this.x = Math.min(180, this.x); } /** * Returns the WKT representation * @return the WKT representation * @type string */ this.toString = function(){ return "POINT("+this.x+" "+this.y+")"; } /** * Returns x coordinate * @return x coordinate * @type float */ this.getX = function() {return this.x;} /** * Returns y coordinate * @return y coordinate * @type float */ this.getY = function() {return this.y;} // JPeng 10/31/2007 : added functions /** * Set x coordinate * @param x coordinate * @type float */ this.setX = function(inX) { this.x = inX;} /** * Set y coordinate * @param y coordinate * @type float */ this.setY = function(inY) { this.y = inY;} /** * Returns latitude coordinate * @return latitude coordinate * @type float */ this.getLat = function() { return this.y; } /** * Returns longitude coordinate * @return longitude coordinate * @type float */ this.getLng = function() { return this.x; } /** * Returns the point * @return the point * @type DMCPoint */ this.getPoints = function() { return [this]; } /** * Sets the point. This can be either a single DMCPoint or an array. If it is an array, only the first element will be used. * @type void */ this.setPoints = function(points) { var point = null; if (typeof(points.length) != 'undefined' && points.length > 0) point = points[0]; else point = points; if (point != null) { this.x = point.x; this.y = point.y; } } /** * Returns the latitude in radians * @return the latitude in radians * @type float */ this.getLatRadians = function() { return this.y*Math.PI/180; } /** * Returns the longitude in radians * @return the longitude in radians * @type float */ this.getLngRadians = function() { return this.x*Math.PI/180; } /** * Returns true if the points are equal * @param {DMCPoint} point A DMCPoint * @return true if the points are equal * @type bool */ this.equals = function(/*DMCPoint*/ point) { return this.y == point.y && this.x == point.x; } /** * Returns true if the point is contained in the polygon * @param {DMCGeometry} geometry Any DMCGeometry : DMCPoint, DMCBounds, DMCPolygon, DMCLineString * @return true if the point is contained in the polygon, * or if the point is exactly on the linestring (within EPSILON tolerance) * @type bool */ this.intersects = function( geometry){ //sanity check if (geometry==null) throw new DMCException("DMCPoint.intersects can not take a null parameter"); //point with point intersection if (geometry.TYPE=="POINT"){ //if x and y are exactly same, return true return this.equals(geometry); } //point with Polygon intersection if (geometry.TYPE=="POLYGON" || geometry.TYPE=="CIRCLE"){ //check if this point is contained within the passed polygon var b = geometry.contains(this); return b; } if (geometry.TYPE=="BOUNDS"){ //check if this point is contained within the passed rectanlge var b = geometry.contains(this); return b; } // JPeng 02/12/2008 : implemented intersection with linestring if (geometry.TYPE=="LINESTRING"){ var bClose = false; var tol = Math.EPSILON; for( var i = 0; i < geometry.getVertexCount()-1; i ++ ) { var bClose = pointCloseToSegment( geometry.getVertex(i), geometry.getVertex(i+1), this, tol ); if( bClose ) break; } return bClose; } throw new DMCException("Other geometry types no supported."); }//intersects /** * Returns the point * @return the point * @type DMCPoint */ this.getCentroid = function(){ return new DMCPoint(this.x,this.y, unbounded); } /** * Returns the point * @return the point * @type DMCPoint */ this.getCenter = function(){ return new DMCPoint(this.x,this.y, unbounded); } //DMCPoint this.getHandles = function(){ var handles = []; var h = {TYPE:"WHOLE", INDEX:0, GEOMETRY:this}; handles.push(h); return handles } this.modifyByHandle = function(handle, newPosPt){ this.x = newPosPt.x; this.y = newPosPt.y; }//modifyByHandle this.projectToPixels = function(map){ return map.latLngToPixel(this); } }//DMCPoint /** * @private **/ function _pointArray1DtoPointArray( pointArray1D ) { var points = []; for(var i=0;isize ) return false; var arr = []; for (var i=0; i maxY ) maxY = this.points[i].getY(); else if( this.points[i].getY() < minY ) minY = this.points[i].getY(); if( this.points[i].getX() > maxX ) maxX = this.points[i].getX(); else if( this.points[i].getX() < minX ) minX = this.points[i].getX(); this.points[i].setX(this.points[i].getX()- savex); this.points[i].setY(this.points[i].getY()- savey); } var cx = 0; var cy = 0; var m; for(var i=0; i maxX ) || ( cy < minY ) || ( cy > maxY ) ) { centroid = this.getAveragePosition(); } return centroid; } /** * @ignore */ this.adjustCenter = function( inPointArray, avgPos ) { if( (typeof(avgPos) == 'undefined') || (avgPos == null ) ) return null; if( (typeof(inPointArray) == 'undefined') || (inPointArray == null ) ) return new DMCPoint(avgPos.getX(), avgPos.getY(), true); var EPSILON = 1e-20; var len = inPointArray.length; if( len < 4 ) return new DMCPoint(avgPos.getX(), avgPos.getY(), true); var l = len-1; var maxY = -1e20; var minY = 1e20; for (var i=0; i<=l; i++) { if( inPointArray[i].getY() > maxY ) maxY = inPointArray[i].getY(); if( inPointArray[i].getY() < minY ) minY = inPointArray[i].getY(); } var cx = avgPos.getX(); var cy = avgPos.getY(); //1. Calculate the horizontal intersection segments through the centroid, choose the right segment if any. var segWidths = new Array(); var segCenters = new Array(); var segCount = 0; if( (cy > minY + EPSILON) && (cy < maxY - EPSILON) ) segCount = this.horizontalSegments( inPointArray, segWidths, segCenters, cy, 0 ); else return new DMCPoint(cx, cy, true); var minInd = -1; var minDis = 1e20; var minCentX = -1; for( var i = 0; i < segCount; i++ ) { var dis = Math.abs( segCenters[i] - cx ); if( dis < minDis ) { minDis = dis; minCentX = segCenters[i]; minInd = i; } } if( minInd >= 0 ) { var cent = new DMCPoint( minCentX, cy, true ); return cent; } var numBins = 4; //2. Seach for neighboring horizontal lines var yArray = new Array(numBins + numBins); var upperRange = maxY - cy; if(upperRange < EPSILON) upperRange = 0; var lowerRange = minY - cy; if(lowerRange > -EPSILON) lowerRange = 0; var upperBinSize = upperRange / numBins; var lowerBinSize = lowerRange / numBins; var accumUpperDelta = upperBinSize; var accumLowerDelta = lowerBinSize; for( var i = 0; i < numBins; i++ ) { yArray[i+i] = cy + accumLowerDelta; yArray[i+i+1] = cy + accumUpperDelta; accumUpperDelta += upperBinSize; accumLowerDelta += lowerBinSize; } for( var i = 0; i < numBins + numBins; i++ ) { var segCount = 0; if( (yArray[i] > minY + EPSILON) && (yArray[i] < maxY - EPSILON) ) segCount = this.horizontalSegments( inPointArray, segWidths, segCenters, yArray[i], 0 ); var minInd = -1; var minDis = 1e20; var minCentX = -1; for( var j = 0; j < segCount; j++ ) { var dis = Math.abs( segCenters[j] - cx ); if(dis < minDis ) { minDis = dis; minCentX = segCenters[j]; minInd = j; } } if( minInd >= 0 ) { var cent = new DMCPoint( minCentX, yArray[i], true ); return cent; } } return new DMCPoint(cx, cy, true); } /** * @ignore */ // JPeng 10/31/2007 this.getCenterForPlacement = function( inPointArray, wid, hei ) { if( (typeof(inPointArray) == 'undefined') || (inPointArray == null ) ) return null; if( wid < 0 ) wid = 0; if( hei < 0 ) hei = 0; var EPSILON = 1e-20; var len = inPointArray.length; if( len < 4 ) return null; var inputPoly = new DMCPolygon( inPointArray ); var area = this.getAreaForInput( inPointArray ); if(area < EPSILON ) { var avgPos = inputPoly.getAveragePosition(); return avgPos; } var l = len-1; var maxY = inPointArray[0].getY(); var minY = inPointArray[0].getY(); var maxX = inPointArray[0].getX(); var minX = inPointArray[0].getX(); for (var i=0; i<=l; i++) { if( inPointArray[i].getY() > maxY ) maxY = inPointArray[i].getY(); else if( inPointArray[i].getY() < minY ) minY = inPointArray[i].getY(); if( inPointArray[i].getX() > maxX ) maxX = inPointArray[i].getX(); else if( inPointArray[i].getX() < minX ) minX = inPointArray[i].getX(); } // Calculate the centroid of input points var centroid = inputPoly.getCentroid(); var cx = centroid.getX(); var cy = centroid.getY(); //1. Calculate the horizontal intersection segments through the centroid, choose the right segment if any. var widRatioThreshold = 1.5; var centroidFine = false; var segWidths = new Array(); var segCenters = new Array(); var segCount = 0; if( (cy > minY + hei/2 + EPSILON) && (cy < maxY - hei/2 - EPSILON) ) segCount = this.horizontalSegments( inPointArray, segWidths, segCenters, cy, hei ); else centroidFine = true; var rightSegmentFound = false; var maxSpan = -1; var maxInd = -1; for( var i = 0; i < segCount; i++ ) { if(segWidths[i] > maxSpan ) { maxSpan = segWidths[i]; maxInd = i; } if( segWidths[i] > widRatioThreshold*wid ) { cx = segCenters[i]; centroidFine = true; break; } } var largestSpan = -1e10; var largestSpanCX = -1e10; var largestSpanCY = cy; if( maxInd >= 0 ) { largestSpan = maxSpan; largestSpanCX = segCenters[maxInd]; } var numBins = 8; if( !centroidFine ) { if( maxSpan > widRatioThreshold*wid ) { cx = segCenters[maxInd]; rightSegmentFound = true; } else { //2. Seach for neighboring horizontal lines var yArray = new Array(numBins + numBins); var upperRange = maxY - cy; if(upperRange < EPSILON) upperRange = 0; var lowerRange = minY - cy; if(lowerRange > -EPSILON) lowerRange = 0; var upperBinSize = upperRange / numBins; var lowerBinSize = lowerRange / numBins; var accumUpperDelta = upperBinSize; var accumLowerDelta = lowerBinSize; for( var i = 0; i < numBins; i++ ) { yArray[i+i] = cy + accumLowerDelta; yArray[i+i+1] = cy + accumUpperDelta; accumUpperDelta += upperBinSize; accumLowerDelta += lowerBinSize; } for( var i = 0; i < numBins + numBins; i++ ) { var segCount = 0; if( (yArray[i] > minY + hei/2 + EPSILON) && (yArray[i] < maxY - hei/2 - EPSILON) ) segCount = this.horizontalSegments( inPointArray, segWidths, segCenters, yArray[i], hei ); var maxSpan = -1; var maxInd = -1; for( var j = 0; j < segCount; j++ ) { if(segWidths[j] > maxSpan ) { maxSpan = segWidths[j]; maxInd = j; } } if( maxSpan > widRatioThreshold*wid ) { cx = segCenters[maxInd]; cy = yArray[i]; rightSegmentFound = true; break; } if( maxSpan > largestSpan ) { largestSpan = maxSpan; largestSpanCX = segCenters[maxInd]; largestSpanCY = yArray[i]; } } if( (!rightSegmentFound) && (largestSpan > wid) ) { cx = largestSpanCX; cy = largestSpanCY; } delete yArray; } } else { rightSegmentFound = true; } delete segWidths; delete segCenters; var cen = new DMCPoint(cx,cy, true); if( ( cx < minX ) || ( cx > maxX ) || ( cy < minY ) || ( cy > maxY ) ) { cen = inputPoly.getAveragePosition(); } return cen; } // JPeng 11/02/2007 : Calculate the segments from line-polygon intersection this.horizontalSegments = function( inPointArray, segWidths, segCenters, y, hei ) { var segCount = 0; var len = inPointArray.length; if( len < 2 ) return 0; var EPSILON = 1e-8; var horizTol = hei; if( horizTol < EPSILON ) horizTol = EPSILON; var ipts = new Array(); var numOfIntersections = 0; for (var i=0; i y) { // (i,i+1) crosses cy, get the intersection isIntersect = true; } } else if (yfrom > (y-EPSILON)) { // crossing up-down if (yto < y) { // (i,i+1) crosses cy, get the intersection isIntersect = true; } } if (isIntersect == true) { var xfrom = inPointArray[i].getX(); var xto = inPointArray[i+1].getX(); var xIntersect = xfrom + ((y - yfrom) * (xto - xfrom)/ (yto - yfrom)); ipts[numOfIntersections] = xIntersect; numOfIntersections++; } } if( numOfIntersections % 2 == 1 ) alert("Odd number of intersections!!"); if (numOfIntersections > 0) { // sort the intersecting points ipts.sort(sortNumber); segCount = 0; for (var i=0; i < numOfIntersections-1; i=i+2) { segWidths[segCount] = ipts[i+1]-ipts[i]; segCenters[segCount] = (ipts[i+1]+ipts[i])/2; segCount++; } } delete ipts; return segCount; } /** * Returns true if the geometry intersects this geometry. * @param {DMCPoint} geometry A DMCPoint * @return true if the geometry intersects this geometry. * @type bool */ this.intersects = function( geometry){ //sanity check if (geometry==null) throw new DMCException("DMCPolygon.intersects can not take a null parameter"); //point with point intersection if (geometry.TYPE=="POINT"){ //check if passed point is contained within this polygon return this.contains(geometry); } else if (geometry.TYPE=="BOUNDS"){ //If someone asks for intersection of a rectangle with //this polygon, we will do rectangle to MBR intersection var mbr = this.getBounds(); return geometry.intersects(mbr); } throw new DMCException("Only Point in polygon is supported"); }//intersects /** * Returns true if the point is contained in the geometry * @param {DMCPoint} p A DMCPoint * @return true if the point is contained in the geometry * @type bool */ //based on http://www.faqs.org/faqs/graphics/algorithms-faq/ Section 2.03. this.contains=function(/*DMCPoint*/ p){ //the points on the edge will be considered in the polygon if (p==null) throw new DMCException("DMCPolygon.intersects can not take a null parameter"); if (p.TYPE!="POINT") throw new DMCException("DMCPolygon.intersects expects only point geometry"); var cn=0; var i=0; var npol=this.points.length; var j=npol-1; for(i,j;i xNext ) ret = true; else ret = false; return ret; } }//End class DMCPolygon DMCPolygon.prototype = new DMCPoly(); //extend from DMCPoly //************************************************* /** * Constructs a DMCCircle * @class DMCCircle is a class that represents a circle * @constructor * @param pointArray -- two handle points : center & boundary. * @param dmcMap -- DMCVEMap object, used mainly for coordinate conversion. * @author: JPeng * */ function DMCCircle( /*DMCPoint[]*/pointArray, /*DMCVEMap*/ dmcMap ) { /** * Geometry type of the object ("CIRCLE") * @type string */ this.TYPE="CIRCLE"; this.dmcMap = dmcMap; this.points = new Array(); this.points[0] = new DMCPoint( pointArray[0].getX(), pointArray[0].getY(), true ); this.points[1] = new DMCPoint( pointArray[1].getX(), pointArray[1].getY(), true ); /** * Returns the vertext count * @return the vertext count * @type int */ this.getVertexCount = function() { return this.points.length; } /** * Returns the vertex at the specified index * @param {int} index Index of vertex * @return the vertex * @type DMCPoint */ this.getVertex = function(/*int*/ index) { return this.points[index]; } /** * @ignore */ // Deprecated // JPeng 12/03/2007 : polygon generation can be simplified by only generate the range of // (0, PI/4), and extrapolate the other ranges by simple coordinate manipulation // have not done so for now. this.calculatePolygon = function() { // Note: the number of points to return is temporarily hardcoded. Change this later. if( this.points == null || this.points.length < 1 ) return null; var southHemi = false; if( this.points[0].getLat() < 0 ) southHemi = true; //calculate the zone var zone=Math.floor((this.points[0].getX()+180)/6)+1; var boundPoints = new Array(); var tempPoints = null; if( this.dmcMap != null ) { tempPoints = new Array(); tempPoints[0] = new DMCPoint( this.points[0].getX(), this.points[0].getY(), true ); tempPoints[1] = new DMCPoint( this.points[1].getX(), this.points[1].getY(), true ); for( var i = 0; i < 2; i++ ) { var xy=new Array(); LatLonToUTMXY(DegToRad(tempPoints[i].getY()), DegToRad(tempPoints[i].getX()), zone, xy); tempPoints[i].setX(xy[0]); tempPoints[i].setY(xy[1]); } } else tempPoints = this.points; var numPts = 100; var dTheta = (Math.PI*2.0)/numPts; var boundPoints = new Array(numPts+1); var dx = tempPoints[1].x - tempPoints[0].x; var dy = tempPoints[1].y - tempPoints[0].y; var radius = Math.sqrt(dx*dx + dy*dy); var center = tempPoints[0]; var sinVal = ( tempPoints[1].getY() - tempPoints[0].getY() ) / radius; var cosVal = ( tempPoints[1].getX() - tempPoints[0].getX() ) / radius; boundPoints[0] = new DMCPoint( radius, 0, true ); boundPoints[numPts] = new DMCPoint( radius, 0, true ); var curTheta = 0; for( var i = 1; i < numPts; i ++ ) { curTheta += dTheta; var x = radius * Math.cos(curTheta); var y = radius * Math.sin(curTheta); boundPoints[i] = new DMCPoint( x, y, true ); } for( var i = 0; i <= numPts; i ++ ) { var x = boundPoints[i].getX()*cosVal - boundPoints[i].getY()*sinVal; var y = boundPoints[i].getY()*cosVal + boundPoints[i].getX()*sinVal; boundPoints[i].setX(center.x + x); boundPoints[i].setY(center.y + y); } if( this.dmcMap != null ) { // Convert boundPoints to LatLng coordinates for( var i = 0; i <= numPts; i++ ) { var latlon = new Array(); UTMXYToLatLon( boundPoints[i].getX(), boundPoints[i].getY(), zone, southHemi, latlon); boundPoints[i].setX( RadToDeg(latlon[1]) ); boundPoints[i].setY( RadToDeg(latlon[0]) ); } } var polygon = new DMCPolygon(boundPoints); return polygon; } this.polygon = this.calculatePolygon(); /** * Returns the center of the circle * @return {DMCPoint} the center point */ this.getCenter = function() { return new DMCPoint(this.points[0].getX(), this.points[0].getY(), true); } /** * Returns true if the geometry intersects this geometry. * @param {DMCPoint} geometry A DMCPoint * @return true if the geometry intersects this geometry. * @type bool */ this.intersects = function( geometry){ //sanity check if (geometry==null) throw new DMCException("DMCCircle.intersects can not take a null parameter"); //point with point intersection if (geometry.TYPE=="POINT"){ //check if passed point is contained within this circle return this.contains(geometry); } else if (geometry.TYPE=="BOUNDS"){ //If someone asks for intersection of a rectangle with //this circle, we will do rectangle to MBR intersection var mbr = this.getBounds(); return geometry.intersects(mbr); } throw new DMCException("Only Point in circle is supported"); }//intersects /** * Returns true if the point is contained in the geometry * @param {DMCPoint} p A DMCPoint * @return true if the point is contained in the geometry * @type bool */ // JPeng 11/16/2007 : p is in LatLng coordinate this.contains=function(/*DMCPoint*/ p){ if (p==null) throw new DMCException("DMCCircle.intersects can not take a null parameter"); if (p.TYPE!="POINT") throw new DMCException("DMCPolygon.intersects expects only point geometry"); if( this.points == null || this.points.length < 1 ) return false; // First, convert p and this.points to pixel coordinates var tempPoints = null; var ip = p; if( this.dmcMap != null ) { tempPoints = new Array(); tempPoints[0] = new DMCPoint( this.points[0].getX(), this.points[0].getY(), true ); tempPoints[1] = new DMCPoint( this.points[1].getX(), this.points[1].getY(), true ); tempPoints[2] = new DMCPoint( p.getX(), p.getY(), true ); for( var i = 0; i < 3; i++ ) { var zone=Math.floor((tempPoints[i].getX()+180)/6)+1; var xy=new Array(); LatLonToUTMXY(DegToRad(tempPoints[i].getY()), DegToRad(tempPoints[i].getX()), zone, xy); tempPoints[i].setX(xy[0]); tempPoints[i].setY(xy[1]); } ip = tempPoints[2]; } else tempPoints = this.points; var dx = tempPoints[1].getX() - tempPoints[0].getX(); var dy = tempPoints[1].getY() - tempPoints[0].getY(); var sqRadius = dx*dx + dy*dy; var dxp = ip.getX() - tempPoints[0].getX(); var dyp = ip.getY() - tempPoints[0].getY(); var sqDis = dxp*dxp + dyp*dyp; if( sqDis <= sqRadius ) return true; else return false; } /** * Returns all the points. * @return all the points. * @type DMCPoint[] */ this.getPoints = function() { return this.points; } this.clearBoundPoly = function() { this.polygon = null; } this.getBoundPoly = function() { if( this.polygon == null ) this.polygon = this.calculatePolygon(); return this.polygon; } // JPeng 11/19/2007: get bounds in LatLon /** * Returns a DMCBounds that contains the circle * @return a DMCBounds that contains the circle * @type DMCBounds */ this.getBounds = function(){ if( this.points == null || this.points.length != 2 ) { throw new DMCException("DMCCircle: do not get bounds of an empty circle!"); } var southHemi = false; if( this.points[0].getLat() < 0 ) southHemi = true; var zone=Math.floor((this.points[0].getX()+180)/6)+1; var tempPoints = null; if( this.dmcMap != null ) { tempPoints = new Array(); tempPoints[0] = new DMCPoint( this.points[0].getX(), this.points[0].getY(), true ); tempPoints[1] = new DMCPoint( this.points[1].getX(), this.points[1].getY(), true ); for( var i = 0; i < 2; i++ ) { var xy=new Array(); LatLonToUTMXY(DegToRad(tempPoints[i].getY()), DegToRad(tempPoints[i].getX()), zone, xy); tempPoints[i].setX(xy[0]); tempPoints[i].setY(xy[1]); } } else tempPoints = this.points; var dx = tempPoints[1].x - tempPoints[0].x; var dy = tempPoints[1].y - tempPoints[0].y; var radius = Math.sqrt(dx*dx + dy*dy); var fourPoints = new Array(); fourPoints[0] = new DMCPoint( tempPoints[0].x + radius, tempPoints[0].y, true ); fourPoints[1] = new DMCPoint( tempPoints[0].x, tempPoints[0].y + radius, true ); fourPoints[2] = new DMCPoint( tempPoints[0].x - radius, tempPoints[0].y, true ); fourPoints[3] = new DMCPoint( tempPoints[0].x, tempPoints[0].y - radius, true ); if( this.dmcMap != null ) { for( var i = 0; i < 4; i++ ) { var latlon = new Array(); UTMXYToLatLon( fourPoints[i].getX(), fourPoints[i].getY(), zone, southHemi, latlon); fourPoints[i].setX( RadToDeg(latlon[1]) ); fourPoints[i].setY( RadToDeg(latlon[0]) ); } } var bounds = new DMCBounds(fourPoints); return bounds; } // JPeng 12/04/2007: get bounds in pixel /** * Returns a DMCBounds in pixel coordinates that contains the circle * @return a DMCBounds that contains the circle * @type DMCBounds */ this.getBoundsInPixel = function(){ if( this.points == null || this.points.length != 2 ) { throw new DMCException("DMCCircle: do not get bounds of an empty circle!"); } var southHemi = false; if( this.points[0].getLat() < 0 ) southHemi = true; var zone=Math.floor((this.points[0].getX()+180)/6)+1; var tempPoints = null; if( this.dmcMap != null ) { tempPoints = new Array(); tempPoints[0] = new DMCPoint( this.points[0].getX(), this.points[0].getY(), true ); tempPoints[1] = new DMCPoint( this.points[1].getX(), this.points[1].getY(), true ); for( var i = 0; i < 2; i++ ) { var xy=new Array(); LatLonToUTMXY(DegToRad(tempPoints[i].getY()), DegToRad(tempPoints[i].getX()), zone, xy); tempPoints[i].setX(xy[0]); tempPoints[i].setY(xy[1]); } } else tempPoints = this.points; var dx = tempPoints[1].x - tempPoints[0].x; var dy = tempPoints[1].y - tempPoints[0].y; var radius = Math.sqrt(dx*dx + dy*dy); var fourPoints = new Array(); fourPoints[0] = new DMCPoint( tempPoints[0].x + radius, tempPoints[0].y, true ); fourPoints[1] = new DMCPoint( tempPoints[0].x, tempPoints[0].y + radius, true ); fourPoints[2] = new DMCPoint( tempPoints[0].x - radius, tempPoints[0].y, true ); fourPoints[3] = new DMCPoint( tempPoints[0].x, tempPoints[0].y - radius, true ); if( this.dmcMap != null ) { for( var i = 0; i < 4; i++ ) { var latlon = new Array(); UTMXYToLatLon( fourPoints[i].getX(), fourPoints[i].getY(), zone, southHemi, latlon); fourPoints[i].setX( RadToDeg(latlon[1]) ); fourPoints[i].setY( RadToDeg(latlon[0]) ); } this.dmcMap.latLngPointsToPixelPoints( fourPoints ); } var bounds = new DMCBounds(fourPoints); return bounds; } // JPeng 11/21/2007 in UTM this.getArea=function(){ //return area unit as squre meter if( this.points == null || this.points.length != 2 ) return 0; var pointArray = this.points; var len=pointArray.length; var newPointArray=new Array(); var xy=new Array(); var area=0; //calculate the zone var zone=Math.floor((pointArray[0].getX()+180)/6)+1; for(var i=0;i * 1. POINT(1 1)
* 2. LINESTRING(1 1, 2 2, 3 3, 4 4);
* 3. POLYGON((1 1, 2 2, 3 3, 4 4,5 5)); // single ring polygon * @type WKT * JPeng 11/09/2007 : also support circle * 4. CIRCLE((1 1, 2 2)); // Center and one point on boundary */ ///////////////////// parsers /////////////////////////// /** * @ignore */ function WKT(wktString) { try { // parses out points var regex = new RegExp(/(?:\()([^)(]*)(?:\))/g); var matches = regex.exec(wktString); var points = null; if(matches != null && matches.length > 0) { points = matches[0].substring(1, matches[0].length - 1); } // parses out type; regex = new RegExp(/[^(]*/g); var m1 = regex.exec(wktString); var geoType = null; if(m1 != null && m1.length > 0) { geoType = m1[0].replace(/ /, ''); } if(points == null || points == '' || geoType== null || geoType == '') return null; var pointsArray1D = __parseWKTPointsString(points); if(geoType=="POINT") { if(pointsArray1D.length!=2) throw null; return new DMCPoint(pointsArray1D[0], pointsArray1D[1]); } else if(geoType=="LINESTRING") { if(pointsArray1D.length<4) throw null; return new DMCLineString(_pointArray1DtoPointArray(pointsArray1D)); } else if(geoType=="POLYGON" || geoType=="MULTIPOLYGON") { if(pointsArray1D.length<4) throw null; return new DMCPolygon(_pointArray1DtoPointArray(pointsArray1D)); } else if( geoType=="CIRCLE" ) { if(pointsArray1D.length<2) throw null; return new DMCCircle(_pointArray1DtoPointArray(pointsArray1D)); } else { return null; } } catch(e) { return null; } } /** * @ignore **/ // input: a string like "1 1, 2 2, 3 3, 4 4,5 5" // output: a String[] like [1 1 2 2 3 3 4 4 5 5] - it always has even number of elements in it. // throw exception if the string is mal-formatted. function __parseWKTPointsString( wktPointString ) { var pointTokens = wktPointString.split(","); var retArray = []; for(var i=0;i= -tol ) && ( a <= E + tol ) && ( sqb < tol*tol ) ) return true; else return false; } } /** * Converts a DMCGeometry into a Google Geometry. * @param {string} id ID to give the geometry * @param {DMCGeometry} dmGeometry A DMCGeometry type * @return the VE geometry * @type VEGeometry */ function DMCtoGoogGeometry( dmGeometry, color, weight, opacity, fillColor, fillOpacity ) { if(!dmGeometry.TYPE) throw new DMCException("DMCtoGoogGeometry: input is not a DMC javascript geometry"); try { var points = dmGeometry.getPoints(); var googPoints = []; for(var i=0;i=0) { //return new VEPolyline(id, vePoints); return new GPolyline(googPoints, color, weight, opacity); } } catch(e) { // continute to throw error at the end. } throw new DMCException("DMCtoGoogGeometry: input is an not a DMC javascript geometry ("+dmGeometry.TYPE+")"); }//DMCtoGoogGeometry /* * ---------------------------------------------------------- There is a bug in * FireFox2.0 that throws an exception in loadMap() method. Marc Sutton created * a fix that enables Firefox 2 to work with Virtual Earth with all the same * features as Firefox 1.5 (polylines, pushpins etc). * * Source : * http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=852512&SiteID=1#857241 * ---------------------------------------------------------- */ function FixForFirefox2(){ // If the browser is Firefox get the version number var ffv = 0; var ffn = "Firefox/" var ffp = navigator.userAgent.indexOf(ffn); if (ffp != -1) ffv = parseFloat(navigator.userAgent.substring(ffp + ffn.length)); // If we're using Firefox 1.5 or above override the Virtual Earth drawing // functions to use SVG if (ffv >= 1.5) { Msn.Drawing.Graphic.CreateGraphic=function(f,b) { return new Msn.Drawing.SVGGraphic(f,b) } } // --- END Marc Sutton's FIX for firefox2.0 } // key for requests function SetDMPKey(val) { _DMP_KEY = val; } // constants var _G_COUNTER = 0; var _DMP_KEY = "user"; var _OUTPUT_TYPE = "PNG"; // PNG var _G_DMP_SERVER_NAME = "http://parcelstream.com"; var G_NUM_SERVERS = 4; var _G_MULTIDOMAIN_SERVER_NAME = new Array(); // Added string array to hold the different piece for each server, //so it can check against each to determine whether or not to perform browser specific operations : MW 7/16/07 for(var i = 0; i < G_NUM_SERVERS; i++) { _G_MULTIDOMAIN_SERVER_NAME[i] = "t" + i; } // Removed the hard coded _G_DMP_SERVER_NAME at the end so that I can check against each server if there are multiple : MW 7/16/07 var _gExpectedFilter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"; function _gOverrideAppendChildIE7(p1, p2, p3, p4){ // handle the case where we don't want to override the functionality if (p1.tagName!="IMG"){ return this._dmcAppendChild(p1, p2, p3, p4); } if (p1.src.indexOf(_G_DMP_SERVER_NAME)<0 && !containsDomainName(p1.src)){ return this._dmcAppendChild(p1, p2, p3, p4); } var cls = p1.style.filter; if (cls==null || cls==""){ return this._dmcAppendChild(p1, p2, p3, p4); } // make sure cls is a string object cls += ""; var removeFilter = "alpha(opacity=100);" if (cls.indexOf(removeFilter)>=0){ // debugger; // finally found our tiles // not get rid of the filter thingies and use proper background URL. // for PNG's to work, I have to remove the removeFilter from the // filte style // Feb 06 2007 p1.style.filter = ''; }// is cls contains filter return this._dmcAppendChild(p1, p2, p3, p4); }// end global function _gOverrideAppendChildIE7 function _gOverrideAppendChildIE6(p1, p2, p3, p4){ if (p1.tagName=="DIV" && p1.innerHTML==""){ var cls = p1.style.filter; if (cls!=null){ cls += ""; if (cls!=""){ if (cls.indexOf(_gExpectedFilter + _G_DMP_SERVER_NAME)>=0 || containsDomainName(cls, _gExpectedFilter, _gExpectedFilter.length)){ // finally found our tiles // not get rid of the filter thingies and use proper // background URL. var urlStart = cls.indexOf ("http://"); var urlEnd = cls.indexOf ("',", urlStart); var url = cls.substring(urlStart, urlEnd); var isOutputPng = false; if(url != null && url.toLowerCase().indexOf("png") > -1) isOutputPng = true; if (isOutputPng){ // for PNG's to work, I have to remove the // alpha(opacity=100); from the filte style // Oct 17 2006 var replaceStr = ", alpha(opacity=100)"; var orgFilter = ""+p1.style.filter; var arr = orgFilter.split(replaceStr); if (arr.length==2){ p1.style.filter = arr[0]+arr[1]; } }else{ // just create friggin IMG obj var img = document.createElement("IMG"); img.src=url; img.style.left = p1.style.left; img.style.top = p1.style.top; img.style.width = p1.style.width; img.style.height = p1.style.height; img.style.border = p1.style.border; img.style.zIndex = p1.style.zIndex; img.style.position = p1.style.position; // now reset the IMG as a p1 p1 = img; // p1.style.filter = ""; // p1.style.background = "transparent url("+url+") // no-repeat scroll"; } } } } } this._dmcAppendChild(p1, p2, p3, p4); }//_gOverrideAppendChildIE6 var _b_dmc_hasInitCalled = false; function gInitializeDMPLayers(map){ if (_b_dmc_hasInitCalled) return; _b_dmc_hasInitCalled = true; // we need to do this only for IE. Mozilla takes care of itself if (document.all){ var mapdiv = document.getElementById(map.ID).firstChild; if (mapdiv==null){ alert("Error in DMP API. Please contact Digital Map Products Inc. Support."); return; } mapdiv._dmcAppendChild = mapdiv.appendChild; // IE7 is a different animal. // Microsoft rewrote their PNG engine but not quite correctly // They allow direct IMG tag to display PNG's but adding any kind // of FILTER style will create slight black streaks at the edges // I will remove FILTER: alpha(opacity=100); from the style for // IE7.0 if (navigator.userAgent.indexOf("MSIE 7.0")>=0){ mapdiv.appendChild = _gOverrideAppendChildIE7; }else{ mapdiv.appendChild = _gOverrideAppendChildIE6; } } }//gInitializeDMPLayers function SetParcelLayerVisibility(vemap, checked) { if (vemap==null){ alert("Please pass Virtual Earth map instance as a parameter to the ToggleDMPParcelLayer() function. "); return; } var tileLayer = vemap.parcelLayer; if (tileLayer){ tileLayer.setVisible(checked); } } function AddDMPParcelLayer(vemap, zindex){ if (vemap==null){ alert("Please pass Virtual Earth map instance as a parameter to the AddDMPParcelLayer() function. "); return; } else if (typeof(vemap.parcelLayer) != 'undefined'){ alert("This map already has a parcel layer defined in it. "); return; } gInitializeDMPLayers(vemap); var tileLayer = new TiledLayer(vemap, ["Parcels"]); tileLayer.setMinZoomLevel(16); tileLayer.setMaxZoomLevel(19); tileLayer.setFormat("image/png"); if(zindex){ tileLayer.setZIndex(zindex); } tileLayer.initialize(); vemap.parcelLayer = tileLayer; } //This function checks to see if the containingString contains any of the server names, appended to the appendString at the specified appendIndex //It is used to determine if browser specific fixes should be implemented : MW 7/16/07 function containsDomainName(containingString, appendString, appendIndex) { var searchString, serverName; //If appendString isn't passed, make it nothing if(appendString == null) { appendString = ""; appendIndex = 0; } //If the index is invalid, append to the beginning of the string else if(appendIndex == null || appendIndex < 0) appendIndex = 0; for(var i = 0; i < G_NUM_SERVERS; i++) { //Construct the server name by adding the unique pieces right after "http://" and add it to the appendString at the appropriate location serverName = _G_DMP_SERVER_NAME.substr(0,7) + _G_MULTIDOMAIN_SERVER_NAME[i] + "." + _G_DMP_SERVER_NAME.substr(7); if(appendIndex < appendString.length) searchString = appendString.substr(0, appendIndex) + serverName + appendString.substr(appendIndex); else searchString = appendString + serverName; //If the containingString has it, then we're good if(containingString.toLowerCase().indexOf(searchString.toLowerCase()) != -1) return true; } return false; } /** *@ignore */ function GoogleTiledLayer(gmap, layers,/*string optional*/ serverPath){ //if (!serverPath) serverPath = "http://bddev.digitalmapcentral.com/Neptune/GifGenerator/geocsTeleAtlasCurrent/-119_32?mapFilePath=geocsTeleAtlasCurrent.map&layerString=38%20Con%20Cou%20St1%20St2%20W%20Cnty%20St3%20St4%20mja%20Urbb%20Urbf%20Hbh%20Hfh%20Hbm%20Hfm%20Hl%20C100%20C100b%20C125%20C25%20C1m%20Cap%20Cap2%20CapL%20CapL2%20HwyLbl%20StL1%20StL2%20CntyLbl%20C%20CL%20C100L%20C125L%20C25L%20C1mL%20Ocn%20Wl%20C100Lb&utmZone=GEOCS"; var _G_DMP_MDE_SERVER_NAME = "http://t%2.parcelstream.com/"; if (!serverPath) { serverPath = _G_DMP_MDE_SERVER_NAME + "VEParcelTileServer.aspx"; } var _map = gmap; var _overlay = null; var _layerVisible = true; var _layers =layers; var _minZoomLevel = 17; var _maxZoomLevel = 19; var _opacity = 1; var _copyrights = new GCopyrightCollection(); var _hasInitialized = false; var _sldUrl = null; var _sldBody = null; var _requestProperties = []; var _format = "image/png"; var _name = "Layer" + new Date().getTime() + "_"+ (_G_COUNTER++); /** *@ignore */ this.setFormat = function(val) { _format = val; if(_hasInitialized) { if(_map != null) { deleteTileLayer(); addTileLayer(); } } } /** *@ignore */ this.getFormat = function() { return _format; } /** *@ignore */ this.addCopyright = function(copyright) { _copyrights.addCopyright(copyright); } /** *@ignore */ this.getCopyrights = function(bounds, zoom) { return _copyrights.getCopyrights(bounds, zoom); } /** *@ignore */ this.getProperty = function(name) { return _requestProperties[name]; } /** *@ignore */ this.setProperty = function(name, value) { if(name != null && name != '') _requestProperties[name] = value; } /** *@ignore */ this.getVisible = function(){ return _layerVisible; } /** *@ignore */ this.setMinZoomLevel = function(val) { _minZoomLevel = val; } /** *@ignore */ this.setMaxZoomLevel = function(val) { _maxZoomLevel = val; } /** *@ignore */ this.getMinZoomLevel = function() { return _minZoomLevel; } /** *@ignore */ this.getMaxZoomLevel = function() { return _maxZoomLevel; } /** *@ignore */ this.setOpacity = function(val) { if(val != null && val >=0 && val <= 1) _opacity = val; if(_hasInitialized) { if(_map != null) { deleteTileLayer(); addTileLayer(); } } } /** *@ignore */ this.getOpacity = function() { return _opacity; } /** *@ignore */ this.setStyleLayerDescriptorUrl = function(val) { _sldUrl = val; } /** *@ignore */ this.getStyleLayerDescriptorUrl = function() { return _sldUrl; } /** *@ignore */ this.setStyleLayerDescriptorText = function(val) { _sldBody = val; } /** *@ignore */ this.getStyleLayerDescriptorText = function() { return _sldBody; } /** *@ignore */ this.setVisible = function(bool) { try { _layerVisible = bool; if(_layerVisible) { deleteTileLayer(); addTileLayer(); } else { _overlay.hide(); } } catch(e) { } }//setVisible /** *@ignore */ this.initialize = function() { //Add a MDE layer by default if(_hasInitialized) return; addTileLayer(); _hasInitialized = true; } function addTileLayer() { var tilelayer = new GTileLayer(_copyrights, _minZoomLevel, _maxZoomLevel); tilelayer.getTileUrl = GetDMCTileURL; //make sure the layer type is defined as PNG tilelayer.isPng = function(){ if(_format == "image/png") return true; else return false; } tilelayer.getOpacity = function() {return _opacity;} _overlay = new GTileLayerOverlay(tilelayer); _map.addOverlay(_overlay); } function deleteTileLayer() { if(_map != null) { _map.removeOverlay(_overlay); } } function GetDMCTileURL(tile, zoom) { if(!_layerVisible || zoom < _minZoomLevel || zoom > _maxZoomLevel) return ""; var path = serverPath.replace("%2", "" + Math.floor(Math.random() * G_NUM_SERVERS)); var tileServerPath2 = path + "?tileid=" + TileXYToQuadKey(tile.x, tile.y, zoom); if(_layers != null && _layers != '' && _layers.length > 0) tileServerPath2 += "&layers=" + encodeString(_layers.join(","));//encodeURIComponent(_layers.join(",")); if(_sldUrl != null) tileServerPath2 += "&SLD="+ encodeString(_sldUrl);//encodeURIComponent(_sldUrl); if(_format != null) tileServerPath2 += "&format="+encodeURIComponent(_format); if(_sldBody != null){ tileServerPath2 += "&SLD_BODY="+ encodeString(_sldBody); } tileServerPath2 +="&IsEncoded=true&SRS=EPSG:4326&REQUEST=MAP"; for(var key in _requestProperties) { var value = _requestProperties[key]; if(value != null && value != '') { if (typeof(value) !== "undefined" && typeof(value) !== "function") { tileServerPath2 += ("&" + key + "=" + encodeURIComponent(value)); } } } //add OverrideMapStyles 1 //tileServerPath2 += "&OverrideMapStyle=" + encodeString("1"); return tileServerPath2; } function TileXYToQuadKey(tileX, tileY, levelOfDetail){ var quadKey = ''; for (var i = levelOfDetail; i > 0; i--) { var digit = '0'; var mask = 1 << (i - 1); if ((tileX & mask) != 0) { digit++; } if ((tileY & mask) != 0) { digit++; digit++; } quadKey += digit; }//for i return quadKey; }//TileXYToQuadKey function encodeString(s) { return encodeURIComponent(s).replace(/%/g, "._-"); } } /** *@ignore */ function GoogleWMSLayer(gmap,/*Array optional*/ layers, /*string optional*/ serverPath){ var _serverPath = serverPath; if (!_serverPath) { _serverPath = _G_DMP_SERVER_NAME + "/VEParcelTileServer.aspx"; } var _map = gmap; var _overlay = null; var _layerVisible = true; var _layers =layers; var _minZoomLevel = 17; var _maxZoomLevel = 19; var _hasInitialized = false; var _sldUrl = null; var _sldBody = null; var _requestProperties = []; var _format = "image/png"; var _name = "Layer" + new Date().getTime() + "_"+ (_G_COUNTER++); /** *@ignore */ this.setFormat = function(val) { _format = val; } /** *@ignore */ this.getFormat = function() { return _format; } /** *@ignore */ this.getProperty = function(name) { return _requestProperties[name]; } /** *@ignore */ this.setProperty = function(name, value) { if(name != null && name != '') _requestProperties[name] = value; if(_hasInitialized) this.onviewchange(); } /** *@ignore */ this.setStyleLayerDescriptorUrl = function(val) { _sldUrl = val; if(_hasInitialized) this.onviewchange(); } /** *@ignore */ this.getStyleLayerDescriptorUrl = function() { return _sldUrl; } /** *@ignore */ this.setStyleLayerDescriptorText = function(val) { _sldBody = val; if(_hasInitialized) this.onviewchange(); } /** *@ignore */ this.getStyleLayerDescriptorText = function() { return _sldBody; } /** *@ignore */ this.getVisible = function(){ return _layerVisible; } /** *@ignore */ this.setMinZoomLevel = function(val) { _minZoomLevel = val; if(_hasInitialized) this.onviewchange(); } /** *@ignore */ this.setMaxZoomLevel = function(val) { _maxZoomLevel = val; if(_hasInitialized) this.onviewchange(); } /** *@ignore */ this.getMinZoomLevel = function() { return _minZoomLevel; } /** *@ignore */ this.getMaxZoomLevel = function() { return _maxZoomLevel; } /** *@ignore */ this.setVisible = function(bool) { _layerVisible = bool; try { if (_layerVisible) this.onviewchange(); else _overlay.hide(); } catch(e) { } }//setVisible /** *@ignore */ this.onviewchange = function(e){ if(_overlay) _map.removeOverlay(_overlay); if(!_this.getVisible()) return; // check for zoom levels var currentZoomLevel = _map.getZoom(); if(_minZoomLevel > currentZoomLevel || _maxZoomLevel < currentZoomLevel) return; var mapBounds = _map.getBounds(); var mapSize = _map.getSize(); var sw = mapBounds.getSouthWest(); var ne = mapBounds.getNorthEast(); var bbox = "?bbox=" + sw.lng() + "," + sw.lat() + "," + ne.lng() + "," + ne.lat(); var url = ""; url += _serverPath + bbox; //url += "?map=" +_mapFile var encodeFunction = encodeURIComponent; if((version >= 5.5) && (version < 7) && (document.body.filters) && (typeof(serverPath) == 'undefined' || serverPath == null) && _format != null && _format.toLowerCase().indexOf("png") > -1) { encodeFunction = encodeString; url += "&IsEncoded=true"; } url += "&width=" + mapSize.width; url += "&height=" + mapSize.height; if(_layers != null && _layers != '' && _layers.length > 0) url += "&layers=" + encodeFunction(_layers.join(",")); //url += encodeURIComponent("&layers=" + _layers.join(",")); if(_sldUrl != null) url += "&SLD="+encodeFunction(_sldUrl); if(_format != null) url += "&format="+encodeFunction(_format); if(_sldBody != null) url += "&SLD_BODY="+encodeFunction(_sldBody); url +="&SRS=EPSG:4326&REQUEST=MAP"; for(var key in _requestProperties) { var value = _requestProperties[key]; if(value != null && value != '') { if (typeof(value) !== "undefined" && typeof(value) !== "function") { url += ("&" + key + "=" + encodeFunction(value)); } } } //add OverrideMapStyles 0 //url += "&OverrideMapStyle="+encodeFunction("0"); _overlay = new GGroundOverlay(url, mapBounds); _map.addOverlay(_overlay); }//onViewChange var arVersion = navigator.appVersion.split("MSIE"); var version = parseFloat(arVersion[1]); var _this = this; /** *@ignore */ this.initialize = function() { //Add a MDE layer by default if(_hasInitialized) return; GEvent.bind(_map, "moveend", _this, _this.onviewchange); _this.onviewchange(); _hasInitialized = true; } function encodeString(s) { return encodeURIComponent(s).replace(/%/g, "._-"); } }//GoogleWMSLayer /** * Creates a new TiledLayer instance based on a map and an Array of layer names. The map type can be VE or Google Maps. * @class TiledLayer represents a Tiled layer on top of a map. * @constructor * @param {map} map Virtual Earth or Google Maps map object * @param {string[]} layers Names of layers to enable on tile layer * @param {string} serverPath The optional server path. */ function TiledLayer(map, layers, /*string optional*/ serverPath) { var _layerObj = null; if(typeof(GMap2) != "undefined" && map instanceof GMap2) { _layerObj = new GoogleTiledLayer(map, layers, serverPath); /** *Adds a copyright to the collection (Google only). *@param {GCopyright} copyright The copyright to add. *@type void */ this.addCopyright = function(copyright) { _layerObj.addCopyright(copyright); } /** *Gets all copyrights that apply for the given bounds and zoom (Google only). *@param {GLatLngBounds} bounds The geographic boundary to which the copyrights apply *@param {int} zoom The zoom level to which the copyrights apply *@return An array of copyright strings which apply to the given map region. *@type string[] */ this.getCopyrights = function(bounds, zoom) { return _layerObj.getCopyrights(bounds, zoom); } } else if(typeof(VEMap) != "undefined" && map instanceof VEMap) { _layerObj = new VETiledLayer(map, layers, serverPath); /** * Sets the ZIndex (VE Only). This will determine the rendering order of the layer. * @param {int} val The ZIndex of the layer * @type void */ this.setZIndex = function(val) { _layerObj.setZIndex(val); } /** * Gets the Zindex (VE Only). * @return The ZIndex of the layer. * @type int */ this.getZIndex = function() { return _layerObj.getZIndex(); } } else { return null; } /** * Sets the format type for the image layer. * ex. ("image/gif", "image/jpeg", "image/png") * @param {int} val The format of the layer. * @type void */ this.setFormat = function(val) { _layerObj.setFormat(val); } /** * Gets the format type. * @return The format type of the layer. * @type string */ this.getFormat = function() { return _layerObj.getFormat(); } /** * Sets the value of a property. This property will be appended to each tile request. * @param {string} name Name of the property * @param {string} value Value of the property * @type void */ this.setProperty = function(name, value) { _layerObj.setProperty(name, value); } /** * Returns the value associated with the property name. * @param {string} name Name of the property * @type string * @return The property value. If the property does not exists null is returned. */ this.getProperty = function(name) { return _layerObj.getProperty(name); } /** * Sets the visibility of the layer * @param {bool} bool The visibility * @type void */ this.setVisible = function(bool) { _layerObj.setVisible(bool); } /** * Returns true if the layer is visible and false otherwise. * @type bool */ this.getVisible = function() { return _layerObj.getVisible(); } /** * Sets the minimum zoom level. * @param {int} val The zoom level. * @type void */ this.setMinZoomLevel = function(val) { _layerObj.setMinZoomLevel(val); } /** * Returns the minimum zoom level. * @type int */ this.getMinZoomLevel = function() { return _layerObj.getMinZoomLevel(); } /** * Sets the maximum zoom level. * @param {int} val The zoom level. * @type void */ this.setMaxZoomLevel = function(val) { _layerObj.setMaxZoomLevel(val); } /** * Returns the maximum zoom level. * @type int */ this.getMaxZoomLevel = function() { return _layerObj.getMaxZoomLevel(); } /** * Sets the opacity. Valid range [0 - 1] * @param {float} val The opacity level. * @type void */ this.setOpacity = function(val) { _layerObj.setOpacity(val); } /** * Returns the opacity of the layer * @type float */ this.getOpacity = function() { return _layerObj.getOpacity(); } /** * Sets the SLD url. This SLD url will be passed in the tile request string. * @param {string} val Url to sld file. * @type void */ this.setStyleLayerDescriptorUrl = function(val) { _layerObj.setStyleLayerDescriptorUrl(val); } /** * Returns the SLD url. * @type string */ this.getStyleLayerDescriptorUrl = function() { return _layerObj.getStyleLayerDescriptorUrl(); } /** * Sets the SLD text. This SLD text will be passed in the tile request string. * @param {string} val Text of sld file. * @type void */ this.setStyleLayerDescriptorText = function(val) { _layerObj.setStyleLayerDescriptorText(val); } /** * Returns the SLD text. * @type string */ this.getStyleLayerDescriptorText = function() { return _layerObj.getStyleLayerDescriptorText(); } /** * Initializes the layer. Must be called before the layer renders. * @type void */ this.initialize = function() { _layerObj.initialize(); } /** * Forces the Layer to redraw. * @type void */ this.draw = function() { }//draw } /** *@ignore */ function VETiledLayer(vemap, layers,/*string optional*/ serverPath){ gInitializeDMPLayers(vemap); //if (!serverPath) serverPath = "http://bddev.digitalmapcentral.com/Neptune/GifGenerator/geocsTeleAtlasCurrent/-119_32?mapFilePath=geocsTeleAtlasCurrent.map&layerString=38%20Con%20Cou%20St1%20St2%20W%20Cnty%20St3%20St4%20mja%20Urbb%20Urbf%20Hbh%20Hfh%20Hbm%20Hfm%20Hl%20C100%20C100b%20C125%20C25%20C1m%20Cap%20Cap2%20CapL%20CapL2%20HwyLbl%20StL1%20StL2%20CntyLbl%20C%20CL%20C100L%20C125L%20C25L%20C1mL%20Ocn%20Wl%20C100Lb&utmZone=GEOCS"; var _G_DMP_MDE_SERVER_NAME = "http://t%2.parcelstream.com/"; if (!serverPath) { serverPath = _G_DMP_MDE_SERVER_NAME + "VEParcelTileServer.aspx"; } var _layerVisible = true; var _layers =layers; var _minZoomLevel = 17; var _maxZoomLevel = 19; var _opacity = 1; var _hasInitialized = false; var _zIndex = 100; var _sldUrl = null; var _sldBody = null; var _requestProperties = []; var _format = "image/png"; var _name = "Layer" + new Date().getTime() + "_"+ (_G_COUNTER++); /** *@ignore */ this.setFormat = function(val) { _format = val; } /** *@ignore */ this.getFormat = function() { return _format; } /** *@ignore */ this.setZIndex = function(val) { _zIndex = val; } /** *@ignore */ this.getZIndex = function() { return _zIndex; } /** *@ignore */ this.getProperty = function(name) { return _requestProperties[name]; } /** *@ignore */ this.setProperty = function(name, value) { if(name != null && name != '') _requestProperties[name] = value; } /** *@ignore */ this.getVisible = function(){ return _layerVisible; } /** *@ignore */ this.setMinZoomLevel = function(val) { _minZoomLevel = val; if(_hasInitialized) { if(vemap != null) { deleteTileLayer(); addTileLayer(); } } } /** *@ignore */ this.setMaxZoomLevel = function(val) { _maxZoomLevel = val; if(_hasInitialized) { if(vemap != null) { deleteTileLayer(); addTileLayer(); } } } /** *@ignore */ this.getMinZoomLevel = function() { return _minZoomLevel; } /** *@ignore */ this.getMaxZoomLevel = function() { return _maxZoomLevel; } /** *@ignore */ this.setOpacity = function(val) { if(val != null && val >=0 && val <= 1) _opacity = val; if(_hasInitialized) { if(vemap != null) { deleteTileLayer(); addTileLayer(); } } } /** *@ignore */ this.getOpacity = function() { return _opacity; } /** *@ignore */ this.setStyleLayerDescriptorUrl = function(val) { _sldUrl = val; if(_hasInitialized) { if(vemap != null) { deleteTileLayer(); addTileLayer(); } } } /** *@ignore */ this.getStyleLayerDescriptorUrl = function() { return _sldUrl; } /** *@ignore */ this.setStyleLayerDescriptorText = function(val) { _sldBody = val; if(_hasInitialized) { if(vemap != null) { deleteTileLayer(); addTileLayer(); } } } /** *@ignore */ this.getStyleLayerDescriptorText = function() { return _sldBody; } /** *@ignore */ this.setVisible = function(bool) { try { _layerVisible = bool; if(this.getVisible()) { if(isDefined(vemap.ShowTileLayer)) { vemap.ShowTileLayer(_name); } else if(isDefined(vemap.ShowLayer)) { deleteTileLayer(); addTileLayer(); } } else { if(isDefined(vemap.HideTileLayer)) { vemap.HideTileLayer(_name); } else if(isDefined(vemap.HideLayer)) { deleteTileLayer(); } } } catch(e) { } }//setVisible _this = this; /** *@ignore */ this.initialize = function() { //Add a MDE layer by default if(_hasInitialized) return; addTileLayer(); _hasInitialized = true; } function addTileLayer() { var tileServerPath = getTileServerPath(); var tileSource = new VETileSourceSpecification(_name, tileServerPath); /* * G_NUM_SERVERS - Set this parameter to 1 unless you also used the %2 place holder in your TileSource path. * This number represents the number of server paths you are using to host your tiles. * The servers must be named sequentially starting from 0 * (eg. TileServer0, TileServer1, TileServer2). */ tileSource.NumServers = G_NUM_SERVERS; tileSource.MinZoomLevel = _minZoomLevel; tileSource.MaxZoomLevel = _maxZoomLevel; tileSource.Opacity = _opacity; tileSource.ZIndex = _zIndex; // ve 5 if(isDefined(vemap.AddTileLayer)) { if(vemap != null) vemap.AddTileLayer(tileSource, true); } else if(isDefined(vemap.AddLayer)) { // below version 5 vemap.AddTileSource(tileSource); var tileLayer = new VELayerSpecification(VELayerType.VETileSource,_name, _name); tileLayer.ZIndex = _zIndex; tileLayer.Opacity=_opacity; vemap.AddLayer(tileLayer); } } function deleteTileLayer() { if(vemap != null) { try { if(isDefined(vemap.DeleteTileLayer)) { vemap.DeleteTileLayer(_name); }else if(isDefined(vemap.DeleteLayer) && isDefined(vemap.DeleteTileSource)) { vemap.DeleteLayer(_name); vemap.DeleteTileSource(_name); } }catch(ex) { } } } function isDefined(val) { return (typeof(val) != 'undefined' && val != null) } function getTileServerPath() { var tileServerPath2 = serverPath + "?tileid=%4"; if(_layers != null && _layers != '' && _layers.length > 0) tileServerPath2 += "&layers=" + encodeString(_layers.join(","));//encodeURIComponent(_layers.join(",")); if(_sldUrl != null) tileServerPath2 += "&SLD="+ encodeString(_sldUrl);//encodeURIComponent(_sldUrl); if(_format != null) tileServerPath2 += "&format="+encodeURIComponent(_format); if(_sldBody != null){ tileServerPath2 += "&SLD_BODY="+ encodeString(_sldBody); } tileServerPath2 +="&IsEncoded=true&SRS=EPSG:4326&REQUEST=MAP"; for(var key in _requestProperties) { var value = _requestProperties[key]; if(value != null && value != '') { if (typeof(value) !== "undefined" && typeof(value) !== "function") { tileServerPath2 += ("&" + key + "=" + encodeURIComponent(value)); } } } //add OverrideMapStyles 1 tileServerPath2 += "&OverrideMapStyle=" + encodeString("1"); return tileServerPath2; } function encodeString(s) { return encodeURIComponent(s).replace(/%/g, "._-"); } } /** *@ignore */ function VEWMSLayer(vemap,/*Array optional*/ layers, /*string optional*/ serverPath){ gInitializeDMPLayers(vemap); var _serverPath = serverPath; if (!_serverPath) { _serverPath = _G_DMP_SERVER_NAME + "/VEParcelTileServer.aspx"; } var _imgMDEObj = null; var _layerVisible = true; var _layers =layers; var _minZoomLevel = 17; var _maxZoomLevel = 19; var _opacity = 1; var _hasInitialized = false; var _sldUrl = null; var _sldBody = null; var _requestProperties = []; var _zIndex = 2; var _format = "image/png"; var _name = "Layer" + new Date().getTime() + "_"+ (_G_COUNTER++); /** *@ignore */ this.setFormat = function(val) { _format = val; } /** *@ignore */ this.getFormat = function() { return _format; } /** *@ignore */ this.setZIndex = function(val) { _zIndex = val; } /** *@ignore */ this.getZIndex = function() { return _zIndex; } /** *@ignore */ this.getProperty = function(name) { return _requestProperties[name]; } /** *@ignore */ this.setProperty = function(name, value) { if(name != null && name != '') _requestProperties[name] = value; } /** *@ignore */ this.setStyleLayerDescriptorUrl = function(val) { _sldUrl = val; } /** *@ignore */ this.getStyleLayerDescriptorUrl = function() { return _sldUrl; } /** *@ignore */ this.setStyleLayerDescriptorText = function(val) { _sldBody = val; } /** *@ignore */ this.getStyleLayerDescriptorText = function() { return _sldBody; } /** *@ignore */ this.getVisible = function(){ return _layerVisible; } /** *@ignore */ this.setMinZoomLevel = function(val) { _minZoomLevel = val; } /** *@ignore */ this.setMaxZoomLevel = function(val) { _maxZoomLevel = val; } /** *@ignore */ this.getMinZoomLevel = function() { return _minZoomLevel; } /** *@ignore */ this.getMaxZoomLevel = function() { return _maxZoomLevel; } /** *@ignore */ this.setOpacity = function(val) { if(val != null && val >=0 && val <= 1) _opacity = val; } /** *@ignore */ this.getOpacity = function() { return _opacity; } /** *@ignore */ this.setVisible = function(bool) { try { _layerVisible = bool; if(this.getVisible()) { this.onviewchange(null); } else { // remove div tag var mapContainer = getMapDiv(); var mapdiv = mapContainer.firstChild; if (_imgMDEObj!=null){ mapdiv.removeChild(_imgMDEObj); _imgMDEObj=null; } } } catch(e) { } }//setVisible /** *@ignore */ this.onviewchange = function(e){ if(!_this.getVisible()) return; var mapContainer = getMapDiv(); var mapdiv = mapContainer.firstChild; if (_imgMDEObj!=null){ mapdiv.removeChild(_imgMDEObj); _imgMDEObj = null; } // check for zoom levels var currentZoomLevel = vemap.GetZoomLevel(); if(_minZoomLevel > currentZoomLevel || _maxZoomLevel < currentZoomLevel) return; var imgWidth = vemap.GetWidth(); var imgHeight = vemap.GetHeight(); var minX = 0; var maxY = 0; var maxX = minX + vemap.GetWidth(); var minY = maxY + vemap.GetHeight(); var latLngMin =vemap.PixelToLatLong(new VEPixel(minX, minY)); var latLngMax =vemap.PixelToLatLong(new VEPixel(maxX, maxY)); var minx = latLngMin.Longitude; var miny = latLngMin.Latitude; var maxx = latLngMax.Longitude; var maxy = latLngMax.Latitude; var url = ""; url += _serverPath; //url += "?map=" +_mapFile url += "?bbox=" + minx + "," + miny + "," + maxx + "," + maxy; var encodeFunction = encodeURIComponent; if((version >= 5.5) && (version < 7) && (document.body.filters) && (typeof(serverPath) == 'undefined' || serverPath == null) && _format != null && _format.toLowerCase().indexOf("png") > -1) { encodeFunction = encodeString; url += "&IsEncoded=true"; } url += "&width="+imgWidth; url += "&height="+imgHeight; if(_layers != null && _layers != '' && _layers.length > 0) url += "&layers=" + encodeFunction(_layers.join(",")); //url += encodeURIComponent("&layers=" + _layers.join(",")); if(_sldUrl != null) url += "&SLD="+encodeFunction(_sldUrl); if(_format != null) url += "&format="+encodeFunction(_format); if(_sldBody != null) url += "&SLD_BODY="+encodeFunction(_sldBody); url +="&SRS=EPSG:4326&REQUEST=MAP"; for(var key in _requestProperties) { var value = _requestProperties[key]; if(value != null && value != '') { if (typeof(value) !== "undefined" && typeof(value) !== "function") { url += ("&" + key + "=" + encodeFunction(value)); } } } //add OverrideMapStyles 0 //url += "&OverrideMapStyle="+encodeFunction("0"); _imgMDEObj = document.createElement("IMG"); _imgMDEObj.setAttribute("id", "MDE"+_name); _imgMDEObj.id = "MDE"+_name; mapdiv.appendChild(_imgMDEObj); // var topOffset = 0-parseInt(mapdiv.style.top); var leftOffset = 0-parseInt(mapdiv.style.left); _imgMDEObj.style.left = leftOffset+"px"; _imgMDEObj.style.top = topOffset+"px"; //imgMDEObj.style.zIndex= 1; _imgMDEObj.style.position= "absolute"; _imgMDEObj.style.width= imgWidth+"px"; _imgMDEObj.style.height= imgHeight+"px"; _imgMDEObj.style.opacity= _opacity; _imgMDEObj.style.filter= "alpha(opacity=" + (_opacity * 100) + ")"; // MDE layer has an issue when on some pan issues where // it gets put below the iamge tiles to fix this we added a // z-index value. _imgMDEObj.style.zIndex= _zIndex; _imgMDEObj.setAttribute("src", url); if(_format != null && _format.toLowerCase().indexOf("png") > -1) _imgMDEObj = fixPNG(_imgMDEObj); }//onViewChange var arVersion = navigator.appVersion.split("MSIE") var version = parseFloat(arVersion[1]) function fixPNG(myImage) { if ((version >= 5.5) && (version < 7) && (document.body.filters)) { var id = myImage.id; var imgID = (myImage.id) ? "id='" + myImage.id + "' " : ""; var imgClass = (myImage.className) ? "class='" + myImage.className + "' " : ""; var imgTitle = (myImage.title) ? "title='" + myImage.title + "' " : "title='" + myImage.alt + "' "; var imgStyle = "display:inline-block;" + myImage.style.cssText var strNewHTML = ""; myImage.outerHTML = strNewHTML; return document.getElementById(id); } return myImage; } // returns the div element that contains the map. function getMapDiv() { return document.getElementById(vemap.ID); } _this = this; /** *@ignore */ this.initialize = function() { //Add a MDE layer by default if(_hasInitialized) return; vemap.AttachEvent("onchangeview", this.onviewchange); this.onviewchange(); _hasInitialized = true; } function encodeString(s) { return encodeURIComponent(s).replace(/%/g, "._-"); } }//VEWMSLayer /** * Create a new WMSLayer. * @class WMSLayer represents a Non-Tiled layer. It will generate a map image for every view change. * Note: If you are querying a WMS server for a png file and have special characters in the url parameters such * as "&, =, #, +" your server must be able to escape ._- into % and then urlDecode the value. * * @constructor * @param {map} map Virtual Earth or Google Maps map object * @param {string[]} layers Names of layers to enable * @param {string} serverPath The optional server path. */ function WMSLayer(map, /*Array optional*/ layers, /*string optional*/ serverPath) { var _layerObj = null; if(typeof(GMap2) != "undefined" && map instanceof GMap2) { _layerObj = new GoogleWMSLayer(map, layers, serverPath); } else if(typeof(VEMap) != "undefined" && map instanceof VEMap) { _layerObj = new VEWMSLayer(map, layers, serverPath); /** * Sets the ZIndex (VE Only). This will determine the rendering order of the layer. * @param {int} val The ZIndex of the layer * @type void */ this.setZIndex = function(val) { _layerObj.setZIndex(val); } /** * Gets the Zindex (VE Only). * @return The ZIndex of the layer. * @type int */ this.getZIndex = function() { return _layerObj.getZIndex(); } /** * Sets the opacity (VE Only). Valid range [0 - 1] * @param {float} val The opacity level. * @type void */ this.setOpacity = function(val) { _layerObj.setOpacity(val); } /** * Returns the opacity of the layer (VE Only). * @type float */ this.getOpacity = function() { return _layerObj.getOpacity(); } } else { return null; } /** * Sets the format type for the image layer. * ex. ("image/gif", "image/jpeg", "image/png") * @param {int} val The format of the layer. * @type void */ this.setFormat = function(val) { _layerObj.setFormat(val); } /** * Gets the format type. * @return The format type of the layer. * @type string */ this.getFormat = function() { return _layerObj.getFormat(); } /** * Sets the value of a property. This property will be appended to each tile request. * @param {string} name Name of the property * @param {string} value Value of the property * @type void */ this.setProperty = function(name, value) { _layerObj.setProperty(name, value); } /** * Returns the value associated with the property name. * @param {string} name Name of the property * @type string * @return The property value. If the property does not exists null is returned. */ this.getProperty = function(name) { return _layerObj.getProperty(name); } /** * Sets the visibility of the layer * @param {bool} bool The visibility * @type void */ this.setVisible = function(bool) { _layerObj.setVisible(bool); } /** * Returns true if the layer is visible and false otherwise. * @type bool */ this.getVisible = function() { return _layerObj.getVisible(); } /** * Sets the minimum zoom level. * @param {int} val The zoom level. * @type void */ this.setMinZoomLevel = function(val) { _layerObj.setMinZoomLevel(val); } /** * Returns the minimum zoom level. * @type int */ this.getMinZoomLevel = function() { return _layerObj.getMinZoomLevel(); } /** * Sets the maximum zoom level. * @param {int} val The zoom level. * @type void */ this.setMaxZoomLevel = function(val) { _layerObj.setMaxZoomLevel(val); } /** * Returns the maximum zoom level. * @type int */ this.getMaxZoomLevel = function() { return _layerObj.getMaxZoomLevel(); } /** * Sets the SLD url. This SLD url will be passed in the tile request string. * @param {string} val Url to sld file. * @type void */ this.setStyleLayerDescriptorUrl = function(val) { _layerObj.setStyleLayerDescriptorUrl(val); } /** * Returns the SLD url. * @type string */ this.getStyleLayerDescriptorUrl = function() { return _layerObj.getStyleLayerDescriptorUrl(); } /** * Sets the SLD text. This SLD text will be passed in the tile request string. * @param {string} val Text of sld file. * @type void */ this.setStyleLayerDescriptorText = function(val) { _layerObj.setStyleLayerDescriptorText(val); } /** * Returns the SLD text. * @type string */ this.getStyleLayerDescriptorText = function() { return _layerObj.getStyleLayerDescriptorText(); } /** * Initializes the layer. Must be called before the layer renders. * @type void */ this.initialize = function() { _layerObj.initialize(); } /** * Forces the Layer to redraw. * @type void */ this.draw = function() { }//draw /** *@ignore */ this.onviewchange = _layerObj.onviewchange; }