将包含 GeoJson FeatureCollection 的字符串 API 响应解析为 Angular 并将它们添加为带有传单地图弹出信息的图钉

Parse String API response containing GeoJson FeatureCollection to Angular and add them as pins with pop-up info on leaflet map

下面是将对象 (FeatureCollectionForGeoJson) 转换为 jsonStr 的服务方法 (JsonObjectBuilderService)。 Get RequestMapping中使用该服务方法向前端发送响应。

FeatureCollectionForGeoJson 对象是 class 映射到 GeoJson FeatureCollection。

GeometryForGeoJson 是另一个 class,它包含具有“Point”值的字符串类型和包含该点的纬度和经度的数组。

PropertyForGeoJson class 包含关于该图钉的 information/properties,当在地图上单击图钉时,该图钉将显示在弹出窗口中。

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class FeatureForGeoJson {

    private final String type = "Feature";
    private GeometryForGeoJson geometry;
    private PropertyForGeoJson properties;

}
@Service
public class JsonObjectBuilderService {

    public String transformObjectToGeoJson(FeatureCollectionForGeoJson featureCollectionForGeoJson){
        ObjectMapper Obj = new ObjectMapper();
        String jsonStr = null;
        try {
           jsonStr = Obj.writeValueAsString(featureCollectionForGeoJson);

        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } //catch (IOException e) {

        return jsonStr;
    }
}

这是将响应发送到 Angular

的 GetMapping
  @GetMapping("/power-plants")
    public ResponseEntity<String> getAllPowerPlants() {
        try {
            FeatureCollectionForGeoJson powerPlantsToFeatureCollectionForGeoJson ;
            //jpa query for the database to return the information
            List<PowerPlant> powerPlantList = powerPlantJpaService.findAll();
            
            if (powerPlantList.isEmpty()) {
                logger.info("The power plant list is empty.");
                return new ResponseEntity<>(HttpStatus.NO_CONTENT);
            }
            logger.info("The power plant list is populated and has been returned successfully.");

            powerPlantsToFeatureCollectionForGeoJson = transformPowerPlantsToFeaturesCollection.transformPowerPlantToGeoJsonElements(powerPlantList);

            String objectToGeoJson = jsonObjectBuilderService.transformObjectToGeoJson(powerPlantsToFeatureCollectionForGeoJson);
            logger.info(objectToGeoJson);

            return new ResponseEntity<>(objectToGeoJson, HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

这是响应在浏览器中的样子

这是获取响应的 Angular 方法。

这是 Angular 组件,我在其中调用获取响应的服务方法,以及我想将图钉添加到带有弹出窗口的地图的位置。

如何从 API(Home.component.ts 的第 27 行 - 右上方 - 或 PowerPlantService 的 getAll() 方法中获取响应) 并处理它以提取 Point Geometry,用它创建一个图钉并提取属性以添加到图钉的弹出窗口中?

如果你使用 angular 你应该使用 Observables 而不是 Promises,也避免使用 post 代码图像,现在我不能 copy/paste 你编码。

你想要做的是 return getAll() 中的一个可观察对象,像这样:

// in component
  this.powerPlantService.getAll$().subscribe(
      res => this.featureCollection = res,
      err => console.log(err)
    );
// in service
 getAll$(): Observable<any[]> {
    return this.http.get(baseUrl).pipe(
      map(data => {
        // transform your data here, or remove this pipe if you don't need it
        return data;
      })
    );
 }

您可以像这样在平面对象中变换特征:

return this.http.get(baseUrl).pipe(
      map(features => {
          return features.map(f => {
            const pointGeometry: any = {
                ...f.geometry,
                ...f.properties
            };
            return pointGeometry;
        });
      })
    );
      


如果你想知道后端如何格式化和发送响应,请查看问题正文。

下面是向后端执行GET请求的服务方法

export class PowerPlantService {
  constructor(private http: HttpClient) { }

  getAll() {
    return this.http.get(baseUrl);
  }

下面是订阅答案并将元素添加到地图的组件方法。

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  private latitude: number = 45.6427;
  private longitude: number = 25.5887;
   
  private map!: L.Map;
  private centroid: L.LatLngExpression = [this.latitude, this.longitude];

  ngOnInit(): void {
    this.initMap();
  }
  
  constructor(private powerPlantService: PowerPlantService) { 
  }

  private initMap(): void {
    this.map = L.map('map', {
      center: this.centroid,
      zoom: 2.8
    });

    const tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 
    {
      minZoom: 2.8,
      attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
    });

    tiles.addTo(this.map);
    
    this.powerPlantService.getAll().subscribe((data: any)=>{
      console.log(data);
      L.geoJSON(data).addTo(this.map) 
    })