[地图]仿射变换矩阵

来源:互联网 发布:rimworld mac a14 编辑:程序博客网 时间:2024/05/18 02:34

(1)前言

公司使用了仿射变换来完成两个坐标系的转换。所有记录一下踩过的坑。


(2)什么是仿射变换

这个链接解释的很好:http://www.cnblogs.com/ghj1976/p/5199086.html


(3)Java mvn 配置

<dependency>  <groupId>com.vividsolutions</groupId>  <artifactId>jts</artifactId>  <version>1.13</version></dependency>


(4)java代码

import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import com.vividsolutions.jts.geom.Coordinate;import com.vividsolutions.jts.geom.GeometryFactory;import com.vividsolutions.jts.geom.Point;import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence;import com.vividsolutions.jts.geom.util.AffineTransformation;import com.vividsolutions.jts.geom.util.AffineTransformationBuilder;import com.vividsolutions.jts.geom.util.NoninvertibleTransformationException;import com.wanda.map.data.domain.po.ImapAffinePointInfo;import org.apache.commons.io.IOUtils;import org.geojson.Feature;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.math.BigDecimal;import java.text.DecimalFormat;import java.text.SimpleDateFormat;import java.util.*;private static Coordinate createCoordinate(BigDecimal x, BigDecimal y) {Coordinate coor = new Coordinate(x.doubleValue(), y.doubleValue());return coor;}private static DecimalFormat createDecimalFormat(){DecimalFormat decimalFormat = new DecimalFormat("##0.########");return decimalFormat;}public static boolean affineTransTst(ImapAffinePointInfo imapAffinePointInfo) {Coordinate s1 = createCoordinate(imapAffinePointInfo.getCoorM1X(), imapAffinePointInfo.getCoorM1Y());Coordinate s2 = createCoordinate(imapAffinePointInfo.getCoorM2X(), imapAffinePointInfo.getCoorM2Y());Coordinate s3 = createCoordinate(imapAffinePointInfo.getCoorM3X(), imapAffinePointInfo.getCoorM3Y());Coordinate t1 = createCoordinate(imapAffinePointInfo.getCoorR1X(), imapAffinePointInfo.getCoorR1Y());Coordinate t2 = createCoordinate(imapAffinePointInfo.getCoorR2X(), imapAffinePointInfo.getCoorR2Y());Coordinate t3 = createCoordinate(imapAffinePointInfo.getCoorR3X(), imapAffinePointInfo.getCoorR3Y());// 建立仿射变换对象AffineTransformationBuilder afb = new AffineTransformationBuilder(s1, s2, s3, t1, t2, t3);AffineTransformation atf = afb.getTransformation();double[] ddd = atf.getMatrixEntries();StringBuilder stringBuilder = new StringBuilder();for (double d : ddd) {stringBuilder.append(createDecimalFormat().format(d)).append(" ");}imapAffinePointInfo.setMtrFormulaPara(stringBuilder.toString());DecimalFormat decimalFormat = createDecimalFormat();List<Feature> featureList = new ArrayList<>();try {AffineTransformation atf2 = atf.getInverse();List<AffineModle> affineModleList = parseFile(filePath);int id = 1;for (AffineModle affineModle : affineModleList) {double[] dd = new double[2];dd[0] = affineModle.getX();dd[1] = affineModle.getY();Point pointReuslt = new Point(new PackedCoordinateSequence.Double(dd,2), new GeometryFactory());//System.out.println("相对坐标  : " +pointReuslt.getX() + " "+ pointReuslt.getY());pointReuslt.apply(atf2);//System.out.println("墨卡托坐标: " + pointReuslt.getX() + " "+ pointReuslt.getY());affineModle.setFormatX(decimalFormat.format(pointReuslt.getX()));affineModle.setFormatY(decimalFormat.format(pointReuslt.getY()));                Date date = new Date(Long.parseLong(affineModle.getTime()+"000"));                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");                GeoMercatorUtil.Point p = GeoMercatorUtil.mercator2lonLat(affineModle.getFormatX(), affineModle.getFormatY());                affineModle.setFormatX(p.getXStr());                affineModle.setFormatY(p.getYStr());//                System.out.println(affineModle.getPlaza() + "," + affineModle.getFormatX() + "," + affineModle.getFormatY()                        + "," + affineModle.getFloor()+ "," +  sdf.format(date));                Feature f = new Feature();                Map<String, Object> props = new HashMap<>();                props.put("x", affineModle.getFormatX());                props.put("y", affineModle.getFormatY());                props.put("time", affineModle.getTime());                props.put("floor", affineModle.getFloor());                props.put("plaza", affineModle.getPlaza());                props.put("id", id);                id ++;                f.setProperties(props);                org.geojson.Point pp = new org.geojson.Point(Double.parseDouble(affineModle.getFormatX()),                        Double.parseDouble(affineModle.getFormatY()));                f.setGeometry(pp);                featureList.add(f);}            JsonModle jsonModle = new JsonModle();jsonModle.setFeatures(featureList);jsonModle.setName("user_lbs_track");jsonModle.setType("FeatureCollection");            ObjectMapper objectMapper = new ObjectMapper();            String sss = null;            try {                sss = objectMapper.writeValueAsString(jsonModle);                try {                    IOUtils.write(sss, new FileOutputStream(new File(filePatha)), "UTF-8");                } catch (IOException e) {                    e.printStackTrace();                }            } catch (JsonProcessingException e) {                e.printStackTrace();            }/* String sss =JSON.toJSONString(jsonModle); */        } catch (NoninvertibleTransformationException e) {logger.error("affine变换错误." + e.getMessage(), e);return false;}return true;}


ImapAffinePointInfo类,就是简单的POJO对象, 使用了BigDecimal对象表示坐标值x和y。