codekasten/osm/dynamic_markers/html/event_map.js

340 lines
12 KiB
JavaScript

/* functions for displaying event icons on a map
* Just include this js file in your html code and add an "event_map" div:
* <script type="text/javascript" src="event_map.js"></script>
* <div id="event_map"></div>
*
* Additionally you may want to override some variables, eg:
* <script type="text/javascript">
* var event_map_center_longitude = <?php echo $_GET['longitude'] + 0 ?>;
* var event_map_center_latitude = <?php echo $_GET['latitude'] + 0 ?>;
* var event_map_zoom = <?php echo $_GET['zoom'] + 0 ?>;
* </script>
* BEWARE: above overrides MUST be placed before including the "event_map.js" file.
*
* Copyright: 2010 by Lars Kruse <devel@sumpfralle.de>
* License: GNU GPL v3 or higher (http://www.gnu.org/licenses/gpl-3.0.txt)
*/
var event_map_zoom_default_for_events = 13;
var event_map_zoom_default_for_marker = 15;
var event_map_zoom_default_for_edit = 12;
// names of fields to be manipulated in "edit" mode
var event_map_fieldname_lat = "edit-field-lat-0-value";
var event_map_fieldname_lon = "edit-field-long-0-value";
// some default startup definitions (can be overwritten in the html file)
// define the base url of local resources - the trailing slash is required!
if (typeof(event_map_base_url) == 'undefined') {
var event_map_base_url = '/event_map/';
}
// location of our css file - relative to the URL of the main html file
if (typeof(event_map_css_file) == 'undefined') {
var event_map_css_file = event_map_base_url + 'html/event_map.css';
}
// location of the GML file to be loaded - relative to the URL of the main html file
if (typeof(event_map_gml_file) == 'undefined') {
var event_map_gml_file = event_map_base_url + 'html/events.gml';
}
// display types: "events" (default), "marker" or "edit"
if (typeof(event_map_display_type) == 'undefined') {
var event_map_display_type = 'events';
}
// set display_type to default, if the value is unknown
// also set default zoom level for that mode
var event_map_default_zoom;
if (event_map_display_type == 'events') {
event_map_default_zoom = event_map_zoom_default_for_events;
} else if (event_map_display_type == 'marker') {
event_map_default_zoom = event_map_zoom_default_for_marker;
} else if (event_map_display_type == 'edit') {
event_map_default_zoom = event_map_zoom_default_for_edit;
} else {
// unknown display_type
event_map_display_type = 'events';
event_map_default_zoom = event_map_zoom_default_for_events;
}
// latitude and longitude of the center of the map - set to zero if undefined
// the real default value will be set a little bit later
// note: zero is the magic value for "undefined"
if (typeof(event_map_center_latitude) == 'undefined') {
var event_map_center_latitude = 0;
}
if (typeof(event_map_center_longitude) == 'undefined') {
var event_map_center_longitude = 0;
}
// remember, if the coordinates were not initialized
var event_map_coordinates_unset = false;
// event mode: set default latitude or longitude, if necessary (center of Rostock)
if (event_map_center_latitude == 0) {
event_map_coordinates_unset = true;
event_map_center_latitude = 54.082004;
}
if (event_map_center_longitude == 0) {
event_map_coordinates_unset = true;
event_map_center_longitude = 12.128275;
}
// initial zoom level of the map
if (typeof(event_map_zoom) == 'undefined') {
var event_map_zoom = 0;
}
// this must be done separately from the previous "undefined" check to avoid re-initialization via "var"
if (event_map_zoom == 0) {
event_map_zoom = event_map_default_zoom;
}
// url of the marker icon
if (typeof(event_map_marker_icon) == 'undefined') {
var event_map_marker_icon = event_map_base_url + 'icons/marker.png';
}
// global variables
var event_map;
var event_map_selectControl;
var event_map_marker_layer;
var event_map_marker;
// run the "event_map_init" function after loading the page
window.onload = event_map_init;
function event_map_addJavascript(jsname, pos) {
var th = document.getElementsByTagName(pos)[0];
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.setAttribute('src', jsname);
th.appendChild(s);
}
function event_map_addCSSfile(cssfile, pos) {
var th = document.getElementsByTagName(pos)[0];
var s = document.createElement('link');
s.setAttribute('rel', 'stylesheet');
s.setAttribute('href', cssfile);
th.appendChild(s);
}
event_map_addJavascript('http://www.openlayers.org/api/OpenLayers.js', 'head');
event_map_addJavascript('http://www.openstreetmap.org/openlayers/OpenStreetMap.js', 'head');
// in case of problems of a browser with loading external ccs files, we could use the local copy
//event_map_addCSSfile(event_map_base_url + 'html/openlayers/style.css', 'head');
event_map_addCSSfile('http://openlayers.org/api/theme/default/style.css', 'head');
event_map_addCSSfile(event_map_css_file, 'head');
function event_map_init() {
event_map = new OpenLayers.Map('event_map', {
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
numZoomLevels: 19,
maxResolution: 156543.0399,
units: 'm',
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326")
});
// define the public transport map (oepnvkarte.de)
OpenLayers.Layer.OSM.OePNV = OpenLayers.Class(OpenLayers.Layer.OSM, {
initialize: function(name, options) {
var url = [
"http://tile.xn--pnvkarte-m4a.de/tilegen/${z}/${x}/${y}.png"
];
options = OpenLayers.Util.extend({ numZoomLevels: 19 }, options);
var newArguments = [name, url, options];
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},
CLASS_NAME: "OpenLayers.Layer.OSM.OePNV"
});
var layerOePNV = new OpenLayers.Layer.OSM.OePNV("&Ouml;PNV-Karte");
var layerCycle = new OpenLayers.Layer.OSM.CycleMap("Radweg-Karte");
var layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
var layerTah = new OpenLayers.Layer.OSM.Osmarender("Osmarender");
event_map.addLayers([layerOePNV, layerCycle, layerMapnik, layerTah]);
// choose default layer
event_map.setBaseLayer(layerMapnik);
event_map_marker_layer = new OpenLayers.Layer.Markers("Markierung");
event_map.addLayer(event_map_marker_layer)
// allow to change the current layer (mapnik/tah/oepnv/cycle)
event_map.addControl(new OpenLayers.Control.LayerSwitcher());
var lonLat = new OpenLayers.LonLat(event_map_center_longitude,
event_map_center_latitude).transform(event_map.displayProjection, event_map.projection);
event_map.setCenter(lonLat, event_map_zoom);
if (event_map_display_type == 'marker') {
event_map_show_marker(lonLat);
} else if (event_map_display_type == 'edit') {
event_map_edit_position(lonLat);
} else {
event_map_show_gml();
}
}
function event_map_get_marker(lonLat) {
var size = new OpenLayers.Size(21, 25);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
var icon = new OpenLayers.Icon(event_map_marker_icon, size, offset)
return new OpenLayers.Marker(lonLat, icon);
}
// return false, if no valid coordinate values are found in the form fields
function event_map_get_form_coordinates() {
var lon;
var lat;
var field_lat = document.getElementById(event_map_fieldname_lat);
var field_lon = document.getElementById(event_map_fieldname_lon);
if (field_lat) { lat = field_lat.value; }
if (field_lon) { lon = field_lon.value; }
if ((lat != "") && (lat != 0) && (lon != "") && (lon != 0)) {
return new OpenLayers.LonLat(lon, lat).transform(
event_map.displayProjection, event_map.projection);
} else {
return false;
}
}
function event_map_update_edit_marker() {
event_map_marker_layer.clearMarkers();
var lonLat = event_map_get_form_coordinates();
if (lonLat) {
event_map_marker = event_map_get_marker(lonLat);
event_map_marker_layer.addMarker(event_map_marker);
// center the map on the item
event_map.setCenter(lonLat, event_map.zoom);
}
}
function event_map_edit_position(lonLat) {
event_map_update_edit_marker();
// catch click events
OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {
defaultHandlerOptions: {
'single': true,
'double': false,
'pixelTolerance': 0,
'stopSingle': false,
'stopDouble': false
},
initialize: function(options) {
this.handlerOptions = OpenLayers.Util.extend({}, this.defaultHandlerOptions);
OpenLayers.Control.prototype.initialize.apply(this, arguments);
this.handler = new OpenLayers.Handler.Click(this, { 'click': this.trigger }, this.handlerOptions);
}
});
var click = new OpenLayers.Control.Click({ trigger: event_map_edit_clicked });
event_map.addControl(click);
click.activate();
}
function event_map_show_marker(lonLat) {
if (event_map_coordinates_unset) {
// hide the map
document.getElementById('event_map').style.display = "none";
} else {
// configure and display the map
event_map_marker = event_map_get_marker(lonLat);
event_map_marker_layer.addMarker(event_map_marker);
}
}
function event_map_show_gml() {
OpenLayers.Feature.prototype.popupClass = OpenLayers.Popup.FramedCloud;
var pois = new OpenLayers.Layer.GML("Veranstaltungen", event_map_gml_file, {
format: OpenLayers.Format.Text,
projection: new OpenLayers.Projection("EPSG:4326")
});
event_map.addLayer(pois);
// add the popups
event_map_selectControl = new OpenLayers.Control.SelectFeature(pois, {
onSelect: event_map_onFeatureSelect,
onUnselect: event_map_onFeatureUnselect,
toggle: true
});
event_map.addControl(event_map_selectControl);
event_map_selectControl.activate();
}
function event_map_onPopupClose(evnt) {
event_map_selectControl.unselect(selectedFeature);
}
function event_map_edit_clicked(evnt) {
var lonLat = event_map.getLonLatFromViewPortPx(evnt.xy).transform(
event_map.projection, event_map.displayProjection);
var field_lat = document.getElementById(event_map_fieldname_lat);
var field_lon = document.getElementById(event_map_fieldname_lon);
// round the numbers to a few digits - otherwise drupal complains about max number of chars
if (field_lat) { field_lat.value = Math.round(lonLat.lat * 10000000) / 10000000; }
if (field_lon) { field_lon.value = Math.round(lonLat.lon * 10000000) / 10000000; }
event_map_update_edit_marker();
}
function event_map_onFeatureSelect(feature) {
selectedFeature = feature;
var content = '<div class="event_map_info">';
content += '<h1>' + feature.attributes.title + '</h1>';
/* the description contains six attributes:
* time/date
* place
* address
* organisation
* details
* url
*/
/* we don't do this formatting here - but in the gml file generation script instead
var items = feature.attributes.description.split('#', 6);
content += '<ul>';
content += '<li>Wann: ' + items[0] + '</li>';
content += '<li>Ort: ' + items[1] + '</li>';
content += '<li>Adresse: ' + items[2] + '</li>';
content += '<li>Veranstalter: ' + items[3] + '</li>';
content += '<li>Details: ' + items[4] + '</li>';
content += '<li><a href="' + items[5] + '" title="mehr Informationen">mehr ...</a></li>';
content += '</ul></div>';
*/
content += feature.attributes.description
content += '</div>'
// do naive protection against Javascript.
if (content.search("<script") != -1) {
content = "Content contained Javascript! Escaped content below.<br />" + content.replace(/</g, "&lt;");
}
popup = new OpenLayers.Popup.FramedCloud("event",
feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(300, 200),
content,
null, true, event_map_onPopupClose);
popup.maxSize = new OpenLayers.Size(350, 300);
feature.popup = popup;
event_map.addPopup(popup);
}
function event_map_onFeatureUnselect(feature) {
event_map.removePopup(feature.popup);
feature.popup.destroy();
feature.popup = null;
}