【问题标题】:Entity Framework CRUD operations with Openlayers Geometry object使用 Openlayers Geometry 对象的实体框架 CRUD 操作
【发布时间】:2021-11-24 14:55:41
【问题描述】:

我正在使用 Openlayers 并尝试将几何信息保存在我的数据库中。

当我在 openlayers 地图上绘制多边形时,生成的对象(特征)就是这种格式

{
 "type": "Polygon",
    "coordinates": [
      [
        [
          54.86572265625,
          74.0013854318592
        ],
        [
          53.59130859375,
          73.62159408606237
        ],
        [
          53.96484375,
          73.16953636227885
        ],
        [
          55.986328125,
          73.59679245247814
        ]
      ]
    ]
  }

上面的对象有 2 个属性。 {type: string, coordinates: someNestedArray}

我将此对象传递给我的 API 以将其保存在数据库中。但是在定义坐标属性类型时遇到了问题。

基本上它是 float[][][] 类型,所以我创建了我的 EF 模型类,如下所示

public class Geometry
  {
     public string Type { get; set; }

     public float[][][] Coordinates { get; set; }
  }

当我尝试获取/更新时,EF 抛出错误

{"The property 'Geometry.Coordinates' could not be mapped, because it is of type 'float[][][]'
 which is not a supported primitive type or a valid entity type. Either explicitly map this property, 
or ignore it using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'."}

错误很明显。 EF 无法自行映射这些不受支持的类型。如何明确定义映射?或者有什么办法可以让它工作吗? float[][][] 类型正确吗?

提前致谢。

【问题讨论】:

  • 数组的深度取决于Type的值。对于 MultiPolygon,它是 [][][][],而对于 Point,它是 []
  • @Mike 感谢您的回复。我的要求仅适用于多边形。

标签: entity-framework entity-framework-core openlayers


【解决方案1】:

您始终可以将坐标保存为字符串,其中坐标用逗号分隔。

例如在 FE 部分你可以这样处理:

        const someLine =  feature.getGeometry().transform("EPSG:4326", 
                        "EPSG:3857");
   
        const geometryLine = someLine
          .clone()
          .getGeometry()
          .transform("EPSG:3857", "EPSG:4326");

        const geometryCoords = geometryLine.getCoordinates().join(";");

然后你会得到这样的东西:“43.520548594674132,26.565803087473146;....”可以作为字符串保存到数据库中。 (还可以用更少的小数点等进行额外调整。)

之后,如果您想通过 API 处理/获取数据并通过自动映射器(或一些自定义实现)将其映射到坐标列表(例如这样的东西)

 public class Coordinates
    {
        public double Longitude { get; set; }
        public double Latitude { get; set; }
    }

要将以前保存的数据映射到 DTO,您可以使用类似的东西

 public class GeneralProfile : Profile
   {
        public GeneralProfile()
        {
            CreateMap<Route, GetSavedRouteDTO>()
                .ForMember(x => x.TripLength, options => options.MapFrom(x => x.Length))
                .ForMember(x => x.RouteCoordinates, options => options.MapFrom(MapFromStringCoordinates));
            CreateMap<Route, RouteCreateDTO>().ReverseMap();
        }


        private List<Coordinates> MapFromStringCoordinates(Route route, GetSavedRouteDTO getSavedRouteDTO)
        {

            var currentCulture = System.Globalization.CultureInfo.InstalledUICulture;
            var numberFormat = (System.Globalization.NumberFormatInfo)currentCulture.NumberFormat.Clone();
            numberFormat.NumberDecimalSeparator = ".";

            var coordinates = new List<Coordinates>();
            var coordinatesSplit = route.Coordinates.Split(";");

            foreach (var coord in coordinatesSplit)
            {
                var currentCoord = coord.Split(","); 
                if (currentCoord.Length > 1)
                {
                    var latitude = double.Parse(currentCoord[0], numberFormat);
                    var longitude = double.Parse(currentCoord[1], numberFormat);
                    var coords= new Coordinates { Latitude = latitude, Longitude = longitude };

                    coordinates.Add(coords);
                }
            }

            return coordinates;
        }
    } 

您将获得包含纬度和经度的坐标列表,您将从该列表中创建几何实体。

【讨论】:

  • 我不能直接序列化我的坐标并保存吗?然后在取回它的同时反序列化?
  • 是的,没错,有多种方法可以做到这一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-25
相关资源
最近更新 更多