first import
This commit is contained in:
393
sites/all/modules/openlayers/js/openlayers.js
Normal file
393
sites/all/modules/openlayers/js/openlayers.js
Normal file
@@ -0,0 +1,393 @@
|
||||
/*jslint white: false */
|
||||
/*jslint forin: true */
|
||||
/*global OpenLayers Drupal $ document jQuery window */
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file holds the main javascript API for OpenLayers. It is
|
||||
* responsable for loading and displaying the map.
|
||||
*
|
||||
* @ingroup openlayers
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a workaround for a bug involving IE and VML support.
|
||||
* See the Drupal Book page describing this problem:
|
||||
* http://drupal.org/node/613002
|
||||
*/
|
||||
|
||||
document.namespaces;
|
||||
|
||||
(function($) {
|
||||
|
||||
Drupal.settings.openlayers = {};
|
||||
Drupal.settings.openlayers.maps = {};
|
||||
|
||||
/**
|
||||
* Minimal OpenLayers map bootstrap.
|
||||
* All additional operations occur in additional Drupal behaviors.
|
||||
*/
|
||||
Drupal.behaviors.openlayers = {
|
||||
'attach': function(context, settings) {
|
||||
if (typeof(Drupal.settings.openlayers) === 'object' &&
|
||||
Drupal.settings.openlayers.maps &&
|
||||
!$(context).data('openlayers')) {
|
||||
$('.openlayers-map:not(.openlayers-processed)').each(function() {
|
||||
// By setting the stop_render variable to TRUE, this will
|
||||
// halt the render process. If set, one could remove this setting
|
||||
// then call Drupal.attachBehaviors again to get it started
|
||||
var map_id = $(this).attr('id');
|
||||
if (Drupal.settings.openlayers.maps[map_id] && Drupal.settings.openlayers.maps[map_id].stop_render != true) {
|
||||
var map = Drupal.settings.openlayers.maps[map_id];
|
||||
$(this).addClass('openlayers-processed');
|
||||
|
||||
// Use try..catch for error handling.
|
||||
try {
|
||||
// Set OpenLayers language based on document language,
|
||||
// rather than browser language
|
||||
OpenLayers.Lang.setCode($('html').attr('lang'));
|
||||
|
||||
$(this)
|
||||
// @TODO: move this into markup in theme function, doing this dynamically is a waste.
|
||||
.css('width', map.width)
|
||||
.css('height', map.height);
|
||||
|
||||
var options = {};
|
||||
// This is necessary because the input JSON cannot contain objects
|
||||
options.projection = new OpenLayers.Projection('EPSG:' + map.projection);
|
||||
options.displayProjection = new OpenLayers.Projection('EPSG:' + map.displayProjection);
|
||||
|
||||
// TODO: work around this scary code
|
||||
if (map.projection === '900913') {
|
||||
options.maxExtent = new OpenLayers.Bounds(
|
||||
-20037508.34, -20037508.34, 20037508.34, 20037508.34);
|
||||
options.units = "m";
|
||||
}
|
||||
if (map.projection === '4326') {
|
||||
options.maxExtent = new OpenLayers.Bounds(-180, -90, 180, 90);
|
||||
}
|
||||
|
||||
options.maxResolution = 'auto'; // 1.40625;
|
||||
options.controls = [];
|
||||
|
||||
// Change image, CSS, and proxy paths if specified
|
||||
if (map.image_path) {
|
||||
OpenLayers.ImgPath = Drupal.openlayers.relatePath(map.image_path,
|
||||
Drupal.settings.basePath);
|
||||
}
|
||||
if (map.css_path) {
|
||||
options.theme = Drupal.openlayers.relatePath(map.css_path,
|
||||
Drupal.settings.basePath);
|
||||
}
|
||||
if (map.proxy_host) {
|
||||
OpenLayers.ProxyHost = Drupal.openlayers.relatePath(map.proxy_host,
|
||||
Drupal.settings.basePath);
|
||||
}
|
||||
|
||||
// Initialize openlayers map
|
||||
var openlayers = new OpenLayers.Map(map.id, options);
|
||||
|
||||
// Run the layer addition first
|
||||
Drupal.openlayers.addLayers(map, openlayers);
|
||||
|
||||
// Attach data to map DOM object
|
||||
$(this).data('openlayers', {'map': map, 'openlayers': openlayers});
|
||||
|
||||
// Finally, attach behaviors
|
||||
Drupal.attachBehaviors(this);
|
||||
|
||||
if ($.browser.msie) {
|
||||
Drupal.openlayers.redrawVectors();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
var errorMessage = e.name + ': ' + e.message;
|
||||
if (typeof console != 'undefined') {
|
||||
console.log(errorMessage);
|
||||
}
|
||||
else {
|
||||
$(this).text('Error during map rendering: ' + errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Collection of helper methods.
|
||||
*/
|
||||
Drupal.openlayers = {
|
||||
// Determine path based on format.
|
||||
'relatePath': function(path, basePath) {
|
||||
// Check for a full URL or an absolute path.
|
||||
if (path.indexOf('://') >= 0 || path.indexOf('/') == 0) {
|
||||
return path;
|
||||
}
|
||||
else {
|
||||
return basePath + path;
|
||||
}
|
||||
},
|
||||
/*
|
||||
* Redraw Vectors.
|
||||
* This is necessary because various version of IE cannot draw vectors on
|
||||
* $(document).ready()
|
||||
*/
|
||||
'redrawVectors': function() {
|
||||
$(window).load(
|
||||
function() {
|
||||
var map;
|
||||
for (map in Drupal.settings.openlayers.maps) {
|
||||
$.each($('#' + map).data('openlayers')
|
||||
.openlayers.getLayersByClass('OpenLayers.Layer.Vector'),
|
||||
function(i, layer) {
|
||||
layer.redraw();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
/**
|
||||
* Add layers to the map
|
||||
*
|
||||
* @param map Drupal settings object for the map.
|
||||
* @param openlayers OpenLayers Map Object.
|
||||
*/
|
||||
'addLayers': function(map, openlayers) {
|
||||
|
||||
var sorted = [];
|
||||
for (var name in map.layers) {
|
||||
sorted.push({'name': name, 'weight': map.layers[name].weight, 'isBaseLayer': map.layers[name].isBaseLayer });
|
||||
}
|
||||
|
||||
sorted.sort(function(a, b) {
|
||||
var x = parseInt(a.weight, 10), y = parseInt(b.weight, 10);
|
||||
return ((a.isBaseLayer && x < y) ? -1 : ((b.isBaseLayer || x > y) ? 1 : 0));
|
||||
});
|
||||
|
||||
for (var i = 0; i < sorted.length; ++i) {
|
||||
var layer,
|
||||
name = sorted[i].name,
|
||||
options = map.layers[name];
|
||||
|
||||
// Add reference to our layer ID
|
||||
options.drupalID = name;
|
||||
// Ensure that the layer handler is available
|
||||
if (options.layer_handler !== undefined &&
|
||||
Drupal.openlayers.layer[options.layer_handler] !== undefined) {
|
||||
var layer = Drupal.openlayers.layer[options.layer_handler](map.layers[name].title, map, options);
|
||||
|
||||
layer.visibility = !!(!map.layer_activated || map.layer_activated[name]);
|
||||
|
||||
if (layer.isBaseLayer === false) {
|
||||
layer.displayInLayerSwitcher = (!map.layer_switcher || map.layer_switcher[name]);
|
||||
}
|
||||
|
||||
if (map.center.wrapdateline === '1') {
|
||||
// TODO: move into layer specific settings
|
||||
layer.wrapDateLine = true;
|
||||
}
|
||||
|
||||
openlayers.addLayer(layer);
|
||||
}
|
||||
}
|
||||
|
||||
openlayers.setBaseLayer(openlayers.getLayersBy('drupalID', map.default_layer)[0]);
|
||||
|
||||
// Set the restricted extent if wanted.
|
||||
// Prevents the map from being panned outside of a specfic bounding box.
|
||||
if (typeof map.center.restrict !== 'undefined' && map.center.restrict.restrictextent) {
|
||||
openlayers.restrictedExtent = OpenLayers.Bounds.fromString(
|
||||
map.center.restrict.restrictedExtent);
|
||||
}
|
||||
|
||||
// Zoom & center
|
||||
if (map.center.initial) {
|
||||
var center = OpenLayers.LonLat.fromString(map.center.initial.centerpoint).transform(
|
||||
new OpenLayers.Projection('EPSG:4326'),
|
||||
new OpenLayers.Projection('EPSG:' + map.projection));
|
||||
var zoom = parseInt(map.center.initial.zoom, 10);
|
||||
openlayers.setCenter(center, zoom, false, false);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Abstraction of OpenLayer's feature adding syntax to work with Drupal output.
|
||||
* Ideally this should be rolled into the PHP code, because we don't want to manually
|
||||
* parse WKT
|
||||
*/
|
||||
'addFeatures': function(map, layer, features) {
|
||||
var newFeatures = [];
|
||||
|
||||
// Go through features
|
||||
for (var key in features) {
|
||||
var feature = features[key];
|
||||
var newFeatureObject = this.objectFromFeature(feature);
|
||||
|
||||
// If we have successfully extracted geometry add additional
|
||||
// properties and queue it for addition to the layer
|
||||
if (newFeatureObject) {
|
||||
var newFeatureSet = [];
|
||||
|
||||
// Check to see if it is a new feature, or an array of new features.
|
||||
if (typeof(newFeatureObject[0]) === 'undefined') {
|
||||
newFeatureSet[0] = newFeatureObject;
|
||||
}
|
||||
else {
|
||||
newFeatureSet = newFeatureObject;
|
||||
}
|
||||
|
||||
// Go through new features
|
||||
for (var i in newFeatureSet) {
|
||||
var newFeature = newFeatureSet[i];
|
||||
|
||||
// Transform the geometry if the 'projection' property is different from the map projection
|
||||
if (feature.projection) {
|
||||
if (feature.projection !== map.projection) {
|
||||
var featureProjection = new OpenLayers.Projection('EPSG:' + feature.projection);
|
||||
var mapProjection = new OpenLayers.Projection('EPSG:' + map.projection);
|
||||
newFeature.geometry.transform(featureProjection, mapProjection);
|
||||
}
|
||||
}
|
||||
|
||||
// Add attribute data
|
||||
if (feature.attributes) {
|
||||
// Attributes belong to features, not single component geometries
|
||||
// of them. But we're creating a geometry for each component for
|
||||
// better performance and clustering support. Let's call these
|
||||
// "pseudofeatures".
|
||||
//
|
||||
// In order to identify the real feature each geometry belongs to
|
||||
// we then add a 'fid' parameter to the "pseudofeature".
|
||||
// NOTE: 'drupalFID' is only unique within a single layer.
|
||||
newFeature.attributes = feature.attributes;
|
||||
newFeature.data = feature.attributes;
|
||||
newFeature.drupalFID = key;
|
||||
}
|
||||
|
||||
// Add style information
|
||||
if (feature.style) {
|
||||
newFeature.style = jQuery.extend({},
|
||||
OpenLayers.Feature.Vector.style['default'],
|
||||
feature.style);
|
||||
}
|
||||
|
||||
// Push new features
|
||||
newFeatures.push(newFeature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add new features if there are any
|
||||
if (newFeatures.length !== 0) {
|
||||
layer.addFeatures(newFeatures);
|
||||
}
|
||||
},
|
||||
|
||||
'getStyleMap': function(map, layername) {
|
||||
if (map.styles) {
|
||||
var stylesAdded = {};
|
||||
|
||||
// Grab and map base styles.
|
||||
for (var style in map.styles) {
|
||||
stylesAdded[style] = new OpenLayers.Style(map.styles[style]);
|
||||
}
|
||||
|
||||
// Implement layer-specific styles. First default, then select.
|
||||
if (map.layer_styles !== undefined && map.layer_styles[layername]) {
|
||||
var style = map.layer_styles[layername];
|
||||
stylesAdded['default'] = new OpenLayers.Style(map.styles[style]);
|
||||
}
|
||||
if (map.layer_styles_select !== undefined && map.layer_styles_select[layername]) {
|
||||
var style = map.layer_styles_select[layername];
|
||||
stylesAdded['select'] = new OpenLayers.Style(map.styles[style]);
|
||||
}
|
||||
|
||||
return new OpenLayers.StyleMap(stylesAdded);
|
||||
}
|
||||
else {
|
||||
return new OpenLayers.StyleMap({
|
||||
'default': new OpenLayers.Style({
|
||||
pointRadius: 5,
|
||||
fillColor: '#ffcc66',
|
||||
strokeColor: '#ff9933',
|
||||
strokeWidth: 4,
|
||||
fillOpacity: 0.5
|
||||
}),
|
||||
'select': new OpenLayers.Style({
|
||||
fillColor: '#66ccff',
|
||||
strokeColor: '#3399ff'
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
'objectFromFeature': function(feature) {
|
||||
var wktFormat = new OpenLayers.Format.WKT();
|
||||
// Extract geometry either from wkt property or lon/lat properties
|
||||
if (feature.wkt) {
|
||||
return wktFormat.read(feature.wkt);
|
||||
}
|
||||
else if (feature.lon) {
|
||||
return wktFormat.read('POINT(' + feature.lon + ' ' + feature.lat + ')');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add Behavior.
|
||||
*
|
||||
* This is a wrapper around adding behaviors for OpenLayers.
|
||||
* a module does not have to use this, but it helps cut
|
||||
* down on code.
|
||||
*
|
||||
* @param id
|
||||
* The identifier of the behavior that is attached to
|
||||
* the map.
|
||||
* @param attach
|
||||
* The callback function for the attach part of the
|
||||
* Drupal behavior.
|
||||
* @param detach
|
||||
* The callback function for the detach part of the
|
||||
* Drupal behavior.
|
||||
*/
|
||||
'addBehavior': function(id, attach, detach) {
|
||||
// Add as a Drupal behavior. Add a prefix, just to be safe.
|
||||
Drupal.behaviors['openlayers_auto_' + id] = {
|
||||
attach: function (context, settings) {
|
||||
var data = $(context).data('openlayers');
|
||||
|
||||
// Ensure that there is a map and that the appropriate
|
||||
// behavior exists. Need "data &&" to avoid js crash
|
||||
// when data is empty
|
||||
var localBehavior = data && data.map.behaviors[id];
|
||||
|
||||
// Ensure scope in the attach callback
|
||||
var that = this;
|
||||
if (localBehavior) {
|
||||
$(context).once('openlayers-' + id, function () {
|
||||
attach.apply(that, [data, data.map.behaviors[id], context, settings]);
|
||||
});
|
||||
}
|
||||
},
|
||||
// Maybe we need a little more handling here.
|
||||
detach: detach
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Add Control.
|
||||
*
|
||||
* This is a wrapper around adding controls to maps. It
|
||||
* is not needed but saves some code.
|
||||
*/
|
||||
'addControl': function(openlayers, controlName, options) {
|
||||
var control = new OpenLayers.Control[controlName](options);
|
||||
openlayers.addControl(control);
|
||||
control.activate();
|
||||
return control;
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.openlayers.layer = {};
|
||||
})(jQuery);
|
Reference in New Issue
Block a user