Home > front end >  Mapping a Point to latitude and longitude with mapstruct
Mapping a Point to latitude and longitude with mapstruct

Time:02-02

I have this Model:

import org.locationtech.jts.geom.Point;

@Entity
@Table(name = "t_hotel")
public class THotel {
    private String name;
    private Point coordinates;
}

And I want this DTO

public class HotelDTO {
    private String nome;
    private Double latitude;
    private Double longitude;
}

How do I map with mapstruct the two?

CodePudding user response:

I did not get deep into org.locationtech.jts.geom.Point class, but I hope it will help. Assume Point.java looks like:

public class Point {
    private Double latitude;
    private Double longitude;

    // constructors and getters/setters present here
}

In this case mapper will look like:

@Mapper(componentModel = "spring")
public interface THotelMapper {

    @Mapping(source = "nome", target = "name")
    @Mapping(expression = "java(toPoint(dto))", target = "coordinates")
    THotel mapToEntity(HotelDTO dto);

    @Mapping(source = "name", target = "nome")
    @Mapping(expression = "java(tHotel.getCoordinates().getLatitude())", target = "latitude")
    @Mapping(expression = "java(tHotel.getCoordinates().getLongitude())", target = "longitude")
    HotelDTO mapToDto(THotel tHotel);

    default Point toPoint(HotelDTO dto) {
        // here you need to set latitude and longitude to Point some how
        return new Point(dto.getLatitude(),dto.getLongitude());
    }
}

CodePudding user response:

You can have mapstruct pass additional arguments on to following mapping actions. In this case I've marked the additional fields as context (org.mapstruct.Context) fields, so that they will not automatically be used for mapping into THotel:

@Mapper(componentModel = "spring")
interface THotelMapper {

    @Mapping(source = "nome", target = "name")
    @Mapping(source = ".", target = "coordinates")
    THotel mapToEntity(HotelDTO dto, @Context PrecisionModel precisionModel, @Context int SRID);

    @Mapping(source = "name", target = "nome")
    @Mapping(source = "coordinates.y", target = "latitude")
    @Mapping(source = "coordinates.x", target = "longitude")
    HotelDTO mapToDto(THotel tHotel);

    default Point toPoint(HotelDTO dto, @Context PrecisionModel precisionModel, @Context int SRID) {
        return new Point(new Coordinate(dto.getLongitude(), dto.getLatitude()), precisionModel, SRID);
    }
}

Or you can do as Egor mentioned and then use default values:

@Mapper(componentModel = "spring")
interface THotelMapper {

    @Mapping(source = "nome", target = "name")
    @Mapping(source = ".", target = "coordinates")
    THotel mapToEntity(HotelDTO dto);

    @Mapping(source = "name", target = "nome")
    @Mapping(source = "coordinates.y", target = "latitude")
    @Mapping(source = "coordinates.x", target = "longitude")
    HotelDTO mapToDto(THotel tHotel);

    default Point toPoint(HotelDTO dto) {
        return new Point( new Coordinate( dto.getLongitude(), dto.getLatitude() ), new PrecisionModel(), 4326 );
    }
}

Also I noticed that the Point constructor was marked deprecated, so here is a version without that constructor:

@Mapper(componentModel = "spring")
interface THotelMapper {

    @Mapping(source = "nome", target = "name")
    @Mapping(source = ".", target = "coordinates")
    THotel mapToEntity(HotelDTO dto, @Context GeometryFactory geomFactory);

    @Mapping(source = "name", target = "nome")
    @Mapping(source = "coordinates.y", target = "latitude")
    @Mapping(source = "coordinates.x", target = "longitude")
    HotelDTO mapToDto(THotel tHotel);

    default Point toPoint(HotelDTO dto, @Context GeometryFactory geomFactory) {
        return geomFactory.createPoint( new Coordinate( dto.getLongitude(), dto.getLatitude() ) );
    }
}

ps. I do hope that I didn't get the longitude/latitude to x/y mixed up, but you can read about that here.

  •  Tags:  
  • Related