From b7e236f0561b90648f20adb9755cc1989e4801c4 Mon Sep 17 00:00:00 2001 From: rlx <0x0073@0x2620.org> Date: Sat, 5 Mar 2011 04:22:22 +0000 Subject: [PATCH] fixing dateline bugs --- build/js/ox.map.js | 43 +---- build/js/ox.ui.js | 455 ++++++++------------------------------------ demos/map/js/map.js | 5 +- 3 files changed, 82 insertions(+), 421 deletions(-) diff --git a/build/js/ox.map.js b/build/js/ox.map.js index a70d3a54..5f35c36b 100644 --- a/build/js/ox.map.js +++ b/build/js/ox.map.js @@ -359,45 +359,4 @@ Ox.getCountryCode = (function() { }); return countryCode; }; -}()); - -Ox.Place = function(options) { - - /* - in: geoname, name, south, west, north, east - out: country, countryCode, geonameReverse, lat, lng - */ - - var self = {}, - that = Ox.extend(this, options); - - ['south', 'west', 'north', 'east'].forEach(function(v) { - self[v + 'Rad'] = Ox.rad(that[v]); - }); - - self.geonames = that.geoname.split(', ').reverse(); - that.geonameReverse = self.geonames.join(', '); - - Ox.forEach(Ox.COUNTRIES, function(country) { - if (country.name == self.geonames[0]) { - that.country = country.name; - that.countryCode = country.code; - return false; - } - }); - - function getArea() { - - } - - function getCenter() { - - } - - function getRad(points) { - - } - - return that; - -}; \ No newline at end of file +}()); \ No newline at end of file diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js index 9a327684..dae9c3ad 100644 --- a/build/js/ox.ui.js +++ b/build/js/ox.ui.js @@ -9770,14 +9770,14 @@ requires self.maxZoomService = new google.maps.MaxZoomService(); self.places = []; self.options.places.forEach(function(place, i) { - var placeBounds = new google.maps.LatLngBounds( + var bounds = new google.maps.LatLngBounds( new google.maps.LatLng(place.south, place.west), new google.maps.LatLng(place.north, place.east) ); if (Ox.isUndefined(place.id)) { place.id = Ox.uid(); } - mapBounds = i == 0 ? placeBounds : mapBounds.union(placeBounds); + mapBounds = i == 0 ? bounds : mapBounds.union(bounds); }); self.center = mapBounds ? mapBounds.getCenter() : new google.maps.LatLng(0, 0); self.zoom = 1; // fixme: should depend on height @@ -9887,7 +9887,7 @@ requires place.edit(); } } else if (self.resultPlace) { - self.resultPlace.select(); + selectPlace(self.resultPlace.id) } } @@ -9897,7 +9897,7 @@ requires if (place.editing) { place.cancel(); } else { - place.deselect(); + selectPlace(null); } } else if (self.resultPlace) { self.resultPlace.remove(); @@ -10031,286 +10031,6 @@ requires } } - function Marker(place) { - var editing = false, - marker = new google.maps.Marker({ - position: place.center, - title: place.name - }), - selected = false, - timeout = 0; - setOptions(); - Ox.print('MARKER', marker) - function click() { - var metaKey = self.metaKey, - shiftKey = self.shiftKey; - timeout = setTimeout(function() { - Ox.print('$$$$ CLICK', metaKey, selected) - if (!selected) { - selected = true; - selectPlace(place.id); - } else if (shiftKey) { - zoomToPlace(place) - } else if (metaKey) { - selected = false; - selectPlace(null); - } else { - panToPlace(place); - } - }, 250); - Ox.print('$$$$ TIMEOUT') - } - function dblclick() { - Ox.print('$$$$ DBLCLICK', timeout) - clearTimeout(timeout); - if (!selected) { - selected = true; - selectPlace(place.id); - } - self.map.fitBounds(place.bounds); - return false; - } - function setOptions() { - marker.setOptions({ - icon: oxui.path + 'png/ox.ui/marker' + - (place.id[0] == '_' ? 'Result' : '') + - (selected ? 'Selected' : (editing ? 'Editing' : '')) + '.png' - }); - } - return { - add: function() { - Ox.print('Marker.add()') - marker.setMap(self.map); - google.maps.event.addListener(marker, 'click', click); - //google.maps.event.addListener(marker, 'dblclick', dblclick); - }, - deselect: function() { - selected = false; - setOptions(); - }, - edit: function() { - editing = true; - setOptions(); - }, - remove: function() { - marker.setMap(null); - google.maps.event.clearListeners(marker); - }, - select: function() { - selected = true; - setOptions(); - }, - submit: function() { - editing = false; - setOptions(); - } - }; - }; - - function Place(place) { - var marker, polygon, selected; - if ('name' in place) { - // place object - //Ox.extend(place, place); - place.bounds = new google.maps.LatLngBounds( - new google.maps.LatLng(place.south, place.west), - new google.maps.LatLng(place.north, place.east) - ); - Ox.print('place.bounds', place.bounds, place.bounds.union) - } else { - // geodata object - if (!place.geometry.bounds) { - Ox.print('NO BOUNDS, ONLY VIEWPORT') - } - Ox.extend(place, { - bounds: place.geometry.bounds || place.geometry.viewport, - countryCode: Ox.getCountryCode(place.formatted_address), - geoname: place.formatted_address, - id: '_' + Ox.uid(), - name: place.formatted_address.split(', ')[0] - }); - Ox.extend(place, { - south: Ox.round(place.bounds.getSouthWest().lat(), 8), - west: Ox.round(place.bounds.getSouthWest().lng(), 8), - north: Ox.round(place.bounds.getNorthEast().lat(), 8), - east: Ox.round(place.bounds.getNorthEast().lng(), 8) - }); - } - place.center = place.bounds.getCenter(); - Ox.extend(place, { - lat: Ox.round(place.center.lat(), 8), - lng: Ox.round(place.center.lng(), 8), - size: Ox.getArea( - {lat: place.south, lng: place.west}, - {lat: place.north, lng: place.east} - ) - }); - place.points = { - sw: new google.maps.LatLng(place.south, place.west), - s: new google.maps.LatLng(place.south, place.lng), - se: new google.maps.LatLng(place.south, place.east), - w: new google.maps.LatLng(place.lat, place.west), - e: new google.maps.LatLng(place.lat, place.east), - nw: new google.maps.LatLng(place.north, place.west), - n: new google.maps.LatLng(place.north, place.lng), - ne: new google.maps.LatLng(place.north, place.east), - }; - marker = Marker(place); - polygon = Polygon(place); - selected = false; - return Ox.extend(place, { - add: function() { - Ox.print('Place.add()', self.resultPlace) - marker.add(); - }, - deselect: function() { - selected = false; - marker.deselect(); - polygon.remove(); - }, - edit: function() { - polygon.select(); - }, - remove: function() { - Ox.print('REMOVE!!!', selected) - if (place.id[0] == '_') { - self.resultPlace = null; - } - selected && polygon.remove(); - marker.remove(); - }, - select: function() { - Ox.print('Place.select()') - selected = true; - marker.select(); - polygon.add(); - }, - submit: function() { - polygon.deselect(); - } - }); - }; - - function Polygon(place) { - var markers = Ox.map(place.points, function(v, k) { - return PolygonMarker(place, k); - }), - polygon = new google.maps.Polygon({ - paths: [ - new google.maps.LatLng(place.south, place.west), - new google.maps.LatLng(place.north, place.west), - new google.maps.LatLng(place.north, place.east), - new google.maps.LatLng(place.south, place.east), - new google.maps.LatLng(place.south, place.west) - ] - }), - selected = false; - Ox.print('markers', markers) - setOptions(); - function click() { - selected = !selected; - if (selected) { - place.edit(); - } else { - place.submit(); - } - } - function setOptions() { - var color = selected ? '#8080FF' : '#FFFFFF'; - polygon.setOptions({ - clickable: true, - fillColor: color, - fillOpacity: selected ? 0.1 : 0, - strokeColor: color, - strokeOpacity: 1, - strokeWeight: 2 - }); - } - return { - add: function() { - Ox.print('Polygon.add()') - polygon.setMap(self.map); - google.maps.event.addListener(polygon, 'click', click); - }, - deselect: function() { - selected = false; - setOptions(); - Ox.forEach(markers, function(marker) { - marker.remove(); - }); - }, - remove: function() { - polygon.setMap(null); - google.maps.event.clearListeners(polygon); - }, - select: function() { - Ox.print('Polygon.select()') - selected = true; - setOptions(); - Ox.forEach(markers, function(marker) { - marker.add(); - }); - } - }; - } - - function PolygonMarker(place, position) { - var markerImage = new google.maps.MarkerImage( - oxui.path + 'png/ox.ui/polygonResize.png', - new google.maps.Size(16, 16), - new google.maps.Point(0, 0), - new google.maps.Point(8, 8) - ), - marker = new google.maps.Marker({ - cursor: position + '-resize', - draggable: true, - icon: markerImage, - position: place.points[position], - raiseOnDrag: false - }); - function dragstart() { - - } - function drag(e) { - var lat = e.latLng.lat(), - lng = e.latLng.lng(); - if (position.indexOf('s') > -1) { - place.south = lat; - } - if (position.indexOf('w') > -1) { - place.west = lng; - } - if (position.indexOf('n') > -1) { - place.north = lat; - } - if (position.indexOf('e') > -1) { - place.east = lng; - } - /* - place.bounds = new google.maps.LatLngBounds({ - new google.maps.LatLng(place.south, place.west), - new google.maps.LatLng(place.north, place.east) - }); - place.center = place.bounds.getCenter(); - */ - } - function dragend() { - - } - return { - add: function() { - marker.setMap(self.map); - google.maps.event.addListener(marker, 'dragstart', dragstart); - google.maps.event.addListener(marker, 'drag', drag); - google.maps.event.addListener(marker, 'dragend', dragend); - }, - remove: function() { - marker.setMap(null); - google.maps.event.clearListeners(marker); - } - } - } - function Rectangle(area) { // fixme: not used var latlng = { sw: new google.maps.LatLng(area[0][0], area[0][1]), @@ -10379,11 +10099,6 @@ requires that.findPlace = function(name, callback) { getPlaceByName(name, function(place) { if (place) { - /* - self.marker = place.marker.add('yellow'); - self.polygon && self.polygon.remove(); - self.polygon = place.polygon.add(); - */ addPlace(place); self.resultPlace = place; selectPlace(place.id); @@ -10478,9 +10193,10 @@ requires nw: new google.maps.LatLng(that.north, that.west), w: new google.maps.LatLng(that.lat, that.west), }); - that.crossesDateline = that.west > that.east; - that.sizeNorthSouth = (that.north - that.south) * Ox.EARTH_CIRCUMFERENCE / 360; - that.sizeEastWest = Math.abs(that.west - that.east) * Ox.getMetersPerDegree(that.lat); + that.sizeNorthSouth = (that.north - that.south) * + Ox.EARTH_CIRCUMFERENCE / 360; + that.sizeEastWest = (that.east + (that.west > that.east ? 360 : 0) - that.west) * + Ox.getMetersPerDegree(that.lat); that.size = Ox.getArea( {lat: that.south, lng: that.west}, {lat: that.north, lng: that.east} @@ -10490,7 +10206,7 @@ requires map: that.map, place: that }); - that.polygon = new Ox.MapPolygon({ + that.rectangle = new Ox.MapRectangle({ map: that.map, place: that }); @@ -10508,15 +10224,19 @@ requires that.undo(); that.editing = false; that.marker.update(); - that.polygon.deselect(); + that.rectangle.deselect(); return that; }; + that.crossesDateline = function() { + return that.west > that.east; + } + that.deselect = function() { that.editing && that.submit(); that.selected = false; that.marker.update(); - that.polygon.remove(); + that.rectangle.remove(); return that; }; @@ -10529,7 +10249,7 @@ requires west: that.west }; that.marker.edit(); - that.polygon.select(); + that.rectangle.select(); return that; } @@ -10544,7 +10264,7 @@ requires that.select = function() { that.selected = true; that.marker.update(); - that.polygon.add(); + that.rectangle.add(); return that; }; @@ -10552,7 +10272,7 @@ requires Ox.print('submit') that.editing = false; that.marker.update(); - that.polygon.deselect(); + that.rectangle.deselect(); return that; }; @@ -10566,7 +10286,7 @@ requires }); that.update(); that.marker.update(); - that.polygon.update(); + that.rectangle.update(); }; return that; @@ -10604,32 +10324,13 @@ requires } } - function setOptions() { - // fixme: setting draggable on cancel seems to make additional marker appear - Ox.print('Marker setOptions') - that.marker.setOptions({ - cursor: that.place.editing ? 'move' : 'pointer', - draggable: that.place.editing, - icon: new google.maps.MarkerImage( - oxui.path + 'png/ox.ui/mapMarker' + - (that.place.id[0] == '_' ? 'Result' : '') + - (that.place.editing ? 'Editing' : ( - that.place.selected ? 'Selected' : '' - )) + '.png', - new google.maps.Size(16, 16), - new google.maps.Point(0, 0), - new google.maps.Point(8, 8) - ), - position: that.place.center, - visible: false - }); - // workaround to prevent marker from appearing twice - // after setting draggable from true to false - setTimeout(function() { - that.marker.setOptions({ - visible: true - }); - }, 0); + function correctLng(lng) { + if (lng < -180) { + lng += 360; + } else if (lng > 180) { + lng -= 360; + } + return lng; } function dragstart(e) { @@ -10644,29 +10345,55 @@ requires Ox.MAX_LATITUDE - northSouth ), lng = e.latLng.lng(), - crossesDateline, degreesPerMeter = Ox.getDegreesPerMeter(lat); - Ox.print('west', that.place.west, 'east', that.place.east); that.place.south += lat - that.place.lat; that.place.north += lat - that.place.lat; that.place.west = lng - that.place.sizeEastWest * degreesPerMeter / 2; that.place.east = lng + that.place.sizeEastWest * degreesPerMeter / 2; - Ox.print('west', that.place.west, 'east', that.place.east); - crossesDateline = that.place.west > that.place.east; - if (that.place.crossesDateline != crossesDateline) { - + if (that.place.west < -180) { + that.place.west += 360; + } else if (that.place.east > 180) { + that.place.east -= 360; } + Ox.print('west', that.place.west, 'east', that.place.east); that.place.update(); that.marker.setOptions({ position: that.place.center }) - that.place.polygon.update(); + that.place.rectangle.update(); } function dragend(e) { } + function setOptions() { + // workaround to prevent marker from appearing twice + // after setting draggable from true to false + var fix = that.marker.getDraggable() && !that.place.editing; + that.marker.setOptions({ + cursor: that.place.editing ? 'move' : 'pointer', + draggable: that.place.editing, + icon: new google.maps.MarkerImage( + oxui.path + 'png/ox.ui/mapMarker' + + (that.place.id[0] == '_' ? 'Result' : '') + + (that.place.editing ? 'Editing' : ( + that.place.selected ? 'Selected' : '' + )) + '.png', + new google.maps.Size(16, 16), + new google.maps.Point(0, 0), + new google.maps.Point(8, 8) + ), + position: that.place.center + }); + if (fix) { + that.marker.setVisible(false); + setTimeout(function() { + that.marker.setVisible(true); + }, 0); + } + } + that.add = function() { Ox.print('MapMarker add', that) that.marker.setMap(that.map.map); @@ -10701,7 +10428,7 @@ requires }; - Ox.MapPolygon = function(options, self) { + Ox.MapRectangle = function(options, self) { var options = Ox.extend({ map: null, @@ -10713,18 +10440,12 @@ requires that[key] = val; }); - that.polygon = new google.maps.Polygon({ + that.rectangle = new google.maps.Rectangle({ clickable: true, - paths: [ - that.place.points.sw, - that.place.points.nw, - that.place.points.ne, - that.place.points.se, - that.place.points.sw - ], + bounds: that.place.bounds, }); that.markers = Ox.map(that.place.points, function(point, position) { - return new Ox.MapPolygonMarker({ + return new Ox.MapRectangleMarker({ map: that.map, place: that.place, position: position @@ -10747,7 +10468,7 @@ requires function setOptions() { var color = that.place.editing ? '#8080FF' : '#FFFFFF'; - that.polygon.setOptions({ + that.rectangle.setOptions({ fillColor: color, fillOpacity: that.place.editing ? 0.1 : 0, strokeColor: color, @@ -10757,8 +10478,8 @@ requires } that.add = function() { - that.polygon.setMap(that.map.map); - google.maps.event.addListener(that.polygon, 'click', click); + that.rectangle.setMap(that.map.map); + google.maps.event.addListener(that.rectangle, 'click', click); return that; }; @@ -10771,8 +10492,8 @@ requires }; that.remove = function() { - that.polygon.setMap(null); - google.maps.event.clearListeners(that.polygon); + that.rectangle.setMap(null); + google.maps.event.clearListeners(that.rectangle); return that } @@ -10785,14 +10506,8 @@ requires }; that.update = function() { - that.polygon.setOptions({ - paths: [ - that.place.points.sw, - that.place.points.nw, - that.place.points.ne, - that.place.points.se, - that.place.points.sw - ] + that.rectangle.setOptions({ + bounds: that.place.bounds }); Ox.forEach(that.markers, function(marker) { marker.update(); @@ -10803,7 +10518,7 @@ requires }; - Ox.MapPolygonMarker = function(options, self) { + Ox.MapRectangleMarker = function(options, self) { var options = Ox.extend({ map: null, @@ -10838,14 +10553,13 @@ requires } function drag(e) { + Ox.print(e.pixel.x, e.pixel.y) var lat = Ox.limit(e.latLng.lat(), Ox.MIN_LATITUDE, Ox.MAX_LATITUDE), - lng = e.latLng.lng(), - crossesDateline = Math.abs(lng - that.drag.lng) > 180; + lng = e.latLng.lng(); that.drag = { lat: lat, lng: lng }; - Ox.print('e', e) if (that.position.indexOf('s') > -1) { that.place.south = lat; } @@ -10853,29 +10567,16 @@ requires that.place.north = lat; } if (that.position.indexOf('w') > -1) { - if (lng < that.place.east) - that.place.west = lng; - else - that.place.east = lng; + that.place.west = lng; } if (that.position.indexOf('e') > -1) { - if (lng > that.place.west) - that.place.east = lng; - else - that.place.west = lng; + that.place.east = lng; } Ox.print('west', that.place.west, 'east', that.place.east); - /* - if (that.place.west > that.place.east) { - var west = that.place.west; - that.place.west = that.place.east; - that.place.east = west; - } - */ - + Ox.print('south', that.place.south, 'north', that.place.north); that.place.update(); that.place.marker.update(); - that.place.polygon.update(); + that.place.rectangle.update(); } function dragend(e) { @@ -10886,7 +10587,7 @@ requires that.place.north = south; that.place.update(); that.place.marker.update(); - that.place.polygon.update(); + that.place.rectangle.update(); } } diff --git a/demos/map/js/map.js b/demos/map/js/map.js index bf2adfa1..be529b82 100644 --- a/demos/map/js/map.js +++ b/demos/map/js/map.js @@ -42,11 +42,12 @@ $(function() { }) .bindEvent({ selectplace: function(event, data) { + Ox.print('DATA', data) panel.replaceElement(1, list = new Ox.TreeList({ - data: { + data: Ox.isEmpty(data) ? [] : { components: data.components, countryCode: data.countryCode, - crossesDateline: data.crossesDateline, + crossesDateline: data.crossesDateline(), east: data.east, fullGeoname: data.fullGeoname, geoname: data.geoname,