fixing dateline bugs

This commit is contained in:
rlx 2011-03-05 04:22:22 +00:00
parent 3605ae1afb
commit b7e236f056
3 changed files with 82 additions and 421 deletions

View file

@ -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;
};
}());

View file

@ -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();
}
}

View file

@ -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,