Skip to content

Commit

Permalink
Merge pull request #220 from developmentseed/enhance/starter-presets
Browse files Browse the repository at this point in the history
Add starter presets for ways
  • Loading branch information
vgeorge authored May 13, 2020
2 parents ad7cb8c + 7628a8f commit 04abdb4
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 39 deletions.
48 changes: 28 additions & 20 deletions app/actions/wayEditing.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,41 @@ export function setSelectedNode (node) {
}

export function editWayEnter (feature) {
const {
properties: { ndrefs },
geometry: { coordinates, type }
} = feature
let way = null

const nodesCoordinates = type === 'Polygon' ? coordinates[0] : coordinates
// The following block is executed when editing a existing feature.
// It adds its member notes to the state, allowing their selection on click.
if (feature) {
const {
properties: { ndrefs },
geometry: { coordinates, type }
} = feature

// Get nodes from line/polygon to allow node selection
const nodes = nodesCoordinates.map((coords, i) => {
const id = `node/${ndrefs[i]}`
return {
id,
type: 'Feature',
properties: {
id
},
geometry: {
type: 'Point',
coordinates: coords
const nodesCoordinates = type === 'Polygon' ? coordinates[0] : coordinates

// Get nodes from line/polygon to allow node selection
const nodes = nodesCoordinates.map((coords, i) => {
const id = `node/${ndrefs[i]}`
return {
id,
type: 'Feature',
properties: {
id
},
geometry: {
type: 'Point',
coordinates: coords
}
}
}
})
})

way = { nodes }
}

return {
type: types.WAY_EDIT_ENTER,
feature,
way: { nodes }
way
}
}

Expand Down
172 changes: 166 additions & 6 deletions app/presets/starter-presets.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,170 @@
{
"presets": {
"building": {"icon": "maki-home", "fields": ["name", "building", "levels", "height", "address"], "moreFields": ["architect", "building/material", "layer", "roof/colour", "smoking", "wheelchair"], "geometry": ["point", "area"], "tags": {"building": "*"}, "matchScore": 0.6, "terms": [], "name": "Building"},
"highway/bus_stop": {"icon": "maki-bus", "fields": ["name", "network", "operator", "bench", "shelter"], "geometry": ["point", "vertex"], "tags": {"highway": "bus_stop"}, "name": "Bus Stop / Platform", "searchable": false},
"natural/tree": {"icon": "maki-park", "fields": ["leaf_type_singular", "leaf_cycle_singular", "denotation"], "geometry": ["point", "vertex"], "tags": {"natural": "tree"}, "terms": [], "name": "Tree"},
"amenity/school": {"icon": "maki-school", "fields": ["name", "operator", "address", "religion", "denomination", "website"], "moreFields": ["internet_access", "internet_access/ssid", "phone", "email", "fax", "wheelchair"], "geometry": ["point", "area"], "terms": ["academy", "elementary school", "middle school", "high school"], "tags": {"amenity": "school"}, "name": "School"},
"amenity/restaurant": {"icon": "maki-restaurant", "fields": ["name", "cuisine", "address", "building_area", "opening_hours", "outdoor_seating"], "moreFields": ["takeaway", "delivery", "capacity", "diet_multi", "smoking", "internet_access", "internet_access/fee", "internet_access/ssid", "website", "phone", "email", "fax", "wheelchair", "bar"], "geometry": ["point", "area"], "terms": ["bar", "breakfast", "cafe", "café", "canteen", "coffee", "dine", "dining", "dinner", "drive-in", "eat", "grill", "lunch", "table"], "tags": {"amenity": "restaurant"}, "name": "Restaurant"},
"point": {"fields": ["name"], "geometry": ["point"], "tags": {}, "name": "Point", "matchScore": 0.1}
"building": {
"icon": "maki-home",
"fields": ["name", "building", "levels", "height", "address"],
"moreFields": [
"architect",
"building/material",
"layer",
"roof/colour",
"smoking",
"wheelchair"
],
"geometry": ["point", "area"],
"tags": { "building": "*" },
"matchScore": 0.6,
"terms": [],
"name": "Building"
},
"highway/bus_stop": {
"icon": "maki-bus",
"fields": ["name", "network", "operator", "bench", "shelter"],
"geometry": ["point", "vertex"],
"tags": { "highway": "bus_stop" },
"name": "Bus Stop / Platform",
"searchable": false
},
"natural/tree": {
"icon": "maki-park",
"fields": ["leaf_type_singular", "leaf_cycle_singular", "denotation"],
"geometry": ["point", "vertex"],
"tags": { "natural": "tree" },
"terms": [],
"name": "Tree"
},
"amenity/school": {
"icon": "maki-school",
"fields": [
"name",
"operator",
"address",
"religion",
"denomination",
"website"
],
"moreFields": [
"internet_access",
"internet_access/ssid",
"phone",
"email",
"fax",
"wheelchair"
],
"geometry": ["point", "area"],
"terms": ["academy", "elementary school", "middle school", "high school"],
"tags": { "amenity": "school" },
"name": "School"
},
"amenity/restaurant": {
"icon": "maki-restaurant",
"fields": [
"name",
"cuisine",
"address",
"building_area",
"opening_hours",
"outdoor_seating"
],
"moreFields": [
"takeaway",
"delivery",
"capacity",
"diet_multi",
"smoking",
"internet_access",
"internet_access/fee",
"internet_access/ssid",
"website",
"phone",
"email",
"fax",
"wheelchair",
"bar"
],
"geometry": ["point", "area"],
"terms": [
"bar",
"breakfast",
"cafe",
"café",
"canteen",
"coffee",
"dine",
"dining",
"dinner",
"drive-in",
"eat",
"grill",
"lunch",
"table"
],
"tags": { "amenity": "restaurant" },
"name": "Restaurant"
},
"point": {
"fields": ["name"],
"geometry": ["point"],
"tags": {},
"name": "Point",
"matchScore": 0.1
},
"highway": {
"fields": ["name", "highway"],
"geometry": ["line"],
"tags": { "highway": "*" },
"searchable": false,
"name": "Highway"
},
"waterway/stream": {
"fields": ["name", "structure_waterway", "width", "intermittent"],
"moreFields": ["covered", "fishing", "gnis/feature_id", "salt", "tidal"],
"geometry": ["line"],
"terms": [
"beck",
"branch",
"brook",
"burn",
"course",
"creek",
"current",
"drift",
"flood",
"flow",
"freshet",
"race",
"rill",
"rindle",
"rivulet",
"run",
"runnel",
"rush",
"spate",
"spritz",
"surge",
"tide",
"torrent",
"tributary",
"watercourse"
],
"tags": { "waterway": "stream" },
"name": "Stream"
},
"barrier/fence": {
"icon": "maki-fence",
"fields": ["fence_type", "height", "material"],
"geometry": ["line"],
"tags": { "barrier": "fence" },
"name": "Fence",
"matchScore": 0.25
},
"barrier/wall": {
"icon": "temaki-wall",
"fields": ["wall", "height", "material"],
"geometry": ["line", "area"],
"tags": { "barrier": "wall" },
"name": "Wall",
"matchScore": 0.25
}
}
}
37 changes: 24 additions & 13 deletions app/screens/Features/SelectFeatureType.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import PageWrapper from '../../components/PageWrapper'
import ObserveIcon from '../../components/ObserveIcon'

import { colors } from '../../style/variables'
import { presets as starterPresets } from '../../presets/starter-presets.json'
import { modeFeatureType } from '../../utils/map-modes'
import _intersection from 'lodash.intersection'
import { presets } from '../../presets/starter-presets.json'

const starterPresets = objToArray(presets)

const win = Dimensions.get('window')

Expand Down Expand Up @@ -106,20 +108,38 @@ class SelectFeatureType extends React.Component {
)
}

