geotools gaussian projection data source for WMS

88 views Asked by At

(Keyword: WMS, local Gaussian projection plane data source, Offset disorder) I am currently developing WMS using geotools, but the front-end request is EPSG4326, while my data source PostGIS stores Gaussian projection coordinates (EPSG: 2383). I tried to first convert the bbox rectangular area to local Gaussian projection coordinates (from 4236 longitude and latitude to 2383 plane projection), and then proceed with viewport mapping. However, when my width and height are fixed to 256 * 256 tiles, there will be a deviation in tile stitching. If the coordinates of the local data source are first converted to the corresponding 3857 web projection, and then bbox requests 3857 as well, there will be no offset. But I cannot convert all local data sources (this is a very bad design). May I ask everyone, is there any way to achieve this? thank you very much for your time!

My core code is as follows, but it will experience offset:

        double x1 = getMapDTO.getBbox()[0];
        double y1 = getMapDTO.getBbox()[1];
        double x2 = getMapDTO.getBbox()[2];
        double y2 = getMapDTO.getBbox()[3];
        // Here, first convert 4326 longitude and latitude to 3857 Mercator coordinates, and then use the four parameters to convert to 2383 plane coordinates
        Point1 =point1.transformMercatorToXy(2383);
        Point2 =point2.transformMercatorToXy(2383);
        x1 = wpgPoint1.getX();
        y1 = wpgPoint1.getY();
        x2 = wpgPoint2.getX();
        y2 = wpgPoint2.getY();
        Double[] box = new Double[]{x1, y1, x2, y2};
        getMapDTO.setBbox(box);
        //'''

        mapArea = new ReferencedEnvelope(x1, x2, y1, y2, CRS.decode("EPSG:2383"));
        map.getViewport().setBounds(new ReferencedEnvelope(mapArea, CRS.decode("EPSG:2383")));
        sr.setMapContent(map);
        // Initialize output image,width = 256, height=256
        BufferedImage bi = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bi.createGraphics();
        bi = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g.dispose();

The result of the code is that the line graph is distorted, like that:

enter image description here

I have tried to convert all PostGIS data sources to the corresponding 3857 Mercator coordinate system first, and then make a bbox3857 request. This will not cause an error, but converting all data sources is a bad design. I wonder if it is possible to directly solve the problem from bbox or other methods.


other information: I will provide a detailed introduction to the method of converting web mercator to a local coordinate system. Firstly, I obtained the plane coordinates of 3857 web mercator from the front-end framework (mapbox), then converted them to latitude and longitude (using the mercator2LonLat method), and then performed Gaussian projection (converting latitude and longitude coordinates to Gaussian projection plane coordinates based on the central longitude 114 of srid2383).Finally, convert the four parameters between the two coordinate systems to the local plane coordinates of srid2383 (using the following method fourParameterConversion).

public static double[] mercator2LonLat(double[] lonLat) {
        double x = lonLat[0] / 20037508.34 * 180;
        double y = lonLat[1] / 20037508.34 * 180;
        y = (180 / Math.PI) * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2);
        return new double[]{x, y};
}
private double[] fourParameterConversion(double x, double y) {
    //The so-called four parameters refer to the x-axis offset, y-axis offset, rotation, and scaling between two coordinate reference systems.
        FourParam fourParam = transformParam.getFourParam();

        double x_off = fourParam.getDx(), y_off = fourParam.getDy(), t = fourParam.getRotate(), m = fourParam.getScale();

        double x1 = x_off + (y * Math.cos(t) - x * Math.sin(t)) * m;
        double y1 = y_off + (x * Math.cos(t) + y * Math.sin(t)) * m;

        double[] xy = new double[]{Math.round(x1 * ROUNDING_FACTOR) / ROUNDING_FACTOR, Math.round(y1 * ROUNDING_FACTOR) / ROUNDING_FACTOR};

        return new double[]{xy[1], xy[0]};
    }

Follow up instructions: Even if I use the original conversion tools of geotools instead of using my own defined tools, the situation shown in the above picture will still occur. My conversion core code is as follows:

            CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326");
            ReferencedEnvelope envelope = new ReferencedEnvelope(x1, x2, y1, y2, sourceCRS);
            // Transform using 10 sample points around the envelope
            CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:2383");
            ReferencedEnvelope result = envelope.transform(targetCRS, true, 10);

            map.getViewport().setBounds(result);
            sr.setMapContent(map);
0

There are 0 answers