// -*- mode: espresso; espresso-indent-level: 4; indent-tabs-mode: nil -*- // This function might be passed either an OpenLayers.LonLat (so has // lon and lat) or an OpenLayers.Geometry.Point (so has x and y) function fixmystreet_update_pin(lonlat) { lonlat.transform( fixmystreet.map.getProjectionObject(), new OpenLayers.Projection("EPSG:4326") ); document.getElementById('fixmystreet.latitude').value = lonlat.lat || lonlat.y; document.getElementById('fixmystreet.longitude').value = lonlat.lon || lonlat.x; } function fixmystreet_activate_drag() { fixmystreet.drag = new OpenLayers.Control.DragFeature( fixmystreet.markers, { onComplete: function(feature, e) { fixmystreet_update_pin( feature.geometry.clone() ); } } ); fixmystreet.map.addControl( fixmystreet.drag ); fixmystreet.drag.activate(); } function fms_markers_list(pins, transform) { var markers = []; for (var i=0; iMore details", { size: new OpenLayers.Size(0,0), offset: new OpenLayers.Pixel(0,-40) }, true, onPopupClose); feature.popup = popup; fixmystreet.map.addPopup(popup); }); fixmystreet.map.addControl( fixmystreet.select_feature ); fixmystreet.select_feature.activate(); } else if (fixmystreet.page == 'new') { fixmystreet_activate_drag(); } fixmystreet.map.addLayer(fixmystreet.markers); if ( fixmystreet.zoomToBounds ) { var bounds = fixmystreet.markers.getDataExtent(); if (bounds) { fixmystreet.map.zoomToExtent( bounds ); } } $('#hide_pins_link').click(function(e) { e.preventDefault(); var showhide = [ 'Show pins', 'Hide pins', 'Dangos pinnau', 'Cuddio pinnau', "Vis nåler", "Gjem nåler" ]; for (var i=0; i div[data-role='footer']"), header = $("div[id='" + containerid + "'] > div[data-role='header']"), content = $("div[id='" + containerid + "'] > div[data-role='content']"), viewHeight = $(window).height(), contentHeight = viewHeight - footer.outerHeight() - header.outerHeight(); if ((content.outerHeight() + footer.outerHeight() + header.outerHeight()) !== viewHeight) { contentHeight -= (content.outerHeight() - content.height() + 1); content.height(contentHeight); content.width($(window).width()); } } $(document).delegate('#submit-problem', 'pageshow', function(event) { $('#mapForm').submit(postReport); $('#mapForm :input[type=submit]').on('click', function() { submit_clicked = $(this); }); $('#side-form, #site-logo').show(); $('#pc').val(localStorage.pc); $('#fixmystreet\\.latitude').val(localStorage.latitude); $('#fixmystreet\\.longitude').val(localStorage.longitude); if ( !localStorage.offline ) { $.getJSON( CONFIG.FMS_URL + 'report/new/ajax', { latitude: $('#fixmystreet\\.latitude').val(), longitude: $('#fixmystreet\\.longitude').val() }, function(data) { if (data.error) { // XXX If they then click back and click somewhere in the area, this error will still show. $('#side-form').html('

Reporting a problem

' + data.error + '

