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 package org.openimaj.demos.mediaeval13.placing;
31
32 import gnu.trove.list.array.TLongArrayList;
33
34 import java.io.File;
35 import java.io.FileNotFoundException;
36 import java.io.IOException;
37 import java.util.List;
38
39 import org.apache.batik.transcoder.TranscoderException;
40 import org.apache.fop.svg.PDFTranscoder;
41 import org.geotools.geometry.DirectPosition2D;
42 import org.geotools.referencing.operation.DefaultMathTransformFactory;
43 import org.geotools.referencing.operation.projection.HotineObliqueMercator;
44 import org.opengis.geometry.DirectPosition;
45 import org.opengis.parameter.ParameterValueGroup;
46 import org.opengis.referencing.FactoryException;
47 import org.opengis.referencing.operation.MathTransformFactory;
48 import org.opengis.referencing.operation.TransformException;
49 import org.openimaj.image.FImage;
50 import org.openimaj.image.SVGImage;
51 import org.openimaj.image.VectorImageUtilities;
52 import org.openimaj.image.renderer.ImageRenderer;
53 import org.openimaj.image.renderer.RenderHints;
54 import org.openimaj.math.geometry.line.Line2d;
55 import org.openimaj.math.geometry.point.Point2d;
56 import org.openimaj.math.geometry.point.Point2dImpl;
57 import org.openimaj.math.geometry.shape.Polygon;
58 import org.openimaj.math.geometry.shape.Shape;
59 import org.openimaj.vis.world.WorldPlace;
60 import org.openimaj.vis.world.WorldPolygons;
61
62 public class DrawMap {
63
64 private static final File BASE = new File("/Users/ss/Experiments/placing");
65 private static final File DEFAULT_LAT_LNG_FILE = new File(BASE, "training_latlng");
66
67 private static final int GRID_WIDTH = 5;
68 private static final int BORDER_WIDTH = 4;
69 private static final Float[] BG_COLOUR = new Float[] { 30 / 255f, 32 / 255f, 78 / 255f };
70 private static final Float[] COUNTRY_BORDER_COLOUR = new Float[] { 90 / 255f, 90 / 255f, 140 / 255f };
71 private static final Float[] GRID_COLOUR = new Float[] { 70 / 255f, 70 / 255f, 78 / 255f };
72
73 public static void main(String[] args) throws FileNotFoundException, IOException, TransformException,
74 FactoryException, TranscoderException
75 {
76 System.out.println("Reading latlong");
77 final List<GeoLocation> lls = Utils.readLatLng(DEFAULT_LAT_LNG_FILE, new TLongArrayList());
78 System.out.println("...done");
79
80 final MathTransformFactory fact = new DefaultMathTransformFactory();
81 final ParameterValueGroup params = fact.getDefaultParameters("Hotine Oblique Mercator");
82 params.parameter("semi_major").setValue(6377397.155);
83 params.parameter("semi_minor").setValue(6356078.963);
84 params.parameter("longitude_of_center").setValue(7.439583333333333);
85 params.parameter("latitude_of_center").setValue(46.952405555555565);
86 params.parameter("azimuth").setValue(90.0);
87 params.parameter("scale_factor").setValue(1);
88 params.parameter("false_easting").setValue(600000.0);
89 params.parameter("false_northing").setValue(200000.0);
90 params.parameter("rectified_grid_angle").setValue(0.0);
91
92 final HotineObliqueMercator transform = (HotineObliqueMercator) fact.createParameterizedTransform(params);
93
94 double minx = 0;
95 double maxx = 0;
96 double miny = 0;
97 double maxy = 0;
98 for (int y = -90; y <= 90; y += 10) {
99 for (int x = -180; x <= 180; x += 10) {
100 final DirectPosition2D dp = new DirectPosition2D(x, y);
101
102 final double[] pt = transform.transform(dp, (DirectPosition) null).getCoordinate();
103
104 if (pt[0] > maxx)
105 maxx = pt[0];
106 if (pt[0] < minx)
107 minx = pt[0];
108 if (pt[1] > maxy)
109 maxy = pt[1];
110 if (pt[1] < miny)
111 miny = pt[1];
112 }
113 }
114
115
116
117 final SVGImage img = new SVGImage(10000, (int) (10000 * ((maxy - miny) / (maxx - minx))));
118 img.fill(BG_COLOUR);
119 final ImageRenderer<Float[], SVGImage> r = img.createRenderer(RenderHints.ANTI_ALIASED);
120 System.out.println("Rendering world");
121 final WorldPolygons wp = new WorldPolygons();
122 for (final WorldPlace place : wp.getShapes()) {
123 for (final Shape s : place.getShapes()) {
124 final Polygon p = transform(s.asPolygon(), transform, minx, maxx, miny, maxy, img.getWidth(),
125 img.getHeight()).asPolygon();
126
127 if (p.nVertices() < 2)
128 return;
129
130 Point2d p1, p2;
131 for (int i = 0; i < p.nVertices() - 1; i++) {
132 p1 = p.getVertices().get(i);
133 p2 = p.getVertices().get(i + 1);
134
135 if (Line2d.distance(p1, p2) < img.getHeight() / 2)
136 r.drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY(), BORDER_WIDTH, COUNTRY_BORDER_COLOUR);
137 }
138
139 p1 = p.getVertices().get(p.nVertices() - 1);
140 p2 = p.getVertices().get(0);
141 if (Line2d.distance(p1, p2) < img.getHeight() / 2)
142 r.drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY(), BORDER_WIDTH, COUNTRY_BORDER_COLOUR);
143 }
144 }
145 System.out.println("Preparing heatmap");
146 final FImage heatmap = new FImage(img.getWidth(), img.getHeight());
147 for (final GeoLocation ll : lls) {
148 final Point2dImpl pt = new Point2dImpl((float) ll.longitude, (float) ll.latitude);
149 final Point2dImpl tpt = transform(transform, minx, maxx, miny, maxy, heatmap.width, heatmap.height, pt);
150
151 final int tx = (int) tpt.x;
152 final int ty = (int) tpt.y;
153
154 if (tx >= 0 && tx < heatmap.width && ty >= 0 && ty < heatmap.height)
155 heatmap.pixels[ty][tx]++;
156 }
157
158 for (int y = 0; y < heatmap.height; y++) {
159 for (int x = 0; x < heatmap.width; x++) {
160 heatmap.pixels[y][x] = heatmap.pixels[y][x] == 0 ? 0 : (float) Math.log(heatmap.pixels[y][x]);
161 }
162 }
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 System.out.println("Writing image..");
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229 VectorImageUtilities.write(img, new File("/Users/ss/out.pdf"), new PDFTranscoder());
230 }
231
232 private static Shape transform(Polygon asPolygon, HotineObliqueMercator transform, double minx, double maxx,
233 double miny, double maxy, int width, int height) throws TransformException
234 {
235 final Polygon p = new Polygon();
236
237 for (final Point2d pt : asPolygon.points) {
238 final Point2dImpl pto = transform(transform, minx, maxx, miny, maxy, width, height, pt);
239
240 p.points.add(pto);
241 }
242
243 return p;
244 }
245
246 private static Point2dImpl transform(HotineObliqueMercator transform, double minx, double maxx, double miny,
247 double maxy, int width, int height, final Point2d pt) throws TransformException
248 {
249 final float x = pt.getX();
250 final float y = pt.getY();
251 final double[] c = transform.transform(new DirectPosition2D(x, y), (DirectPosition) null)
252 .getCoordinate();
253
254 final float px = (float) (width * (c[0] - minx) / (maxx - minx));
255 final float py = (float) (height - height * (c[1] - miny) / (maxy - miny));
256 final Point2dImpl pto = new Point2dImpl(px, py);
257 return pto;
258 }
259 }