Skip to content

Commit

Permalink
Merge ec7bbd6 into c0aba5a
Browse files Browse the repository at this point in the history
  • Loading branch information
jrflood committed Apr 22, 2019
2 parents c0aba5a + ec7bbd6 commit 1c5b842
Show file tree
Hide file tree
Showing 35 changed files with 1,975 additions and 23 deletions.
2 changes: 0 additions & 2 deletions app/controllers/collecting_events_controller.rb
Expand Up @@ -242,8 +242,6 @@ def filter_params
:start_date,
:end_date,
:partial_overlap_dates,
:start_day, :start_month, :start_year,
:end_day, :end_month, :end_year,
keyword_ids: [],
spatial_geographic_area_ids: []
)
Expand Down
@@ -0,0 +1,8 @@
class Tasks::CollectingEvents::SearchLocalityController < ApplicationController
include TaskControllerConfiguration

# GET
def index
end

end
3 changes: 3 additions & 0 deletions app/javascript/packs/application.js
Expand Up @@ -10,6 +10,7 @@
// Styles
require('../style/application.scss')
require('leaflet/dist/leaflet.css')
require('leaflet-draw/dist/leaflet.draw.css')

require('../vue/citations/otus/main.js')
require('../vue/content/editor/main.js')
Expand All @@ -31,6 +32,8 @@ require('../vue/tasks/uniquify/sources/main.js')
require('../vue/tasks/single_bibtex_source/main.js')
require('../vue/tasks/nomenclature/by_source/main.js')
require('../vue/tasks/people/author_by_letter/main.js')
require('../vue/tasks/collecting_events/search_localities/main.js')

require('../vue/tasks/digitize/main.js')
require('../vue/tasks/labels/print_labels/main.js')
require('../vue/tasks/projects/preferences/main.js')
Expand Down
Expand Up @@ -76,8 +76,8 @@
}
else {
return 'search'
}
}
}
}
}
</script>
</script>
227 changes: 227 additions & 0 deletions app/javascript/vue/components/leaflet/map.vue
@@ -0,0 +1,227 @@
<template>
<div
:style="{ width: this.width, height: this.height }"
ref="leafletMap"
:id="mapId"/>
</template>

