Skip to content

Commit

Permalink
Ensure GeoJSON
Browse files Browse the repository at this point in the history
  • Loading branch information
tmcw committed May 28, 2018
1 parent b73c22d commit de1ccf0
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 95 deletions.
4 changes: 4 additions & 0 deletions css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@ div#geojsonnet .leaflet-bar a {
div#geojsonnet .leaflet-bar a:hover {
background: var(--yellow);
}

div#geojsonnet .leaflet-container {
font-family: inherit;
}
22 changes: 6 additions & 16 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import Map from "./ui/map";
import GithubModal from "./ui/github_modal";
import Panel from "./panel/index";
import ApolloClient from "apollo-client";
import stringify from "json-stringify-pretty-compact";
import { createHttpLink } from "apollo-link-http";
import { ApolloLink } from "apollo-link";
import { InMemoryCache } from "apollo-cache-inmemory";
Expand Down Expand Up @@ -48,8 +47,7 @@ class App extends React.Component {
mode: "code",
layer: "mapbox",
githubModal: false,
geojson: JSON.stringify(initialGeojson),
geojsonObject: initialGeojson,
geojson: initialGeojson,
changeFrom: undefined
};
setMode = mode => {
Expand All @@ -64,14 +62,7 @@ class App extends React.Component {
this.setState({ layer });
};
setGeojson = (geojson, changeFrom) => {
this.setState({ geojson, geojsonObject: JSON.parse(geojson), changeFrom });
};
setGeojsonObject = (geojsonObject, changeFrom) => {
this.setState({
geojsonObject,
geojson: stringify(geojsonObject),
changeFrom
});
this.setState({ geojson, changeFrom });
};
render() {
const {
Expand All @@ -83,26 +74,25 @@ class App extends React.Component {
mode,
githubModal
} = this.state;
const { setGeojson, setLayer, setMode, setGeojsonObject } = this;
const { setGeojson, setLayer, setMode } = this;
return (
<ApolloProvider client={client}>
<div className="f6">
<div className="vh-100 flex sans-serif">
<div className="f6 sans-serif fw6">
<div className="vh-100 flex">
<div className="w-50 flex flex-column z-0">
<div className="bg-white flex justify-between bb">
<FileBar
geojson={geojson}
geojsonObject={geojsonObject}
setGeojson={setGeojson}
setGeojsonObject={setGeojsonObject}
toggleGithubModal={this.toggleGithubModal}
/>
</div>
<Map
layer={layer}
geojson={geojson}
setGeojson={setGeojson}
setGeojsonObject={setGeojsonObject}
changeFrom={changeFrom}
/>
<LayerSwitch layer={layer} setLayer={setLayer} />
</div>
Expand Down
29 changes: 18 additions & 11 deletions src/panel/json.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ import matchBrackets from "codemirror/addon/edit/matchbrackets";
import stringify from "json-stringify-pretty-compact";
import zoomextent from "../lib/zoomextent";
import { hint } from "@mapbox/geojsonhint";
import equal from "deep-equal";

function maybeParse(str) {
try {
return JSON.parse(str);
} catch (e) {
return new Error("could not parse");
}
}

export default class Code extends React.Component {
state = {
Expand All @@ -25,13 +34,13 @@ export default class Code extends React.Component {
} else if (err.length) {
this.handleGeoJSONError(editor, err);
} else {
console.log("valid geojson, sending");
const zoom =
changeObj.from.ch === 0 &&
changeObj.from.line === 0 &&
changeObj.origin == "paste";
try {
JSON.parse(val);
return setGeojson(val, "cm");
return setGeojson(JSON.parse(val), "cm");
} catch (e) {
console.error(e);
this.setState({
Expand Down Expand Up @@ -104,22 +113,20 @@ export default class Code extends React.Component {
lineNumbers: true,
theme: "idea"
});
editor.setValue(geojson);
editor.setValue(stringify(geojson));
editor.on("change", this.maybeChange);
this.setState({
editor
});
}
componentDidUpdate() {
componentDidUpdate(prevProps) {
const { editor } = this.state;
const { geojson, changeFrom } = this.props;
if (changeFrom === "cm") {
// we caused this change, don't react to it
return;
if (changeFrom !== "cm") {
editor.off("change", this.maybeChange);
editor.setValue(stringify(geojson));
editor.on("change", this.maybeChange);
}
const { editor } = this.state;
editor.off("change", this.maybeChange);
editor.setValue(geojson);
editor.on("change", this.maybeChange);
}
render() {
return <div className="flex-auto flex" ref={this.codeMirrorContainer} />;
Expand Down
56 changes: 28 additions & 28 deletions src/ui/file_bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ export default class FileBar extends React.Component {
this.fileInputRef.current.click();
};
onFileInputChange = e => {
const { setGeojsonObject } = this.props;
const { setGeojson } = this.props;
const { files } = e.target;
if (!(files && files[0])) return;
readFile.readAsText(files[0], function(err, text) {
const result = readFile.readFile(files[0], text);
if (result instanceof Error) {
} else {
setGeojsonObject(result);
setGeojson(result);
}
if (files[0].path) {
// context.data.set({
Expand All @@ -46,11 +46,11 @@ export default class FileBar extends React.Component {
});
};
downloadTopo = () => {
const { geojsonObject } = this.props;
const { geojson } = this.props;
var content = JSON.stringify(
topojson.topology(
{
collection: clone(geojsonObject)
collection: clone(geojson)
},
{
"property-transform": function(properties, key, value) {
Expand All @@ -74,9 +74,9 @@ export default class FileBar extends React.Component {
};

downloadGPX = () => {
const { geojsonObject } = this.props;
const { geojson } = this.props;
this.download(
togpx(geojsonObject, {
togpx(geojson, {
creator: "geojson.net"
}),
"map.gpx",
Expand All @@ -85,26 +85,26 @@ export default class FileBar extends React.Component {
};

downloadGeoJSON = () => {
const { geojsonObject } = this.props;
const { geojson } = this.props;
this.download(
JSON.stringify(geojsonObject, null, 2),
JSON.stringify(geojson, null, 2),
"map.geojson",
"text/plain;charset=utf-8"
);
};

downloadDSV = () => {
const { geojsonObject } = this.props;
const { geojson } = this.props;
this.download(
geojson2dsv(geojsonObject),
geojson2dsv(geojson),
"points.csv",
"text/plain;charset=utf-8"
);
};

downloadKML = () => {
const { geojsonObject } = this.props;
this.download(tokml(geojsonObject), "map.kml", "text/plain;charset=utf-8");
const { geojson } = this.props;
this.download(tokml(geojson), "map.kml", "text/plain;charset=utf-8");
};

downloadShp = () => {
Expand All @@ -117,15 +117,15 @@ export default class FileBar extends React.Component {
};

downloadWKT = () => {
const { geojsonObject } = this.props;
var features = geojsonObject.features;
const { geojson } = this.props;
var features = geojson.features;
if (features.length === 0) return;
var content = features.map(wellknown.stringify).join("\n");
this.download(content, "map.wkt", "text/plain;charset=utf-8");
};

render() {
const { setGeojsonObject } = this.props;
const { setGeojson } = this.props;
const exportFormats = [
{
title: "GeoJSON",
Expand Down Expand Up @@ -178,42 +178,42 @@ export default class FileBar extends React.Component {
"Are you sure you want to delete all features from this map?"
)
) {
setGeojsonObject({ type: "FeatureCollection", features: [] });
setGeojson({ type: "FeatureCollection", features: [] });
}
}
},
{
title: "Random: Points",
alt: "Add random points to your map",
action: () => {
const { setGeojsonObject, geojsonObject } = this.props;
const { setGeojson, geojson } = this.props;
var response = prompt("Number of points (default: 100)");
if (response === null) return;
var count = parseInt(response, 10);
if (isNaN(count)) count = 100;
const fc = geojsonNormalize(geojsonObject);
const fc = geojsonNormalize(geojson);
fc.features.push.apply(
fc.features,
geojsonRandom(count, "point").features
);
setGeojsonObject(fc);
setGeojson(fc);
}
},
{
title: "Add bboxes",
alt: "Add bounding box members to all applicable GeoJSON objects",
action: () => {
const { setGeojsonObject, geojsonObject } = this.props;
setGeojsonObject(geojsonExtent.bboxify(geojsonObject));
const { setGeojson, geojson } = this.props;
setGeojson(geojsonExtent.bboxify(geojson));
}
},
{
title: "Flatten Multi Features",
alt:
"Flatten MultiPolygons, MultiLines, and GeometryCollections into simple geometries",
action: () => {
const { setGeojsonObject, geojsonObject } = this.props;
setGeojsonObject(geojsonFlatten(geojsonObject));
const { setGeojson, geojson } = this.props;
setGeojson(geojsonFlatten(geojson));
}
},
// https://developers.google.com/maps/documentation/utilities/polylinealgorithm
Expand All @@ -222,11 +222,11 @@ export default class FileBar extends React.Component {
alt:
"Decode and show an encoded polyline. Precision 5 is supported.",
action: () => {
const { setGeojsonObject } = this.props;
const { setGeojson } = this.props;
const input = prompt("Enter your polyline");
try {
const decoded = polyline.toGeoJSON(input);
setGeojsonObject(decoded);
setGeojson(decoded);
} catch (e) {
alert("Sorry, we were unable to decode that polyline");
}
Expand All @@ -240,7 +240,7 @@ export default class FileBar extends React.Component {
try {
// TODO: base64 in browser
var decoded = wkx.Geometry.parse(Buffer.from(input, "base64"));
setGeojsonObject(decoded.toGeoJSON());
setGeojson(decoded.toGeoJSON());
// zoomextent(context); TODO
} catch (e) {
console.error(e);
Expand All @@ -257,7 +257,7 @@ export default class FileBar extends React.Component {
const input = prompt("Enter your Hex encoded WKB/EWKB");
try {
var decoded = wkx.Geometry.parse(Buffer.from(input, "hex"));
setGeojsonObject(decoded.toGeoJSON());
setGeojson(decoded.toGeoJSON());
// zoomextent(context); TODO
} catch (e) {
console.error(e);
Expand All @@ -274,7 +274,7 @@ export default class FileBar extends React.Component {
const input = prompt("Enter your WKT/EWKT String");
try {
var decoded = wkx.Geometry.parse(input);
setGeojsonObject(decoded.toGeoJSON());
setGeojson(decoded.toGeoJSON());
// zoomextent(context); TODO
} catch (e) {
console.error(e);
Expand Down
8 changes: 4 additions & 4 deletions src/ui/layer_switch.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import L from "leaflet";
import { layers } from "../layers";

export default ({ layer, setLayer }) => (
<div className="bt">
<div className="bt flex">
{layers.map(({ id, title }) => (
<button
<span
key={id}
onClick={() => setLayer(id)}
className={`pointer bn pa2 outline-0 ${
className={`db pointer bn pa2 outline-0 ${
layer === id ? "bg-light-yellow" : ""
}`}
>
{title}
</button>
</span>
))}
</div>
);
Loading

0 comments on commit de1ccf0

Please sign in to comment.