// From an array of presets, filter which are applicable to the current
// feature mode and sort by name
getApplicablePresets (presets) {
return presets
.filter(
(p) =>
_intersection(p.geometry, modeFeatureType[this.props.mode]).length
)
.sort((a, b) => {
var nameA = a.name.toLowerCase()
var nameB = b.name.toLowerCase()
if (nameA < nameB) return -1
if (nameA > nameB) return 1
return 0
})
}

getFilteredPresets (presets, text) {
// If there is no passed text or presets to filter, apply starterPresets
if (!text || !presets || !presets.length || text.length < 3) {
return objToArray(starterPresets)
return this.getApplicablePresets(starterPresets)
}

return presets.filter((preset) => {
// Or apply text filter to passed presets
return this.getApplicablePresets(presets).filter((preset) => {
return preset.name.toLowerCase().includes(text.toLowerCase())
})
}

renderPresets () {
const { presets, searchText } = this.state

// FIXME: starter presets should also have way presets
const filteredPresets = this.getFilteredPresets(presets, searchText)

return (
Expand All @@ -132,16 +152,7 @@ class SelectFeatureType extends React.Component {
static getDerivedStateFromProps (props, state) {
if (state.presets.length !== props.presets.length) {
state.presets = objToArray(props.presets)
.filter((preset) => _intersection(preset.geometry, modeFeatureType[props.mode]).length)
.sort((a, b) => {
var nameA = a.name.toLowerCase()
var nameB = b.name.toLowerCase()
if (nameA < nameB) return -1
if (nameA > nameB) return 1
return 0
})
}

return state
}

Expand Down

0 comments on commit 04abdb4

Please sign in to comment.