将地图坐标转换为屏幕

时间:2017-03-10 19:46:49

标签: java gis shapefile

我正在尝试将世界坐标转换为像素坐标。问题是,有些文件(shapefile)不能正常转换。线条倾斜或移动,它们看起来应该与我加载文件时完全一样。

我转换线条的原因是因为它需要在Adobe Illustrator中显示,并且法线贴图要大得多以便正确显示。

有更好的方法可以更可靠地将世界坐标转换为屏幕坐标吗? (convertLines方法是发生所有转换的地方)

    ArrayList<FeatureLine> temp = new ArrayList();

    public static void main(String[] args) throws Exception {

        MCV_TestProgram test = new MCV_TestProgram();
    }

    public MCV_TestProgram() {
        temp.add(new FeatureLine("2466308.97 709571.48, 2466306.03 709566.79", 0));
        temp.add(new FeatureLine("2466800.14 710357.15, 2466308.97 709571.48", 1));
        temp.add(new FeatureLine("2456506.25 707356.2, 2456487.75 707715.23, 2456450.68 707809.01", 2));
        temp.add(new FeatureLine("2324352.2 669626.61, 2324365.6 669328.81, 2324146.77 669316.22, 2324165.41 669264.1, 2324174.26 669057.93, 2324192.39 668895.68, 2324211.04 668561.95, 2324219.11 668494.04, 2324230.7 668370.9, 2324247.66 668128.16, 2324260.89 667951.94, 2324268.86 667848.91, 2324278.83 667705.33, 2324289.97 667508.67", 3));

        convertLines(temp);
    }

    // Converts map lines to fit in smaller window (mainly for Adobe Illustrator)
    private ArrayList<FeatureLine> convertLines(ArrayList<FeatureLine> lines) {
        ArrayList<FeatureLine> convertedCoords = new ArrayList();

        try {
            Rectangle imageBounds = new Rectangle(250, 200, 1000, 800);
            CoordinateReferenceSystem crs = createCRS();
            ReferencedEnvelope mapBounds = new ReferencedEnvelope(2104208.77, 2595754.33, 500627.08, 1286916.23, crs);
            AffineTransform world2screen = createTransform(mapBounds, imageBounds);

            for (FeatureLine coord : lines) {
                Point2D screenCoordStart = world2screen.transform(coord.StartPoint, null);
                Point2D screenCoordEnd = world2screen.transform(coord.EndPoint, null);

                if (coord.StartPoint.x != 0.0) {
                    convertedCoords.add(new FeatureLine(screenCoordStart, screenCoordEnd));
                }
            }
        } catch (FactoryException | MismatchedDimensionException ex) {
            Logger.getLogger(MCV_TestProgram.class.getSimpleName()).log(Level.SEVERE, "Error occured while converting lines", ex);
        }

        return convertedCoords;
    }

    // Custom line class to store line data, StartPoint and Endpoint (coordinates)
    // of one unbreaking line.
    public class FeatureLine {

        private Point2D.Double StartPoint = new Point2D.Double();
        private Point2D.Double EndPoint = new Point2D.Double();

        public FeatureLine(double x1, double y1, double x2, double y2) {
            StartPoint.x = x1;
            StartPoint.y = y1;
            EndPoint.x = x2;
            EndPoint.y = y2;
        }

        public FeatureLine(Point2D.Double start, Point2D.Double end) {
            StartPoint = start;
            EndPoint = end;
        }

        public FeatureLine(Point2D start, Point2D end) {
            StartPoint = (Point2D.Double) start;
            EndPoint = (Point2D.Double) end;
        }

        public FeatureLine(String parseString, int index) {

            String latlon[];
            String xy1[];
            String xy2[];

            double x1, y1;
            double x2, y2;

            try {
                if (!parseString.equals("")) {
                    latlon = parseString.split(",");

                    xy1 = latlon[0].split(" ");
                    xy2 = latlon[1].replaceFirst(" ", "").split(" ");

                    x1 = Double.parseDouble(xy1[0]);
                    y1 = Double.parseDouble(xy1[1]);

                    x2 = Double.parseDouble(xy2[0]);
                    y2 = Double.parseDouble(xy2[1]);

                    StartPoint.x = x1;
                    StartPoint.y = y1;

                    EndPoint.x = x2;
                    EndPoint.y = y2;
                }
            } catch (Exception ex) {
                logger.log(Level.SEVERE, "Error occured while creating line at: " + index + " ", ex);
            }
        }

        public double getX(int index) {
            if (index == 0) {
                return StartPoint.x;
            } else {
                return EndPoint.x;
            }
        }

        public double getY(int index) {
            if (index == 0) {
                return StartPoint.y;
            } else {
                return EndPoint.y;
            }
        }

        public void setX(double x, int index) {
            if (index == 0) {
                StartPoint.x = x;
            } else {
                EndPoint.x = x;
            }
        }

        public void setY(double y, int index) {
            if (index == 0) {
                StartPoint.y = y;
            } else {
                EndPoint.y = y;
            }
        }

        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();

            return (builder.append(String.valueOf(StartPoint.x)).append(" ").append(String.valueOf(StartPoint.y)).append(", ")
                    .append(String.valueOf(EndPoint.x)).append(" ").append(String.valueOf(EndPoint.y))).toString();
        }
    }

    /**
    * Uses the window's aspect ratio to choose a scale factor for the map,
    * and constructs an AffineTransform to scale the shapefile's contents.
    */
    private AffineTransform createTransform(ReferencedEnvelope mapEnvelope, Rectangle imageBounds) {
        double mapWidth = mapEnvelope.getWidth();
        double mapHeight = mapEnvelope.getHeight();
        double imageWidth = imageBounds.getWidth();
        double imageHeight = imageBounds.getHeight();
        double sx = imageWidth / mapWidth;
        double sy = imageHeight / mapHeight;
        double aspectRatio = mapWidth / mapHeight;
        double scale = aspectRatio < 1 ? sy : sx;
        AffineTransform m = new AffineTransform();
        m.scale(scale, scale);
        return m;
    }

    // Create CRS from custom data
    private CoordinateReferenceSystem createCRS() throws FactoryException {

        String wkt = "PROJCS[\"NAD_1983_Michigan_GeoRef_Feet_US\"," +
            "GEOGCS[\"GCS_North_American_1983\"," +
            "DATUM[\"D_North_American_1983\"," +
            "SPHEROID[\"GRS_1980\", 6378137.0, 298.257222101]]," +
            "PRIMEM[\"Greenwich\", 0.0]," +
            "UNIT[\"degree\", 0.017453292519943295]," +
            "AXIS[\"Longitude\", EAST]," +
            "AXIS[\"Latitude\", NORTH]]," +
            "PROJECTION[\"Hotine_Oblique_Mercator\"]," +
            "PARAMETER[\"longitude_of_center\", -86.0]," +
            "PARAMETER[\"latitude_of_center\", 45.30916666666666]," +
            "PARAMETER[\"azimuth\", 337.25555555555593]," +
            "PARAMETER[\"scale_factor\", 0.9996]," +
            "PARAMETER[\"false_easting\", 8355401.583000001]," +
            "PARAMETER[\"false_northing\", -14284780.538]," +
            "PARAMETER[\"rectified_grid_angle\", 337.25555555555593]," +
            "UNIT[\"foot_survey_us\", 0.3048006096012192]," +
            "AXIS[\"X\", EAST]," +
            "AXIS[\"Y\", NORTH]]";

        CRSFactory crsFactory = ReferencingFactoryFinder.getCRSFactory(null);
        CoordinateReferenceSystem crs = crsFactory.createFromWKT(wkt);

        return crs;
    }

0 个答案:

没有答案