'); return; } $('#councils_text').html(data.councils_text); $('#form_category_row').html(data.category); }); } else { $('#councils_text').html("You are currently operating in offline mode so you can save the details of the problem but you'll need to finish reporting when you have internet access."); $('#form_category_row').hide(); $('#email_label').hide(); $('#form_email').hide(); $('#form_sign_in').hide(); } }); function show_map(event) { ensureNonZeroHeight(); set_map_config(); fixmystreet.map = new OpenLayers.Map("map", { controls: fixmystreet.controls, displayProjection: new OpenLayers.Projection("EPSG:4326") }); if ($('html').hasClass('mobile') && fixmystreet.page == 'around') { $('#fms_pan_zoom').css({ top: '2.75em !important' }); } fixContentHeight(fixmystreet.map); fixmystreet.layer_options = OpenLayers.Util.extend({ zoomOffset: fixmystreet.zoomOffset, transitionEffect: 'resize', numZoomLevels: fixmystreet.numZoomLevels }, fixmystreet.layer_options); var layer = new fixmystreet.map_type("", fixmystreet.layer_options); fixmystreet.map.addLayer(layer); if (!fixmystreet.map.getCenter()) { var centre = new OpenLayers.LonLat( fixmystreet.longitude, fixmystreet.latitude ); centre.transform( new OpenLayers.Projection("EPSG:4326"), fixmystreet.map.getProjectionObject() ); fixmystreet.map.setCenter(centre, fixmystreet.zoom || 3); } if (fixmystreet.state_map && fixmystreet.state_map == 'full') { console.log('full page'); // TODO Work better with window resizing, this is pretty 'set up' only at present var $content = $('.content'), q = ( $content.offset().left + $content.width() ) / 2; // Need to try and fake the 'centre' being 75% from the left fixmystreet.map.pan(-q, -25, { animate: false }); fixmystreet.map.events.register("movestart", null, function(e){ fixmystreet.map.moveStart = { zoom: this.getZoom(), center: this.getCenter() }; }); fixmystreet.map.events.register("zoomend", null, function(e){ if ( fixmystreet.map.moveStart && !fixmystreet.map.moveStart.zoom && fixmystreet.map.moveStart.zoom !== 0 ) { return true; // getZoom() on Firefox appears to return null at first? } if ( !fixmystreet.map.moveStart || !this.getCenter().equals(fixmystreet.map.moveStart.center) ) { // Centre has moved, e.g. by double-click. Same whether zoom in or out fixmystreet.map.pan(-q, -25, { animate: false }); return; } var zoom_change = this.getZoom() - fixmystreet.map.moveStart.zoom; if (zoom_change == -1) { // Zoomed out, need to re'centre' fixmystreet.map.pan(-q/2, 0, { animate: false }); } else if (zoom_change == 1) { // Using a zoom button fixmystreet.map.pan(q, 0, { animate: false }); } }); } /* if (document.getElementById('mapForm')) { var click = new OpenLayers.Control.Click(); fixmystreet.map.addControl(click); click.activate(); } */ $(window).hashchange(function(){ if (location.hash == '#report' && $('.rap-notes').is(':visible')) { $('.rap-notes-close').click(); return; } if (location.hash && location.hash != '#') { return; } // Okay, back to around view. fixmystreet.bbox_strategy.activate(); fixmystreet.markers.refresh( { force: true } ); if ( fixmystreet.state_pins_were_hidden ) { // If we had pins hidden when we clicked map (which had to show the pin layer as I'm doing it in one layer), hide them again. $('#hide_pins_link').click(); } fixmystreet.drag.deactivate(); $('#side-form').hide(); $('#side').show(); $('#sub_map_links').show(); //only on mobile $('#mob_sub_map_links').remove(); $('.mobile-map-banner').text('Place pin on map') .prepend('home'); fixmystreet.page = 'around'; }); // Vector layers must be added onload as IE sucks if ($.browser.msie) { $(window).load(fixmystreet_onload); } else { fixmystreet_onload(); } fixContentHeight(fixmystreet.map); } $(document).delegate('#around-page', 'pageshow', show_map ); $(document).delegate('#report-page', 'pageshow', show_map ); OpenLayers.Control.Crosshairs = OpenLayers.Class.create(); OpenLayers.Control.Crosshairs.CROSSHAIR_SIDE = 100; OpenLayers.Control.Crosshairs.DIV_ID = "OpenLayers_Control_Crosshairs_crosshairs"; OpenLayers.Control.Crosshairs.prototype = OpenLayers.Class.inherit( OpenLayers.Control, { element: null, position: null, initialize: function(element) { OpenLayers.Control.prototype.initialize.apply(this, arguments); this.element = OpenLayers.Util.getElement(element); this.imageSize = new OpenLayers.Size(OpenLayers.Control.Crosshairs.CROSSHAIR_SIDE, OpenLayers.Control.Crosshairs.CROSSHAIR_SIDE); }, draw: function() { var position; OpenLayers.Control.prototype.draw.apply(this, arguments); position = this.getIdealPosition(); this.buttons = new Array(); var imgLocation = OpenLayers.Util.getImagesLocation() + "crosshairs-100.png"; return OpenLayers.Util.createAlphaImageDiv(OpenLayers.Control.Crosshairs.DIV_ID, position, this.imageSize, imgLocation, "absolute"); }, getIdealPosition: function() { this.map.updateSize(); var mapSize = this.map.getSize(); return new OpenLayers.Pixel((mapSize.w / 2) - (this.imageSize.w / 2), (2 * mapSize.h / 5) - (this.imageSize.h / 2)); }, getMapPosition: function() { var left = parseInt( $('#' + OpenLayers.Control.Crosshairs.DIV_ID).css('left') ); var top = parseInt( $('#' + OpenLayers.Control.Crosshairs.DIV_ID).css('top') ); left += ( this.imageSize.w / 2 ); top += ( this.imageSize.h / 2 ); var pos = this.map.getLonLatFromViewPortPx( new OpenLayers.Pixel( left, top ) ); return pos; }, reposition: function() { var position = this.getIdealPosition(); $('#' + OpenLayers.Control.Crosshairs.DIV_ID).css({ left: position.x, top: position.y}); }, CLASS_NAME: "OpenLayers.Control.Crosshairs" }); /* Overridding the buttonDown function of PanZoom so that it does zoomTo(0) rather than zoomToMaxExtent() */ OpenLayers.Control.PanZoomFMS = OpenLayers.Class(OpenLayers.Control.PanZoom, { buttonDown: function (evt) { if (!OpenLayers.Event.isLeftClick(evt)) { return; } switch (this.action) { case "panup": this.map.pan(0, -this.getSlideFactor("h")); break; case "pandown": this.map.pan(0, this.getSlideFactor("h")); break; case "panleft": this.map.pan(-this.getSlideFactor("w"), 0); break; case "panright": this.map.pan(this.getSlideFactor("w"), 0); break; case "zoomin": this.map.zoomIn(); break; case "zoomout": this.map.zoomOut(); break; case "zoomworld": this.map.zoomTo(0); break; } OpenLayers.Event.stop(evt); } }); /* Overriding Permalink so that it can pass the correct zoom to OSM */ OpenLayers.Control.PermalinkFMS = OpenLayers.Class(OpenLayers.Control.Permalink, { updateLink: function() { var separator = this.anchor ? '#' : '?'; var href = this.base; if (href.indexOf(separator) != -1) { href = href.substring( 0, href.indexOf(separator) ); } href += separator + OpenLayers.Util.getParameterString(this.createParams(null, this.map.getZoom()+fixmystreet.zoomOffset)); // Could use mlat/mlon here as well if we are on a page with a marker if (this.anchor && !this.element) { window.location.href = href; } else { this.element.href = href; } } }); /* Pan data handler */ OpenLayers.Format.FixMyStreet = OpenLayers.Class(OpenLayers.Format.JSON, { read: function(json, filter) { if (typeof json == 'string') { obj = OpenLayers.Format.JSON.prototype.read.apply(this, [json, filter]); } else { obj = json; } var current, current_near; if (typeof(obj.current) != 'undefined' && (current = document.getElementById('current'))) { current.innerHTML = obj.current; } if (typeof(obj.current_near) != 'undefined' && (current_near = document.getElementById('current_near'))) { current_near.innerHTML = obj.current_near; } var markers = fms_markers_list( obj.pins, false ); return markers; }, CLASS_NAME: "OpenLayers.Format.FixMyStreet" }); /* Click handler */ OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, { defaultHandlerOptions: { 'single': true, 'double': false, 'pixelTolerance': 0, 'stopSingle': false, 'stopDouble': false }, initialize: function(options) { this.handlerOptions = OpenLayers.Util.extend( {}, this.defaultHandlerOptions); OpenLayers.Control.prototype.initialize.apply( this, arguments ); this.handler = new OpenLayers.Handler.Click( this, { 'click': this.trigger }, this.handlerOptions); }, trigger: function(e) { if (typeof fixmystreet.nav_control != 'undefined') { fixmystreet.nav_control.disableZoomWheel(); } var lonlat = fixmystreet.map.getLonLatFromViewPortPx(e.xy); if (fixmystreet.page == 'new') { /* Already have a pin */ fixmystreet.markers.features[0].move(lonlat); } else { var markers = fms_markers_list( [ [ lonlat.lat, lonlat.lon, 'green' ] ], false ); fixmystreet.bbox_strategy.deactivate(); fixmystreet.markers.removeAllFeatures(); fixmystreet.markers.addFeatures( markers ); fixmystreet_activate_drag(); } fixmystreet_update_pin(lonlat); // check to see if markers are visible. We click the // link so that it updates the text in case they go // back if ( ! fixmystreet.markers.getVisibility() ) { fixmystreet.state_pins_were_hidden = true; $('#hide_pins_link').click(); } if (fixmystreet.page == 'new') { return; } $.getJSON( CONFIG.FMS_URL + 'report/new/ajax', { latitude: $('#fixmystreet\\.latitude').val(), longitude: $('#fixmystreet\\.longitude').val() }, function(data) { if (data.error) { // XXX If they then click back and click somewhere in the area, this error will still show. $('#side-form').html('

