Home > Back-end >  Entity Framework CRUD operations with Openlayers Geometry object
Entity Framework CRUD operations with Openlayers Geometry object

Time:12-02

I am using Openlayers and trying to save the geometry information in my DB.

When i draw a polygon on openlayers map, the object(feature) generated is in this format

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

Above object has 2 properties. {type: string, coordinates: someNestedArray}

I am passing this object to my API to save it in DB. But am facing issue with defining type of coordinates property.

Basically it is of type float[][][] so i created my EF model class as below

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

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

when i try to get/update, EF is throwing below error

{"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'."}

the error is clear. EF cannot map these un-supported types on its own. How can i define a mapping explicitly ? Or is there any way i can make it work ? is the type float[][][] correct ?

Thanks in advance.

CodePudding user response:

You can always save coordinates as string where coordinates are separated by comma.

For instance in FE part you can handle it like this:

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

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

Then you will get something like this: "43.520548594674132,26.565803087473146;...." which can be saved to database as a string. (it can be additionally tweaked with fewer decimal points, etc..)

After that, if you want to handle/fetch data through API and map it via automapper(or some custom implementation)to List of Coordinates (for example something like this)

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

To map previously saved data to DTO you can use something like this

 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;
        }
    } 

With that you ll get the list of coordinates that will contain latitude and longitude and from which will you create geometry entity.

  • Related