Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@
/libpeerconnection.log
npm-debug.log*
testem.log
.DS_Store
.vscode/*
14 changes: 0 additions & 14 deletions .vscode/settings.json

This file was deleted.

18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ yarn installation
ember g excel2geojson
```

## Development

### Clone this repo and install dependencies
~~~bash
git clone https://github.com/Atlanta-Explorer/ember-cli-excel2geojson.git
cd ember-cli-excel2geojson
yarn install # or npm install
bower install # this may not be needed
~~~

### Run the dummy app
~~~bash
ember s
~~~

See the dummy app at [http://localhost:4200](http://localhost:4200)


### Usage
When used as a block, a simple file input filed will be rendered. After an excel file is uploaded, it will appear in an [ember-light-table](http://offirgolan.github.io/ember-light-table/). Below the table will be a list of select fields for the control attributes.

Expand Down
246 changes: 246 additions & 0 deletions addon/components/geojson-parse-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
import { assert } from '@ember/debug';
import { inject as service } from '@ember/service';
import { oneWay } from '@ember/object/computed';
import Component from '@ember/component';
import { get, set, setProperties } from '@ember/object';
import { A } from '@ember/array';
import layout from '../templates/components/geojson-parse-data';
import $ from 'jquery';
import GeojsonData from '../lib/geojson-data';
import GeoData from '../lib/geo-data';
import SpreadsheetData from '../lib/spreadsheet-data';

const fileTypes = A(['xlsx', 'json', 'geojson']);
const reader = new FileReader();

export default Component.extend({
layout,
store: service(),
data: null,
table: null,
tableObject: null,
bounds: A([[33.7489954, -84.3879824]]),
/*
newBounds: Ember.computed('bounds', function() {
return L.fitBounds(bounds);
}),
*/

getExtension(fileName) {
// TODO: Should we check mime type? https://stackoverflow.com/a/29672957/1792144
// It would be nice, but not a prioritory.
return fileName.name.split('.').pop();
},
attributeMap: {
lat: null,
lng: null,
coords: null,
title: null,
description: null,
video: null,
audio: null,
images: null,
filters: null
},

// types: {label: 'Title'},
types: [{
label: 'Title',
disabled: false,
value: 'title'
},
{
label: 'Coords',
disabled: false,
value: 'coords'
},
{
label: 'Lat',
disabled: false,
value: 'lat'
},
{
label: 'Lng',
disabled: false,
value: 'lng'
},
{
label: 'Description',
disabled: false,
value: 'description'
},
{
label: 'Image(s)',
disabled: false,
value: 'images'
},
{
label: 'Image Credit',
disabled: false,
value: 'image-credit'
},
{
label: 'Video',
disabled: false,
value: 'video'
},
{
label: 'Audio',
disabled: false,
value: 'audio'
},
{
label: 'Filter',
disabled: false,
value: 'filters'
}
],
sheetJson: null,

imageArray(images) {
// TODO account for more cases.
// This only accounts for image urls that are sperated by
// a comma and a space. It does acount for filenames with
// spaces by checking for `http` after the space.
if (images) {
return images.replace(/(.)(\s*http)/gi, '$1, $2').split(',');
} else {
return undefined;
}
},

didInsertElement() {
let dataInput = $('#datafile').first()[0];
dataInput.onchange = (event) => {
const file = event.target.files[0];
const extension = this.getExtension(file);
assert(`File must be ${fileTypes.join(', ')}`, fileTypes.includes(extension));
if (extension === 'xlsx') {
reader.onload = () => {
set(this, 'data', SpreadsheetData.init());
};
reader.readAsBinaryString(file);

} else {
reader.onload = () => {
set(this, 'data', GeojsonData.init());
set(this, 'table', get(this, 'data.table'));
};
reader.readAsText(file);
}
};
},

actions: {
layerAdded(feature) {

if (feature.layer._latlng) {
// get(this, 'bounds').push([feature.layer._latlng.lat, feature.layer._latlng.lng]);
get(this, 'bounds').push([feature.layer._latlng]);
}
else {
get(this, 'bounds').push(feature.layer._latlngs);
}
feature.layer._map.fitBounds(get(this, 'bounds'));


},

updateLocation(feature, event) {
let location = event.target.getLatLng();
setProperties(feature, {
lat: location.lat,
lng: location.lng
});
},

onEachFeature(feature, layer) {
var popupText = "";
for (var key in feature.properties) {
if (!feature.properties.hasOwnProperty(key)) continue;
var obj = feature.properties[key];

popupText += (key + ": " + obj + "<br />");

layer.bindPopup(popupText);
}

layer.options.draggable = true;
},


updateFeature(attribute, feature, event) {
set(feature, `${attribute}`, event);
},

onClickFeature(feature, layer) {
// Assuming the clicked feature is a shape, not a point marker.
map.fitBounds(event.layer.getBounds());
},

generateFeatures() {
let table = get(this, 'data.tableJson');
//alert(Object.keys(table));
let attributeMap = get(this, 'attributeMap');
let foo = [];

table.forEach((d) => {
//alert([d[attributeMap['title']]]);
if(d.hasOwnProperty('coords')) {
let feature = {
type: 'Feature',
geometry: {
type: d['type'],
coordinates: d[attributeMap['coords']]
},
properties: {
title: d[attributeMap['title']],
description: d[attributeMap['description']],
images: this.imageArray(d[attributeMap['images']]),
video: d[attributeMap['video']],
audio: d[attributeMap['audio']],
filters: {}
}
}
feature.properties.filters[attributeMap['filters']] = d[attributeMap['filters']];
foo.push(feature);
} else {
let feature = {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [d[attributeMap['lng']], d[attributeMap['lat']]]
},
properties: {
title: d[attributeMap['title']],
description: d[attributeMap['description']],
images: this.imageArray(d[attributeMap['images']]),
video: d[attributeMap['video']],
audio: d[attributeMap['audio']],
filters: {}
}
}
feature.properties.filters[attributeMap['filters']] = d[attributeMap['filters']];
foo.push(feature);
}



// get(this, 'store').createRecord('vector_feature', {geojson: feature, vector_layer: get(this, 'layer')});


});
set(this, 'data.features', foo);

},

mapAttribute(type, column) {
const tdata = get(this, 'data.tableJson');
if (type === 'description') {
$(`<p>${tdata[0][column.target.value]}</p>`).appendTo('#preview-description');
}
get(this, 'attributeMap')[type] = column.target.value
}
}
});

Loading