$(document).ready(function () {
var params = OSM.mapParams();
- var newNotes;
- function saveNewNotes(o) {
- var layer = o.object;
- newNotes = layer.getFeaturesByAttribute("status", "new")
- layer.removeFeatures(newNotes, { silent: true });
- }
+ var noteIcons = {
+ "new": L.icon({
+ iconUrl: "<%= image_path 'new_note_marker.png' %>",
+ iconSize: [22, 22],
+ iconAnchor: [11, 11]
+ }),
+ "open": L.icon({
+ iconUrl: "<%= image_path 'open_note_marker.png' %>",
+ iconSize: [22, 22],
+ iconAnchor: [11, 11]
+ }),
+ "closed": L.icon({
+ iconUrl: "<%= image_path 'closed_note_marker.png' %>",
+ iconSize: [22, 22],
+ iconAnchor: [11, 11]
+ })
+ };
+
+ var noteLayer = new L.LayerGroup();
+ var notes = {};
+ var newNote;
+
+ map.on("layeradd", function (e) {
+ if (e.layer == noteLayer) {
+ loadNotes();
+ map.on("moveend", loadNotes);
+ }
+ });
- function restoreNewNotes(o) {
- var layer = o.object;
- layer.addFeatures(newNotes);
- newNotes = undefined;
- }
+ map.on("layerremove", function (e) {
+ if (e.layer == noteLayer) {
+ map.off("moveend", loadNotes);
+ noteLayer.clearLayers();
+ notes = {};
+ }
+ });
- function createNote(feature, form) {
- var location = unproj(feature.geometry.getBounds().getCenterLonLat());
+ map.on("popupopen", function (e) {
+ $(e.popup._container).find(".comment").focus();
+ });
- $(form).find("input[type=submit]").prop("disabled", true);
+ map.on("popupclose", function (e) {
+ if (newNote && e.popup == newNote._popup) {
+ $(newNote).oneTime(10, "removenote", function () {
+ map.removeLayer(newNote);
+ newNote = null;
+ });
+ }
+ });
- $.ajax($("#createnoteanchor").attr("href"), {
- type: "POST",
- data: {
- lon: location.lon,
- lat: location.lat,
- text: $(form.text).val()
- },
- success: function (data) {
- map.noteSelector.unselect(feature);
+ if (OSM.STATUS != 'api_offline' && OSM.STATUS != 'database_offline') {
+ map.layersControl.addOverlay(noteLayer, I18n.t("browse.start_rjs.notes_layer_name"));
- feature.attributes = data.properties;
+ if (params.notes) map.addLayer(noteLayer);
- map.noteLayer.drawFeature(feature);
+ if (params.note) {
+ $.ajax({
+ url: "/api/" + OSM.API_VERSION + "/notes/" + params.note + ".json",
+ success: function (feature) {
+ var marker = updateMarker(notes[feature.properties.id], feature);
- map.noteMover.deactivate();
- }
- });
+ notes[feature.properties.id] = marker;
+
+ map.addLayer(noteLayer);
+ marker.openPopup();
+ }
+ });
+ }
}
- function updateNote(feature, form, close) {
- var url = close ? feature.attributes.close_url : feature.attributes.comment_url;
+ function updateMarker(marker, feature) {
+ if (marker)
+ {
+ marker.setIcon(noteIcons[feature.properties.status]);
+ marker._popup.setContent(createPopupContent(marker, feature.properties));
+ }
+ else
+ {
+ marker = L.marker(feature.geometry.coordinates.reverse(), {
+ icon: noteIcons[feature.properties.status],
+ opacity: 0.7
+ });
+
+ marker.addTo(noteLayer).bindPopup(
+ createPopupContent(marker, feature.properties),
+ popupOptions()
+ );
+ }
+
+ return marker;
+ }
- $(form).find("input[type=submit]").prop("disabled", true);
+ var noteLoader;
- $.ajax(url, {
- type: "POST",
- data: {
- text: $(form.text).val()
- },
- success: function (data) {
- map.noteSelector.unselect(feature)
-
- feature.attributes = data.properties;
-
- map.noteSelector.select(feature)
- }
- });
- }
+ function loadNotes() {
+ var bounds = map.getBounds();
+ var size = bounds.getSize();
- function noteSelected(o) {
- var feature = o.feature;
- var location = feature.geometry.getBounds().getCenterLonLat();
- var content;
- var onClose;
+ if (size <= OSM.MAX_NOTE_REQUEST_AREA) {
+ var url = "/api/" + OSM.API_VERSION + "/notes.json?bbox=" + bounds.toBBOX();
- if (feature.attributes.status === "new") {
- content = JST["templates/notes/new"]();
+ if (noteLoader) noteLoader.abort();
- onClose = function (e) {
- feature.attributes.status = "cancelled";
+ noteLoader = $.ajax({
+ url: url,
+ success: function (json) {
+ var oldNotes = notes;
- map.noteSelector.unselect(feature);
- map.noteLayer.removeFeatures(feature);
+ notes = {};
- feature.destroy();
+ json.features.forEach(function (feature) {
+ var marker = oldNotes[feature.properties.id];
- map.noteMover.deactivate();
- };
- } else {
- content = JST["templates/notes/show"]({ note: feature.attributes });
+ delete oldNotes[feature.properties.id];
- onClose = function (e) {
- map.noteSelector.unselect(feature)
- };
- };
+ notes[feature.properties.id] = updateMarker(marker, feature);
+ });
- feature.popup = new OpenLayers.Popup.FramedCloud(
- feature.attributes.id, location, null, content, null, true, onClose
- );
+ for (id in oldNotes) {
+ noteLayer.removeLayer(oldNotes[id]);
+ }
- map.addPopup(feature.popup);
- // feature.popup.show();
+ noteLoader = null;
+ }
+ });
+ }
+ };
+
+ function popupOptions() {
+ var mapSize = map.getSize();
+
+ return {
+ minWidth: 320,
+ maxWidth: mapSize.y * 1 / 3,
+ maxHeight: mapSize.y * 2 / 3,
+ offset: new L.Point(0, -3),
+ autoPanPadding: new L.Point(60, 40)
+ };
+ }
- $(feature.popup.contentDiv).find("textarea").autoGrow();
+ function createPopupContent(marker, properties) {
+ var content = $(JST["templates/notes/show"]({ note: properties }));
- $(feature.popup.contentDiv).find("textarea").on("input", function (e) {
+ content.find("textarea").on("input", function (e) {
var form = e.target.form;
if ($(e.target).val() == "") {
- $(form.close).val(I18n.t("javascripts.notes.show.close"));
+ $(form.close).val(I18n.t("javascripts.notes.show.resolve"));
+ $(form.comment).prop("disabled", true);
} else {
- $(form.close).val(I18n.t("javascripts.notes.show.comment_and_close"));
+ $(form.close).val(I18n.t("javascripts.notes.show.comment_and_resolve"));
+ $(form.comment).prop("disabled", false);
}
});
- $(feature.popup.contentDiv).find("input#note-add").click(function (e) {
+ content.find("input[type=submit]").on("click", function (e) {
e.preventDefault();
-
- createNote(feature, e.target.form);
+ var data = $(e.target).data();
+ updateNote(marker, e.target.form, data.method, data.url);
});
- $(feature.popup.contentDiv).find("input#note-comment").click(function (e) {
- e.preventDefault();
+ return content[0];
+ }
- updateNote(feature, e.target.form, false);
- });
+ function createNote(marker, form, url) {
+ var location = marker.getLatLng();
- $(feature.popup.contentDiv).find("input#note-close").click(function (e) {
- e.preventDefault();
+ $(form).find("input[type=submit]").prop("disabled", true);
- updateNote(feature, e.target.form, true);
- });
+ $.ajax({
+ url: url,
+ type: "POST",
+ oauth: true,
+ data: {
+ lat: location.lat,
+ lon: location.lng,
+ text: $(form.text).val()
+ },
+ success: function (feature) {
+ notes[feature.properties.id] = updateMarker(marker, feature);
+ newNote = null;
- feature.popup.updateSize();
+ $("#createnoteanchor").removeClass("disabled").addClass("geolink");
+ }
+ });
}
- function noteUnselected(o) {
- var feature = o.feature;
+ function updateNote(marker, form, method, url) {
+ $(form).find("input[type=submit]").prop("disabled", true);
- map.removePopup(feature.popup);
- }
+ $.ajax({
+ url: url,
+ type: method,
+ oauth: true,
+ data: {
+ text: $(form.text).val()
+ },
+ success: function (feature) {
+ if (feature.properties.status == "hidden") {
+ noteLayer.removeLayer(marker);
- function addNote() {
- var lonlat = map.getCenter();
- var layer = map.noteLayer;
- var geometry = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);
- var feature = new OpenLayers.Feature.Vector(geometry, {
- status: "new"
- });
+ delete notes[feature.properties.id];
+ } else {
+ var popupContent = createPopupContent(marker, feature.properties);
- layer.addFeatures(feature);
- map.noteSelector.unselectAll();
- map.noteSelector.select(feature);
- map.noteMover.activate();
- map.noteLayer.setVisibility(true);
+ marker.setIcon(noteIcons[feature.properties.status]);
+ marker._popup.setContent(popupContent);
+ }
+ }
+ });
}
- $("#map").on("initialised", function () {
- map.noteLayer = new OpenLayers.Layer.Vector("Notes", {
- visibility: params.notes,
- displayInLayerSwitcher: false,
- projection: new OpenLayers.Projection("EPSG:4326"),
- styleMap: new OpenLayers.StyleMap(new OpenLayers.Style({
- graphicWidth: 22,
- graphicHeight: 22,
- graphicOpacity: 0.7,
- graphicXOffset: -11,
- graphicYOffset: -11
- }, {
- rules: [
- new OpenLayers.Rule({
- filter: new OpenLayers.Filter.Comparison({
- type: OpenLayers.Filter.Comparison.EQUAL_TO,
- property: "status",
- value: "new"
- }),
- symbolizer: {
- externalGraphic: "<%= image_path 'new_note_marker.png' %>"
- }
- }),
- new OpenLayers.Rule({
- filter: new OpenLayers.Filter.Comparison({
- type: OpenLayers.Filter.Comparison.EQUAL_TO,
- property: "status",
- value: "open"
- }),
- symbolizer: {
- externalGraphic: "<%= image_path 'open_note_marker.png' %>"
- }
- }),
- new OpenLayers.Rule({
- filter: new OpenLayers.Filter.Comparison({
- type: OpenLayers.Filter.Comparison.EQUAL_TO,
- property: "status",
- value: "closed"
- }),
- symbolizer: {
- externalGraphic: "<%= image_path 'closed_note_marker.png' %>"
- }
- })
- ]
- })),
- strategies: [
- new OpenLayers.Strategy.BBOX()
- ],
- protocol: new OpenLayers.Protocol.HTTP({
- url: $("#show_notes").attr("href"),
- format: new OpenLayers.Format.GeoJSON()
- })
- });
+ $("#createnoteanchor").click(function (e) {
+ e.preventDefault();
- map.noteLayer.events.register("beforefeaturesremoved", map, saveNewNotes);
- map.noteLayer.events.register("featuresremoved", map, restoreNewNotes);
- map.noteLayer.events.register("featureselected", map, noteSelected);
- map.noteLayer.events.register("featureunselected", map, noteUnselected);
+ if ($(e.target).hasClass("disabled")) return;
- map.addLayer(map.noteLayer);
+ $(e.target).removeClass("geolink").addClass("disabled");
- map.noteSelector = new OpenLayers.Control.SelectFeature(map.noteLayer, {
- autoActivate: true
- });
+ map.addLayer(noteLayer);
- map.addControl(map.noteSelector);
+ var mapSize = map.getSize();
+ var markerPosition;
- map.noteMover = new OpenLayers.Control.DragFeature(map.noteLayer, {
- onDrag: function (feature, pixel) {
- feature.popup.lonlat = feature.geometry.getBounds().getCenterLonLat();
- feature.popup.updatePosition();
- },
- featureCallbacks: {
- over: function (feature) {
- if (feature.attributes.status === "new") {
- map.noteMover.overFeature.apply(map.noteMover, [feature]);
- }
- }
- }
+ if (mapSize.y > 800)
+ {
+ markerPosition = [mapSize.x / 2, mapSize.y / 2];
+ }
+ else if (mapSize.y > 400)
+ {
+ markerPosition = [mapSize.x / 2, 400];
+ }
+ else
+ {
+ markerPosition = [mapSize.x / 2, mapSize.y];
+ }
+
+ newNote = L.marker(map.containerPointToLatLng(markerPosition), {
+ icon: noteIcons["new"],
+ opacity: 0.7,
+ draggable: true
});
- map.addControl(map.noteMover);
+ var popupContent = $(JST["templates/notes/new"]({ create_url: $(e.target).attr("href") }));
- $("#show_notes").click(function (e) {
- map.noteLayer.setVisibility(true);
+ popupContent.find("textarea").on("input", function (e) {
+ var form = e.target.form;
+ if ($(e.target).val() == "") {
+ $(form.add).prop("disabled", true);
+ } else {
+ $(form.add).prop("disabled", false);
+ }
+ });
+
+ popupContent.find("input[type=submit]").on("click", function (e) {
e.preventDefault();
+ createNote(newNote, e.target.form, $(e.target).data("url"));
});
- $("#createnoteanchor").click(function (e) {
- map.noteLayer.setVisibility(true);
+ newNote.addTo(noteLayer).bindPopup(popupContent[0], popupOptions()).openPopup();
- addNote();
+ newNote.on("remove", function (e) {
+ $("#createnoteanchor").removeClass("disabled").addClass("geolink");
+ });
- e.preventDefault();
+ newNote.on("dragstart", function (e) {
+ $(newNote).stopTime("removenote");
+ });
+
+ newNote.on("dragend", function (e) {
+ e.target.openPopup();
});
});
});