forked from calvinmetcalf/esri2geo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathesri2geo.js
148 lines (146 loc) · 4.55 KB
/
esri2geo.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
var esri2geo = {};
(function () {
function toGeoJSON(data, cb){
if(typeof data === 'string'){
if(cb){
ajax(data, function(err, d){
toGeoJSON(d,cb);
});
return;
}else{
throw new TypeError('callback needed for url');
}
}
var outPut = { "type": "FeatureCollection","features": []};
var fl = data.features.length;
var i = 0;
while(fl>i){
var ft = data.features[i];
/* as only ESRI based products care if all the features are the same type of geometry, check for geometry type at a feature level*/
var outFT = {
"type": "Feature",
"properties":prop(ft.attributes)
};
if(ft.geometry.x){
//check if it's a point
outFT.geometry=point(ft.geometry);
}else if(ft.geometry.points){
//check if it is a multipoint
outFT.geometry=points(ft.geometry);
}else if(ft.geometry.paths){
//check if a line (or "ARC" in ESRI terms)
outFT.geometry=line(ft.geometry);
}else if(ft.geometry.rings){
//check if a poly.
outFT.geometry=poly(ft.geometry);
}
outPut.features.push(outFT);
i++;
}
cb(null, outPut);
}
function point(geometry){
//this one is easy
return {"type": "Point","coordinates": [geometry.x,geometry.y]};
}
function points(geometry){
//checks if the multipoint only has one point, if so exports as point instead
if(geometry.points.length===1){
return {"type": "Point","coordinates": geometry.points[0]};
}else{
return { "type": "MultiPoint","coordinates":geometry.points};
}
}
function line(geometry){
//checks if their are multiple paths or just one
if(geometry.paths.length===1){
return {"type": "LineString","coordinates": geometry.paths[0]};
}else{
return { "type": "MultiLineString","coordinates":geometry.paths};
}
}
function poly(geometry){
//first we check for some easy cases, like if their is only one ring
if(geometry.rings.length===1){
return {"type": "Polygon","coordinates": geometry.rings};
}else{
/*if it isn't that easy then we have to start checking ring direction, basically the ring goes clockwise its part of the polygon,
if it goes counterclockwise it is a hole in the polygon, but geojson does it by haveing an array with the first element be the polygons
and the next elements being holes in it*/
return decodePolygon(geometry.rings);
}
}
function decodePolygon(a){
//returns the feature
var coords = [],type;
var len = a.length;
var i = 0;
var len2 = coords.length-1;
while(len>i){
if(ringIsClockwise(a[i])){
coords.push([a[i]]);
len2++;
}else{
coords[len2].push(a[i]);
}
i++;
}
if(coords.length===1){
type="Polygon";
}else{
type="MultiPolygon";
}
return {"type":type,"coordinates":(coords.length===1)?coords[0]:coords};
}
/*determine if polygon ring coordinates are clockwise. clockwise signifies outer ring, counter-clockwise an inner ring
or hole. this logic was found at http://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-
points-are-in-clockwise-order
this code taken from http://esri.github.com/geojson-utils/src/jsonConverters.js by James Cardona (MIT lisense)
*/
function ringIsClockwise(ringToTest) {
var total = 0,
i = 0,
rLength = ringToTest.length,
pt1 = ringToTest[i],
pt2;
for (i; i < rLength - 1; i++) {
pt2 = ringToTest[i + 1];
total += (pt2[0] - pt1[0]) * (pt2[1] + pt1[1]);
pt1 = pt2;
}
return (total >= 0);
}
function prop(a){
var p = {};
for(var k in a){
if(a[k]){
p[k]=a[k];
}
}
return p;
}
function ajax(url, cb){
if(typeof module !== "undefined"){
var request = require("request");
request(url,{json:true},function(e,r,b){
cb(e,b);
});
return;
}
// the following is from JavaScript: The Definitive Guide
var response;
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState === 4 && req.status === 200) {
cb(null, JSON.parse(req.responseText));
}
};
req.open("GET", url);
req.send();
}
if (typeof module !== "undefined"){
module.exports = toGeoJSON;
} else {
esri2geo.toGeoJSON = toGeoJSON;
}
}());