Reporting a problem

' + data.error + '

'); return; } $('#councils_text').html(data.councils_text); $('#form_category_row').html(data.category); }); $('#side-form, #site-logo').show(); //fixmystreet.map.updateSize(); // might have done, and otherwise Firefox gets confused. /* For some reason on IOS5 if you use the jQuery show method it * doesn't display the JS validation error messages unless you do this * or you cause a screen redraw by changing the phone orientation. * NB: This has to happen after the call to show() */ if ( navigator.userAgent.match(/like Mac OS X/i)) { //document.getElementById('side-form').style.display = 'block'; } $('#side').hide(); if (typeof heightFix !== 'undefined') { heightFix('#report-a-problem-sidebar', '.content', 26); } // If we clicked the map somewhere inconvenient var sidebar = $('#report-a-problem-sidebar'); if (sidebar.css('position') == 'absolute') { var w = sidebar.width(), h = sidebar.height(), o = sidebar.offset(), $map_box = $('#map_box'), bo = $map_box.offset(); // e.xy is relative to top left of map, which might not be top left of page e.xy.x += bo.left; e.xy.y += bo.top; if (e.xy.y <= o.top || (e.xy.x >= o.left && e.xy.x <= o.left + w + 24 && e.xy.y >= o.top && e.xy.y <= o.top + h + 64)) { // top of the page, pin hidden by header; // or underneath where the new sidebar will appear lonlat.transform( new OpenLayers.Projection("EPSG:4326"), fixmystreet.map.getProjectionObject() ); var p = fixmystreet.map.getViewPortPxFromLonLat(lonlat); p.x -= ( o.left + w ) / 2; lonlat = fixmystreet.map.getLonLatFromViewPortPx(p); fixmystreet.map.panTo(lonlat); } } $('#sub_map_links').hide(); var $map_box = $('#map_box'); $map_box.append( '' ); // .css({ position: 'relative', width: width, height: height, marginBottom: '1em' }); // Making it relative here makes it much easier to do the scrolling later $('.mobile-map-banner').text('Right place?').prepend('home'); $('#try_again').on('click', function(){ fixmystreet.bbox_strategy.activate(); fixmystreet.markers.refresh( { force: true } ); if ( fixmystreet.state_pins_were_hidden ) { // If we had pins hidden when we clicked map (which had to show the pin layer as I'm doing it in one layer), hide them again. $('#hide_pins_link').click(); } fixmystreet.drag.deactivate(); $('#sub_map_links').show(); $('#mob_sub_map_links').remove(); }); $('#mob_ok').on('click', function(){ localStorage.latitude = $('#fixmystreet\\.latitude').val(); localStorage.longitude = $('#fixmystreet\\.longitude').val(); $.mobile.changePage('submit-problem.html') }); fixmystreet.page = 'new'; location.hash = 'report'; } });