1 /* -------------------------------------------------------------------
2 GeoVISTA Center (Penn State, Dept. of Geography)
3 Java source file for the class ShapeFileProjection
4 Copyright (c), 2002, GeoVISTA Center
5 All Rights Reserved.
6 Original Author: Frank Hardisty
7 $Author: hardisty $
8 $Id: ShapeFileProjection.java,v 1.10 2003/07/13 18:18:23 hardisty Exp $
9 $Date: 2003/07/13 18:18:23 $
10 Reference: Document no:
11 ___ ___
12 ------------------------------------------------------------------- *
13 */
14 package edu.psu.geovista.data.geog;
15
16 import edu.psu.geovista.app.map.*;
17
18 //import edu.psu.geovista.io.geog.*;
19 import java.awt.*;
20 import java.awt.event.*;
21 import java.awt.geom.*;
22 import java.awt.image.*;
23
24 import java.util.*;
25
26 import javax.swing.*;
27 import javax.swing.event.*;
28 import edu.psu.geovista.ui.event.DataSetEvent;
29 import edu.psu.geovista.ui.event.DataSetListener;
30
31 /***
32 * This class, when passed a ShapeFile, will project it using it's current
33 * projection. The original spatial data will not be changed. An ActionEvent will be
34 * fired as well. It will also project and fire an ActionEvent
35 * on being passed a new projection.
36 */
37 public class ShapeFileProjection
38 implements ActionListener {
39 private transient DataSetForApps inputDataSetForApps;
40 private transient DataSetForApps outputDataSetForApps;
41 private transient DataSetForApps inputAuxSpatialData;
42 private transient DataSetForApps outputAuxSpatialData;
43 private transient Projection proj;
44 private transient ProjectionEquidistantConic projEQ;
45 private EventListenerList listenerList;
46
47 //let's assume projections always get changed upon setting data sets.
48 //private transient boolean constantProjection = true;
49 private transient double[] boundingBox = null;
50
51 public ShapeFileProjection() {
52 super();
53
54 //proj = new ProjectionIdentity();
55 projEQ = new ProjectionEquidistantConic();
56 listenerList = new EventListenerList();
57 }
58
59 public Shape[] project(Shape[] shpFile) {
60 Shape[] shpNew = new Shape[shpFile.length];
61 int shapeType = 0;
62
63 switch (shapeType) {
64 //case ShapeFile.SHAPE_TYPE_POINT:
65 case 2:
66
67 //newData = projectPoints(oldData);
68 break;
69
70 // case ShapeFile.SHAPE_TYPE_POLYLINE:
71 // newData = projectPolylines(oldData);
72 //
73 // break;
74 case 0:
75 shpNew = projectPolygons(shpFile);
76
77 break;
78
79 default:
80 throw new IllegalArgumentException("ShapeFileProjection.project," +
81 " unknown file type");
82 }
83
84 return shpNew;
85 }
86
87 //todo: write me
88 private double[] findBBox(Shape[] shp) {
89 double minX;
90 double maxX;
91 double minY;
92 double maxY;
93 minX = Double.MAX_VALUE;
94 maxX = Double.MAX_VALUE * -1;
95 minY = Double.MAX_VALUE;
96 maxY = Double.MAX_VALUE * -1;
97
98 for (int i = 0; i < shp.length; i++) {
99 Shape sha = shp[i];
100 Rectangle2D rect = sha.getBounds2D();
101
102 if (rect.getMinX() < minX) {
103 minX = rect.getMinX();
104 }
105
106 if (rect.getMaxX() > maxX) {
107 maxX = rect.getMaxX();
108 }
109
110 if (rect.getMinY() < minY) {
111 minY = rect.getMinY();
112 }
113
114 if (rect.getMinY() > maxY) {
115 maxY = rect.getMinY();
116 }
117 }
118
119 //centralLat = bBox[1] + bBox[3];
120 //centralLong = bBox[0] + bBox[2];
121 double[] returnNums = new double[] {
122 minX, minY, maxX, maxY};
123
124 return returnNums;
125 }
126
127 private Projection initProjection(Shape[] shp) {
128 double[] bBox = null;
129
130 bBox = this.findBBox(shp);
131 this.boundingBox = bBox;
132
133 // boundingBox: {xMin, yMin, xMax, yMax, zMin, zMax, mMin, mMax}
134 double centralLat;
135
136 // boundingBox: {xMin, yMin, xMax, yMax, zMin, zMax, mMin, mMax}
137 double centralLong;
138
139 // boundingBox: {xMin, yMin, xMax, yMax, zMin, zMax, mMin, mMax}
140 double paraOne;
141
142 // boundingBox: {xMin, yMin, xMax, yMax, zMin, zMax, mMin, mMax}
143 double paraTwo;
144 centralLat = bBox[1] + bBox[3];
145 centralLat = centralLat / 2;
146 centralLat = Math.toRadians(centralLat);
147 centralLong = bBox[0] + bBox[2];
148 centralLong = centralLong / 2;
149 centralLong = Math.toRadians(centralLong);
150
151 double paraDist = bBox[3] - bBox[1];
152
153 //paraOne = centralLat - (paraDist * .25);
154 paraOne = bBox[1];
155 paraOne = Math.toRadians(paraOne);
156
157 //paraTwo = centralLat + (paraDist * .25);
158 paraTwo = bBox[3];
159 paraTwo = Math.toRadians(paraTwo);
160 projEQ.setCentralLatitude(centralLat);
161 projEQ.setCentralMeridian(centralLong);
162 projEQ.setStandardParallelOne(paraTwo);
163 projEQ.setStandardParallelTwo(paraOne);
164
165 return projEQ;
166 }
167
168 // private Vector projectPoints(Vector oldData) {
169 // Vector newData = new Vector();
170 // double xMax;
171 // double xMin;
172 // double yMax;
173 // double yMin;
174 //
175 // Point2D.Double pt = new Point2D.Double();
176 //
177 // for (Enumeration e = oldData.elements(); e.hasMoreElements();) {
178 // ShapeFileRecordPoint pointOld = (ShapeFileRecordPoint) e.nextElement();
179 //
180 // //xMax = Double.MAX_VALUE * -1;
181 // //xMin = Double.MAX_VALUE;
182 // //yMax = Double.MAX_VALUE * -1;
183 // //yMin = Double.MAX_VALUE;
184 // ShapeFileRecordPoint pointNew = new ShapeFileRecordPoint();
185 // double xVal = pointOld.getX();
186 // xVal = Math.toRadians(xVal);
187 //
188 // double yVal = pointOld.getY();
189 // yVal = Math.toRadians(yVal);
190 // this.proj.project(yVal, xVal, pt);
191 // pointNew.setX(pt.getX());
192 // pointNew.setY(pt.getY());
193 // newData.add(pointNew);
194 // }
195 //
196 // return newData;
197 // }
198 private Vector projectPolylines(Vector oldData) {
199 Vector newData = new Vector();
200
201 return newData;
202 }
203
204 private Shape[] projectPolygons(Shape[] oldData) {
205 Shape[] newData = new Shape[oldData.length];
206
207 for (int i = 0; i < oldData.length; i++) {
208 newData[i] = proj.project(oldData[i]);
209 }
210
211 return newData;
212 }
213
214 public void setInputDataSetForApps(DataSetForApps inputDataSet) {
215 if (inputDataSet != null) {
216 this.inputDataSetForApps = inputDataSet;
217 this.outputDataSetForApps = new DataSetForApps();
218
219 Object[] rawData = inputDataSet.getDataObjectOriginal();
220 Object[] newData = new Object[rawData.length];
221
222 for (int i = 0; i < rawData.length; i++) {
223 newData[i] = rawData[i];
224 }
225
226 //ShapeFile spatialData = inputDataSet.getShapeFileData();
227 Shape[] spatialData = inputDataSet.getShapeData();
228 proj = this.initProjection(spatialData);
229
230 int place = inputDataSet.getShapeDataPlace();
231 newData[place] = this.project(spatialData);
232 outputDataSetForApps.setDataObject(newData);
233 this.fireActionPerformed("projected data");
234 this.fireDataSetChanged(outputDataSetForApps.getDataObjectOriginal());
235 }
236 }
237
238 public DataSetForApps getOutputDataSetForApps() {
239 return this.outputDataSetForApps;
240 }
241
242 public Object[] getOutputDataSet() {
243 //System.out.println("ShapeFileProject.getOutputDataSet(), Hi!!");
244 return this.outputDataSetForApps.getDataObjectOriginal();
245 }
246
247 public void setInputDataSet(Object[] inputDataSet) {
248 if (inputDataSet != null) {
249 this.inputDataSetForApps = new DataSetForApps();
250 this.inputDataSetForApps.setDataObject(inputDataSet);
251 this.setInputDataSetForApps(this.inputDataSetForApps);
252 }
253 }
254
255 public void setInputAuxiliaryData(Object[] auxDataSet) {
256 if (auxDataSet != null) {
257 this.inputAuxSpatialData = new DataSetForApps();
258 this.inputAuxSpatialData.setDataObject(auxDataSet);
259 this.setInputAuxiliaryData(this.inputAuxSpatialData);
260 }
261 }
262
263 public void setInputAuxiliaryData(DataSetForApps auxDataSet) {
264 if (auxDataSet != null) {
265 this.inputAuxSpatialData = auxDataSet;
266 this.outputAuxSpatialData = new DataSetForApps();
267
268 Object[] rawData = auxDataSet.getDataObjectOriginal();
269 Object[] newData = new Object[rawData.length];
270
271 for (int i = 0; i < rawData.length; i++) {
272 newData[i] = rawData[i];
273 }
274
275 Shape[] spatialData = auxDataSet.getShapeData();
276 int place = inputAuxSpatialData.getShapeDataPlace();
277 newData[place] = this.project(spatialData);
278 outputAuxSpatialData.setDataObject(newData);
279 this.fireChangePerformed("projected aux data");
280
281 //this.fireActionPerformed("projected aux data");
282 }
283 }
284
285 public Object[] getOutputAuxiliarySpatialData() {
286 if (this.outputAuxSpatialData != null) {
287 return this.outputAuxSpatialData.getDataObjectOriginal();
288 }
289
290 return null;
291 }
292
293 public DataSetForApps getOutputAuxiliarySpatialDataForApps() {
294 return this.outputAuxSpatialData;
295 }
296
297 public void setProj(Projection proj) {
298 this.proj = proj;
299 }
300
301 public Projection getProj() {
302 return this.proj;
303 }
304
305 public void setListenerList(EventListenerList listenerList) {
306 this.listenerList = listenerList;
307 }
308
309 public EventListenerList getListenerList() {
310 return this.listenerList;
311 }
312
313 public void actionPerformed(ActionEvent e) {
314 Object obj = e.getSource();
315
316 //Package pack = obj.getClass().getPackage(); can't find package when we are an applet
317 String className = obj.getClass().getName();
318
319 //System.out.println(pack.getName());
320 if (className.equals("edu.psu.geovista.data.geog.GeoDataWestCoast") ||
321 className.equals("edu.psu.geovista.data.geog.GeoData48States")) {
322 if (e.getSource()instanceof GeoData48States) {
323 GeoData48States data = (GeoData48States) e.getSource();
324 this.setInputDataSet(data.getDataSet());
325 }
326 else if (e.getSource()instanceof GeoDataWestCoast) {
327 GeoDataWestCoast data = (GeoDataWestCoast) e.getSource();
328 this.setInputDataSet(data.getDataSet());
329 }
330 }
331 }
332
333 /***
334 * implements ActionListener
335 */
336 public void addActionListener(ActionListener l) {
337 listenerList.add(ActionListener.class, l);
338 }
339
340 /***
341 * removes an ActionListener from the button
342 */
343 public void removeActionListener(ActionListener l) {
344 listenerList.remove(ActionListener.class, l);
345 }
346
347 /***
348 * Notify all listeners that have registered interest for
349 * notification on this event type. The event instance
350 * is lazily created using the parameters passed into
351 * the fire method.
352 * @see EventListenerList
353 */
354 protected void fireActionPerformed(String command) {
355 // Guaranteed to return a non-null array
356 Object[] listeners = listenerList.getListenerList();
357 ActionEvent e = null;
358
359 // Process the listeners last to first, notifying
360 // those that are interested in this event
361 for (int i = listeners.length - 2; i >= 0; i -= 2) {
362 if (listeners[i] == ActionListener.class) {
363 // Lazily create the event:
364 if (e == null) {
365 e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, command);
366 }
367
368 ( (ActionListener) listeners[i + 1]).actionPerformed(e);
369 }
370 }
371 }
372
373 /***
374 * implements ChangeListener
375 */
376 public void addChangeListener(ChangeListener l) {
377 listenerList.add(ChangeListener.class, l);
378 }
379
380 /***
381 * removes an ChangeListener from the button
382 */
383 public void removeChangeListener(ChangeListener l) {
384 listenerList.remove(ChangeListener.class, l);
385 }
386
387 /***
388 * Notify all listeners that have registered interest for
389 * notification on this event type. The event instance
390 * is lazily created using the parameters passed into
391 * the fire method.
392 * @see EventListenerList
393 */
394 protected void fireChangePerformed(String command) {
395 // Guaranteed to return a non-null array
396 Object[] listeners = listenerList.getListenerList();
397 ChangeEvent e = null;
398
399 // Process the listeners last to first, notifying
400 // those that are interested in this event
401 for (int i = listeners.length - 2; i >= 0; i -= 2) {
402 if (listeners[i] == ChangeListener.class) {
403 // Lazily create the event:
404 if (e == null) {
405 e = new ChangeEvent(this);
406 }
407
408 ( (ChangeListener) listeners[i + 1]).stateChanged(e);
409 }
410 }
411 }
412
413 /***
414 * implements DataSetListener
415 */
416 public void addDataSetListener(DataSetListener l) {
417 listenerList.add(DataSetListener.class, l);
418 }
419
420 /***
421 * removes an DataSetListener from the button
422 */
423 public void removeDataSetListener(DataSetListener l) {
424 listenerList.remove(DataSetListener.class, l);
425 }
426
427 /***
428 * Notify all listeners that have registered interest for
429 * notification on this event type. The event instance
430 * is lazily created using the parameters passed into
431 * the fire method.
432 * @see EventListenerList
433 */
434 protected void fireDataSetChanged(Object[] dataSet) {
435 //System.out.println("ShpToShp.fireDataSetChanged, Hi!!");
436 // Guaranteed to return a non-null array
437 Object[] listeners = listenerList.getListenerList();
438 DataSetEvent e = null;
439 // Process the listeners last to first, notifying
440 // those that are interested in this event
441 for (int i = listeners.length - 2; i >= 0; i -= 2) {
442 if (listeners[i] == DataSetListener.class) {
443 // Lazily create the event:
444 if (e == null) {
445 e = new DataSetEvent(this, dataSet);
446
447 }
448 ( (DataSetListener) listeners[i + 1]).dataSetChanged(e);
449 }
450 }
451 }
452
453 }
This page was automatically generated by Maven