zhanmingkan
2022-05-14 0fc43fe898d14895c97427801293edfb3a0c5bf1
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
 
function decodeCoordinate(coordinate, encodeOffset) {
    var result = []
    var cx, cy
    var offset = encodeOffset.slice()
 
    for (var i = 0, L = coordinate.length; i < L; i += 2) {
        cx = coordinate.charCodeAt(i) - 64
        cy = coordinate.charCodeAt(i + 1) - 64
        cx = ((cx >> 1) ^ (-(cx & 1))) + offset[0]
        cy = ((cy >> 1) ^ (-(cy & 1))) + offset[1]
        offset[0] = cx
        offset[1] = cy
        result.push([cx / 1024, cy / 1024])
    }
 
    return result
}
 
function decodeGeoJSON(geoJSON) {
    var decoder = {
        MultiPolygon: function (coordinates, encodeOffset) {
            return coordinates.map(function (coordinate, index) {
                return decodeCoordinate(coordinate, encodeOffset[index])
            })
        },
        Polygon: decodeCoordinate
    }
    var features = []
 
    if (typeof geoJSON === 'string') {
        geoJSON = JSON.parse(geoJSON)
    }
    features = geoJSON.features
    // If is unminified json format, do nothing
    if (!geoJSON.UTF8Encoding) {
        return geoJSON
    }
 
    for (var i = 0, M = features.length; i < M; i++) {
        var geometry = features[i].geometry
        var coordinates = geometry.coordinates
        var encodeOffsets = geometry.encodeOffsets
 
        coordinates.forEach(function (coordinate, index) {
            coordinates[index] = decoder[geometry.type](
                coordinate,
                encodeOffsets[index]
            )
        })
    }
    geoJSON.UTF8Encoding = false
 
    return geoJSON
}
 
function Region(name, contours, center) {
    this.name = name
    this.contours = contours
 
    if (!center) {
        var boundingRect = this.getBoundingRect()
 
        center = [
            (boundingRect.xMin + boundingRect.xMax) / 2,
            (boundingRect.yMin + boundingRect.yMax) / 2
        ]
    }
    this.center = center
}
 
Region.prototype.getBoundingRect = function () {
    var LIMIT = Number.MAX_VALUE
    var getBoundingRect = function (contour) {
        var min = [LIMIT, LIMIT], max = [-LIMIT, -LIMIT]
 
        contour.forEach(function (coordinate) {
            min[0] = Math.min(min[0], coordinate[0])
            max[0] = Math.max(max[0], coordinate[0])
            min[1] = Math.min(min[1], coordinate[1])
            max[1] = Math.max(max[1], coordinate[1])
        })
 
        return { xMin: min[0], yMin: min[1], xMax: max[0], yMax: max[1] }
    }
    var result = { xMin: LIMIT, yMin: LIMIT, xMax: -LIMIT, yMax: -LIMIT }
 
    this.contours.forEach(function (contour) {
        contour.forEach(function (coordinates) {
            var boundingRect = getBoundingRect(coordinates)
 
            result.xMin = Math.min(result.xMin, boundingRect.xMin)
            result.xMax = Math.max(result.xMax, boundingRect.xMax)
            result.yMin = Math.min(result.yMin, boundingRect.yMin)
            result.yMax = Math.max(result.yMax, boundingRect.yMax)
        })
    })
 
    return result
}
 
var geoJSONParser = function (geoJSON) {
    var decodedGeoJSON = decodeGeoJSON(geoJSON)
    var features = decodedGeoJSON.features.filter(function (feature) {
        return (
            feature.properties
            && feature.geometry
            && feature.geometry.coordinates.length > 0
        )
    })
 
    return features.map(function (feature) {
        var geometry = feature.geometry
        var coordinates = geometry.coordinates
 
        if (geometry.type === 'Polygon') {
            coordinates = coordinates.map(function (coordinate) {
                return [coordinate]
            })
        }
 
        return new Region(
            feature.properties.name,
            coordinates,
            feature.properties.cp
        )
    })
}
geoJSONParser.Region = Region;
geoJSONParser.decodeCoordinate = decodeCoordinate;
geoJSONParser.decodeGeoJSON = decodeGeoJSON;
if (typeof module === "undefined") {
    this.geoJSONParser = geoJSONParser;
} else {
    module.exports = geoJSONParser;
}
if (typeof define === "function") {
    define(function () { return geoJSONParser; });
}