update 3D graphic projection function

This commit is contained in:
wyq 2022-02-02 17:00:28 +08:00
parent 0a1dbfd5dd
commit 396c7b4474
7 changed files with 198 additions and 25 deletions

View File

@ -51,7 +51,7 @@ public class MapPlot3D extends Plot3DGL {
if (proj.equals(this.projInfo)) {
super.addGraphic(graphic);
} else {
Graphic nGraphic = ProjectionUtil.projectGraphic(graphic, proj, this.projInfo);
Graphic nGraphic = ProjectionUtil.projectClipGraphic(graphic, proj, this.projInfo);
super.addGraphic(nGraphic);
}
}

View File

@ -104,7 +104,7 @@ public class VolumeTest {
test.readData();
test.readColorMap();
VolumeGraphics graphics = test.createGraphics();
graphics.setRayCastingType(RayCastingType.MAX_VALUE);
graphics.setRayCastingType(RayCastingType.SPECULAR);
JFrame frame = new JFrame("Volume Test");
Plot3DGL plot = new Plot3DGL();
plot.setOrthographic(true);

View File

@ -55,7 +55,7 @@ public class GeoProjectionUtil {
* @param yy Y array
* @param fromProj From projection
* @param toProj To projection
* @return Porjected grid data
* @return Projected grid data
* @throws InvalidRangeException
*/
public static Object[] reprojectGrid(Array data, Array xx, Array yy, ProjectionInfo fromProj,

View File

@ -23,6 +23,7 @@ import org.meteoinfo.geometry.shape.*;
import org.meteoinfo.ndarray.Array;
import org.meteoinfo.ndarray.DataType;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -1502,11 +1503,15 @@ public class GeoComputation {
Collections.reverse(clipPList);
}
Polygon aPolygon = new Polygon();
aPolygon.setOutLine(new ArrayList<>(clipPList));
//aPolygon.setHoleLines(new ArrayList<List<PointD>>());
try {
Polygon aPolygon = inPolygon.getClass().getDeclaredConstructor().newInstance();
aPolygon.setOutLine(new ArrayList<>(clipPList));
//aPolygon.setHoleLines(new ArrayList<List<PointD>>());
newPolygons.add(aPolygon);
newPolygons.add(aPolygon);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
@ -1921,10 +1926,14 @@ public class GeoComputation {
if (pIdx == i) {
if (aPList.size() > 0) {
aPolygon = new Polygon();
aPolygon.setOutLine(new ArrayList<>(aPList));
//aPolygon.setHoleLines(new ArrayList<List<PointD>>());
aPolygonList.add(aPolygon);
try {
aPolygon = inPolygon.getClass().getDeclaredConstructor().newInstance();
aPolygon.setOutLine(new ArrayList<>(aPList));
//aPolygon.setHoleLines(new ArrayList<List<PointD>>());
aPolygonList.add(aPolygon);
} catch (Exception e) {
e.printStackTrace();
}
}
break;
}
@ -1992,11 +2001,15 @@ public class GeoComputation {
if (pIdx == i) {
if (aPList.size() > 0) {
aPolygon = new Polygon();
Collections.reverse(aPList);
aPolygon.setOutLine(new ArrayList<>(aPList));
//aPolygon.setHoleLines(new ArrayList<List<PointD>>());
aPolygonList.add(aPolygon);
try {
aPolygon = inPolygon.getClass().getDeclaredConstructor().newInstance();
Collections.reverse(aPList);
aPolygon.setOutLine(new ArrayList<>(aPList));
//aPolygon.setHoleLines(new ArrayList<List<PointD>>());
aPolygonList.add(aPolygon);
} catch (Exception e) {
e.printStackTrace();
}
}
break;
}

View File

@ -110,4 +110,16 @@ public class PolygonZShape extends PolygonShape {
((List<PolygonZ>)_polygons).add(aPolygon);
}
}
@Override
public PolygonShape valueClone() {
PolygonShape aPGS = new PolygonZShape();
aPGS.highValue = highValue;
aPGS.lowValue = lowValue;
aPGS.setVisible(this.isVisible());
aPGS.setSelected(this.isSelected());
aPGS.setLegendIndex(this.getLegendIndex());
return aPGS;
}
}

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MeteoInfo File="milconfig.xml" Type="configurefile">
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\3d_earth">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\bar"/>
<Path OpenPath="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\geoshow">
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\wrf"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart"/>
@ -12,21 +11,24 @@
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart\axis"/>
<RecentFolder Folder="D:\Temp\LaSW\script"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\bar"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\isosurface"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\volume"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d_earth"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\geoshow"/>
</Path>
<File>
<OpenedFiles>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\volume\volumeplot_2.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\volume\volumeplot_4.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\volume\volumeplot_1.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\geoshow\geoshow_proj.py"/>
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\geoshow\typhoon_map_volume.py"/>
</OpenedFiles>
<RecentFiles>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\volume\volumeplot_2.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\volume\volumeplot_4.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\volume\volumeplot_1.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\geoshow\geoshow_proj.py"/>
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl\geoshow\typhoon_map_volume.py"/>
</RecentFiles>
</File>
<Font>
@ -34,5 +36,5 @@
</Font>
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
<Figure DoubleBuffering="true"/>
<Startup MainFormLocation="-7,0" MainFormSize="1388,807"/>
<Startup MainFormLocation="-7,-7" MainFormSize="1293,685"/>
</MeteoInfo>

View File

@ -14,7 +14,9 @@
package org.meteoinfo.projection;
import org.meteoinfo.common.Extent;
import org.meteoinfo.common.MIMath;
import org.meteoinfo.common.PointD;
import org.meteoinfo.geometry.geoprocess.GeoComputation;
import org.meteoinfo.geometry.graphic.Graphic;
import org.meteoinfo.geometry.graphic.GraphicCollection;
import org.meteoinfo.geometry.shape.*;
@ -525,7 +527,7 @@ public class ProjectionUtil {
*
* @param aPGS A polygon shape
* @param fromProj From projection
* @param toProj To porjection
* @param toProj To projection
* @return Projected polygon shape
*/
public static PolygonShape projectPolygonShape(PolygonShape aPGS, ProjectionInfo fromProj, ProjectionInfo toProj) {
@ -635,6 +637,86 @@ public class ProjectionUtil {
}
}
/**
* Project polygon shape - clip the polygon is necessary
*
* @param aPGS A polygon shape
* @param fromProj From projection
* @param toProj To projection
* @return Projected polygon shape
*/
public static List<PolygonShape> projectClipPolygonShape(PolygonShape aPGS, ProjectionInfo fromProj, ProjectionInfo toProj) {
double refLon = toProj.getCoordinateReferenceSystem().getProjection().getProjectionLongitudeDegrees();
refLon += 180;
if (refLon > 180) {
refLon = refLon - 360;
} else if (refLon < -180) {
refLon = refLon + 360;
}
float cutoff = toProj.getCutoff();
List<PolygonShape> pgsList = new ArrayList<>();
if (fromProj.getProjectionName() == ProjectionNames.LongLat) {
switch (toProj.getProjectionName()) {
case Lambert_Conformal_Conic:
if (aPGS.getExtent().minY < cutoff) {
aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, cutoff, true);
}
break;
case North_Polar_Stereographic_Azimuthal:
if (aPGS.getExtent().minY < cutoff) {
//continue;
aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, cutoff, true);
}
break;
case South_Polar_Stereographic_Azimuthal:
if (aPGS.getExtent().maxY > cutoff) {
//continue;
aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, cutoff, false);
}
break;
case Mercator:
if (aPGS.getExtent().maxY > cutoff) {
aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, cutoff, false);
}
if (aPGS.getExtent().minY < -cutoff) {
aPGS = GeoComputation.clipPolygonShape_Lat(aPGS, -cutoff, true);
}
break;
}
if (aPGS == null) {
return null;
}
if (aPGS.getExtent().minX <= refLon && aPGS.getExtent().maxX >= refLon) {
switch (toProj.getProjectionName()) {
case North_Polar_Stereographic_Azimuthal:
case South_Polar_Stereographic_Azimuthal:
pgsList.add(aPGS);
break;
default:
pgsList.add(GeoComputation.clipPolygonShape_Lon(aPGS, refLon));
break;
}
} else {
pgsList.add(aPGS);
}
} else {
pgsList.add(aPGS);
}
List<PolygonShape> newPolygons = new ArrayList<>();
for (int i = 0; i < pgsList.size(); i++) {
aPGS = pgsList.get(i);
aPGS = projectPolygonShape(aPGS, fromProj, toProj);
if (aPGS != null) {
newPolygons.add(aPGS);
}
}
return newPolygons;
}
/**
* Project graphic
*
@ -660,7 +742,37 @@ public class ProjectionUtil {
}
}
public static GraphicCollection projectGraphic(GraphicCollection aGCollection, ProjectionInfo fromProj, ProjectionInfo toProj) {
/**
* Project graphic
*
* @param graphic The graphic
* @param fromProj From projection
* @param toProj To projection
* @return Projected graphic
*/
public static Graphic projectClipGraphic(Graphic graphic, ProjectionInfo fromProj, ProjectionInfo toProj) {
if (graphic instanceof GraphicCollection) {
GraphicCollection newGCollection = new GraphicCollection();
for (Graphic aGraphic : ((GraphicCollection) graphic).getGraphics()) {
List<? extends Shape> shapes = projectClipShape(aGraphic.getShape(), fromProj, toProj);
if (shapes != null) {
aGraphic.setShape(shapes.get(0));
newGCollection.add(aGraphic);
}
}
return newGCollection;
} else {
List<? extends Shape> shapes = projectClipShape(graphic.getShape(), fromProj, toProj);
if (shapes != null) {
return new Graphic(shapes.get(0), graphic.getLegend());
} else {
return null;
}
}
}
/*public static GraphicCollection projectGraphic(GraphicCollection aGCollection, ProjectionInfo fromProj, ProjectionInfo toProj) {
GraphicCollection newGCollection = new GraphicCollection();
for (Graphic aGraphic : aGCollection.getGraphics()) {
aGraphic.setShape(projectShape(aGraphic.getShape(), fromProj, toProj));
@ -670,7 +782,7 @@ public class ProjectionUtil {
}
return newGCollection;
}
}*/
public static List<Graphic> projectGraphic(List<Graphic> graphics, ProjectionInfo fromProj, ProjectionInfo toProj) {
List<Graphic> newGraphics = new ArrayList<>();
@ -721,6 +833,40 @@ public class ProjectionUtil {
return newShape;
}
private static List<? extends Shape> projectClipShape(Shape shape, ProjectionInfo fromProj, ProjectionInfo toProj) {
List<? extends Shape> shapes = null;
switch (shape.getShapeType()) {
case POINT:
case POINT_M:
//shapes = projectPointShape((PointShape) shape, fromProj, toProj);
break;
case POLYLINE:
case POLYLINE_M:
//shapes = projectPolylineShape((PolylineShape) shape, fromProj, toProj);
break;
case CURVE_LINE:
//shapes = projectCurvelineShape((CurveLineShape) shape, fromProj, toProj);
break;
case POLYGON:
case POLYGON_M:
case POLYGON_Z:
case RECTANGLE:
shapes = projectClipPolygonShape((PolygonShape) shape, fromProj, toProj);
break;
case CURVE_POLYGON:
//shapes = projectCurvePolygonShape((CurvePolygonShape) shape, fromProj, toProj);
break;
case CIRCLE:
//shapes = projectCircleShape((CircleShape) shape, fromProj, toProj);
break;
case ELLIPSE:
//shapes = projectEllipseShape((EllipseShape) shape, fromProj, toProj);
break;
}
return shapes;
}
private static CurveLineShape projectCurvelineShape(CurveLineShape aPLS, ProjectionInfo fromProj, ProjectionInfo toProj) {
List<Polyline> polyLines = new ArrayList<>();
for (int i = 0; i < aPLS.getPolylines().size(); i++) {