Improve preset searching
Add preset searching of terms Add more synonyms, improve matching - levenstein for terms too.
11
data/presets/lint.js
Normal file
@@ -0,0 +1,11 @@
|
||||
var fs = require('fs');
|
||||
var p = JSON.parse(fs.readFileSync('presets.json', 'utf8'));
|
||||
|
||||
p = p.map(function(preset) {
|
||||
preset.match.terms = (preset.match.terms || []).map(function(t) {
|
||||
return t.trim();
|
||||
});
|
||||
return preset;
|
||||
});
|
||||
|
||||
fs.writeFileSync('presets.json', JSON.stringify(p, null, 4));
|
||||
1041
data/presets/presets.json
Normal file
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
@@ -194,8 +194,11 @@
|
||||
|
||||
var id = iD();
|
||||
|
||||
iD.util.asyncMap(['keys.json', 'presets/presets.json', 'presets/defaults.json',
|
||||
'presets/categories.json', 'presets/forms.json'], d3.json, function(err, data) {
|
||||
iD.util.asyncMap(['keys.json',
|
||||
'data/presets/presets.json',
|
||||
'data/presets/defaults.json',
|
||||
'data/presets/categories.json',
|
||||
'data/presets/forms.json'], d3.json, function(err, data) {
|
||||
id.connection()
|
||||
.keys(data[0]);
|
||||
|
||||
|
||||
@@ -39,25 +39,34 @@ iD.presets.Collection = function(collection) {
|
||||
|
||||
value = value.toLowerCase();
|
||||
|
||||
// Uses levenshtein distance, with a couple of hacks
|
||||
// to prioritize exact substring matches
|
||||
return iD.presets.Collection(collection.sort(function(a, b) {
|
||||
var ia = a.name.indexOf(value) >= 0,
|
||||
ib = b.name.indexOf(value) >= 0;
|
||||
var substring_name = _.filter(collection, function(a) {
|
||||
return a.name.indexOf(value) !== -1;
|
||||
}),
|
||||
substring_terms = _.filter(collection, function(a) {
|
||||
return _.any(a.match.terms || [], function(b) {
|
||||
return iD.util.editDistance(value, b) - b.length + value.length < 3;
|
||||
});
|
||||
}),
|
||||
levenstein_name = collection.map(function(a) {
|
||||
return { preset: a, dist: iD.util.editDistance(value, a.name) };
|
||||
}).filter(function(a) {
|
||||
return a.dist - a.preset.name.length + value.length < 3;
|
||||
}).sort(function(a, b) {
|
||||
return a.dist - b.dist;
|
||||
}).map(function(a) {
|
||||
return a.preset;
|
||||
}),
|
||||
other = _.find(collection, function(a) {
|
||||
return a.name === 'other';
|
||||
});
|
||||
|
||||
if (ia && !ib) {
|
||||
return -1;
|
||||
} else if (ib && !ia) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return iD.util.editDistance(value, a.name) - iD.util.editDistance(value, b.name);
|
||||
}).filter(function(d) {
|
||||
return iD.util.editDistance(value, d.name) - d.name.length + value.length < 3 ||
|
||||
d.name === 'other';
|
||||
}));
|
||||
return iD.presets.Collection(
|
||||
_.unique(
|
||||
substring_name.concat(
|
||||
substring_terms,
|
||||
levenstein_name,
|
||||
other)));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return presets;
|
||||
|
||||
@@ -1,467 +0,0 @@
|
||||
[
|
||||
{
|
||||
"name": "cafe",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "cafe"
|
||||
}
|
||||
},
|
||||
"icon": "cafe",
|
||||
"form": ["cuisine", "internet_access", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "park",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"leisure": "park"
|
||||
}
|
||||
},
|
||||
"icon": "park"
|
||||
},
|
||||
{
|
||||
"name": "water",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"natural": "water"
|
||||
}
|
||||
},
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"name": "wetland",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"natural": "wetland"
|
||||
}
|
||||
},
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"name": "wood",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"natural": "wood"
|
||||
}
|
||||
},
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"name": "coastline",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"natural": "coastline"
|
||||
}
|
||||
},
|
||||
"icon": ""
|
||||
},
|
||||
{
|
||||
"name": "supermarket",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"shop": "supermarket"
|
||||
}
|
||||
},
|
||||
"icon": "grocery",
|
||||
"form": ["operator", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "restaurant",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "restaurant"
|
||||
}
|
||||
},
|
||||
"icon": "restaurant",
|
||||
"form": ["cuisine", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "place of worship",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "place_of_worship"
|
||||
}
|
||||
},
|
||||
"icon": "place-of-worship",
|
||||
"form": ["religion", "denomination", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "school",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "school"
|
||||
}
|
||||
},
|
||||
"icon": "school",
|
||||
"form": ["operator", "building", "address"]
|
||||
},
|
||||
{
|
||||
"name": "parking",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "parking"
|
||||
}
|
||||
},
|
||||
"icon": "parking",
|
||||
"form": ["fee", "access", "address"]
|
||||
},
|
||||
{
|
||||
"name": "bank",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "bank"
|
||||
}
|
||||
},
|
||||
"icon": "bank",
|
||||
"form": ["atm", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "fast food",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "fast_food"
|
||||
}
|
||||
},
|
||||
"icon": "fast-food",
|
||||
"form": ["cuisine", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "bar",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "bar"
|
||||
}
|
||||
},
|
||||
"icon": "bar",
|
||||
"form": ["building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "bus stop",
|
||||
"match": {
|
||||
"type": ["point"],
|
||||
"tags": {
|
||||
"highway": "bus_stop"
|
||||
}
|
||||
},
|
||||
"icon": "bus",
|
||||
"form": ["operator", "shelter"]
|
||||
},
|
||||
{
|
||||
"name": "cinema",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "cinema"
|
||||
}
|
||||
},
|
||||
"icon": "cinema",
|
||||
"form": ["building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "hospital",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "hospital"
|
||||
}
|
||||
},
|
||||
"icon": "hospital",
|
||||
"form": ["emergency", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "pharmacy",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "pharmacy"
|
||||
}
|
||||
},
|
||||
"icon": "police",
|
||||
"form": ["dispensing", "operator", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "fire station",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "fire_station"
|
||||
}
|
||||
},
|
||||
"icon": "fire-station",
|
||||
"form": ["operator", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "police",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"amenity": "police"
|
||||
}
|
||||
},
|
||||
"icon": "pharmacy",
|
||||
"form": ["operator", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "museum",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"tourism": "museum"
|
||||
}
|
||||
},
|
||||
"icon": "museum",
|
||||
"form": ["operator", "building_area", "address"]
|
||||
},
|
||||
{
|
||||
"name": "golf course",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"leisure": "golf_course"
|
||||
}
|
||||
},
|
||||
"icon": "golf",
|
||||
"form": ["operator", "address"]
|
||||
},
|
||||
{
|
||||
"name": "river",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"waterway": "river"
|
||||
}
|
||||
},
|
||||
"icon": "waterway-river"
|
||||
},
|
||||
{
|
||||
"name": "stream",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"waterway": "stream"
|
||||
}
|
||||
},
|
||||
"icon": "waterway-river",
|
||||
"form": ["layer"]
|
||||
},
|
||||
{
|
||||
"name": "motorway",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"highway": "motorway"
|
||||
}
|
||||
},
|
||||
"icon": "highway-motorway",
|
||||
"form": ["oneway", "bridge", "tunnel", "access", "maxspeed"]
|
||||
},
|
||||
{
|
||||
"name": "residential road",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"highway": "residential"
|
||||
}
|
||||
},
|
||||
"icon": "highway-residential",
|
||||
"form": ["oneway", "bridge", "tunnel", "access", "maxspeed"]
|
||||
},
|
||||
{
|
||||
"name": "primary road",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"highway": "primary"
|
||||
}
|
||||
},
|
||||
"icon": "highway-primary",
|
||||
"form": ["oneway", "bridge", "tunnel", "access", "maxspeed"]
|
||||
},
|
||||
{
|
||||
"name": "secondary road",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"highway": "secondary"
|
||||
}
|
||||
},
|
||||
"icon": "highway-secondary",
|
||||
"form": ["oneway", "bridge", "tunnel", "access", "maxspeed"]
|
||||
},
|
||||
{
|
||||
"name": "tertiary road",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"highway": "tertiary"
|
||||
}
|
||||
},
|
||||
"icon": "highway-tertiary",
|
||||
"form": ["oneway", "bridge", "tunnel", "access", "maxspeed"]
|
||||
},
|
||||
{
|
||||
"name": "service road",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"highway": "service"
|
||||
}
|
||||
},
|
||||
"icon": "highway-service",
|
||||
"form": ["oneway", "bridge", "tunnel", "access", "maxspeed"]
|
||||
},
|
||||
{
|
||||
"name": "track",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"highway": "track"
|
||||
}
|
||||
},
|
||||
"icon": "highway-track",
|
||||
"form": ["oneway", "bridge", "tunnel", "access", "maxspeed"]
|
||||
},
|
||||
{
|
||||
"name": "rail",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"railway": "rail"
|
||||
}
|
||||
},
|
||||
"icon": "railway-rail"
|
||||
},
|
||||
{
|
||||
"name": "subway",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"railway": "subway"
|
||||
}
|
||||
},
|
||||
"icon": "railway-rail"
|
||||
},
|
||||
{
|
||||
"name": "trunk highway",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"highway": "trunk"
|
||||
}
|
||||
},
|
||||
"icon": "highway-trunk",
|
||||
"form": ["oneway", "bridge", "tunnel", "access", "maxspeed"]
|
||||
},
|
||||
{
|
||||
"name": "foot path",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"highway": "footway"
|
||||
}
|
||||
},
|
||||
"icon": "highway-footway"
|
||||
},
|
||||
{
|
||||
"name": "cycle path",
|
||||
"match": {
|
||||
"type": ["line"],
|
||||
"tags": {
|
||||
"highway": "cycleway"
|
||||
}
|
||||
},
|
||||
"icon": "highway-cycleway",
|
||||
"form": ["oneway", "bridge", "tunnel", "access", "maxspeed"]
|
||||
},
|
||||
{
|
||||
"name": "sport pitch",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": { "leisure": "pitch" }
|
||||
},
|
||||
"icon": "pitch",
|
||||
"form": ["surface"]
|
||||
},
|
||||
{
|
||||
"name": "basketball court",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"leisure": "pitch",
|
||||
"sport": "basketball"
|
||||
}
|
||||
},
|
||||
"icon": "basketball",
|
||||
"form": ["surface"]
|
||||
},
|
||||
{
|
||||
"name": "baseball diamond",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"leisure": "pitch",
|
||||
"sport": "baseball"
|
||||
}
|
||||
},
|
||||
"icon": "baseball",
|
||||
"form": ["surface"]
|
||||
},
|
||||
{
|
||||
"name": "soccer field",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"leisure": "pitch",
|
||||
"sport": "soccer"
|
||||
}
|
||||
},
|
||||
"icon": "soccer",
|
||||
"form": ["surface"]
|
||||
},
|
||||
{
|
||||
"name": "tennis court",
|
||||
"match": {
|
||||
"type": ["point", "area"],
|
||||
"tags": {
|
||||
"leisure": "pitch",
|
||||
"sport": "tennis"
|
||||
}
|
||||
},
|
||||
"icon": "tennis",
|
||||
"form": ["surface"]
|
||||
},
|
||||
{
|
||||
"name": "building",
|
||||
"match": {
|
||||
"type": ["area"],
|
||||
"tags": {
|
||||
"building": "*"
|
||||
}
|
||||
},
|
||||
"icon": "warehouse",
|
||||
"form": ["building_yes", "address"]
|
||||
},
|
||||
{
|
||||
"name": "turning circle",
|
||||
"match": {
|
||||
"type": ["vertex"],
|
||||
"tags": {
|
||||
"highway": "turning_circle"
|
||||
}
|
||||
},
|
||||
"icon": "circle"
|
||||
}
|
||||
]
|
||||