mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-21 19:26:41 +02:00
add alternative formats for coordinate search: (#10805)
* zoom/x/y – copy/paste from an osm.org URL or web map with map-hash param (this also sets map zoom to the respective value) * x/y – like the above, but does not set zoom level * x y – where x and y are numbers in the user's locale's number format
This commit is contained in:
@@ -38,6 +38,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
|
||||
# unreleased (v2.33.0-dev)
|
||||
|
||||
#### :sparkles: Usability & Accessibility
|
||||
* Allow searching for coordinates in localized number format in search box ([#10805])
|
||||
#### :scissors: Operations
|
||||
#### :camera: Street-Level
|
||||
#### :white_check_mark: Validation
|
||||
@@ -49,6 +50,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
|
||||
#### :mortar_board: Walkthrough / Help
|
||||
#### :hammer: Development
|
||||
|
||||
[#10805]: https://github.com/openstreetmap/iD/pull/10805
|
||||
[#10299]: https://github.com/openstreetmap/iD/issues/10299
|
||||
[#10843]: https://github.com/openstreetmap/iD/pull/10843
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ export function uiFeatureList(context) {
|
||||
var result = [];
|
||||
var graph = context.graph();
|
||||
var visibleCenter = context.map().extent().center();
|
||||
var q = search.property('value').toLowerCase();
|
||||
var q = search.property('value').toLowerCase().trim();
|
||||
|
||||
if (!q) return result;
|
||||
|
||||
@@ -132,8 +132,9 @@ export function uiFeatureList(context) {
|
||||
|
||||
const isLatLonValid = latLon[0] >= -90 && latLon[0] <= 90 && latLon[1] >= -180 && latLon[1] <= 180;
|
||||
let isLonLatValid = lonLat[0] >= -90 && lonLat[0] <= 90 && lonLat[1] >= -180 && lonLat[1] <= 180;
|
||||
isLonLatValid &&= !q.match(/[NSEW]/i);
|
||||
isLonLatValid &&= lonLat[0] !== lonLat[1];
|
||||
isLonLatValid &&= !q.match(/[NSEW]/i); // don't flip coords with explicit cardinal directions
|
||||
isLonLatValid &&= !locationMatch[2]; // don't flip zoom/x/y coords
|
||||
isLonLatValid &&= lonLat[0] !== lonLat[1]; // don't flip when lat=lon
|
||||
|
||||
if (isLatLonValid) {
|
||||
result.push({
|
||||
@@ -141,7 +142,8 @@ export function uiFeatureList(context) {
|
||||
geometry: 'point',
|
||||
type: t('inspector.location'),
|
||||
name: dmsCoordinatePair([latLon[1], latLon[0]]),
|
||||
location: latLon
|
||||
location: latLon,
|
||||
zoom: locationMatch[2]
|
||||
});
|
||||
}
|
||||
if (isLonLatValid) {
|
||||
@@ -369,7 +371,7 @@ export function uiFeatureList(context) {
|
||||
d3_event.preventDefault();
|
||||
|
||||
if (d.location) {
|
||||
context.map().centerZoomEase([d.location[1], d.location[0]], 19);
|
||||
context.map().centerZoomEase([d.location[1], d.location[0]], d.zoom || 19);
|
||||
|
||||
} else if (d.entity) {
|
||||
utilHighlightEntities([d.id], false, context);
|
||||
|
||||
+28
-7
@@ -188,7 +188,7 @@ export function decimalCoordinatePair(coord) {
|
||||
|
||||
// Return the parsed value that @mapbox/sexagesimal can't parse
|
||||
// return value format : [D, D] ex:[ 35.1861, 136.83161 ]
|
||||
export function dmsMatcher(q) {
|
||||
export function dmsMatcher(q, _localeCode = undefined) {
|
||||
const matchers = [
|
||||
// D M SS , D M SS ex: 35 11 10.1 , 136 49 53.8
|
||||
{
|
||||
@@ -199,9 +199,7 @@ export function dmsMatcher(q) {
|
||||
const lng = (+match[6]) + (+match[7]) / 60 + (+match[8]) / 3600;
|
||||
const isNegLat = match[1] === '-' ? -lat : lat;
|
||||
const isNegLng = match[5] === '-' ? -lng : lng;
|
||||
const d = [isNegLat, isNegLng];
|
||||
|
||||
return d;
|
||||
return [isNegLat, isNegLng];
|
||||
}
|
||||
},
|
||||
// D MM , D MM ex: 35 11.1683 , 136 49.8966
|
||||
@@ -213,12 +211,35 @@ export function dmsMatcher(q) {
|
||||
const lng = +match[5] + (+match[6]) / 60;
|
||||
const isNegLat = match[1] === '-' ? -lat : lat;
|
||||
const isNegLng = match[4] === '-' ? -lng : lng;
|
||||
const d = [isNegLat, isNegLng];
|
||||
|
||||
return d;
|
||||
return [isNegLat, isNegLng];
|
||||
}
|
||||
},
|
||||
// zoom/x/y ex: 2/1.23/34.44
|
||||
{
|
||||
condition: /^\s*(\d+\.?\d*)\s*\/\s*(-?\d+\.?\d*)\s*\/\s*(-?\d+\.?\d*)\s*$/,
|
||||
parser: function(q) {
|
||||
const match = this.condition.exec(q);
|
||||
const lat = +match[2];
|
||||
const lng = +match[3];
|
||||
const zoom = +match[1];
|
||||
return [lat, lng, zoom];
|
||||
}
|
||||
},
|
||||
// x/y , x, y , x y where x and y are localized floats, e.g. in German locale: 49,4109399, 8,7147086
|
||||
{
|
||||
condition: { test: q => !!localizedNumberCoordsParser(q) },
|
||||
parser: localizedNumberCoordsParser
|
||||
}
|
||||
];
|
||||
function localizedNumberCoordsParser(q, ) {
|
||||
const parseLocaleFloat = localizer.floatParser(_localeCode || localizer.localeCode());
|
||||
let parts = q.split(/,?\s+|\s*[\/\\]\s*/);
|
||||
if (parts.length !== 2) return false;
|
||||
const lat = parseLocaleFloat(parts[0]);
|
||||
const lng = parseLocaleFloat(parts[1]);
|
||||
if (isNaN(lat) || isNaN(lng)) return false;
|
||||
return [lat, lng];
|
||||
}
|
||||
for (const matcher of matchers) {
|
||||
if (matcher.condition.test(q)){
|
||||
return matcher.parser(q);
|
||||
|
||||
@@ -21,6 +21,28 @@ describe('iD.units', function() {
|
||||
expect(result[0]).to.be.closeTo( -35.18614, 0.00001);
|
||||
expect(result[1]).to.be.closeTo(-136.83161, 0.00001);
|
||||
});
|
||||
it('parses z/x/y coordinate', () => {
|
||||
var result = iD.dmsMatcher('2/-1.23/34.44');
|
||||
expect(result[0]).to.be.closeTo(-1.23, 0.00001);
|
||||
expect(result[1]).to.be.closeTo(34.44, 0.00001);
|
||||
expect(result[2]).to.eql(2);
|
||||
});
|
||||
it('parses x/y coordinate', () => {
|
||||
var result = iD.dmsMatcher('-1.23/34.44');
|
||||
expect(result[0]).to.be.closeTo(-1.23, 0.00001);
|
||||
expect(result[1]).to.be.closeTo(34.44, 0.00001);
|
||||
});
|
||||
it('parses z/x/y coordinate', () => {
|
||||
var result = iD.dmsMatcher('2/-1.23/34.44');
|
||||
expect(result[0]).to.be.closeTo(-1.23, 0.00001);
|
||||
expect(result[1]).to.be.closeTo(34.44, 0.00001);
|
||||
expect(result[2]).to.eql(2);
|
||||
});
|
||||
it('parses coordinate with localized numbers', () => {
|
||||
var result = iD.dmsMatcher('49,4109399, 8,7147086', 'de');
|
||||
expect(result[0]).to.be.closeTo(49.4109399, 0.00001);
|
||||
expect(result[1]).to.be.closeTo( 8.7147086, 0.00001);
|
||||
});
|
||||
|
||||
it('handles invalid input', function() {
|
||||
var result = iD.dmsMatcher('!@#$');
|
||||
|
||||
Reference in New Issue
Block a user