<script>
import L from 'leaflet'
import LeafletDraw from 'leaflet-draw'
delete L.Icon.Default.prototype._getIconUrl
L.Icon.Default.mergeOptions({
iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
iconUrl: require('leaflet/dist/images/marker-icon.png'),
shadowUrl: require('leaflet/dist/images/marker-shadow.png')
})
export default {
props: {
width: {
type: String,
default: () => { return '500px' }
},
height: {
type: String,
default: () => { return '500px' }
},
zoom: {
type: Number,
default: () => { return 18 }
},
drawControls: {
type: Boolean,
default: () => { return false }
},
tilesSelection: {
type: Boolean,
default: true
},
center: {
type: Array,
default: () => { return [0, 0] }
},
geojson: {
type: Array,
default: () => { return [] }
}
},
data () {
return {
mapId: Math.random().toString(36).substring(7),
mapObject: undefined,
drawnItems: undefined,
drawControl: undefined,
tiles: {
osm: L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 18
}),
google: L.tileLayer('http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}', {
attribution: 'Google',
maxZoom: 18
})
},
layers: []
}
},
watch: {
geojson (newVal) {
if (newVal.length) {
this.geoJSON(newVal)
}
}
},
mounted () {
this.mapObject = L.map(this.mapId, {
center: this.center,
zoom: this.zoom
})
this.drawnItems = new L.FeatureGroup()
this.mapObject.addLayer(this.drawnItems)
this.addDrawControllers()
this.handleEvents()
if (this.geojson.length) {
this.geoJSON(this.geojson)
}
},
methods: {
antimeridian (elem, anti) {
if (Array.isArray(elem)) {
for (var i = 0; i < elem.length; i++) {
if (Array.isArray(elem[i][0])) {
this.antimeridian(elem[i], anti)
} else {
if (Array.isArray(elem[i])) {
if (elem[i][0] < 0) {
if (anti) {
elem[i][0] = 180 + (180 + elem[i][0])
}
} else {
if (!anti && (elem[i][0] > 180)) {
elem[i][0] = elem[i][0] - 360
}
}
} else {
if (elem[0] < 0) {
if (anti) {
elem[0] = 180 + (180 + elem[0])
}
} else {
if (!anti && (elem[0] > 180)) {
elem[0] = elem[0] - 360
}
}
}
}
}
}
},
addDrawControllers () {
if (this.tilesSelection) {
L.control.layers({
'OSM': this.tiles.osm.addTo(this.mapObject),
'Google': this.tiles.google
}, { 'Draw layers': this.drawnItems }, { position: 'topleft', collapsed: false }).addTo(this.mapObject)
}
if (this.drawControls) {
this.mapObject.addControl(new L.Control.Draw({
edit: {
featureGroup: this.drawnItems,
poly: {
allowIntersection: false
},
edit: true
},
draw: {
polygon: {
allowIntersection: false,
showArea: true
}
}
}))
this.mapObject.addControl(this.drawnItems)
}
},
showCoords(click) {
L.popup().setLatLng(click.latlng)
.setContent(click.latlng.toString())
.openOn(this.mapObject);
},
handleEvents () {
let that = this
this.mapObject.on(L.Draw.Event.CREATED, function (e) {
var layer = e.layer;
var popUp = L.popup();
var geoJsonLayer = layer.toGeoJSON()
if (geoJsonLayer.hasOwnProperty('geometry') && geoJsonLayer.geometry.hasOwnProperty('coordinates')) {
//that.antimeridian(geoJsonLayer.geometry.coordinates, false)
}
if (e.layerType === 'circle') {
geoJsonLayer.properties.radius = layer.getRadius()
}
that.$emit('shapeCreated', layer)
that.$emit('geoJsonLayerCreated', geoJsonLayer)
that.drawnItems.addLayer(layer)
})
this.mapObject.on('draw:edited', (e) => {
var layers = e.layers
that.$emit('shapesEdited', layers)
that.$emit('geoJsonLayersEdited', that.convertGeoJSONWithPointRadius(layers))
})
// this.mapObject.on('mouseover', this.showCoords);
},
removeLayers () {
this.drawnItems.clearLayers()
},
convertGeoJSONWithPointRadius (layerArray) {
let arrayLayers = []
layerArray.eachLayer(layer => {
let layerJson = layer.toGeoJSON()
if (typeof layer.getRadius === 'function') {
layerJson.properties.radius = layer.getRadius()
}
//this.antimeridian(layerJson.geometry.coordinates, false)
arrayLayers.push(layerJson)
})
return arrayLayers
},
toGeoJSON () {
return this.convertGeoJSONWithPointRadius(this.drawnItems)
},
addJsonCircle (layer) {
L.circle(layer.geometry.coordinates.reverse(), layer.properties.radius).addTo(this.drawnItems)
// L.circle(layer.geometry.coordinates, layer.properties.radius).addTo(this.drawnItems)
},
geoJSON (geojsonFeature) {
if (!Array.isArray(geojsonFeature) || geojsonFeature.length === 0) return
this.removeLayers()
let newGeojson = []
geojsonFeature.forEach(layer => { // scan feature array and either (i) or (ii)
//this.antimeridian(layer.geometry.coordinates, true)
if (layer.geometry.type === 'Point' && layer.properties.hasOwnProperty('radius')) {
this.addJsonCircle(layer) // (i) add a leaflet circle to the drawnItems data element
} else {
newGeojson.push(layer) // (ii) add this feature to the other array
}
})
L.geoJSON(newGeojson).getLayers().forEach(layer => {
this.drawnItems.on('mouseover', this.showCoords);
this.drawnItems.addLayer(layer)
});
this.mapObject.fitBounds(this.drawnItems.getBounds())
}
}
}
</script>
@@ -0,0 +1,17 @@
<template>
<div>
<h1>Search and List Localities</h1>
<collecting-event
@itemid="selectedItem=$event"
/>
</div>
</template>
<script>
import CollectingEvent from './components/collectingEvent.vue'
// TODO: ? (de)/persist lists
export default {
components: {
CollectingEvent,
},
}
</script>
@@ -0,0 +1,49 @@
<template>
<div>
<table>
<tr
v-for="(row, index) in rows"
:key="index">
<td
v-for="letter in row"
:key="letter"
:class="{ 'selected-letter': (letter == selected) }"
@click="sendLetter(letter)">{{ letter }}
</td>
</tr>
</table>
</div>
</template>
<script>
export default {
data() {
return {
rows: {
alphabet1: "ABCDEFGHIJKLM".split(""),
alphabet2: "NOPQRSTUVWXYZ".split("")
},
selected: ''
}
},
methods: {
sendLetter(letter) {
if(letter == this.selected) return
this.setSelectedLetter(letter)
this.$emit("keypress", letter);
},
setSelectedLetter(letter) {
this.selected = letter
let urlParams = new URLSearchParams(window.location.search)
urlParams.set('letter', letter)
history.pushState(null, null, `/tasks/collecting_events/search_locality/letter?${urlParams.toString()}`)
}
}
}
</script>

<style scoped>
.selected-letter {
color: #FFF;
background-color: #E3E8E3;
}
</style>

0 comments on commit 1c5b842

Please sign in to comment.