1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.locationtech.spatial4j.io;
20
21 import java.io.IOException;
22 import java.io.StringWriter;
23 import java.io.Writer;
24 import java.util.Iterator;
25
26 import org.locationtech.spatial4j.context.SpatialContext;
27 import org.locationtech.spatial4j.context.SpatialContextFactory;
28 import org.locationtech.spatial4j.shape.Circle;
29 import org.locationtech.spatial4j.shape.Point;
30 import org.locationtech.spatial4j.shape.Rectangle;
31 import org.locationtech.spatial4j.shape.Shape;
32 import org.locationtech.spatial4j.shape.ShapeCollection;
33 import org.locationtech.spatial4j.shape.impl.BufferedLine;
34 import org.locationtech.spatial4j.shape.impl.BufferedLineString;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class PolyshapeWriter implements ShapeWriter {
50
51 public PolyshapeWriter(SpatialContext ctx, SpatialContextFactory factory) {
52
53 }
54
55 @Override
56 public String getFormatName() {
57 return ShapeIO.POLY;
58 }
59
60
61 @Override
62 public void write(Writer output, Shape shape) throws IOException {
63 if (shape == null) {
64 throw new NullPointerException("Shape can not be null");
65 }
66 write(new Encoder(output), shape);
67 }
68
69 public void write(Encoder enc, Shape shape) throws IOException {
70 if (shape instanceof Point) {
71 Point v = (Point) shape;
72 enc.write(KEY_POINT);
73 enc.write(v.getX(), v.getY());
74 return;
75 }
76 if (shape instanceof Rectangle) {
77 Rectangle v = (Rectangle) shape;
78 enc.write(KEY_BOX);
79 enc.write(v.getMinX(), v.getMinY());
80 enc.write(v.getMaxX(), v.getMaxY());
81 return;
82 }
83 if (shape instanceof BufferedLine) {
84 BufferedLine v = (BufferedLine) shape;
85 enc.write(KEY_LINE);
86 if(v.getBuf()>0) {
87 enc.writeArg(v.getBuf());
88 }
89 enc.write(v.getA().getX(), v.getA().getY());
90 enc.write(v.getB().getX(), v.getB().getY());
91 return;
92 }
93 if (shape instanceof BufferedLineString) {
94 BufferedLineString v = (BufferedLineString) shape;
95 enc.write(KEY_LINE);
96 if(v.getBuf()>0) {
97 enc.writeArg(v.getBuf());
98 }
99 BufferedLine last = null;
100 Iterator<BufferedLine> iter = v.getSegments().iterator();
101 while (iter.hasNext()) {
102 BufferedLine seg = iter.next();
103 enc.write(seg.getA().getX(), seg.getA().getY());
104 last = seg;
105 }
106 if (last != null) {
107 enc.write(last.getB().getX(), last.getB().getY());
108 }
109 return;
110 }
111 if (shape instanceof Circle) {
112
113 Circle v = (Circle) shape;
114 Point center = v.getCenter();
115 double radius = v.getRadius();
116 enc.write(KEY_CIRCLE);
117 enc.writeArg(radius);
118 enc.write(center.getX(), center.getY());
119 return;
120 }
121 if (shape instanceof ShapeCollection) {
122 @SuppressWarnings("unchecked") ShapeCollection<Shape> v = (ShapeCollection<Shape>) shape;
123 Iterator<Shape> iter = v.iterator();
124 while(iter.hasNext()) {
125 write(enc, iter.next());
126 if(iter.hasNext()) {
127 enc.seperator();
128 }
129 }
130 return;
131 }
132 enc.writer.write("{unkwnwon " + LegacyShapeWriter.writeShape(shape) +"}");
133 }
134
135 @Override
136 public String toString(Shape shape) {
137 try {
138 StringWriter buffer = new StringWriter();
139 write(buffer, shape);
140 return buffer.toString();
141 } catch (IOException ex) {
142 throw new RuntimeException(ex);
143 }
144 }
145
146 public static final char KEY_POINT = '0';
147 public static final char KEY_LINE = '1';
148 public static final char KEY_POLYGON = '2';
149 public static final char KEY_MULTIPOINT = '3';
150 public static final char KEY_CIRCLE = '4';
151 public static final char KEY_BOX = '5';
152
153 public static final char KEY_ARG_START = '(';
154 public static final char KEY_ARG_END = ')';
155 public static final char KEY_SEPERATOR = ' ';
156
157
158
159
160
161
162
163
164 public static class Encoder {
165 long lastLat = 0;
166 long lastLng = 0;
167
168 final Writer writer;
169
170 public Encoder(Writer writer) {
171 this.writer = writer;
172 }
173
174 public void seperator() throws IOException {
175 writer.write(KEY_SEPERATOR);
176 lastLat = lastLng = 0;
177 }
178
179 public void startRing() throws IOException {
180 writer.write(KEY_ARG_START);
181 lastLat = lastLng = 0;
182 }
183
184 public void write(char event) throws IOException {
185 writer.write(event);
186 lastLat = lastLng = 0;
187 }
188
189 public void writeArg(double value) throws IOException {
190 writer.write(KEY_ARG_START);
191 encode(Math.round(value * 1e5));
192 writer.write(KEY_ARG_END);
193 }
194
195 public void write(double latitude, double longitude) throws IOException {
196
197 long lat = Math.round(latitude * 1e5);
198 long lng = Math.round(longitude * 1e5);
199
200 long dLat = lat - lastLat;
201 long dLng = lng - lastLng;
202
203 encode(dLat);
204 encode(dLng);
205
206 lastLat = lat;
207 lastLng = lng;
208 }
209
210 private void encode(long v) throws IOException {
211 v = v < 0 ? ~(v << 1) : v << 1;
212 while (v >= 0x20) {
213 writer.write(Character.toChars((int) ((0x20 | (v & 0x1f)) + 63)));
214 v >>= 5;
215 }
216 writer.write(Character.toChars((int) (v + 63)));
217 }
218 }
219 }