Port to Leaflet

This commit is contained in:
John Firebaugh 2012-08-25 10:55:46 -07:00
parent e316f0e425
commit 30ad58c01f
32 changed files with 9715 additions and 823 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

@ -4,7 +4,9 @@
//= require jquery.timers
//= require jquery.cookie
//= require augment
//= require openlayers
//= require leaflet
//= require leaflet.osm
//= require leaflet.draw
//= require i18n/translations
//= require osm
//= require piwik

View file

@ -21,16 +21,14 @@ $(document).ready(function () {
return false;
}
var map = createMap("small_map", {
controls: [ new OpenLayers.Control.Navigation() ]
});
var map = createMap("small_map");
var params = $("#small_map").data();
if (params.type == "changeset") {
var bbox = new OpenLayers.Bounds(params.minlon, params.minlat, params.maxlon, params.maxlat);
var centre = bbox.getCenterLonLat();
var bbox = L.latLngBounds([params.minlat, params.minlon],
[params.maxlat, params.maxlon]);
map.zoomToExtent(proj(bbox));
map.fitBounds(bbox);
addBoxToMap(bbox);
$("#loading").hide();
@ -40,7 +38,8 @@ $(document).ready(function () {
return remoteEditHandler(bbox);
});
updatelinks(centre.lon, centre.lat, 16, null, params.minlon, params.minlat, params.maxlon, params.maxlat);
var centre = bbox.getCenter();
updatelinks(centre.lng, centre.lat, 16, null, params.minlon, params.minlat, params.maxlon, params.maxlat);
} else {
$("#object_larger_map").hide();
$("#object_edit").hide();
@ -56,10 +55,6 @@ $(document).ready(function () {
$("#browse_map .geolink").show();
if (extent) {
extent = unproj(extent);
var centre = extent.getCenterLonLat();
$("a.bbox[data-editor=remote]").click(function () {
return remoteEditHandler(extent);
});
@ -71,7 +66,8 @@ $(document).ready(function () {
$("#object_larger_map").show();
$("#object_edit").show();
updatelinks(centre.lon, centre.lat, 16, null, extent.left, extent.bottom, extent.right, extent.top, object);
var centre = extent.getCenter();
updatelinks(centre.lng, centre.lat, 16, null, extent.left, extent.bottom, extent.right, extent.top, object);
} else {
$("#small_map").hide();
}

View file

@ -1,83 +1,53 @@
$(document).ready(function () {
var highlight;
function highlightChangeset(id) {
var feature = vectors.getFeatureByFid(id);
var bounds = feature.geometry.getBounds();
if (bounds.containsBounds(map.getExtent())) {
bounds = map.getExtent().scale(1.1);
}
if (highlight) vectors.removeFeatures(highlight);
highlight = new OpenLayers.Feature.Vector(bounds.toGeometry(), {}, {
strokeWidth: 2,
strokeColor: "#ee9900",
fillColor: "#ffff55",
fillOpacity: 0.5
});
vectors.addFeatures(highlight);
$("#tr-changeset-" + id).addClass("selected");
}
function unHighlightChangeset(id) {
vectors.removeFeatures(highlight);
$("#tr-changeset-" + id).removeClass("selected");
}
var map = createMap("changeset_list_map", {
controls: [
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.Zoom(),
new OpenLayers.Control.SimplePanZoom()
]
});
var bounds = new OpenLayers.Bounds();
var rects = {};
var map = createMap("changeset_list_map");
var group = L.featureGroup().addTo(map);
$("[data-changeset]").each(function () {
var changeset = $(this).data('changeset');
if (changeset.bbox) {
var bbox = new OpenLayers.Bounds(changeset.bbox.minlon, changeset.bbox.minlat, changeset.bbox.maxlon, changeset.bbox.maxlat);
bounds.extend(bbox);
addBoxToMap(bbox, changeset.id, true);
var rect = L.rectangle([[changeset.bbox.minlat, changeset.bbox.minlon],
[changeset.bbox.maxlat, changeset.bbox.maxlon]],
{weight: 2, color: "#ee9900", fillColor: "#ffff55", fillOpacity: 0});
rect.id = changeset.id;
rects[changeset.id] = rect;
rect.addTo(group);
}
});
vectors.events.on({
"featureselected": function(feature) {
highlightChangeset(feature.feature.fid);
function highlightChangeset(id) {
rects[id].setStyle({fillOpacity: 0.5});
$("#tr-changeset-" + id).addClass("selected");
}
function unHighlightChangeset(id) {
rects[id].setStyle({fillOpacity: 0});
$("#tr-changeset-" + id).removeClass("selected");
}
group.on({
mouseover: function (e) {
highlightChangeset(e.layer.id);
},
"featureunselected": function(feature) {
unHighlightChangeset(feature.feature.fid);
mouseout: function (e) {
unHighlightChangeset(e.layer.id);
}
});
var selectControl = new OpenLayers.Control.SelectFeature(vectors, {
multiple: false,
hover: true
$("[data-changeset]").on({
mouseover: function () {
highlightChangeset($(this).data("changeset").id);
},
mouseout: function () {
unHighlightChangeset($(this).data("changeset").id);
}
});
map.addControl(selectControl);
selectControl.activate();
var params = OSM.mapParams();
if (params.bbox) {
map.zoomToExtent(proj(new OpenLayers.Bounds(params.minlon, params.minlat, params.maxlon, params.maxlat)));
map.fitBounds([[params.minlat, params.minlon],
[params.maxlat, params.maxlon]]);
} else {
map.zoomToExtent(proj(bounds));
map.fitBounds(group.getBounds());
}
$("[data-changeset]").mouseover(function() {
highlightChangeset($(this).data("changeset").id);
});
$("[data-changeset]").mouseout(function() {
unHighlightChangeset($(this).data("changeset").id);
});
});

View file

@ -2,18 +2,14 @@ $(document).ready(function () {
var marker;
function setLocation(e) {
closeMapPopup();
var lonlat = getEventPosition(e);
$("#latitude").val(lonlat.lat);
$("#longitude").val(lonlat.lon);
$("#latitude").val(e.latlng.lat);
$("#longitude").val(e.latlng.lng);
if (marker) {
removeMarkerFromMap(marker);
}
marker = addMarkerToMap(lonlat, null, I18n.t('diary_entry.edit.marker_text'));
marker = addMarkerToMap(e.latlng, null, I18n.t('diary_entry.edit.marker_text'));
}
$("#usemap").click(function (e) {
@ -23,15 +19,15 @@ $(document).ready(function () {
$("#usemap").hide();
var params = $("#map").data();
var centre = new OpenLayers.LonLat(params.lon, params.lat);
var centre = [params.lat, params.lon];
var map = createMap("map");
setMapCenter(centre, params.zoom);
map.setView(centre, params.zoom);
if ($("#latitude").val() && $("#longitude").val()) {
marker = addMarkerToMap(centre, null, I18n.t('diary_entry.edit.marker_text'));
}
map.events.register("click", map, setLocation);
map.on("click", setLocation);
});
});

View file

@ -3,24 +3,32 @@
//= require index/key
$(document).ready(function () {
var permalinks = $("#permalink").html();
var marker;
var params = OSM.mapParams();
var map = createMap("map");
map.events.register("moveend", map, updateLocation);
map.events.register("changelayer", map, updateLocation);
// https://github.com/CloudMade/Leaflet/issues/1063
map.on('load', function () {
L.control.scale().addTo(map);
});
map.attributionControl.setPrefix(permalinks);
map.on("moveend layeradd layerremove", updateLocation);
if (!params.object_zoom) {
if (params.bbox) {
var bbox = new OpenLayers.Bounds(params.minlon, params.minlat, params.maxlon, params.maxlat);
var bbox = L.latLngBounds([params.minlat, params.minlon],
[params.maxlat, params.maxlon]);
map.zoomToExtent(proj(bbox));
map.fitBounds(bbox);
if (params.box) {
addBoxToMap(bbox);
}
} else {
setMapCenter(new OpenLayers.LonLat(params.lon, params.lat), params.zoom);
map.setView([params.lat, params.lon], params.zoom);
}
}
@ -29,7 +37,7 @@ $(document).ready(function () {
}
if (params.marker) {
marker = addMarkerToMap(new OpenLayers.LonLat(params.mlon, params.mlat));
marker = addMarkerToMap([params.mlat, params.mlon]);
}
if (params.object) {
@ -38,16 +46,17 @@ $(document).ready(function () {
handleResize();
$("body").on("click", "a.set_position", function () {
$("body").on("click", "a.set_position", function (e) {
e.preventDefault();
var data = $(this).data();
var centre = new OpenLayers.LonLat(data.lon, data.lat);
var centre = L.latLng(data.lat, data.lon);
if (data.minLon && data.minLat && data.maxLon && data.maxLat) {
var bbox = new OpenLayers.Bounds(data.minLon, data.minLat, data.maxLon, data.maxLat);
map.zoomToExtent(proj(bbox));
map.fitBounds([[data.minLat, data.minLon],
[data.maxLat, data.maxLon]]);
} else {
setMapCenter(centre, data.zoom);
map.setView(centre, data.zoom);
}
if (marker) {
@ -55,29 +64,38 @@ $(document).ready(function () {
}
marker = addMarkerToMap(centre, getArrowIcon());
return false;
});
function updateLocation() {
var lonlat = unproj(map.getCenter());
var center = map.getCenter();
var zoom = map.getZoom();
var layers = getMapLayers();
var extents = unproj(map.getExtent());
var extents = map.getBounds();
updatelinks(center.lng,
center.lat,
zoom,
layers,
extents.getWestLng(),
extents.getSouthLat(),
extents.getEastLng(),
extents.getNorthLat(),
params.object);
var expiry = new Date();
updatelinks(lonlat.lon, lonlat.lat, zoom, layers, extents.left, extents.bottom, extents.right, extents.top, params.object);
expiry.setYear(expiry.getFullYear() + 10);
$.cookie("_osm_location", [lonlat.lon, lonlat.lat, zoom, layers].join("|"), {expires: expiry});
$.cookie("_osm_location", [center.lng, center.lat, zoom, layers].join("|"), {expires: expiry});
}
function remoteEditHandler(event) {
var extent = unproj(map.getExtent());
function remoteEditHandler() {
var extent = map.getBounds();
var loaded = false;
$("#linkloader").load(function () { loaded = true; });
$("#linkloader").attr("src", "http://127.0.0.1:8111/load_and_zoom?left=" + extent.left + "&top=" + extent.top + "&right=" + extent.right + "&bottom=" + extent.bottom);
$("#linkloader").attr("src", "http://127.0.0.1:8111/load_and_zoom?left=" + extent.getWestLng()
+ "&bottom=" + extent.getSouthLat()
+ "&right=" + extent.getEastLng()
+ "&top=" + extent.getNorthLat());
setTimeout(function () {
if (!loaded) alert(I18n.t('site.index.remote_failed'));
@ -102,15 +120,15 @@ $(document).ready(function () {
});
$("#search_form").submit(function () {
var extent = unproj(map.getExtent());
var bounds = map.getBounds();
$("#sidebar_title").html(I18n.t('site.sidebar.search_results'));
$("#sidebar_content").load($(this).attr("action"), {
query: $("#query").val(),
minlon: extent.left,
minlat: extent.bottom,
maxlon: extent.right,
maxlat: extent.top
minlon: bounds.getSouthWest().lng,
minlat: bounds.getSouthWest().lat,
maxlon: bounds.getNorthEast().lng,
maxlat: bounds.getNorthEast().lat
}, openSidebar);
return false;

View file

@ -11,114 +11,86 @@ $(document).ready(function () {
});
function startBrowse(sidebarHtml) {
var browseBoxControl;
var browseMode = "auto";
var browseBounds;
var browseFeatureList;
var browseActiveFeature;
var browseDataLayer;
var browseSelectControl;
var layersById;
var selectedLayer;
var browseObjectList;
var areasHidden = false;
OpenLayers.Feature.Vector.style['default'].strokeWidth = 3;
OpenLayers.Feature.Vector.style['default'].cursor = "pointer";
var dataLayer = new L.OSM(null, {
styles: {
way: {
weight: 3,
color: "#000000",
opacity: 0.4
},
area: {
weight: 3,
color: "#ff0000"
},
node: {
color: "#00ff00"
}
}
});
map.dataLayer.active = true;
dataLayer.addTo(map);
dataLayer.isWayArea = function () {
return !areasHidden && L.OSM.prototype.isWayArea.apply(this, arguments);
};
var drawHandler = new L.Rectangle.Draw(map, {title: I18n.t('browse.start_rjs.drag_a_box')});
map.on('draw:rectangle-created', endDrag);
$("#sidebar_title").html(I18n.t('browse.start_rjs.data_frame_title'));
$("#sidebar_content").html(sidebarHtml);
openSidebar();
var vectors = new OpenLayers.Layer.Vector();
browseBoxControl = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, {
handlerOptions: {
sides: 4,
snapAngle: 90,
irregular: true,
persist: true
}
});
browseBoxControl.handler.callbacks.done = endDrag;
map.addControl(browseBoxControl);
map.events.register("moveend", map, updateData);
map.events.triggerEvent("moveend");
map.on("moveend", updateData);
updateData();
$("#browse_select_view").click(useMap);
$("#browse_select_box").click(startDrag);
$("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas'));
$("#browse_hide_areas_box").toggle(hideAreas, showAreas);
function updateData() {
if (browseMode == "auto") {
if (map.getZoom() >= 15) {
useMap(false);
useMap();
} else {
setStatus(I18n.t('browse.start_rjs.zoom_or_select'));
setStatus(I18n.t('browse.start_rjs.zoom_or_select'));
}
}
}
$("#sidebar").one("closed", function () {
if (map.dataLayer.active) {
map.dataLayer.active = false;
if (browseSelectControl) {
browseSelectControl.destroy();
browseSelectControl = null;
}
if (browseBoxControl) {
browseBoxControl.destroy();
browseBoxControl = null;
}
if (browseActiveFeature) {
browseActiveFeature.destroy();
browseActiveFeature = null;
}
if (browseDataLayer) {
browseDataLayer.destroy();
browseDataLayer = null;
}
map.dataLayer.setVisibility(false);
map.events.unregister("moveend", map, updateData);
}
map.removeLayer(dataLayer);
map.off("moveend", updateData);
map.off('draw:rectangle-created', endDrag);
drawHandler.disable();
});
function startDrag() {
$("#browse_select_box").click(function () {
$("#browse_select_box").html(I18n.t('browse.start_rjs.drag_a_box'));
browseBoxControl.activate();
drawHandler.enable();
return false;
}
});
function useMap(reload) {
var bounds = map.getExtent();
var projected = unproj(bounds);
if (!browseBounds || !browseBounds.containsBounds(projected)) {
var center = bounds.getCenterLonLat();
var tileWidth = bounds.getWidth() * 1.2;
var tileHeight = bounds.getHeight() * 1.2;
var tileBounds = new OpenLayers.Bounds(center.lon - (tileWidth / 2),
center.lat - (tileHeight / 2),
center.lon + (tileWidth / 2),
center.lat + (tileHeight / 2));
browseBounds = tileBounds;
getData(tileBounds, reload);
function useMap() {
var bounds = map.getBounds();
if (!browseBounds || !browseBounds.contains(bounds)) {
browseBounds = bounds;
browseMode = "auto";
getData();
$("#browse_select_view").hide();
}
@ -130,7 +102,7 @@ $(document).ready(function () {
areasHidden = true;
useMap(true);
getData();
}
function showAreas() {
@ -138,21 +110,19 @@ $(document).ready(function () {
areasHidden = false;
useMap(true);
getData();
}
function endDrag(bbox) {
var bounds = bbox.getBounds();
var projected = unproj(bounds);
browseBoxControl.deactivate();
browseBounds = projected;
getData(bounds);
function endDrag(e) {
browseBounds = e.rect.getBounds();
browseMode = "manual";
getData();
$("#browse_select_box").html(I18n.t('browse.start_rjs.manually_select'));
$("#browse_select_view").show();
drawHandler.disable();
}
function displayFeatureWarning(count, limit, callback) {
@ -174,148 +144,75 @@ $(document).ready(function () {
$("#browse_content").append(div);
}
function customDataLoader(resp, options) {
if (map.dataLayer.active) {
var request = resp.priv;
var doc = request.responseXML;
if (!doc || !doc.documentElement) {
doc = request.responseText;
}
resp.features = this.format.read(doc);
if (!this.maxFeatures || resp.features.length <= this.maxFeatures) {
options.callback.call(options.scope, resp);
} else {
displayFeatureWarning(resp.features.length, this.maxFeatures, function () {
options.callback.call(options.scope, resp);
});
}
}
}
function getData(bounds, reload) {
var projected = unproj(bounds);
var size = projected.getWidth() * projected.getHeight();
function getData() {
var size = browseBounds.getSize();
if (size > OSM.MAX_REQUEST_AREA) {
setStatus(I18n.t("browse.start_rjs.unable_to_load_size", { max_bbox_size: OSM.MAX_REQUEST_AREA, bbox_size: size }));
} else {
loadData("/api/" + OSM.API_VERSION + "/map?bbox=" + projected.toBBOX(), reload);
return;
}
}
function loadData(url, reload) {
setStatus(I18n.t('browse.start_rjs.loading'));
$("#browse_content").empty();
dataLayer.clearLayers();
selectedLayer = null;
var formatOptions = {
checkTags: true,
interestingTagsExclude: ['source','source_ref','source:ref','history','attribution','created_by','tiger:county','tiger:tlid','tiger:upload_uuid']
};
var url = "/api/" + OSM.API_VERSION + "/map?bbox=" + browseBounds.toBBOX();
if (areasHidden) formatOptions.areaTags = [];
/*
* Modern browsers are quite happy showing far more than 100 features in
* the data browser, so increase the limit to 2000 by default, but keep
* it restricted to 500 for IE8 and 100 for older IEs.
*/
var maxFeatures = 2000;
if (!browseDataLayer || reload) {
var style = new OpenLayers.Style();
style.addRules([new OpenLayers.Rule({
symbolizer: {
Polygon: { fillColor: '#ff0000', strokeColor: '#ff0000' },
Line: { fillColor: '#ffff00', strokeColor: '#000000', strokeOpacity: '0.4' },
Point: { fillColor: '#00ff00', strokeColor: '#00ff00' }
}
})]);
if (browseDataLayer) browseDataLayer.destroyFeatures();
/*
* Modern browsers are quite happy showing far more than 100 features in
* the data browser, so increase the limit to 2000 by default, but keep
* it restricted to 500 for IE8 and 100 for older IEs.
*/
var maxFeatures = 2000;
/*@cc_on
if (navigator.appVersion < 8) {
maxFeatures = 100;
} else if (navigator.appVersion < 9) {
maxFeatures = 500;
}
@*/
browseDataLayer = new OpenLayers.Layer.Vector("Data", {
strategies: [
new OpenLayers.Strategy.Fixed()
],
protocol: new OpenLayers.Protocol.HTTP({
url: url,
format: new OpenLayers.Format.OSM(formatOptions),
maxFeatures: maxFeatures,
handleRead: customDataLoader
}),
projection: new OpenLayers.Projection("EPSG:4326"),
displayInLayerSwitcher: false,
styleMap: new OpenLayers.StyleMap({
'default': style,
'select': { strokeColor: '#0000ff', strokeWidth: 8 }
})
});
browseDataLayer.events.register("loadend", browseDataLayer, dataLoaded );
map.addLayer(browseDataLayer);
browseSelectControl = new OpenLayers.Control.SelectFeature(browseDataLayer, { onSelect: onFeatureSelect });
browseSelectControl.handlers.feature.stopDown = false;
browseSelectControl.handlers.feature.stopUp = false;
map.addControl(browseSelectControl);
browseSelectControl.activate();
} else {
browseDataLayer.destroyFeatures();
browseDataLayer.refresh({ url: url });
}
browseActiveFeature = null;
}
function dataLoaded() {
if (this.map.dataLayer.active) {
clearStatus();
var features = [];
for (var i = 0; i < this.features.length; i++) {
var feature = this.features[i];
features.push({
typeName: featureTypeName(feature),
url: "/browse/" + featureType(feature) + "/" + feature.osm_id,
name: featureName(feature),
id: feature.id
});
/*@cc_on
if (navigator.appVersion < 8) {
maxFeatures = 100;
} else if (navigator.appVersion < 9) {
maxFeatures = 500;
}
@*/
browseObjectList = $(JST["templates/browse/feature_list"]({
features: features,
url: this.protocol.url
}))[0];
$.ajax({
url: url,
success: function (xml) {
clearStatus();
loadObjectList();
}
dataLayer.addData(xml);
layersById = {};
var features = [];
dataLayer.eachLayer(function (layer) {
var feature = layer.feature;
layersById[feature.id] = layer;
features.push({
typeName: featureTypeName(feature),
url: "/browse/" + feature.type + "/" + feature.id,
name: featureName(feature),
id: feature.id
});
});
browseObjectList = $(JST["templates/browse/feature_list"]({
features: features,
url: url
}))[0];
loadObjectList();
}
});
}
function viewFeatureLink() {
var feature = browseDataLayer.getFeatureById($(this).data("feature-id"));
var layer = feature.layer;
var layer = layersById[$(this).data("feature-id")];
for (var i = 0; i < layer.selectedFeatures.length; i++) {
var f = layer.selectedFeatures[i];
layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default"));
}
onFeatureSelect(feature);
onSelect(layer);
if (browseMode != "auto") {
map.setCenter(feature.geometry.getBounds().getCenterLonLat());
map.setCenter(layer.getBounds().getCenter());
}
return false;
@ -328,19 +225,15 @@ $(document).ready(function () {
return false;
}
function onFeatureSelect(feature) {
function onSelect(layer) {
// Unselect previously selected feature
if (browseActiveFeature) {
browseActiveFeature.layer.drawFeature(
browseActiveFeature,
browseActiveFeature.layer.styleMap.createSymbolizer(browseActiveFeature, "default")
);
if (selectedLayer) {
selectedLayer.setStyle(selectedLayer.originalStyle);
}
// Redraw in selected style
feature.layer.drawFeature(
feature, feature.layer.styleMap.createSymbolizer(feature, "select")
);
layer.originalStyle = layer.options;
layer.setStyle({color: '#0000ff', weight: 8});
// If the current object is the list, don't innerHTML="", since that could clear it.
if ($("#browse_content").firstChild == browseObjectList) {
@ -349,35 +242,41 @@ $(document).ready(function () {
$("#browse_content").empty();
}
var feature = layer.feature;
$("#browse_content").html(JST["templates/browse/feature"]({
name: featureNameSelect(feature),
url: "/browse/" + featureType(feature) + "/" + feature.osm_id,
attributes: feature.attributes
url: "/browse/" + feature.type + "/" + feature.id,
attributes: feature.tags
}));
$("#browse_content").find("a.browse_show_list").click(loadObjectList);
$("#browse_content").find("a.browse_show_history").click(loadHistory);
// Stash the currently drawn feature
browseActiveFeature = feature;
selectedLayer = layer;
}
dataLayer.on("click", function (e) {
onSelect(e.layer);
});
function loadHistory() {
$(this).attr("href", "").text(I18n.t('browse.start_rjs.wait'));
var feature = browseActiveFeature;
var feature = selectedLayer.feature;
$.ajax({
url: "/api/" + OSM.API_VERSION + "/" + featureType(feature) + "/" + feature.osm_id + "/history",
url: "/api/" + OSM.API_VERSION + "/" + feature.type + "/" + feature.id + "/history",
success: function (xml) {
if (browseActiveFeature != feature || $("#browse_content").firstChild == browseObjectList) {
if (selectedLayer.feature != feature || $("#browse_content").firstChild == browseObjectList) {
return;
}
$(this).remove();
var history = [];
var nodes = xml.getElementsByTagName(featureType(feature));
var nodes = xml.getElementsByTagName(feature.type);
for (var i = nodes.length - 1; i >= 0; i--) {
history.push({
user: nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user'),
@ -387,7 +286,7 @@ $(document).ready(function () {
$("#browse_content").append(JST["templates/browse/feature_history"]({
name: featureNameHistory(feature),
url: "/browse/" + featureType(feature) + "/" + feature.osm_id,
url: "/browse/" + feature.type + "/" + feature.id,
history: history
}));
}.bind(this)
@ -396,57 +295,26 @@ $(document).ready(function () {
return false;
}
function featureType(feature) {
if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
return "node";
} else {
return "way";
}
}
function featureTypeName(feature) {
if (featureType(feature) == "node") {
return I18n.t('browse.start_rjs.object_list.type.node');
} else if (featureType(feature) == "way") {
return I18n.t('browse.start_rjs.object_list.type.way');
}
return I18n.t('browse.start_rjs.object_list.type.' + feature.type);
}
function featureName(feature) {
var lang = $('html').attr('lang');
if (feature.attributes['name:' + lang]) {
return feature.attributes['name:' + lang];
} else if (feature.attributes.name) {
return feature.attributes.name;
} else {
return feature.osm_id;
}
return feature.tags['name:' + $('html').attr('lang')] ||
feature.tags.name ||
feature.id;
}
function featureNameSelect(feature) {
var lang = $('html').attr('lang');
if (feature.attributes['name:' + lang]) {
return feature.attributes['name:' + lang];
} else if (feature.attributes.name) {
return feature.attributes.name;
} else if (featureType(feature) == "node") {
return I18n.t("browse.start_rjs.object_list.selected.type.node", { id: feature.osm_id });
} else if (featureType(feature) == "way") {
return I18n.t("browse.start_rjs.object_list.selected.type.way", { id: feature.osm_id });
}
return feature.tags['name:' + $('html').attr('lang')] ||
feature.tags.name ||
I18n.t("browse.start_rjs.object_list.selected.type." + feature.type, { id: feature.id });
}
function featureNameHistory(feature) {
var lang = $('html').attr('lang');
if (feature.attributes['name:' + lang]) {
return feature.attributes['name:' + lang];
} else if (feature.attributes.name) {
return feature.attributes.name;
} else if (featureType(feature) == "node") {
return I18n.t("browse.start_rjs.object_list.history.type.node", { id: feature.osm_id });
} else if (featureType(feature) == "way") {
return I18n.t("browse.start_rjs.object_list.history.type.way", { id: feature.osm_id });
}
return feature.tags['name:' + $('html').attr('lang')] ||
feature.tags.name ||
I18n.t("browse.start_rjs.object_list.history.type." + feature.type, { id: feature.id });
}
function setStatus(status) {
@ -459,4 +327,4 @@ $(document).ready(function () {
$("#browse_status").hide();
}
}
});
});

View file

@ -11,37 +11,13 @@ $(document).ready(function () {
}
function startExport(sidebarHtml) {
var vectors,
box,
transform,
markerLayer,
markerControl;
var marker, rectangle;
vectors = new OpenLayers.Layer.Vector("Vector Layer", {
displayInLayerSwitcher: false
});
map.addLayer(vectors);
var drawHandler = new L.Rectangle.Draw(map, {title: I18n.t('export.start_rjs.drag_a_box')});
map.on('draw:rectangle-created', endDrag);
box = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, {
handlerOptions: {
sides: 4,
snapAngle: 90,
irregular: true,
persist: true
}
});
box.handler.callbacks.done = endDrag;
map.addControl(box);
transform = new OpenLayers.Control.TransformFeature(vectors, {
rotate: false,
irregular: true
});
transform.events.register("transformcomplete", transform, transformComplete);
map.addControl(transform);
map.events.register("moveend", map, mapMoved);
map.events.register("changebaselayer", map, htmlUrlChanged);
map.on("moveend", mapMoved);
map.on("layeradd layerremove", htmlUrlChanged);
$("#sidebar_title").html(I18n.t('export.start_rjs.export'));
$("#sidebar_content").html(sidebarHtml);
@ -58,12 +34,12 @@ $(document).ready(function () {
openSidebar();
if (map.baseLayer.name == "Mapnik") {
if (map.hasLayer(layers[0].layer)) {
$("#format_mapnik").prop("checked", true);
}
setBounds(map.getBounds());
formatChanged();
setBounds(map.getExtent());
$("body").removeClass("site-index").addClass("site-export");
@ -72,23 +48,30 @@ $(document).ready(function () {
clearBox();
clearMarker();
map.events.unregister("moveend", map, mapMoved);
map.events.unregister("changebaselayer", map, htmlUrlChanged);
map.removeLayer(vectors);
map.off("moveend", mapMoved);
map.off("layeradd layerremove", htmlUrlChanged);
map.off('draw:rectangle-created', endDrag);
drawHandler.disable();
});
function getMercatorBounds() {
var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(),
$("#maxlon").val(), $("#maxlat").val());
function getBounds() {
return L.latLngBounds(L.latLng($("#minlat").val(), $("#minlon").val()),
L.latLng($("#maxlat").val(), $("#maxlon").val()));
}
return proj(bounds);
function getMercatorBounds() {
var bounds = getBounds();
return L.bounds(L.CRS.EPSG3857.project(bounds.getSouthWest()),
L.CRS.EPSG3857.project(bounds.getNorthEast()));
}
function boundsChanged() {
var bounds = getMercatorBounds();
var bounds = getBounds();
map.events.unregister("moveend", map, mapMoved);
map.zoomToExtent(bounds);
map.off("moveend", mapMoved);
map.fitBounds(bounds);
clearBox();
drawBox(bounds);
@ -101,16 +84,15 @@ $(document).ready(function () {
$("#drag_box").html(I18n.t('export.start_rjs.drag_a_box'));
clearBox();
box.activate();
};
drawHandler.enable();
}
function endDrag(bbox) {
var bounds = bbox.getBounds();
function endDrag(e) {
var bounds = e.rect.getBounds();
map.events.unregister("moveend", map, mapMoved);
map.off("moveend", mapMoved);
setBounds(bounds);
drawBox(bounds);
box.deactivate();
validateControls();
$("#drag_box").html(I18n.t('export.start_rjs.manually_select'));
@ -124,41 +106,27 @@ $(document).ready(function () {
function startMarker() {
$("#add_marker").html(I18n.t('export.start_rjs.click_add_marker'));
if (!markerLayer) {
markerLayer = new OpenLayers.Layer.Vector("",{
displayInLayerSwitcher: false,
style: {
externalGraphic: OpenLayers.Util.getImageLocation("marker.png"),
graphicXOffset: -10.5,
graphicYOffset: -25,
graphicWidth: 21,
graphicHeight: 25
}
});
map.addLayer(markerLayer);
markerControl = new OpenLayers.Control.DrawFeature(markerLayer, OpenLayers.Handler.Point);
map.addControl(markerControl);
markerLayer.events.on({ "featureadded": endMarker });
}
markerLayer.destroyFeatures();
markerControl.activate();
map.on("click", endMarker);
return false;
}
function endMarker(event) {
markerControl.deactivate();
map.off("click", endMarker);
$("#add_marker").html(I18n.t('export.start_rjs.change_marker'));
$("#marker_inputs").show();
var geom = unproj(event.feature.geometry);
var latlng = event.latlng;
$("#marker_lon").val(geom.x.toFixed(5));
$("#marker_lat").val(geom.y.toFixed(5));
if (marker) {
map.removeLayer(marker);
}
marker = L.marker(latlng).addTo(map);
$("#marker_lon").val(latlng.lng.toFixed(5));
$("#marker_lat").val(latlng.lat.toFixed(5));
htmlUrlChanged();
}
@ -168,49 +136,45 @@ $(document).ready(function () {
$("#marker_inputs").hide();
$("#add_marker").html(I18n.t('export.start_rjs.add_marker'));
if (markerLayer) {
markerControl.destroy();
markerLayer.destroy();
markerLayer = null;
markerControl = null;
if (marker) {
map.removeLayer(marker);
}
}
function mapMoved() {
setBounds(map.getExtent());
setBounds(map.getBounds());
validateControls();
}
function setBounds(bounds) {
var toPrecision = zoomPrecision(map.getZoom());
bounds = unproj(bounds);
$("#minlon").val(toPrecision(bounds.left));
$("#minlat").val(toPrecision(bounds.bottom));
$("#maxlon").val(toPrecision(bounds.right));
$("#maxlat").val(toPrecision(bounds.top));
$("#minlon").val(toPrecision(bounds.getWestLng()));
$("#minlat").val(toPrecision(bounds.getSouthLat()));
$("#maxlon").val(toPrecision(bounds.getEastLng()));
$("#maxlat").val(toPrecision(bounds.getNorthLat()));
mapnikSizeChanged();
htmlUrlChanged();
}
function clearBox() {
transform.deactivate();
vectors.destroyFeatures();
if (rectangle) {
map.removeLayer(rectangle);
}
rectangle = null;
}
function drawBox(bounds) {
var feature = new OpenLayers.Feature.Vector(bounds.toGeometry());
vectors.addFeatures(feature);
transform.setFeature(feature);
rectangle = L.rectangle(bounds);
rectangle.addTo(map);
}
function validateControls() {
var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(), $("#maxlon").val(), $("#maxlat").val());
var bounds = getBounds();
if (bounds.getWidth() * bounds.getHeight() > OSM.MAX_REQUEST_AREA) {
var tooLarge = bounds.getSize() > OSM.MAX_REQUEST_AREA;
if (tooLarge) {
$("#export_osm_too_large").show();
} else {
$("#export_osm_too_large").hide();
@ -220,7 +184,7 @@ $(document).ready(function () {
var disabled = true;
if ($("#format_osm").prop("checked")) {
disabled = bounds.getWidth() * bounds.getHeight() > OSM.MAX_REQUEST_AREA;
disabled = tooLarge;
} else if ($("#format_mapnik").prop("checked")) {
disabled = $("#mapnik_scale").val() < max_scale;
}
@ -230,8 +194,9 @@ $(document).ready(function () {
}
function htmlUrlChanged() {
var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(), $("#maxlon").val(), $("#maxlat").val());
var layerName = map.baseLayer.keyid;
var bounds = getBounds();
var layerName = getMapBaseLayer().keyid;
var url = "http://" + OSM.SERVER_URL + "/export/embed.html?bbox=" + bounds.toBBOX() + "&amp;layer=" + layerName;
var markerUrl = "";
@ -243,9 +208,9 @@ $(document).ready(function () {
var html = '<iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="'+url+'" style="border: 1px solid black"></iframe>';
// Create "larger map" link
var center = bounds.getCenterLonLat();
var center = bounds.getCenter();
var zoom = map.getZoomForExtent(proj(bounds));
var zoom = map.getBoundsZoom(bounds);
var layers = getMapLayers();
@ -257,7 +222,7 @@ $(document).ready(function () {
escaped.push(c < 127 ? text.charAt(i) : "&#" + c + ";");
}
html += '<br /><small><a href="http://' + OSM.SERVER_URL + '/?lat='+center.lat+'&amp;lon='+center.lon+'&amp;zoom='+zoom+'&amp;layers='+layers+markerUrl+'">'+escaped.join("")+'</a></small>';
html += '<br /><small><a href="http://' + OSM.SERVER_URL + '/?lat='+center.lat+'&amp;lon='+center.lng+'&amp;zoom='+zoom+'&amp;layers='+layers+markerUrl+'">'+escaped.join("")+'</a></small>';
$("#export_html_text").val(html);
@ -276,7 +241,7 @@ $(document).ready(function () {
}
if ($("#format_mapnik").prop("checked")) {
$("#mapnik_scale").val(roundScale(map.getScale()));
// $("#mapnik_scale").val(roundScale(map.getScale()));
$("#export_mapnik").show();
mapnikSizeChanged();
@ -306,8 +271,8 @@ $(document).ready(function () {
function mapnikImageSize(scale) {
var bounds = getMercatorBounds();
return new OpenLayers.Size(Math.round(bounds.getWidth() / scale / 0.00028),
Math.round(bounds.getHeight() / scale / 0.00028));
return {w: Math.round(bounds.getWidth() / scale / 0.00028),
h: Math.round(bounds.getHeight() / scale / 0.00028)};
}
function roundScale(scale) {

View file

@ -1,10 +1,12 @@
$(document).ready(function () {
$("#open_map_key").click(function (e) {
e.preventDefault();
var url = $(this).attr('href'),
title = $(this).text();
function updateMapKey() {
var mapLayer = map.baseLayer.keyid,
var mapLayer = getMapBaseLayer().keyid,
mapZoom = map.getZoom();
$(".mapkey-table-entry").each(function () {
@ -24,13 +26,9 @@ $(document).ready(function () {
openSidebar({ title: title });
$("#sidebar").one("closed", function () {
map.events.unregister("zoomend", map, updateMapKey);
map.events.unregister("changelayer", map, updateMapKey);
map.off("zoomend layeradd layerremove", updateMapKey);
});
map.events.register("zoomend", map, updateMapKey);
map.events.register("changelayer", map, updateMapKey);
e.preventDefault();
map.on("zoomend layeradd layerremove", updateMapKey);
});
});

View file

@ -1,265 +1,192 @@
var epsg4326 = new OpenLayers.Projection("EPSG:4326");
// Leaflet extensions
L.LatLngBounds.include({
getSouthLat: function () {
return this._southWest.lat;
},
getWestLng: function () {
return this._southWest.lng;
},
getNorthLat: function () {
return this._northEast.lat;
},
getEastLng: function () {
return this._northEast.lng;
},
toBBOX: function () {
var decimal = 6;
var mult = Math.pow(10, decimal);
var xmin = Math.round(this.getWestLng() * mult) / mult;
var ymin = Math.round(this.getSouthLat() * mult) / mult;
var xmax = Math.round(this.getEastLng() * mult) / mult;
var ymax = Math.round(this.getNorthLat() * mult) / mult;
return xmin + "," + ymin + "," + xmax + "," + ymax;
},
getSize: function () {
return (this._northEast.lat - this._southWest.lat) *
(this._northEast.lng - this._southWest.lng);
}
});
L.Bounds.include({
getWidth: function () {
return this.max.x - this.min.x;
},
getHeight: function () {
return this.max.y - this.min.y;
}
});
var map;
var markers;
var vectors;
var popup;
function createMap(divName, options) {
options = options || {};
var layers = [
{
urlTemplate: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: "",
keyid: "mapnik",
layerCode: "M",
name: I18n.t("javascripts.map.base.standard")
},
{
urlTemplate: 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png',
attribution: "Tiles courtesy of <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>",
keyid: "cyclemap",
layerCode: "C",
name: I18n.t("javascripts.map.base.cycle_map")
},
{
urlTemplate: 'http://{s}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png',
attribution: "Tiles courtesy of <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>",
keyid: "transportmap",
layerCode: "T",
name: I18n.t("javascripts.map.base.transport_map")
},
{
urlTemplate: 'http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png',
subdomains: '1234',
attribution: "Tiles courtesy of <a href='http://www.mapquest.com/' target='_blank'>MapQuest</a> <img src='http://developer.mapquest.com/content/osm/mq_logo.png'>",
keyid: "mapquest",
layerCode: "Q",
name: I18n.t("javascripts.map.base.mapquest")
}
];
map = new OpenLayers.Map(divName, {
controls: options.controls || [
new OpenLayers.Control.ArgParser(),
new OpenLayers.Control.Attribution(),
new SimpleLayerSwitcher(),
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.Zoom(),
new OpenLayers.Control.SimplePanZoom(),
new OpenLayers.Control.ScaleLine({geodesic: true})
],
numZoomLevels: 20,
displayProjection: new OpenLayers.Projection("EPSG:4326"),
theme: "<%= asset_path 'theme/openstreetmap/style.css' %>"
});
function createMap(divName) {
map = L.map(divName);
var mapnik = new OpenLayers.Layer.OSM.Mapnik(I18n.t("javascripts.map.base.standard"), {
attribution: "",
keyid: "mapnik",
displayOutsideMaxExtent: true,
wrapDateLine: true,
layerCode: "M"
});
map.addLayer(mapnik);
map.attributionControl.setPrefix(''); // For tmcw
var cyclemap = new OpenLayers.Layer.OSM.CycleMap(I18n.t("javascripts.map.base.cycle_map"), {
attribution: "Tiles courtesy of <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>",
keyid: "cyclemap",
displayOutsideMaxExtent: true,
wrapDateLine: true,
layerCode: "C"
});
map.addLayer(cyclemap);
var layersControl = L.control.layers().addTo(map);
var transportmap = new OpenLayers.Layer.OSM.TransportMap(I18n.t("javascripts.map.base.transport_map"), {
attribution: "Tiles courtesy of <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>",
keyid: "transportmap",
displayOutsideMaxExtent: true,
wrapDateLine: true,
layerCode: "T"
});
map.addLayer(transportmap);
for (var i = 0; i < layers.length; i++) {
layers[i].layer = L.tileLayer(layers[i].urlTemplate, layers[i]);
if (i == 0) {
layers[i].layer.addTo(map);
}
layersControl.addBaseLayer(layers[i].layer, layers[i].name);
}
var mapquest = new OpenLayers.Layer.OSM(I18n.t("javascripts.map.base.mapquest"), [
"http://otile1.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile2.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile3.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile4.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png"
], {
attribution: "Tiles courtesy of <a href='http://www.mapquest.com/' target='_blank'>MapQuest</a> <img src='http://developer.mapquest.com/content/osm/mq_logo.png'>",
keyid: "mapquest",
displayOutsideMaxExtent: true,
wrapDateLine: true,
numZoomLevels: 19,
layerCode: "Q"
});
map.addLayer(mapquest);
$("#" + divName).on("resized", function () {
map.invalidateSize();
});
markers = new OpenLayers.Layer.Markers("Markers", {
displayInLayerSwitcher: false,
numZoomLevels: 20,
projection: "EPSG:900913"
});
map.addLayer(markers);
map.dataLayer = new OpenLayers.Layer(I18n.t('browse.start_rjs.data_layer_name'), {
visibility: false,
displayInLayerSwitcher: false
});
map.addLayer(map.dataLayer);
$("#" + divName).on("resized", function () {
map.updateSize();
});
return map;
return map;
}
function getArrowIcon() {
var size = new OpenLayers.Size(25, 22);
var offset = new OpenLayers.Pixel(-22, -20);
var icon = new OpenLayers.Icon("<%= asset_path 'arrow.png' %>", size, offset);
return icon;
return L.icon({
iconUrl: <%= asset_path('arrow.png').to_json %>,
iconSize: [25, 22],
iconAnchor: [22, 20]
});
}
function addMarkerToMap(position, icon, description) {
var marker = new OpenLayers.Marker(proj(position), icon);
var marker = L.marker(position, icon ? {icon: icon} : null).addTo(map);
markers.addMarker(marker);
if (description) {
marker.bindPopup(description);
}
if (description) {
marker.events.register("mouseover", marker, function() {
openMapPopup(marker, description);
});
}
return marker;
}
return marker;
function removeMarkerFromMap(marker) {
map.removeLayer(marker);
}
function addObjectToMap(object, zoom, callback) {
var layer = new OpenLayers.Layer.Vector("Objects", {
strategies: [
new OpenLayers.Strategy.Fixed()
],
protocol: new OpenLayers.Protocol.HTTP({
url: OSM.apiUrl(object),
format: new OpenLayers.Format.OSM()
}),
style: {
$.ajax({
url: OSM.apiUrl(object),
dataType: "xml",
success: function (xml) {
var layer = new L.OSM(xml, {
style: {
strokeColor: "blue",
strokeWidth: 3,
strokeOpacity: 0.5,
fillOpacity: 0.2,
fillColor: "lightblue",
pointRadius: 6
},
projection: new OpenLayers.Projection("EPSG:4326"),
displayInLayerSwitcher: false
});
}
});
layer.events.register("loadend", layer, function() {
var extent;
var bounds = layer.getBounds();
if (this.features.length) {
extent = this.features[0].geometry.getBounds();
for (var i = 1; i < this.features.length; i++) {
extent.extend(this.features[i].geometry.getBounds());
}
if (zoom) {
if (extent) {
this.map.zoomToExtent(extent);
} else {
this.map.zoomToMaxExtent();
}
}
if (zoom) {
map.fitBounds(bounds);
}
if (callback) {
callback(extent);
callback(bounds);
}
});
map.addLayer(layer);
layer.addTo(map);
}
});
}
function addBoxToMap(boxbounds, id, outline) {
if (!vectors) {
// Be aware that IE requires Vector layers be initialised on page load, and not under deferred script conditions
vectors = new OpenLayers.Layer.Vector("Boxes", {
displayInLayerSwitcher: false
});
map.addLayer(vectors);
}
var geometry;
if (outline) {
vertices = boxbounds.toGeometry().getVertices();
vertices.push(new OpenLayers.Geometry.Point(vertices[0].x, vertices[0].y));
geometry = proj(new OpenLayers.Geometry.LineString(vertices));
} else {
geometry = proj(boxbounds.toGeometry());
}
var box = new OpenLayers.Feature.Vector(geometry, {}, {
strokeWidth: 2,
strokeColor: '#ee9900',
fillOpacity: 0
});
box.fid = id;
function addBoxToMap(bounds) {
var box = L.rectangle(bounds, {
weight: 2,
color: '#e90',
fillOpacity: 0
});
vectors.addFeatures(box);
box.addTo(map);
return box;
return box;
}
function openMapPopup(marker, description) {
closeMapPopup();
popup = new OpenLayers.Popup.FramedCloud("popup", marker.lonlat, null,
description, marker.icon, true);
popup.setBackgroundColor("#E3FFC5");
map.addPopup(popup);
return popup;
}
function closeMapPopup() {
if (popup) {
map.removePopup(popup);
}
}
function removeMarkerFromMap(marker){
markers.removeMarker(marker);
}
function proj(x) {
return x.clone().transform(epsg4326, map.getProjectionObject());
}
function unproj(x) {
return x.clone().transform(map.getProjectionObject(), epsg4326);
}
function setMapCenter(center, zoom) {
zoom = parseInt(zoom, 10);
var numzoom = map.getNumZoomLevels();
if (zoom >= numzoom) zoom = numzoom - 1;
map.setCenter(proj(center), zoom);
}
function getEventPosition(event) {
return unproj(map.getLonLatFromViewPortPx(event.xy));
function getMapBaseLayer() {
for (var i = 0; i < layers.length; i++) {
if (map.hasLayer(layers[i].layer)) {
return layers[i];
}
}
}
function getMapLayers() {
var layerConfig = "";
for (var i = 0; i < layers.length; i++) {
if (map.hasLayer(layers[i].layer)) {
return layers[i].layerCode;
}
}
for (var i = 0; i < map.layers.length; i++) {
if (map.layers[i].layerCode && map.layers[i].getVisibility()) {
layerConfig += map.layers[i].layerCode;
}
}
return layerConfig;
return "";
}
function setMapLayers(layerConfig) {
if (layerConfig.charAt(0) == "B" || layerConfig.charAt(0) == "0") {
var l = 0;
for (var layers = map.getLayersBy("isBaseLayer", true), i = 0; i < layers.length; i++) {
var c = layerConfig.charAt(l++);
if (c == "B") {
map.setBaseLayer(layers[i]);
} else {
map.layers[i].setVisibility(false);
}
}
} else {
for (var i = 0; i < map.layers.length; i++) {
if (map.layers[i].layerCode) {
if (layerConfig.indexOf(map.layers[i].layerCode) >= 0) {
if (map.layers[i].isBaseLayer) {
map.setBaseLayer(map.layers[i]);
} else {
map.layers[i].setVisibility(true);
}
} else if (!map.layers[i].isBaseLayer) {
map.layers[i].setVisibility(false);
}
}
}
}
for (var i = 0; i < layers.length; i++) {
if (~layerConfig.indexOf(layers[i].layerCode)) {
map.addLayer(layers[i].layer);
} else {
map.removeLayer(layers[i].layer);
}
}
}

View file

@ -1,39 +0,0 @@
//= require OpenLayers
//= require OpenStreetMap
//= require SimpleLayerSwitcher
//= require SimplePanZoom
OpenLayers.Util.imageURLs = {
"404.png": "<%= asset_path 'img/404.png' %>",
"blank.gif": "<%= asset_path 'img/blank.gif' %>",
"cloud-popup-relative.png": "<%= asset_path 'img/cloud-popup-relative.png' %>",
"drag-rectangle-off.png": "<%= asset_path 'img/drag-rectangle-off.png' %>",
"drag-rectangle-on.png": "<%= asset_path 'img/drag-rectangle-on.png' %>",
"east-mini.png": "<%= asset_path 'img/east-mini.png' %>",
"layer-switcher-maximize.png": "<%= asset_path 'img/layer-switcher-maximize.png' %>",
"layer-switcher-minimize.png": "<%= asset_path 'img/layer-switcher-minimize.png' %>",
"marker-blue.png": "<%= asset_path 'img/marker-blue.png' %>",
"marker-gold.png": "<%= asset_path 'img/marker-gold.png' %>",
"marker-green.png": "<%= asset_path 'img/marker-green.png' %>",
"marker.png": "<%= asset_path 'img/marker.png' %>",
"measuring-stick-off.png": "<%= asset_path 'img/measuring-stick-off.png' %>",
"measuring-stick-on.png": "<%= asset_path 'img/measuring-stick-on.png' %>",
"north-mini.png": "<%= asset_path 'img/north-mini.png' %>",
"panning-hand-off.png": "<%= asset_path 'img/panning-hand-off.png' %>",
"panning-hand-on.png": "<%= asset_path 'img/panning-hand-on.png' %>",
"slider.png": "<%= asset_path 'img/slider.png' %>",
"south-mini.png": "<%= asset_path 'img/south-mini.png' %>",
"west-mini.png": "<%= asset_path 'img/west-mini.png' %>",
"zoombar.png": "<%= asset_path 'img/zoombar.png' %>",
"zoom-minus-mini.png": "<%= asset_path 'img/zoom-minus-mini.png' %>",
"zoom-plus-mini.png": "<%= asset_path 'img/zoom-plus-mini.png' %>",
"zoom-world-mini.png": "<%= asset_path 'img/zoom-world-mini.png' %>"
};
OpenLayers.Util.origGetImageLocation = OpenLayers.Util.getImageLocation;
OpenLayers.Util.getImageLocation = function(image) {
return OpenLayers.Util.imageURLs[image] || OpenLayers.Util.origGetImageLocation(image);
};
OpenLayers.Lang.setCode($('html').attr('lang'));

View file

@ -2,40 +2,36 @@ $(document).ready(function () {
var map = createMap("map");
if (OSM.home) {
setMapCenter(new OpenLayers.LonLat(OSM.home.lon, OSM.home.lat), 12);
map.setView([OSM.home.lat, OSM.home.lon], 12);
} else {
setMapCenter(new OpenLayers.LonLat(0, 0), 0);
map.setView([0, 0], 0);
}
if ($("#map").hasClass("set_location")) {
var marker;
if (OSM.home) {
marker = addMarkerToMap(new OpenLayers.LonLat(OSM.home.lon, OSM.home.lat));
marker = addMarkerToMap([OSM.home.lat, OSM.home.lon]);
}
map.events.register("click", map, function (e) {
map.on("click", function (e) {
if ($('#updatehome').is(':checked')) {
var lonlat = getEventPosition(e);
$('#homerow').removeClass();
$('#home_lat').val(lonlat.lat);
$('#home_lon').val(lonlat.lon);
$('#home_lat').val(e.latlng.lat);
$('#home_lon').val(e.latlng.lng);
if (marker) {
removeMarkerFromMap(marker);
}
marker = addMarkerToMap(lonlat);
marker = addMarkerToMap(e.latlng);
}
});
} else {
$("[data-user]").each(function () {
var user = $(this).data('user');
if (user.lon && user.lat) {
var icon = OpenLayers.Marker.defaultIcon();
icon.url = OpenLayers.Util.getImageLocation(user.icon);
addMarkerToMap(new OpenLayers.LonLat(user.lon, user.lat), icon, user.description);
addMarkerToMap([user.lat, user.lon], L.icon({iconUrl: user.icon}), user.description);
}
});
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

View file

@ -1,66 +0,0 @@
/*
*= require theme/default/style
*= require theme/openstreetmap/SimpleLayerSwitcher
*= require theme/openstreetmap/SimplePanZoom
*/
.olControlOverviewMapExtentRectangle {
background-image: image-url("theme/default/img/blank.gif");
}
.olControlOverviewMapRectReplacement {
background-image: image-url("theme/default/img/overview_replacement.gif");
}
.olControlNavigationHistory {
background-image: image-url("theme/default/img/navigation_history.png");
}
div.olControlSaveFeaturesItemActive {
background-image: image-url("theme/default/img/save_features_on.png");
}
div.olControlSaveFeaturesItemInactive {
background-image: image-url("theme/default/img/save_features_off.png");
}
.olControlPanPanel div {
background-image: image-url("theme/default/img/pan-panel.png");
}
.olControlZoomPanel div {
background-image: image-url("theme/default/img/zoom-panel.png");
}
.olPopupCloseBox {
background: image-url("theme/default/img/close.gif") no-repeat;
}
.olImageLoadError {
// remove opacity?
// remove filter?
background: image-url("theme/openstreetmap/img/missing-tile.png") no-repeat;
}
.olControlNavToolbar div,
.olControlEditingToolbar div {
background-image: image-url("theme/default/img/editing_tool_bar.png");
}
div.olControlZoom a {
color: black;
background: #ffffff;
border: 1px solid #cccccc;
margin: 0 !important;
// remove filter
}
div.olControlZoom a.olControlZoomIn {
border-bottom: 0;
}
div.olControlZoom a:hover {
background: #f5f5f5;
}
// remove max-width hover?

View file

@ -5,7 +5,13 @@
<%= stylesheet_link_tag "small-#{dir}", :media => "only screen and (max-width:641px)" %>
<%= stylesheet_link_tag "large-#{dir}", :media => "screen and (min-width: 642px)" %>
<%= stylesheet_link_tag "print-#{dir}", :media => "print" %>
<!--[if IE]><%= stylesheet_link_tag "large-#{dir}", :media => "screen" %><![endif]--> <!-- IE is totally broken with CSS media queries -->
<%= stylesheet_link_tag "leaflet" %>
<%= stylesheet_link_tag "leaflet.draw" %>
<!--[if IE]>
<%= stylesheet_link_tag "leaflet.ie" %>
<%= stylesheet_link_tag "leaflet.draw.ie" %>
<%= stylesheet_link_tag "large-#{dir}", :media => "screen" %>
<![endif]--> <!-- IE is totally broken with CSS media queries -->
<%= favicon_link_tag "favicon.ico" %>
<%= favicon_link_tag "osm_logo.png", :rel => "apple-touch-icon", :type => "image/png" %>
<%= tag("link", { :rel => "publisher", :href => "https://plus.google.com/111953119785824514010" }) %>

View file

@ -3,7 +3,7 @@
user_data = {
:lon => contact.home_lon,
:lat => contact.home_lat,
:icon => type == "friend" ? "marker-blue.png" : "marker-green.png",
:icon => image_path(type == "friend" ? "marker-blue.png" : "marker-green.png"),
:description => render(:partial => "popup", :object => contact, :locals => {:type => type})
}
%>

View file

@ -118,7 +118,7 @@
user_data = {
:lon => @user.home_lon,
:lat => @user.home_lat,
:icon => "marker.png",
:icon => image_path("marker-red.png"),
:description => render(:partial => "popup", :object => @user, :locals => {:type => "your location"})
}
%>

BIN
vendor/assets/leaflet/images/layers.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
vendor/assets/leaflet/images/zoom-in.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

378
vendor/assets/leaflet/leaflet.css vendored Normal file
View file

@ -0,0 +1,378 @@
/* required styles */
.leaflet-map-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-pane,
.leaflet-overlay-pane,
.leaflet-shadow-pane,
.leaflet-marker-pane,
.leaflet-popup-pane,
.leaflet-overlay-pane svg,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer { /* TODO optimize classes */
position: absolute;
}
.leaflet-container {
overflow: hidden;
outline: 0;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
.leaflet-clickable {
cursor: pointer;
}
.leaflet-dragging, .leaflet-dragging .leaflet-clickable {
cursor: move;
}
.leaflet-container img {
/* map is broken in FF if you have max-width: 100% on tiles */
max-width: none !important;
}
.leaflet-container img.leaflet-image-layer {
/* stupid Android 2 doesn't understand "max-width: none" properly */
max-width: 15000px !important;
}
.leaflet-tile-pane { z-index: 2; }
.leaflet-objects-pane { z-index: 3; }
.leaflet-overlay-pane { z-index: 4; }
.leaflet-shadow-pane { z-index: 5; }
.leaflet-marker-pane { z-index: 6; }
.leaflet-popup-pane { z-index: 7; }
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
}
/* Leaflet controls */
.leaflet-control {
position: relative;
z-index: 7;
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
.leaflet-control-zoom {
-moz-border-radius: 7px;
-webkit-border-radius: 7px;
border-radius: 7px;
}
.leaflet-control-zoom {
padding: 5px;
background: rgba(0, 0, 0, 0.25);
}
.leaflet-control-zoom a {
background-color: rgba(255, 255, 255, 0.75);
}
.leaflet-control-zoom a, .leaflet-control-layers a {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-control-zoom a {
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
width: 19px;
height: 19px;
}
.leaflet-control-zoom a:hover {
background-color: #fff;
}
.leaflet-touch .leaflet-control-zoom a {
width: 27px;
height: 27px;
}
.leaflet-control-zoom-in {
background-image: url(images/zoom-in.png);
margin-bottom: 5px;
}
.leaflet-control-zoom-out {
background-image: url(images/zoom-out.png);
}
.leaflet-control-layers {
box-shadow: 0 1px 7px #999;
background: #f8f8f9;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}
.leaflet-control-layers a {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-touch .leaflet-control-layers a {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
color: #333;
background: #fff;
}
.leaflet-control-layers input {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
.leaflet-container .leaflet-control-attribution {
background-color: rgba(255, 255, 255, 0.7);
box-shadow: 0 0 5px #bbb;
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
}
.leaflet-container .leaflet-control-attribution,
.leaflet-container .leaflet-control-scale {
font: 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
color: black;
line-height: 1;
font-size: 10px;
padding-bottom: 2px;
text-shadow: 1px 1px 1px #fff;
background-color: rgba(255, 255, 255, 0.5);
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
padding-top: 1px;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution, .leaflet-touch .leaflet-control-layers {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers {
border: 5px solid #bbb;
}
/* Zoom and fade animations */
.leaflet-fade-anim .leaflet-tile, .leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-tile-loaded, .leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0.25,0.1,0.25,0.75);
-moz-transition: -moz-transform 0.25s cubic-bezier(0.25,0.1,0.25,0.75);
-o-transition: -o-transform 0.25s cubic-bezier(0.25,0.1,0.25,0.75);
transition: transform 0.25s cubic-bezier(0.25,0.1,0.25,0.75);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile,
.leaflet-touching .leaflet-zoom-animated {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* Popup layout */
.leaflet-popup {
position: absolute;
text-align: center;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
}
.leaflet-popup-content {
margin: 14px 20px;
}
.leaflet-popup-tip-container {
margin: 0 auto;
width: 40px;
height: 20px;
position: relative;
overflow: hidden;
}
.leaflet-popup-tip {
width: 15px;
height: 15px;
padding: 1px;
margin: -8px auto 0;
-moz-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
padding: 4px 5px 0 0;
text-align: center;
width: 18px;
height: 14px;
font: 16px/14px Tahoma, Verdana, sans-serif;
color: #c3c3c3;
text-decoration: none;
font-weight: bold;
}
.leaflet-container a.leaflet-popup-close-button:hover {
color: #999;
}
.leaflet-popup-content p {
margin: 18px 0;
}
.leaflet-popup-scrolled {
overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
}
/* Visual appearance */
.leaflet-container {
background: #ddd;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-container a.leaflet-active {
outline: 2px solid orange;
}
.leaflet-zoom-box {
border: 2px dotted #05f;
background: white;
opacity: 0.5;
}
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}
.leaflet-editing-icon {
border-radius: 2px;
}
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
background: white;
box-shadow: 0 3px 14px rgba(0,0,0,0.35);
-webkit-box-shadow: 0 3px 18px rgba(0,0,0,0.33);
}
.leaflet-popup-content-wrapper {
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
}
.leaflet-popup-content {
font: 12px/1.4 "Helvetica Neue", Arial, Helvetica, sans-serif;
}

130
vendor/assets/leaflet/leaflet.draw.css vendored Normal file
View file

@ -0,0 +1,130 @@
/* Leaflet controls */
.leaflet-control-draw {
background-color: rgba(0, 0, 0, 0.25);
-webkit-border-radius: 7px;
-moz-border-radius: 7px;
border-radius: 7px;
padding: 5px;
}
.leaflet-control-draw a {
background-color: rgba(255, 255, 255, 0.75);
background-position: 50% 50%;
background-repeat: no-repeat;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
display: block;
margin-top: 5px;
width: 19px;
height: 19px;
}
.leaflet-control-draw a:first-child{
margin-top: 0;
}
.leaflet-control-draw a:hover {
background-color: #fff;
}
.leaflet-touch .leaflet-control-draw a {
width: 27px;
height: 27px;
}
.leaflet-control-draw-polyline {
background-image: url(images/draw-polyline.png);
}
.leaflet-control-draw-polygon {
background-image: url(images/draw-polygon.png);
}
.leaflet-control-draw-rectangle {
background-image: url(images/draw-rectangle.png);
}
.leaflet-control-draw-circle {
background-image: url(images/draw-circle.png);
}
.leaflet-control-draw-marker {
background-image: url(images/draw-marker-icon.png);
}
.leaflet-mouse-marker {
background-color: #fff;
cursor: crosshair;
}
.leaflet-draw-label {
background-color: #fff;
border: 1px solid #ccc;
color: #222;
font: 12px/18px "Helvetica Neue", Arial, Helvetica, sans-serif;
margin-left: 20px;
margin-top: -21px;
padding: 2px 4px;
position: absolute;
white-space: nowrap;
z-index: 6;
}
.leaflet-error-draw-label {
background-color: #F2DEDE;
border-color: #E6B6BD;
color: #B94A48;
}
.leaflet-draw-label-single {
margin-top: -12px
}
.leaflet-draw-label-subtext {
color: #999;
}
.leaflet-draw-guide-dash {
font-size: 1%;
opacity: 0.6;
position: absolute;
width: 5px;
height: 5px;
}
.leaflet-flash-anim {
-webkit-animation-duration: 0.66s;
-moz-animation-duration: 0.66s;
-o-animation-duration: 0.66s;
animation-duration: 0.66s;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-name: leaflet-flash;
-moz-animation-name: leaflet-flash;
-o-animation-name: leaflet-flash;
animation-name: leaflet-flash;
}
@-webkit-keyframes leaflet-flash {
0%, 50%, 100% { opacity: 1; }
25%, 75% { opacity: 0.3; }
}
@-moz-keyframes leaflet-flash {
0%, 50%, 100% { opacity: 1; }
25%, 75% { opacity: 0.3; }
}
@-o-keyframes leaflet-flash {
0%, 50%, 100% { opacity: 1; }
25%, 75% { opacity: 0.3; }
}
@keyframes leaflet-flash {
0%, 50%, 100% { opacity: 1; }
25%, 75% { opacity: 0; }
}

View file

@ -0,0 +1,10 @@
/* Conditional stylesheet for IE. */
.leaflet-control-draw {
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#3F000000', EndColorStr='#3F000000');
}
.leaflet-control-draw a {
background-color: #eee;
filter: alpha(opacity=90);
}

931
vendor/assets/leaflet/leaflet.draw.js vendored Normal file
View file

@ -0,0 +1,931 @@
/*
Copyright (c) 2012, Smartrak, Jacob Toye
Leaflet.draw is an open-source JavaScript library for drawing shapes/markers on leaflet powered maps.
https://github.com/jacobtoye/Leaflet.draw
*/
(function (window, undefined) {
L.drawVersion = '0.1.4';
L.Util.extend(L.LineUtil, {
// Checks to see if two line segments intersect. Does not handle degenerate cases.
// http://compgeom.cs.uiuc.edu/~jeffe/teaching/373/notes/x06-sweepline.pdf
segmentsIntersect: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2, /*Point*/ p3) {
return this._checkCounterclockwise(p, p2, p3) !==
this._checkCounterclockwise(p1, p2, p3) &&
this._checkCounterclockwise(p, p1, p2) !==
this._checkCounterclockwise(p, p1, p3);
},
// check to see if points are in counterclockwise order
_checkCounterclockwise: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
return (p2.y - p.y) * (p1.x - p.x) > (p1.y - p.y) * (p2.x - p.x);
}
});
L.Polyline.include({
// Check to see if this polyline has any linesegments that intersect.
// NOTE: does not support detecting intersection for degenerate cases.
intersects: function () {
var points = this._originalPoints,
len = points ? points.length : 0,
i, j, p, p1, p2, p3;
if (this._tooFewPointsForIntersection()) {
return false;
}
for (i = len - 1; i >= 3; i--) {
p = points[i - 1];
p1 = points[i];
if (this._lineSegmentsIntersectsRange(p, p1, i - 2)) {
return true;
}
}
return false;
},
// Check for intersection if new latlng was added to this polyline.
// NOTE: does not support detecting intersection for degenerate cases.
newLatLngIntersects: function (latlng, skipFirst) {
// Cannot check a polyline for intersecting lats/lngs when not added to the map
if (!this._map) {
return false;
}
return this.newPointIntersects(this._map.latLngToLayerPoint(latlng), skipFirst);
},
// Check for intersection if new point was added to this polyline.
// newPoint must be a layer point.
// NOTE: does not support detecting intersection for degenerate cases.
newPointIntersects: function (newPoint, skipFirst) {
var points = this._originalPoints,
len = points ? points.length : 0,
lastPoint = points ? points[len - 1] : null,
// The previous previous line segment. Previous line segement doesn't need testing.
maxIndex = len - 2;
if (this._tooFewPointsForIntersection(1)) {
return false;
}
return this._lineSegmentsIntersectsRange(lastPoint, newPoint, maxIndex, skipFirst ? 1 : 0);
},
// Polylines with 2 sides can only intersect in cases where points are collinear (we don't support detecting these).
// Cannot have intersection when < 3 line segments (< 4 points)
_tooFewPointsForIntersection: function (extraPoints) {
var points = this._originalPoints,
len = points ? points.length : 0;
// Increment length by extraPoints if present
len += extraPoints || 0;
return !this._originalPoints || len <= 3;
},
// Checks a line segment intersections with any line segements before its predecessor.
// Don't need to check the predecessor as will never intersect.
_lineSegmentsIntersectsRange: function (p, p1, maxIndex, minIndex) {
var points = this._originalPoints,
p2, p3;
minIndex = minIndex || 0;
// Check all previous line segments (beside the immediately previous) for intersections
for (var j = maxIndex; j > minIndex; j--) {
p2 = points[j - 1];
p3 = points[j];
if (L.LineUtil.segmentsIntersect(p, p1, p2, p3)) {
return true;
}
}
return false;
}
});
L.Polygon.include({
// Checks a polygon for any intersecting line segments. Ignores holes.
intersects: function () {
var polylineIntersects,
points = this._originalPoints,
len, firstPoint, lastPoint, maxIndex;
if (this._tooFewPointsForIntersection()) {
return false;
}
polylineIntersects = L.Polyline.prototype.intersects.call(this);
// If already found an intersection don't need to check for any more.
if (polylineIntersects) {
return true;
}
len = points.length;
firstPoint = points[0];
lastPoint = points[len - 1];
maxIndex = len - 2;
// Check the line segment between last and first point. Don't need to check the first line segment (minIndex = 1)
return this._lineSegmentsIntersectsRange(lastPoint, firstPoint, maxIndex, 1);
}
});
L.Handler.Draw = L.Handler.extend({
includes: L.Mixin.Events,
initialize: function (map, options) {
this._map = map;
this._container = map._container;
this._overlayPane = map._panes.overlayPane;
this._popupPane = map._panes.popupPane;
// Merge default shapeOptions options with custom shapeOptions
if (options && options.shapeOptions) {
options.shapeOptions = L.Util.extend({}, this.options.shapeOptions, options.shapeOptions);
}
L.Util.extend(this.options, options);
},
enable: function () {
this.fire('activated');
L.Handler.prototype.enable.call(this);
},
addHooks: function () {
if (this._map) {
L.DomUtil.disableTextSelection();
this._label = L.DomUtil.create('div', 'leaflet-draw-label', this._popupPane);
this._singleLineLabel = false;
L.DomEvent.addListener(this._container, 'keyup', this._cancelDrawing, this);
}
},
removeHooks: function () {
if (this._map) {
L.DomUtil.enableTextSelection();
this._popupPane.removeChild(this._label);
delete this._label;
L.DomEvent.removeListener(this._container, 'keyup', this._cancelDrawing);
}
},
_updateLabelText: function (labelText) {
labelText.subtext = labelText.subtext || '';
// update the vertical position (only if changed)
if (labelText.subtext.length === 0 && !this._singleLineLabel) {
L.DomUtil.addClass(this._label, 'leaflet-draw-label-single');
this._singleLineLabel = true;
}
else if (labelText.subtext.length > 0 && this._singleLineLabel) {
L.DomUtil.removeClass(this._label, 'leaflet-draw-label-single');
this._singleLineLabel = false;
}
this._label.innerHTML =
(labelText.subtext.length > 0 ? '<span class="leaflet-draw-label-subtext">' + labelText.subtext + '</span>' + '<br />' : '') +
'<span>' + labelText.text + '</span>';
},
_updateLabelPosition: function (pos) {
L.DomUtil.setPosition(this._label, pos);
},
// Cancel drawing when the escape key is pressed
_cancelDrawing: function (e) {
if (e.keyCode === 27) {
this.disable();
}
}
});
L.Polyline.Draw = L.Handler.Draw.extend({
Poly: L.Polyline,
options: {
allowIntersection: true,
drawError: {
color: '#b00b00',
message: '<strong>Error:</strong> shape edges cannot cross!',
timeout: 2500
},
icon: new L.DivIcon({
iconSize: new L.Point(8, 8),
className: 'leaflet-div-icon leaflet-editing-icon'
}),
guidelineDistance: 20,
shapeOptions: {
stroke: true,
color: '#f06eaa',
weight: 4,
opacity: 0.5,
fill: false,
clickable: true
},
zIndexOffset: 2000 // This should be > than the highest z-index any map layers
},
initialize: function (map, options) {
// Merge default drawError options with custom options
if (options && options.drawError) {
options.drawError = L.Util.extend({}, this.options.drawError, options.drawError);
}
L.Handler.Draw.prototype.initialize.call(this, map, options);
},
addHooks: function () {
L.Handler.Draw.prototype.addHooks.call(this);
if (this._map) {
this._markers = [];
this._markerGroup = new L.LayerGroup();
this._map.addLayer(this._markerGroup);
this._poly = new L.Polyline([], this.options.shapeOptions);
this._updateLabelText(this._getLabelText());
// Make a transparent marker that will used to catch click events. These click
// events will create the vertices. We need to do this so we can ensure that
// we can create vertices over other map layers (markers, vector layers). We
// also do not want to trigger any click handlers of objects we are clicking on
// while drawing.
if (!this._mouseMarker) {
this._mouseMarker = L.marker(this._map.getCenter(), {
icon: L.divIcon({
className: 'leaflet-mouse-marker',
iconAnchor: [20, 20],
iconSize: [40, 40]
}),
opacity: 0,
zIndexOffset: this.options.zIndexOffset
});
}
this._mouseMarker
.on('click', this._onClick, this)
.addTo(this._map);
this._map.on('mousemove', this._onMouseMove, this);
}
},
removeHooks: function () {
L.Handler.Draw.prototype.removeHooks.call(this);
this._clearHideErrorTimeout();
this._cleanUpShape();
// remove markers from map
this._map.removeLayer(this._markerGroup);
delete this._markerGroup;
delete this._markers;
this._map.removeLayer(this._poly);
delete this._poly;
this._mouseMarker.off('click', this._onClick);
this._map.removeLayer(this._mouseMarker);
delete this._mouseMarker;
// clean up DOM
this._clearGuides();
this._map.off('mousemove', this._onMouseMove);
},
_finishShape: function () {
if (!this.options.allowIntersection && this._poly.newLatLngIntersects(this._poly.getLatLngs()[0], true)) {
this._showErrorLabel();
return;
}
if (!this._shapeIsValid()) {
this._showErrorLabel();
return;
}
this._map.fire(
'draw:poly-created',
{ poly: new this.Poly(this._poly.getLatLngs(), this.options.shapeOptions) }
);
this.disable();
},
//Called to verify the shape is valid when the user tries to finish it
//Return false if the shape is not valid
_shapeIsValid: function () {
return true;
},
_onMouseMove: function (e) {
var newPos = e.layerPoint,
latlng = e.latlng,
markerCount = this._markers.length;
// Save latlng
this._currentLatLng = latlng;
// update the label
this._updateLabelPosition(newPos);
if (markerCount > 0) {
this._updateLabelText(this._getLabelText());
// draw the guide line
this._clearGuides();
this._drawGuide(
this._map.latLngToLayerPoint(this._markers[markerCount - 1].getLatLng()),
newPos
);
}
// Update the mouse marker position
this._mouseMarker.setLatLng(latlng);
L.DomEvent.preventDefault(e.originalEvent);
},
_onClick: function (e) {
var latlng = e.target.getLatLng(),
markerCount = this._markers.length;
if (markerCount > 0 && !this.options.allowIntersection && this._poly.newLatLngIntersects(latlng)) {
this._showErrorLabel();
return;
}
else if (this._errorShown) {
this._hideErrorLabel();
}
this._markers.push(this._createMarker(latlng));
this._poly.addLatLng(latlng);
if (this._poly.getLatLngs().length === 2) {
this._map.addLayer(this._poly);
}
this._updateMarkerHandler();
this._vertexAdded(latlng);
},
_updateMarkerHandler: function () {
// The last marker shold have a click handler to close the polyline
if (this._markers.length > 1) {
this._markers[this._markers.length - 1].on('click', this._finishShape, this);
}
// Remove the old marker click handler (as only the last point should close the polyline)
if (this._markers.length > 2) {
this._markers[this._markers.length - 2].off('click', this._finishShape);
}
},
_createMarker: function (latlng) {
var marker = new L.Marker(latlng, {
icon: this.options.icon,
zIndexOffset: this.options.zIndexOffset * 2
});
this._markerGroup.addLayer(marker);
return marker;
},
_drawGuide: function (pointA, pointB) {
var length = Math.floor(Math.sqrt(Math.pow((pointB.x - pointA.x), 2) + Math.pow((pointB.y - pointA.y), 2))),
i,
fraction,
dashPoint,
dash;
//create the guides container if we haven't yet (TODO: probaly shouldn't do this every time the user starts to draw?)
if (!this._guidesContainer) {
this._guidesContainer = L.DomUtil.create('div', 'leaflet-draw-guides', this._overlayPane);
}
//draw a dash every GuildeLineDistance
for (i = this.options.guidelineDistance; i < length; i += this.options.guidelineDistance) {
//work out fraction along line we are
fraction = i / length;
//calculate new x,y point
dashPoint = {
x: Math.floor((pointA.x * (1 - fraction)) + (fraction * pointB.x)),
y: Math.floor((pointA.y * (1 - fraction)) + (fraction * pointB.y))
};
//add guide dash to guide container
dash = L.DomUtil.create('div', 'leaflet-draw-guide-dash', this._guidesContainer);
dash.style.backgroundColor =
!this._errorShown ? this.options.shapeOptions.color : this.options.drawError.color;
L.DomUtil.setPosition(dash, dashPoint);
}
},
_updateGuideColor: function (color) {
if (this._guidesContainer) {
for (var i = 0, l = this._guidesContainer.childNodes.length; i < l; i++) {
this._guidesContainer.childNodes[i].style.backgroundColor = color;
}
}
},
// removes all child elements (guide dashes) from the guides container
_clearGuides: function () {
if (this._guidesContainer) {
while (this._guidesContainer.firstChild) {
this._guidesContainer.removeChild(this._guidesContainer.firstChild);
}
}
},
_updateLabelText: function (labelText) {
if (!this._errorShown) {
L.Handler.Draw.prototype._updateLabelText.call(this, labelText);
}
},
_getLabelText: function () {
var labelText,
distance,
distanceStr;
if (this._markers.length === 0) {
labelText = {
text: 'Click to start drawing line.'
};
} else {
// calculate the distance from the last fixed point to the mouse position
distance = this._measurementRunningTotal + this._currentLatLng.distanceTo(this._markers[this._markers.length - 1].getLatLng());
// show metres when distance is < 1km, then show km
distanceStr = distance > 1000 ? (distance / 1000).toFixed(2) + ' km' : Math.ceil(distance) + ' m';
if (this._markers.length === 1) {
labelText = {
text: 'Click to continue drawing line.',
subtext: distanceStr
};
} else {
labelText = {
text: 'Click last point to finish line.',
subtext: distanceStr
};
}
}
return labelText;
},
_showErrorLabel: function () {
this._errorShown = true;
// Update label
L.DomUtil.addClass(this._label, 'leaflet-error-draw-label');
L.DomUtil.addClass(this._label, 'leaflet-flash-anim');
L.Handler.Draw.prototype._updateLabelText.call(this, { text: this.options.drawError.message });
// Update shape
this._updateGuideColor(this.options.drawError.color);
this._poly.setStyle({ color: this.options.drawError.color });
// Hide the error after 2 seconds
this._clearHideErrorTimeout();
this._hideErrorTimeout = setTimeout(L.Util.bind(this._hideErrorLabel, this), this.options.drawError.timeout);
},
_hideErrorLabel: function () {
this._errorShown = false;
this._clearHideErrorTimeout();
// Revert label
L.DomUtil.removeClass(this._label, 'leaflet-error-draw-label');
L.DomUtil.removeClass(this._label, 'leaflet-flash-anim');
this._updateLabelText(this._getLabelText());
// Revert shape
this._updateGuideColor(this.options.shapeOptions.color);
this._poly.setStyle({ color: this.options.shapeOptions.color });
},
_clearHideErrorTimeout: function () {
if (this._hideErrorTimeout) {
clearTimeout(this._hideErrorTimeout);
this._hideErrorTimeout = null;
}
},
_vertexAdded: function (latlng) {
if (this._markers.length === 1) {
this._measurementRunningTotal = 0;
}
else {
this._measurementRunningTotal +=
latlng.distanceTo(this._markers[this._markers.length - 2].getLatLng());
}
},
_cleanUpShape: function () {
if (this._markers.length > 0) {
this._markers[this._markers.length - 1].off('click', this._finishShape);
}
}
});
L.Polygon.Draw = L.Polyline.Draw.extend({
Poly: L.Polygon,
options: {
shapeOptions: {
stroke: true,
color: '#f06eaa',
weight: 4,
opacity: 0.5,
fill: true,
fillColor: null, //same as color by default
fillOpacity: 0.2,
clickable: false
}
},
_updateMarkerHandler: function () {
// The first marker shold have a click handler to close the polygon
if (this._markers.length === 1) {
this._markers[0].on('click', this._finishShape, this);
}
},
_getLabelText: function () {
var text;
if (this._markers.length === 0) {
text = 'Click to start drawing shape.';
} else if (this._markers.length < 3) {
text = 'Click to continue drawing shape.';
} else {
text = 'Click first point to close this shape.';
}
return {
text: text
};
},
_shapeIsValid: function () {
return this._markers.length >= 3;
},
_vertexAdded: function (latlng) {
//calc area here
},
_cleanUpShape: function () {
if (this._markers.length > 0) {
this._markers[0].off('click', this._finishShape);
}
}
});
L.SimpleShape = {};
L.SimpleShape.Draw = L.Handler.Draw.extend({
addHooks: function () {
L.Handler.Draw.prototype.addHooks.call(this);
if (this._map) {
this._map.dragging.disable();
//TODO refactor: move cursor to styles
this._container.style.cursor = 'crosshair';
this._updateLabelText({ text: this._initialLabelText });
this._map
.on('mousedown', this._onMouseDown, this)
.on('mousemove', this._onMouseMove, this);
}
},
removeHooks: function () {
L.Handler.Draw.prototype.removeHooks.call(this);
if (this._map) {
this._map.dragging.enable();
//TODO refactor: move cursor to styles
this._container.style.cursor = '';
this._map
.off('mousedown', this._onMouseDown, this)
.off('mousemove', this._onMouseMove, this);
L.DomEvent.off(document, 'mouseup', this._onMouseUp);
// If the box element doesn't exist they must not have moved the mouse, so don't need to destroy/return
if (this._shape) {
this._map.removeLayer(this._shape);
delete this._shape;
}
}
this._isDrawing = false;
},
_onMouseDown: function (e) {
this._isDrawing = true;
this._startLatLng = e.latlng;
L.DomEvent
.on(document, 'mouseup', this._onMouseUp, this)
.preventDefault(e.originalEvent);
},
_onMouseMove: function (e) {
var layerPoint = e.layerPoint,
latlng = e.latlng;
this._updateLabelPosition(layerPoint);
if (this._isDrawing) {
this._updateLabelText({ text: 'Release mouse to finish drawing.' });
this._drawShape(latlng);
}
},
_onMouseUp: function (e) {
if (this._shape) {
this._fireCreatedEvent();
}
this.disable();
}
});
L.Circle.Draw = L.SimpleShape.Draw.extend({
options: {
shapeOptions: {
stroke: true,
color: '#f06eaa',
weight: 4,
opacity: 0.5,
fill: true,
fillColor: null, //same as color by default
fillOpacity: 0.2,
clickable: true
}
},
_initialLabelText: 'Click and drag to draw circle.',
_drawShape: function (latlng) {
if (!this._shape) {
this._shape = new L.Circle(this._startLatLng, this._startLatLng.distanceTo(latlng), this.options.shapeOptions);
this._map.addLayer(this._shape);
} else {
this._shape.setRadius(this._startLatLng.distanceTo(latlng));
}
},
_fireCreatedEvent: function () {
this._map.fire(
'draw:circle-created',
{ circ: new L.Circle(this._startLatLng, this._shape.getRadius(), this.options.shapeOptions) }
);
}
});
L.Rectangle.Draw = L.SimpleShape.Draw.extend({
options: {
shapeOptions: {
stroke: true,
color: '#f06eaa',
weight: 4,
opacity: 0.5,
fill: true,
fillColor: null, //same as color by default
fillOpacity: 0.2,
clickable: true
}
},
_initialLabelText: 'Click and drag to draw rectangle.',
_drawShape: function (latlng) {
if (!this._shape) {
this._shape = new L.Rectangle(new L.LatLngBounds(this._startLatLng, latlng), this.options.shapeOptions);
this._map.addLayer(this._shape);
} else {
this._shape.setBounds(new L.LatLngBounds(this._startLatLng, latlng));
}
},
_fireCreatedEvent: function () {
this._map.fire(
'draw:rectangle-created',
{ rect: new L.Rectangle(this._shape.getBounds(), this.options.shapeOptions) }
);
}
});
L.Marker.Draw = L.Handler.Draw.extend({
options: {
icon: new L.Icon.Default(),
zIndexOffset: 2000 // This should be > than the highest z-index any markers
},
addHooks: function () {
L.Handler.Draw.prototype.addHooks.call(this);
if (this._map) {
this._updateLabelText({ text: 'Click map to place marker.' });
this._map.on('mousemove', this._onMouseMove, this);
}
},
removeHooks: function () {
L.Handler.Draw.prototype.removeHooks.call(this);
if (this._map) {
if (this._marker) {
this._marker.off('click', this._onClick);
this._map
.off('click', this._onClick)
.removeLayer(this._marker);
delete this._marker;
}
this._map.off('mousemove', this._onMouseMove);
}
},
_onMouseMove: function (e) {
var newPos = e.layerPoint,
latlng = e.latlng;
this._updateLabelPosition(newPos);
if (!this._marker) {
this._marker = new L.Marker(latlng, {
icon: this.options.icon,
zIndexOffset: this.options.zIndexOffset
});
// Bind to both marker and map to make sure we get the click event.
this._marker.on('click', this._onClick, this);
this._map
.on('click', this._onClick, this)
.addLayer(this._marker);
}
else {
this._marker.setLatLng(latlng);
}
},
_onClick: function (e) {
this._map.fire(
'draw:marker-created',
{ marker: new L.Marker(this._marker.getLatLng(), { icon: this.options.icon }) }
);
this.disable();
}
});
L.Map.mergeOptions({
drawControl: false
});
L.Control.Draw = L.Control.extend({
options: {
position: 'topleft',
polyline: {
title: 'Draw a polyline'
},
polygon: {
title: 'Draw a polygon'
},
rectangle: {
title: 'Draw a rectangle'
},
circle: {
title: 'Draw a circle'
},
marker: {
title: 'Add a marker'
}
},
handlers: {},
initialize: function (options) {
L.Util.extend(this.options, options);
},
onAdd: function (map) {
var className = 'leaflet-control-draw',
container = L.DomUtil.create('div', className);
if (this.options.polyline) {
this.handlers.polyline = new L.Polyline.Draw(map, this.options.polyline);
this._createButton(
this.options.polyline.title,
className + '-polyline',
container,
this.handlers.polyline.enable,
this.handlers.polyline
);
this.handlers.polyline.on('activated', this._disableInactiveModes, this);
}
if (this.options.polygon) {
this.handlers.polygon = new L.Polygon.Draw(map, this.options.polygon);
this._createButton(
this.options.polygon.title,
className + '-polygon',
container,
this.handlers.polygon.enable,
this.handlers.polygon
);
this.handlers.polygon.on('activated', this._disableInactiveModes, this);
}
if (this.options.rectangle) {
this.handlers.rectangle = new L.Rectangle.Draw(map, this.options.rectangle);
this._createButton(
this.options.rectangle.title,
className + '-rectangle',
container,
this.handlers.rectangle.enable,
this.handlers.rectangle
);
this.handlers.rectangle.on('activated', this._disableInactiveModes, this);
}
if (this.options.circle) {
this.handlers.circle = new L.Circle.Draw(map, this.options.circle);
this._createButton(
this.options.circle.title,
className + '-circle',
container,
this.handlers.circle.enable,
this.handlers.circle
);
this.handlers.circle.on('activated', this._disableInactiveModes, this);
}
if (this.options.marker) {
this.handlers.marker = new L.Marker.Draw(map, this.options.marker);
this._createButton(
this.options.marker.title,
className + '-marker',
container,
this.handlers.marker.enable,
this.handlers.marker
);
this.handlers.marker.on('activated', this._disableInactiveModes, this);
}
return container;
},
_createButton: function (title, className, container, fn, context) {
var link = L.DomUtil.create('a', className, container);
link.href = '#';
link.title = title;
L.DomEvent
.on(link, 'click', L.DomEvent.stopPropagation)
.on(link, 'mousedown', L.DomEvent.stopPropagation)
.on(link, 'dblclick', L.DomEvent.stopPropagation)
.on(link, 'click', L.DomEvent.preventDefault)
.on(link, 'click', fn, context);
return link;
},
// Need to disable the drawing modes if user clicks on another without disabling the current mode
_disableInactiveModes: function () {
for (var i in this.handlers) {
// Check if is a property of this object and is enabled
if (this.handlers.hasOwnProperty(i) && this.handlers[i].enabled()) {
this.handlers[i].disable();
}
}
}
});
L.Map.addInitHook(function () {
if (this.options.drawControl) {
this.drawControl = new L.Control.Draw();
this.addControl(this.drawControl);
}
});
}(this));

44
vendor/assets/leaflet/leaflet.ie.css vendored Normal file
View file

@ -0,0 +1,44 @@
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
.leaflet-control {
display: inline;
}
.leaflet-popup-tip {
width: 21px;
_width: 27px;
margin: 0 auto;
_margin-top: -3px;
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
}
.leaflet-popup-tip-container {
margin-top: -1px;
}
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
border: 1px solid #bbb;
}
.leaflet-control-zoom {
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#3F000000',EndColorStr='#3F000000');
}
.leaflet-control-zoom a {
background-color: #eee;
}
.leaflet-control-zoom a:hover {
background-color: #fff;
}
.leaflet-control-layers-toggle {
}
.leaflet-control-attribution, .leaflet-control-layers {
background: white;
}

7629
vendor/assets/leaflet/leaflet.js vendored Normal file

File diff suppressed because it is too large Load diff

133
vendor/assets/leaflet/leaflet.osm.js vendored Normal file
View file

@ -0,0 +1,133 @@
L.OSM = L.FeatureGroup.extend({
options: {
areaTags: ['area', 'building', 'leisure', 'tourism', 'ruins', 'historic', 'landuse', 'military', 'natural', 'sport'],
uninterestingTags: ['source', 'source_ref', 'source:ref', 'history', 'attribution', 'created_by', 'tiger:county', 'tiger:tlid', 'tiger:upload_uuid'],
styles: {}
},
initialize: function (xml, options) {
L.Util.setOptions(this, options);
L.FeatureGroup.prototype.initialize.call(this);
if (xml) {
this.addData(xml);
}
},
addData: function (xml) {
var nodes = L.OSM.getNodes(xml),
ways = L.OSM.getWays(xml);
for (var i = 0; i < ways.length; i++) {
var way = ways[i],
latLngs = new Array(way.nodes.length);
for (var j = 0; j < way.nodes.length; j++) {
latLngs[j] = nodes[way.nodes[j]].latLng;
}
var layer;
if (this.isWayArea(way)) {
latLngs.pop(); // Remove last == first.
layer = L.polygon(latLngs, this.options.styles.area);
} else {
layer = L.polyline(latLngs, this.options.styles.way);
}
layer.addTo(this);
layer.feature = way;
}
for (var node_id in nodes) {
var node = nodes[node_id];
if (this.interestingNode(node)) {
var layer = L.circleMarker(node.latLng, this.options.styles.node);
layer.addTo(this);
layer.feature = node;
}
}
},
isWayArea: function (way) {
if (way.nodes[0] != way.nodes[way.nodes.length - 1]) {
return false;
}
for (var key in way.tags) {
if (~this.options.areaTags.indexOf(key)) {
return true;
}
}
return false;
},
interestingNode: function (node) {
for (var key in node.tags) {
if (!~this.options.uninterestingTags.indexOf(key)) {
return true;
}
}
return false;
}
});
L.Util.extend(L.OSM, {
getNodes: function (xml) {
var result = {};
var nodes = xml.getElementsByTagName("node");
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i], id = node.getAttribute("id");
result[id] = {
id: id,
type: "node",
latLng: L.latLng(node.getAttribute("lat"),
node.getAttribute("lon"),
true),
tags: this.getTags(node)
};
}
return result;
},
getWays: function (xml) {
var result = [];
var ways = xml.getElementsByTagName("way");
for (var i = 0; i < ways.length; i++) {
var way = ways[i], nds = way.getElementsByTagName("nd");
var way_object = {
id: way.getAttribute("id"),
type: "way",
nodes: new Array(nds.length),
tags: this.getTags(way)
};
for (var j = 0; j < nds.length; j++) {
way_object.nodes[j] = nds[j].getAttribute("ref");
}
result.push(way_object);
}
return result;
},
getTags: function (xml) {
var result = {};
var tags = xml.getElementsByTagName("tag");
for (var j = 0; j < tags.length; j++) {
result[tags[j].getAttribute("k")] = tags[j].getAttribute("v");
}
return result;
}
});